From 2cf48bc32cfcd577cd5233ed33757de103ef8f40 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Tue, 13 Jun 2023 11:15:18 -0700 Subject: [PATCH 01/99] GekkoDisassembler: Remove unread variable m_type Writes to m_type are pointless because it's never read. --- Source/Core/Common/GekkoDisassembler.cpp | 7 ------- Source/Core/Common/GekkoDisassembler.h | 1 - 2 files changed, 8 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index 8d849b35c5..17db752b7b 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -153,7 +153,6 @@ u32* GekkoDisassembler::m_instr = nullptr; u32* GekkoDisassembler::m_iaddr = nullptr; std::string GekkoDisassembler::m_opcode; std::string GekkoDisassembler::m_operands; -unsigned char GekkoDisassembler::m_type = 0; unsigned char GekkoDisassembler::m_flags = PPCF_ILLEGAL; unsigned short GekkoDisassembler::m_sreg = 0; u32 GekkoDisassembler::m_displacement = 0; @@ -385,8 +384,6 @@ std::string GekkoDisassembler::imm(u32 in, int uimm, int type, bool hex) { int i = (int)(in & 0xffff); - m_type = PPCINSTR_IMM; - if (uimm == 0) { if (i > 0x7fff) @@ -587,7 +584,6 @@ void GekkoDisassembler::bc(u32 in) else m_operands = fmt::format("{} ->0x{:08X}", m_operands, *m_iaddr + d); - m_type = PPCINSTR_BRANCH; m_displacement = d; } @@ -605,7 +601,6 @@ void GekkoDisassembler::bli(u32 in) else m_operands = fmt::format("->0x{:08X}", *m_iaddr + d); - m_type = PPCINSTR_BRANCH; m_displacement = d; } @@ -931,7 +926,6 @@ void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg, unsigned c int a = (int)PPCGETA(in); int d = (u32)(in & 0xffff); - m_type = PPCINSTR_LDST; m_flags |= dmode; m_sreg = (short)a; // if (d >= 0x8000) @@ -1276,7 +1270,6 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) m_opcode.clear(); m_operands.clear(); - m_type = PPCINSTR_OTHER; m_flags = 0; switch (PPCGETIDX(in)) diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index 34991a28c4..40ca3380b3 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -112,7 +112,6 @@ private: static u32* m_iaddr; // Instruction.address., usually the same as instr static std::string m_opcode; // Buffer for opcode, min. 10 chars. static std::string m_operands; // Operand buffer, min. 24 chars. - static unsigned char m_type; // Type of instruction, see below static unsigned char m_flags; // Additional flags static unsigned short m_sreg; // Register in load/store instructions static u32 m_displacement; // Branch- or load/store displacement From 2472269d06dfe7fac7a0eb206673e790e2016fe7 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Tue, 13 Jun 2023 11:16:39 -0700 Subject: [PATCH 02/99] GekkoDisassembler: Remove unused enum InstructionType --- Source/Core/Common/GekkoDisassembler.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index 40ca3380b3..b7a6e7bf5f 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -92,14 +92,6 @@ private: static u32* DoDisassembly(bool big_endian); - enum InstructionType - { - PPCINSTR_OTHER = 0, // No additional info for other instr. - PPCINSTR_BRANCH = 1, // Branch dest. = PC+displacement - PPCINSTR_LDST = 2, // Load/store instruction: displ(sreg) - PPCINSTR_IMM = 3, // 16-bit immediate val. in displacement - }; - enum Flags { PPCF_ILLEGAL = (1 << 0), // Illegal PowerPC instruction From 3627398cf53056341701f8e9d846d14c92c77a16 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 10 Jun 2023 12:35:36 -0500 Subject: [PATCH 03/99] VideoBackends: support multiple compute images for some backends (D3D, OGL, Vulkan) --- Source/Core/VideoBackends/D3D/D3DGfx.cpp | 5 +- Source/Core/VideoBackends/D3D/D3DGfx.h | 2 +- Source/Core/VideoBackends/D3D/D3DState.cpp | 9 ++-- Source/Core/VideoBackends/D3D/D3DState.h | 10 ++-- Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp | 2 +- Source/Core/VideoBackends/D3D12/D3D12Gfx.h | 2 +- Source/Core/VideoBackends/Metal/MTLGfx.h | 2 +- Source/Core/VideoBackends/Metal/MTLGfx.mm | 2 +- Source/Core/VideoBackends/OGL/OGLGfx.cpp | 25 ++++++---- Source/Core/VideoBackends/OGL/OGLGfx.h | 4 +- .../Vulkan/CommandBufferManager.cpp | 5 +- Source/Core/VideoBackends/Vulkan/Constants.h | 7 ++- .../Core/VideoBackends/Vulkan/ObjectCache.cpp | 21 +++++++-- .../VideoBackends/Vulkan/ShaderCompiler.cpp | 4 +- .../VideoBackends/Vulkan/StateTracker.cpp | 46 +++++++++++++------ .../Core/VideoBackends/Vulkan/StateTracker.h | 5 +- Source/Core/VideoBackends/Vulkan/VKGfx.cpp | 6 +-- Source/Core/VideoBackends/Vulkan/VKGfx.h | 2 +- Source/Core/VideoCommon/AbstractGfx.h | 2 +- Source/Core/VideoCommon/Constants.h | 3 +- Source/Core/VideoCommon/TextureCacheBase.cpp | 2 +- 21 files changed, 107 insertions(+), 59 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/D3DGfx.cpp b/Source/Core/VideoBackends/D3D/D3DGfx.cpp index a4d1f5b8b9..27b4f0a4a0 100644 --- a/Source/Core/VideoBackends/D3D/D3DGfx.cpp +++ b/Source/Core/VideoBackends/D3D/D3DGfx.cpp @@ -239,9 +239,10 @@ void Gfx::SetSamplerState(u32 index, const SamplerState& state) D3D::stateman->SetSampler(index, m_state_cache.Get(state)); } -void Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) +void Gfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) { - D3D::stateman->SetComputeUAV(texture ? static_cast(texture)->GetD3DUAV() : nullptr); + D3D::stateman->SetComputeUAV(index, + texture ? static_cast(texture)->GetD3DUAV() : nullptr); } void Gfx::UnbindTexture(const AbstractTexture* texture) diff --git a/Source/Core/VideoBackends/D3D/D3DGfx.h b/Source/Core/VideoBackends/D3D/D3DGfx.h index e23867e73b..07c47e93af 100644 --- a/Source/Core/VideoBackends/D3D/D3DGfx.h +++ b/Source/Core/VideoBackends/D3D/D3DGfx.h @@ -52,7 +52,7 @@ public: void SetScissorRect(const MathUtil::Rectangle& rc) override; void SetTexture(u32 index, const AbstractTexture* texture) override; void SetSamplerState(u32 index, const SamplerState& state) override; - void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) override; + void SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) override; void UnbindTexture(const AbstractTexture* texture) override; void SetViewport(float x, float y, float width, float height, float near_depth, float far_depth) override; diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp index 06f01792f5..0372252b9a 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.cpp +++ b/Source/Core/VideoBackends/D3D/D3DState.cpp @@ -222,13 +222,14 @@ void StateManager::SetTextureByMask(u32 textureSlotMask, ID3D11ShaderResourceVie } } -void StateManager::SetComputeUAV(ID3D11UnorderedAccessView* uav) +void StateManager::SetComputeUAV(u32 index, ID3D11UnorderedAccessView* uav) { - if (m_compute_image == uav) + if (m_compute_images[index] == uav) return; - m_compute_image = uav; - D3D::context->CSSetUnorderedAccessViews(0, 1, &uav, nullptr); + m_compute_images[index] = uav; + D3D::context->CSSetUnorderedAccessViews(0, static_cast(m_compute_images.size()), + m_compute_images.data(), nullptr); } void StateManager::SetComputeShader(ID3D11ComputeShader* shader) diff --git a/Source/Core/VideoBackends/D3D/D3DState.h b/Source/Core/VideoBackends/D3D/D3DState.h index eba58c2431..0893220e71 100644 --- a/Source/Core/VideoBackends/D3D/D3DState.h +++ b/Source/Core/VideoBackends/D3D/D3DState.h @@ -218,7 +218,7 @@ public: // Binds constant buffers/textures/samplers to the compute shader stage. // We don't track these explicitly because it's not often-used. - void SetComputeUAV(ID3D11UnorderedAccessView* uav); + void SetComputeUAV(u32 index, ID3D11UnorderedAccessView* uav); void SetComputeShader(ID3D11ComputeShader* shader); void SyncComputeBindings(); @@ -277,9 +277,11 @@ private: // Compute resources are synced with the graphics resources when we need them. ID3D11Buffer* m_compute_constants = nullptr; - std::array m_compute_textures{}; - std::array m_compute_samplers{}; - ID3D11UnorderedAccessView* m_compute_image = nullptr; + std::array + m_compute_textures{}; + std::array m_compute_samplers{}; + std::array + m_compute_images{}; ID3D11ComputeShader* m_compute_shader = nullptr; }; diff --git a/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp index 3f8e6ae4f3..3f6035feda 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp +++ b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp @@ -263,7 +263,7 @@ void Gfx::SetSamplerState(u32 index, const SamplerState& state) m_dirty_bits |= DirtyState_Samplers; } -void Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) +void Gfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) { const DXTexture* dxtex = static_cast(texture); if (m_state.compute_image_texture == dxtex) diff --git a/Source/Core/VideoBackends/D3D12/D3D12Gfx.h b/Source/Core/VideoBackends/D3D12/D3D12Gfx.h index 77ce4da899..b3426cb95e 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12Gfx.h +++ b/Source/Core/VideoBackends/D3D12/D3D12Gfx.h @@ -60,7 +60,7 @@ public: void SetScissorRect(const MathUtil::Rectangle& rc) override; void SetTexture(u32 index, const AbstractTexture* texture) override; void SetSamplerState(u32 index, const SamplerState& state) override; - void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) override; + void SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) override; void UnbindTexture(const AbstractTexture* texture) override; void SetViewport(float x, float y, float width, float height, float near_depth, float far_depth) override; diff --git a/Source/Core/VideoBackends/Metal/MTLGfx.h b/Source/Core/VideoBackends/Metal/MTLGfx.h index c1a698711a..e92ae285e6 100644 --- a/Source/Core/VideoBackends/Metal/MTLGfx.h +++ b/Source/Core/VideoBackends/Metal/MTLGfx.h @@ -59,7 +59,7 @@ public: void SetScissorRect(const MathUtil::Rectangle& rc) override; void SetTexture(u32 index, const AbstractTexture* texture) override; void SetSamplerState(u32 index, const SamplerState& state) override; - void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) override; + void SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) override; void UnbindTexture(const AbstractTexture* texture) override; void SetViewport(float x, float y, float width, float height, float near_depth, float far_depth) override; diff --git a/Source/Core/VideoBackends/Metal/MTLGfx.mm b/Source/Core/VideoBackends/Metal/MTLGfx.mm index 1137c45e5f..f37dce39c7 100644 --- a/Source/Core/VideoBackends/Metal/MTLGfx.mm +++ b/Source/Core/VideoBackends/Metal/MTLGfx.mm @@ -386,7 +386,7 @@ void Metal::Gfx::SetSamplerState(u32 index, const SamplerState& state) g_state_tracker->SetSampler(index, state); } -void Metal::Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) +void Metal::Gfx::SetComputeImageTexture(u32, AbstractTexture* texture, bool read, bool write) { g_state_tracker->SetComputeTexture(static_cast(texture)); } diff --git a/Source/Core/VideoBackends/OGL/OGLGfx.cpp b/Source/Core/VideoBackends/OGL/OGLGfx.cpp index e545ed7f4b..fb773a6a2d 100644 --- a/Source/Core/VideoBackends/OGL/OGLGfx.cpp +++ b/Source/Core/VideoBackends/OGL/OGLGfx.cpp @@ -22,6 +22,7 @@ #include "VideoCommon/Present.h" #include "VideoCommon/VideoConfig.h" +#include #include namespace OGL @@ -303,8 +304,11 @@ void OGLGfx::DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x static_cast(m_current_pipeline)->GetProgram()->shader.Bind(); // Barrier to texture can be used for reads. - if (m_bound_image_texture) + if (std::any_of(m_bound_image_textures.begin(), m_bound_image_textures.end(), + [](auto image) { return image != nullptr; })) + { glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); + } } void OGLGfx::SelectLeftBuffer() @@ -652,23 +656,23 @@ void OGLGfx::SetSamplerState(u32 index, const SamplerState& state) g_sampler_cache->SetSamplerState(index, state); } -void OGLGfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) +void OGLGfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) { - if (m_bound_image_texture == texture) + if (m_bound_image_textures[index] == texture) return; if (texture) { const GLenum access = read ? (write ? GL_READ_WRITE : GL_READ_ONLY) : GL_WRITE_ONLY; - glBindImageTexture(0, static_cast(texture)->GetGLTextureId(), 0, GL_TRUE, 0, + glBindImageTexture(index, static_cast(texture)->GetGLTextureId(), 0, GL_TRUE, 0, access, static_cast(texture)->GetGLFormatForImageTexture()); } else { - glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); + glBindImageTexture(index, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); } - m_bound_image_texture = texture; + m_bound_image_textures[index] = texture; } void OGLGfx::UnbindTexture(const AbstractTexture* texture) @@ -683,10 +687,13 @@ void OGLGfx::UnbindTexture(const AbstractTexture* texture) m_bound_textures[i] = nullptr; } - if (m_bound_image_texture == texture) + for (size_t i = 0; i < m_bound_image_textures.size(); i++) { - glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); - m_bound_image_texture = nullptr; + if (m_bound_image_textures[i] != texture) + continue; + + glBindImageTexture(static_cast(i), 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); + m_bound_image_textures[i] = nullptr; } } diff --git a/Source/Core/VideoBackends/OGL/OGLGfx.h b/Source/Core/VideoBackends/OGL/OGLGfx.h index 8d552a661b..1f392c7296 100644 --- a/Source/Core/VideoBackends/OGL/OGLGfx.h +++ b/Source/Core/VideoBackends/OGL/OGLGfx.h @@ -49,7 +49,7 @@ public: void SetScissorRect(const MathUtil::Rectangle& rc) override; void SetTexture(u32 index, const AbstractTexture* texture) override; void SetSamplerState(u32 index, const SamplerState& state) override; - void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) override; + void SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) override; void UnbindTexture(const AbstractTexture* texture) override; void SetViewport(float x, float y, float width, float height, float near_depth, float far_depth) override; @@ -103,6 +103,8 @@ private: std::unique_ptr m_main_gl_context; std::unique_ptr m_system_framebuffer; std::array m_bound_textures{}; + std::array + m_bound_image_textures{}; AbstractTexture* m_bound_image_texture = nullptr; RasterizationState m_current_rasterization_state; DepthState m_current_depth_state; diff --git a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp index be02034f67..3aa05dbaf0 100644 --- a/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/CommandBufferManager.cpp @@ -157,8 +157,9 @@ VkDescriptorPool CommandBufferManager::CreateDescriptorPool(u32 max_descriptor_s const std::array pool_sizes{{ {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, max_descriptor_sets * 3}, {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - max_descriptor_sets * (VideoCommon::MAX_PIXEL_SHADER_SAMPLERS + NUM_COMPUTE_SHADER_SAMPLERS + - NUM_UTILITY_PIXEL_SAMPLERS)}, + max_descriptor_sets * + (VideoCommon::MAX_PIXEL_SHADER_SAMPLERS + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS + + NUM_UTILITY_PIXEL_SAMPLERS)}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, max_descriptor_sets * 2}, {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, max_descriptor_sets * 3}, {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, max_descriptor_sets * 1}, diff --git a/Source/Core/VideoBackends/Vulkan/Constants.h b/Source/Core/VideoBackends/Vulkan/Constants.h index 255cfe4929..2bdceefe3b 100644 --- a/Source/Core/VideoBackends/Vulkan/Constants.h +++ b/Source/Core/VideoBackends/Vulkan/Constants.h @@ -49,9 +49,9 @@ enum DESCRIPTOR_SET_LAYOUT // - 1 texel buffer (accessible from PS) [set=1, binding=8] // - Compute // - 1 uniform buffer [set=0, binding=0] -// - 2 combined image samplers [set=0, binding=1-2] -// - 2 texel buffers [set=0, binding=3-4] -// - 1 storage image [set=0, binding=5] +// - 8 combined image samplers [set=0, binding=1-8] +// - 2 texel buffers [set=0, binding=9-10] +// - 8 storage image [set=0, binding=11-18] // // All four pipeline layout share the first two descriptor sets (uniform buffers, PS samplers). // The third descriptor set (see bind points above) is used for storage or texel buffers. @@ -78,7 +78,6 @@ enum UNIFORM_BUFFER_DESCRIPTOR_SET_BINDING constexpr u32 MAX_VERTEX_ATTRIBUTES = 16; // Number of pixel shader texture slots -constexpr u32 NUM_COMPUTE_SHADER_SAMPLERS = 2; constexpr u32 NUM_UTILITY_PIXEL_SAMPLERS = 8; // Number of texel buffer binding points. diff --git a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp index 6b8f66ae80..d899191614 100644 --- a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp @@ -148,13 +148,26 @@ bool ObjectCache::CreateDescriptorSetLayouts() {8, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT}, }}; - static const std::array compute_set_bindings{{ + static const std::array compute_set_bindings{{ {0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1, VK_SHADER_STAGE_COMPUTE_BIT}, {1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, {2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, - {3, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, - {4, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, - {5, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {7, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {8, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {9, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {10, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {11, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {12, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {13, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {14, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {15, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {16, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {17, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, + {18, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT}, }}; std::array ubo_bindings = standard_ubo_bindings; diff --git a/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp b/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp index 3555a6c9b7..ab9b015cec 100644 --- a/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp +++ b/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp @@ -58,8 +58,8 @@ static const char COMPUTE_SHADER_HEADER[] = R"( // All resources are packed into one descriptor set for compute. #define UBO_BINDING(packing, x) layout(packing, set = 0, binding = (x - 1)) #define SAMPLER_BINDING(x) layout(set = 0, binding = (1 + x)) - #define TEXEL_BUFFER_BINDING(x) layout(set = 0, binding = (3 + x)) - #define IMAGE_BINDING(format, x) layout(format, set = 0, binding = (5 + x)) + #define TEXEL_BUFFER_BINDING(x) layout(set = 0, binding = (9 + x)) + #define IMAGE_BINDING(format, x) layout(format, set = 0, binding = (11 + x)) // hlsl to glsl function translation #define API_VULKAN 1 diff --git a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp index edf57ae3b1..d6e4e3c422 100644 --- a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp +++ b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp @@ -49,8 +49,10 @@ void StateTracker::DestroyInstance() // Clear everything out so this doesn't happen. for (auto& it : s_state_tracker->m_bindings.samplers) it.imageView = VK_NULL_HANDLE; - s_state_tracker->m_bindings.image_texture.imageView = VK_NULL_HANDLE; + for (auto& it : s_state_tracker->m_bindings.image_textures) + it.imageView = VK_NULL_HANDLE; s_state_tracker->m_dummy_texture.reset(); + s_state_tracker->m_dummy_compute_texture.reset(); s_state_tracker.reset(); } @@ -64,6 +66,14 @@ bool StateTracker::Initialize() return false; m_dummy_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + // Create a dummy compute texture which can be used in place of a real binding + m_dummy_compute_texture = VKTexture::Create( + TextureConfig(1, 1, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage), + ""); + if (!m_dummy_compute_texture) + return false; + m_dummy_compute_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentInitCommandBuffer(), + VK_IMAGE_LAYOUT_GENERAL); // Initialize all samplers to point by default for (size_t i = 0; i < VideoCommon::MAX_PIXEL_SHADER_SAMPLERS; i++) @@ -73,6 +83,13 @@ bool StateTracker::Initialize() m_bindings.samplers[i].sampler = g_object_cache->GetPointSampler(); } + for (size_t i = 0; i < VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS; i++) + { + m_bindings.image_textures[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL; + m_bindings.image_textures[i].imageView = m_dummy_compute_texture->GetView(); + m_bindings.image_textures[i].sampler = g_object_cache->GetPointSampler(); + } + // Default dirty flags include all descriptors InvalidateCachedState(); return true; @@ -217,13 +234,13 @@ void StateTracker::SetTexelBuffer(u32 index, VkBufferView view) m_dirty_flags |= DIRTY_FLAG_UTILITY_BINDINGS | DIRTY_FLAG_COMPUTE_BINDINGS; } -void StateTracker::SetImageTexture(VkImageView view) +void StateTracker::SetImageTexture(u32 index, VkImageView view) { - if (m_bindings.image_texture.imageView == view) + if (m_bindings.image_textures[index].imageView == view) return; - m_bindings.image_texture.imageView = view; - m_bindings.image_texture.imageLayout = VK_IMAGE_LAYOUT_GENERAL; + m_bindings.image_textures[index].imageView = view; + m_bindings.image_textures[index].imageLayout = VK_IMAGE_LAYOUT_GENERAL; m_dirty_flags |= DIRTY_FLAG_COMPUTE_BINDINGS; } @@ -238,10 +255,13 @@ void StateTracker::UnbindTexture(VkImageView view) } } - if (m_bindings.image_texture.imageView == view) + for (VkDescriptorImageInfo& it : m_bindings.image_textures) { - m_bindings.image_texture.imageView = m_dummy_texture->GetView(); - m_bindings.image_texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + if (it.imageView == view) + { + it.imageView = m_dummy_compute_texture->GetView(); + it.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + } } } @@ -667,7 +687,7 @@ void StateTracker::UpdateComputeDescriptorSet() m_compute_descriptor_set, 1, 0, - NUM_COMPUTE_SHADER_SAMPLERS, + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_bindings.samplers.data(), nullptr, @@ -675,7 +695,7 @@ void StateTracker::UpdateComputeDescriptorSet() dswrites[2] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, m_compute_descriptor_set, - 3, + 1 + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS, 0, NUM_COMPUTE_TEXEL_BUFFERS, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, @@ -685,11 +705,11 @@ void StateTracker::UpdateComputeDescriptorSet() dswrites[3] = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, m_compute_descriptor_set, - 5, + 1 + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS + NUM_COMPUTE_TEXEL_BUFFERS, 0, - 1, + VideoCommon::MAX_COMPUTE_SHADER_SAMPLERS, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - &m_bindings.image_texture, + m_bindings.image_textures.data(), nullptr, nullptr}; diff --git a/Source/Core/VideoBackends/Vulkan/StateTracker.h b/Source/Core/VideoBackends/Vulkan/StateTracker.h index 1113cfc994..8de5fd54cc 100644 --- a/Source/Core/VideoBackends/Vulkan/StateTracker.h +++ b/Source/Core/VideoBackends/Vulkan/StateTracker.h @@ -43,7 +43,7 @@ public: void SetSampler(u32 index, VkSampler sampler); void SetSSBO(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range); void SetTexelBuffer(u32 index, VkBufferView view); - void SetImageTexture(VkImageView view); + void SetImageTexture(u32 index, VkImageView view); void UnbindTexture(VkImageView view); @@ -146,7 +146,7 @@ private: std::array texel_buffers; VkDescriptorBufferInfo ssbo; VkDescriptorBufferInfo gx_uber_vertex_ssbo; - VkDescriptorImageInfo image_texture; + std::array image_textures; } m_bindings = {}; std::array m_gx_descriptor_sets = {}; std::array m_utility_descriptor_sets = {}; @@ -158,6 +158,7 @@ private: // uniform buffers std::unique_ptr m_dummy_texture; + std::unique_ptr m_dummy_compute_texture; VKFramebuffer* m_framebuffer = nullptr; VkRenderPass m_current_render_pass = VK_NULL_HANDLE; diff --git a/Source/Core/VideoBackends/Vulkan/VKGfx.cpp b/Source/Core/VideoBackends/Vulkan/VKGfx.cpp index 7364541426..d5f11df9bf 100644 --- a/Source/Core/VideoBackends/Vulkan/VKGfx.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKGfx.cpp @@ -512,13 +512,13 @@ void VKGfx::SetSamplerState(u32 index, const SamplerState& state) m_sampler_states[index] = state; } -void VKGfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) +void VKGfx::SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) { VKTexture* vk_texture = static_cast(texture); if (vk_texture) { StateTracker::GetInstance()->EndRenderPass(); - StateTracker::GetInstance()->SetImageTexture(vk_texture->GetView()); + StateTracker::GetInstance()->SetImageTexture(index, vk_texture->GetView()); vk_texture->TransitionToLayout(g_command_buffer_mgr->GetCurrentCommandBuffer(), read ? (write ? VKTexture::ComputeImageLayout::ReadWrite : VKTexture::ComputeImageLayout::ReadOnly) : @@ -526,7 +526,7 @@ void VKGfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool wri } else { - StateTracker::GetInstance()->SetImageTexture(VK_NULL_HANDLE); + StateTracker::GetInstance()->SetImageTexture(index, VK_NULL_HANDLE); } } diff --git a/Source/Core/VideoBackends/Vulkan/VKGfx.h b/Source/Core/VideoBackends/Vulkan/VKGfx.h index c6d6201714..539b427a9d 100644 --- a/Source/Core/VideoBackends/Vulkan/VKGfx.h +++ b/Source/Core/VideoBackends/Vulkan/VKGfx.h @@ -66,7 +66,7 @@ public: void SetScissorRect(const MathUtil::Rectangle& rc) override; void SetTexture(u32 index, const AbstractTexture* texture) override; void SetSamplerState(u32 index, const SamplerState& state) override; - void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) override; + void SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) override; void UnbindTexture(const AbstractTexture* texture) override; void SetViewport(float x, float y, float width, float height, float near_depth, float far_depth) override; diff --git a/Source/Core/VideoCommon/AbstractGfx.h b/Source/Core/VideoCommon/AbstractGfx.h index 952369e11e..5d2679f68f 100644 --- a/Source/Core/VideoCommon/AbstractGfx.h +++ b/Source/Core/VideoCommon/AbstractGfx.h @@ -61,7 +61,7 @@ public: virtual void SetScissorRect(const MathUtil::Rectangle& rc) {} virtual void SetTexture(u32 index, const AbstractTexture* texture) {} virtual void SetSamplerState(u32 index, const SamplerState& state) {} - virtual void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) {} + virtual void SetComputeImageTexture(u32 index, AbstractTexture* texture, bool read, bool write) {} virtual void UnbindTexture(const AbstractTexture* texture) {} virtual void SetViewport(float x, float y, float width, float height, float near_depth, float far_depth) diff --git a/Source/Core/VideoCommon/Constants.h b/Source/Core/VideoCommon/Constants.h index 8da73e8054..bd939b1f3c 100644 --- a/Source/Core/VideoCommon/Constants.h +++ b/Source/Core/VideoCommon/Constants.h @@ -8,4 +8,5 @@ namespace VideoCommon { constexpr u32 MAX_PIXEL_SHADER_SAMPLERS = 8; -} +constexpr u32 MAX_COMPUTE_SHADER_SAMPLERS = 8; +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index c26cbb5f4c..6198eea0ff 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -3009,7 +3009,7 @@ bool TextureCacheBase::DecodeTextureOnGPU(RcTcacheEntry& entry, u32 dst_level, c aligned_height, src_offset, row_stride / bytes_per_buffer_elem, palette_offset}; g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); - g_gfx->SetComputeImageTexture(m_decoding_texture.get(), false, true); + g_gfx->SetComputeImageTexture(0, m_decoding_texture.get(), false, true); auto dispatch_groups = TextureConversionShaderTiled::GetDispatchCount(info, aligned_width, aligned_height); From 6ea49c6746de19c09ede7f539cf3cafc42280e5a Mon Sep 17 00:00:00 2001 From: iwubcode Date: Thu, 29 Jun 2023 00:56:06 -0500 Subject: [PATCH 04/99] VideoCommon: add a pixel shader asset --- Source/Core/DolphinLib.props | 2 + .../VideoCommon/Assets/CustomAssetLibrary.h | 4 + .../VideoCommon/Assets/CustomAssetLoader.cpp | 7 + .../VideoCommon/Assets/CustomAssetLoader.h | 5 + .../Assets/DirectFilesystemAssetLibrary.cpp | 95 +++++++++++ .../Assets/DirectFilesystemAssetLibrary.h | 1 + .../Core/VideoCommon/Assets/ShaderAsset.cpp | 147 ++++++++++++++++++ Source/Core/VideoCommon/Assets/ShaderAsset.h | 47 ++++++ Source/Core/VideoCommon/CMakeLists.txt | 2 + 9 files changed, 310 insertions(+) create mode 100644 Source/Core/VideoCommon/Assets/ShaderAsset.cpp create mode 100644 Source/Core/VideoCommon/Assets/ShaderAsset.h diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 1a398f3bf5..4ddf550edf 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -637,6 +637,7 @@ + @@ -1252,6 +1253,7 @@ + diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h index eb78e9f770..196372fab8 100644 --- a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h +++ b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h @@ -11,6 +11,7 @@ namespace VideoCommon { class CustomTextureData; +struct PixelShaderData; // This class provides functionality to load // specific data (like textures). Where this data @@ -45,5 +46,8 @@ public: // Loads a texture as a game texture, providing additional checks like confirming // each mip level size is correct and that the format is consistent across the data LoadInfo LoadGameTexture(const AssetID& asset_id, CustomTextureData* data); + + // Loads a pixel shader + virtual LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) = 0; }; } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp index bb404064d2..ce76a368d2 100644 --- a/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp +++ b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp @@ -90,4 +90,11 @@ CustomAssetLoader::LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id, { return LoadOrCreateAsset(asset_id, m_game_textures, std::move(library)); } + +std::shared_ptr +CustomAssetLoader::LoadPixelShader(const CustomAssetLibrary::AssetID& asset_id, + std::shared_ptr library) +{ + return LoadOrCreateAsset(asset_id, m_pixel_shaders, std::move(library)); +} } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLoader.h b/Source/Core/VideoCommon/Assets/CustomAssetLoader.h index 6e4596b8b2..cca83af960 100644 --- a/Source/Core/VideoCommon/Assets/CustomAssetLoader.h +++ b/Source/Core/VideoCommon/Assets/CustomAssetLoader.h @@ -12,6 +12,7 @@ #include "Common/Flag.h" #include "Common/WorkQueueThread.h" #include "VideoCommon/Assets/CustomAsset.h" +#include "VideoCommon/Assets/ShaderAsset.h" #include "VideoCommon/Assets/TextureAsset.h" namespace VideoCommon @@ -42,6 +43,9 @@ public: std::shared_ptr LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id, std::shared_ptr library); + std::shared_ptr LoadPixelShader(const CustomAssetLibrary::AssetID& asset_id, + std::shared_ptr library); + private: // TODO C++20: use a 'derived_from' concept against 'CustomAsset' when available template @@ -74,6 +78,7 @@ private: std::map> m_textures; std::map> m_game_textures; + std::map> m_pixel_shaders; std::thread m_asset_monitor_thread; Common::Flag m_asset_monitor_thread_shutdown; diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp index 9c126bf9e1..c234b4088e 100644 --- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp +++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp @@ -10,6 +10,7 @@ #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "VideoCommon/Assets/CustomTextureData.h" +#include "VideoCommon/Assets/ShaderAsset.h" namespace VideoCommon { @@ -49,6 +50,100 @@ DirectFilesystemAssetLibrary::GetLastAssetWriteTime(const AssetID& asset_id) con return {}; } +CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadPixelShader(const AssetID& asset_id, + PixelShaderData* data) +{ + const auto asset_map = GetAssetMapForID(asset_id); + + // Asset map for a pixel shader is the shader and some metadata + if (asset_map.size() != 2) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have two files mapped!", asset_id); + return {}; + } + + const auto metadata = asset_map.find("metadata"); + const auto shader = asset_map.find("shader"); + if (metadata == asset_map.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have a metadata entry mapped!", asset_id); + return {}; + } + + if (shader == asset_map.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' expected to have a shader entry mapped!", asset_id); + return {}; + } + + std::size_t metadata_size; + { + std::error_code ec; + metadata_size = std::filesystem::file_size(metadata->second, ec); + if (ec) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' error - failed to get shader metadata file size with error '{}'!", + asset_id, ec); + return {}; + } + } + std::size_t shader_size; + { + std::error_code ec; + shader_size = std::filesystem::file_size(shader->second, ec); + if (ec) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' error - failed to get shader source file size with error '{}'!", + asset_id, ec); + return {}; + } + } + const auto approx_mem_size = metadata_size + shader_size; + + if (!File::ReadFileToString(shader->second.string(), data->m_shader_source)) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the shader file '{}',", asset_id, + shader->second.string()); + return {}; + } + + std::string json_data; + if (!File::ReadFileToString(metadata->second.string(), json_data)) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the json file '{}',", asset_id, + metadata->second.string()); + return {}; + } + + picojson::value root; + const auto error = picojson::parse(root, json_data); + + if (!error.empty()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' error - failed to load the json file '{}', due to parse error: {}", + asset_id, metadata->second.string(), error); + return {}; + } + if (!root.is()) + { + ERROR_LOG_FMT( + VIDEO, + "Asset '{}' error - failed to load the json file '{}', due to root not being an object!", + asset_id, metadata->second.string()); + return {}; + } + + const auto& root_obj = root.get(); + + if (!PixelShaderData::FromJson(asset_id, root_obj, data)) + return {}; + + return LoadInfo{approx_mem_size, GetLastAssetWriteTime(asset_id)}; +} + CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const AssetID& asset_id, CustomTextureData* data) { diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h index 4f02d107cf..9a842c6988 100644 --- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h +++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h @@ -22,6 +22,7 @@ public: using AssetMap = std::map; LoadInfo LoadTexture(const AssetID& asset_id, CustomTextureData* data) override; + LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) override; // Gets the latest time from amongst all the files in the asset map TimeType GetLastAssetWriteTime(const AssetID& asset_id) const override; diff --git a/Source/Core/VideoCommon/Assets/ShaderAsset.cpp b/Source/Core/VideoCommon/Assets/ShaderAsset.cpp new file mode 100644 index 0000000000..d09e572bab --- /dev/null +++ b/Source/Core/VideoCommon/Assets/ShaderAsset.cpp @@ -0,0 +1,147 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "VideoCommon/Assets/ShaderAsset.h" + +#include "Common/Logging/Log.h" +#include "VideoCommon/Assets/CustomAssetLibrary.h" + +namespace VideoCommon +{ +bool ParseShaderProperties(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, + const picojson::array& properties_data, + std::map* shader_properties) +{ + if (!shader_properties) [[unlikely]] + return false; + + for (const auto& property_data : properties_data) + { + VideoCommon::ShaderProperty property; + if (!property_data.is()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, property is not the right json type", + asset_id); + return false; + } + const auto& property_data_obj = property_data.get(); + + const auto type_iter = property_data_obj.find("type"); + if (type_iter == property_data_obj.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, property entry 'type' not found", + asset_id); + return false; + } + if (!type_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, property entry 'type' is not " + "the right json type", + asset_id); + return false; + } + std::string type = type_iter->second.to_str(); + std::transform(type.begin(), type.end(), type.begin(), + [](unsigned char c) { return std::tolower(c); }); + + if (type == "sampler2d") + { + property.m_type = ShaderProperty::Type::Type_Sampler2D; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, property entry 'description' is " + "an invalid option", + asset_id); + return false; + } + + const auto description_iter = property_data_obj.find("description"); + if (description_iter == property_data_obj.end()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, property entry 'description' not found", + asset_id); + return false; + } + if (!description_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, property entry 'description' is not " + "the right json type", + asset_id); + return false; + } + property.m_description = description_iter->second.to_str(); + + const auto code_name_iter = property_data_obj.find("code_name"); + if (code_name_iter == property_data_obj.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, property entry 'code_name' not found", + asset_id); + return false; + } + if (!code_name_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, property entry 'code_name' is not " + "the right json type", + asset_id); + return false; + } + shader_properties->try_emplace(code_name_iter->second.to_str(), std::move(property)); + } + + return true; +} + +bool PixelShaderData::FromJson(const VideoCommon::CustomAssetLibrary::AssetID& asset_id, + const picojson::object& json, PixelShaderData* data) +{ + const auto properties_iter = json.find("properties"); + if (properties_iter == json.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'properties' not found", asset_id); + return false; + } + if (!properties_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'properties' is not the right json type", + asset_id); + return false; + } + const auto& properties_array = properties_iter->second.get(); + if (!ParseShaderProperties(asset_id, properties_array, &data->m_properties)) + return false; + + for (const auto& [name, property] : data->m_properties) + { + if (data->m_shader_source.find(name) == std::string::npos) + { + ERROR_LOG_FMT( + VIDEO, + "Asset '{}' failed to parse json, the code name '{}' defined in the metadata was not " + "found in the shader source", + asset_id, name); + return false; + } + } + + return true; +} +CustomAssetLibrary::LoadInfo PixelShaderAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) +{ + auto potential_data = std::make_shared(); + const auto loaded_info = m_owning_library->LoadPixelShader(asset_id, potential_data.get()); + if (loaded_info.m_bytes_loaded == 0) + return {}; + { + std::lock_guard lk(m_data_lock); + m_loaded = true; + m_data = std::move(potential_data); + } + return loaded_info; +} +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/ShaderAsset.h b/Source/Core/VideoCommon/Assets/ShaderAsset.h new file mode 100644 index 0000000000..98712f0d78 --- /dev/null +++ b/Source/Core/VideoCommon/Assets/ShaderAsset.h @@ -0,0 +1,47 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include + +#include "VideoCommon/Assets/CustomAsset.h" + +namespace VideoCommon +{ +struct ShaderProperty +{ + enum class Type + { + Type_Undefined, + Type_Sampler2D, + Type_Max = Type_Sampler2D + }; + Type m_type; + std::string m_description; +}; +struct PixelShaderData +{ + static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, + PixelShaderData* data); + + // These shader properties describe the input that the + // shader expects to expose. The key is text + // expected to be in the shader code and the propery + // describes various details about the input + std::map m_properties; + std::string m_shader_source; +}; + +class PixelShaderAsset final : public CustomLoadableAsset +{ +public: + using CustomLoadableAsset::CustomLoadableAsset; + +private: + CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override; +}; +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index ed8642fb1e..97ad7b0c3e 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -18,6 +18,8 @@ add_library(videocommon Assets/CustomTextureData.h Assets/DirectFilesystemAssetLibrary.cpp Assets/DirectFilesystemAssetLibrary.h + Assets/ShaderAsset.cpp + Assets/ShaderAsset.h Assets/TextureAsset.cpp Assets/TextureAsset.h AsyncRequests.cpp From b086051de685bce95d7d9186eac3c655676ea179 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Fri, 30 Jun 2023 22:02:54 +0200 Subject: [PATCH 05/99] Add Bloom Definitions for Skylanders: Spyro's Adventure --- .../Skylanders Spyro's Adventure/SSP.txt | 0 .../metadata.json | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 Data/Sys/Load/GraphicMods/Skylanders Spyro's Adventure/SSP.txt create mode 100644 Data/Sys/Load/GraphicMods/Skylanders Spyro's Adventure/metadata.json diff --git a/Data/Sys/Load/GraphicMods/Skylanders Spyro's Adventure/SSP.txt b/Data/Sys/Load/GraphicMods/Skylanders Spyro's Adventure/SSP.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Data/Sys/Load/GraphicMods/Skylanders Spyro's Adventure/metadata.json b/Data/Sys/Load/GraphicMods/Skylanders Spyro's Adventure/metadata.json new file mode 100644 index 0000000000..4f954e708c --- /dev/null +++ b/Data/Sys/Load/GraphicMods/Skylanders Spyro's Adventure/metadata.json @@ -0,0 +1,19 @@ +{ + "meta": + { + "title": "Bloom Texture Definitions", + "author": "SuperSamus" + }, + "groups": + [ + { + "name": "Bloom", + "targets": [ + { + "type": "efb", + "texture_filename": "efb1_n000008_80x57_6" + } + ] + } + ] +} From 6fe3cfe24501f58c4c3fe7f820ff4935c9c850e4 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 1 Jul 2023 11:21:10 -0700 Subject: [PATCH 06/99] QtUtils: Remove unused FlowLayout FlowLayout hasn't been used since b65faa0549e2a017dfe1170eb191523e48af81a7. --- Source/Core/DolphinQt/CMakeLists.txt | 2 - Source/Core/DolphinQt/DolphinQt.vcxproj | 2 - Source/Core/DolphinQt/QtUtils/FlowLayout.cpp | 176 ------------------- Source/Core/DolphinQt/QtUtils/FlowLayout.h | 45 ----- 4 files changed, 225 deletions(-) delete mode 100644 Source/Core/DolphinQt/QtUtils/FlowLayout.cpp delete mode 100644 Source/Core/DolphinQt/QtUtils/FlowLayout.h diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index e302287677..dc877da54c 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -280,8 +280,6 @@ add_executable(dolphin-emu QtUtils/ElidedButton.h QtUtils/FileOpenEventFilter.cpp QtUtils/FileOpenEventFilter.h - QtUtils/FlowLayout.cpp - QtUtils/FlowLayout.h QtUtils/ImageConverter.cpp QtUtils/ImageConverter.h QtUtils/ModalMessageBox.cpp diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 79b05b372b..462bfd354b 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -182,7 +182,6 @@ - @@ -238,7 +237,6 @@ - diff --git a/Source/Core/DolphinQt/QtUtils/FlowLayout.cpp b/Source/Core/DolphinQt/QtUtils/FlowLayout.cpp deleted file mode 100644 index b2c4eb75d5..0000000000 --- a/Source/Core/DolphinQt/QtUtils/FlowLayout.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** SPDX-License-Identifier: BSD-3-Clause -** -****************************************************************************/ - -#include "DolphinQt/QtUtils/FlowLayout.h" - -#include - -FlowLayout::FlowLayout(QWidget* parent, int margin, int h_spacing, int v_spacing) - : QLayout(parent), m_h_space(h_spacing), m_v_space(v_spacing) -{ - setContentsMargins(margin, margin, margin, margin); -} - -FlowLayout::FlowLayout(int margin, int h_spacing, int v_spacing) - : m_h_space(h_spacing), m_v_space(v_spacing) -{ - setContentsMargins(margin, margin, margin, margin); -} - -FlowLayout::~FlowLayout() -{ - while (QLayoutItem* item = takeAt(0)) - delete item; -} - -void FlowLayout::addItem(QLayoutItem* item) -{ - m_item_list.append(item); -} - -int FlowLayout::horizontalSpacing() const -{ - if (m_h_space >= 0) - { - return m_h_space; - } - else - { - return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); - } -} - -int FlowLayout::verticalSpacing() const -{ - if (m_v_space >= 0) - { - return m_v_space; - } - else - { - return smartSpacing(QStyle::PM_LayoutVerticalSpacing); - } -} - -int FlowLayout::count() const -{ - return m_item_list.size(); -} - -QLayoutItem* FlowLayout::itemAt(int index) const -{ - return m_item_list.value(index); -} - -QLayoutItem* FlowLayout::takeAt(int index) -{ - if (index >= 0 && index < m_item_list.size()) - return m_item_list.takeAt(index); - else - return nullptr; -} - -Qt::Orientations FlowLayout::expandingDirections() const -{ - return {}; -} - -bool FlowLayout::hasHeightForWidth() const -{ - return true; -} - -int FlowLayout::heightForWidth(int width) const -{ - int height = doLayout(QRect(0, 0, width, 0), true); - return height; -} - -void FlowLayout::setGeometry(const QRect& rect) -{ - QLayout::setGeometry(rect); - doLayout(rect, false); -} - -QSize FlowLayout::sizeHint() const -{ - return minimumSize(); -} - -QSize FlowLayout::minimumSize() const -{ - QSize size; - for (const auto& item : m_item_list) - size = size.expandedTo(item->minimumSize()); - - // Any direction's margin works, as they all set the same within the constructor. - int margin = 0; - getContentsMargins(&margin, nullptr, nullptr, nullptr); - - size += QSize(2 * margin, 2 * margin); - return size; -} - -int FlowLayout::doLayout(const QRect& rect, bool testOnly) const -{ - int left, top, right, bottom; - getContentsMargins(&left, &top, &right, &bottom); - QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); - int x = effectiveRect.x(); - int y = effectiveRect.y(); - int lineHeight = 0; - - for (const auto& item : m_item_list) - { - QWidget* wid = item->widget(); - int spaceX = horizontalSpacing(); - if (spaceX == -1) - spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, - Qt::Horizontal); - int spaceY = verticalSpacing(); - if (spaceY == -1) - spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, - Qt::Vertical); - int nextX = x + item->sizeHint().width() + spaceX; - if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) - { - x = effectiveRect.x(); - y = y + lineHeight + spaceY; - nextX = x + item->sizeHint().width() + spaceX; - lineHeight = 0; - } - - if (!testOnly) - item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); - - x = nextX; - lineHeight = qMax(lineHeight, item->sizeHint().height()); - } - return y + lineHeight - rect.y() + bottom; -} - -int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const -{ - QObject* parent = this->parent(); - if (!parent) - { - return -1; - } - else if (parent->isWidgetType()) - { - QWidget* pw = static_cast(parent); - return pw->style()->pixelMetric(pm, nullptr, pw); - } - else - { - return static_cast(parent)->spacing(); - } -} diff --git a/Source/Core/DolphinQt/QtUtils/FlowLayout.h b/Source/Core/DolphinQt/QtUtils/FlowLayout.h deleted file mode 100644 index 4f145e7e4d..0000000000 --- a/Source/Core/DolphinQt/QtUtils/FlowLayout.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** SPDX-License-Identifier: BSD-3-Clause -** -****************************************************************************/ - -#pragma once - -#include -#include -#include - -class FlowLayout : public QLayout -{ -public: - explicit FlowLayout(QWidget* parent, int margin = -1, int h_spacing = -1, int v_spacing = -1); - explicit FlowLayout(int margin = -1, int h_spacing = -1, int v_spacing = -1); - ~FlowLayout(); - - void addItem(QLayoutItem* item) override; - int horizontalSpacing() const; - int verticalSpacing() const; - Qt::Orientations expandingDirections() const override; - bool hasHeightForWidth() const override; - int heightForWidth(int) const override; - int count() const override; - QLayoutItem* itemAt(int index) const override; - QSize minimumSize() const override; - void setGeometry(const QRect& rect) override; - QSize sizeHint() const override; - QLayoutItem* takeAt(int index) override; - -private: - int doLayout(const QRect& rect, bool testOnly) const; - int smartSpacing(QStyle::PixelMetric pm) const; - - QList m_item_list; - int m_h_space; - int m_v_space; -}; From f700faf6ab9da09cdb011961906dc0e66df5767d Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 2 Jun 2023 21:17:43 -0400 Subject: [PATCH 07/99] Expose Achievements Data for Display Added some small methods to AchievementManager to expose useful data for displaying in an achievement UI. Also moved a couple things from private to public for the same purpose. --- Source/Core/Core/AchievementManager.cpp | 88 ++++++++++++++++++------- Source/Core/Core/AchievementManager.h | 37 +++++++---- 2 files changed, 87 insertions(+), 38 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 1a05af90bc..27e82a8c55 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -183,6 +183,11 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, }); } +bool AchievementManager::IsGameLoaded() const +{ + return m_is_game_loaded; +} + void AchievementManager::LoadUnlockData(const ResponseCallback& callback) { m_queue.EmplaceItem([this, callback] { @@ -313,6 +318,64 @@ void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runti } } +std::string AchievementManager::GetPlayerDisplayName() const +{ + return IsLoggedIn() ? m_display_name : ""; +} + +u32 AchievementManager::GetPlayerScore() const +{ + return IsLoggedIn() ? m_player_score : 0; +} + +std::string AchievementManager::GetGameDisplayName() const +{ + return IsGameLoaded() ? m_game_data.title : ""; +} + +AchievementManager::PointSpread AchievementManager::TallyScore() const +{ + PointSpread spread{}; + if (!IsGameLoaded()) + return spread; + for (const auto& entry : m_unlock_map) + { + u32 points = entry.second.points; + spread.total_count++; + spread.total_points += points; + if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::HARDCORE || + (hardcore_mode_enabled && entry.second.session_unlock_count > 0)) + { + spread.hard_unlocks++; + spread.hard_points += points; + } + else if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::SOFTCORE || + entry.second.session_unlock_count > 0) + { + spread.soft_unlocks++; + spread.soft_points += points; + } + } + return spread; +} + +rc_api_fetch_game_data_response_t* AchievementManager::GetGameData() +{ + return &m_game_data; +} + +AchievementManager::UnlockStatus +AchievementManager::GetUnlockStatus(AchievementId achievement_id) const +{ + return m_unlock_map.at(achievement_id); +} + +void AchievementManager::GetAchievementProgress(AchievementId achievement_id, u32* value, + u32* target) +{ + rc_runtime_get_achievement_measured(&m_runtime, achievement_id, value, target); +} + void AchievementManager::CloseGame() { m_is_game_loaded = false; @@ -353,6 +416,7 @@ AchievementManager::ResponseType AchievementManager::VerifyCredentials(const std { Config::SetBaseOrCurrent(Config::RA_API_TOKEN, login_data.api_token); m_display_name = login_data.display_name; + m_player_score = login_data.score; } rc_api_destroy_login_response(&login_data); return r_type; @@ -618,30 +682,6 @@ void AchievementManager::HandleLeaderboardTriggeredEvent(const rc_runtime_event_ } } -AchievementManager::PointSpread AchievementManager::TallyScore() const -{ - PointSpread spread{}; - for (const auto& entry : m_unlock_map) - { - u32 points = entry.second.points; - spread.total_count++; - spread.total_points += points; - if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::HARDCORE || - (hardcore_mode_enabled && entry.second.session_unlock_count > 0)) - { - spread.hard_unlocks++; - spread.hard_points += points; - } - else if (entry.second.remote_unlock_status == UnlockStatus::UnlockType::SOFTCORE || - entry.second.session_unlock_count > 0) - { - spread.soft_unlocks++; - spread.soft_points += points; - } - } - return spread; -} - // Every RetroAchievements API call, with only a partial exception for fetch_image, follows // the same design pattern (here, X is the name of the call): // Create a specific rc_api_X_request_t struct and populate with the necessary values diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index f35cd5f659..00c2055920 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -52,12 +52,26 @@ public: u32 soft_points; }; + struct UnlockStatus + { + AchievementId game_data_index = 0; + enum class UnlockType + { + LOCKED, + SOFTCORE, + HARDCORE + } remote_unlock_status = UnlockType::LOCKED; + u32 session_unlock_count = 0; + u32 points = 0; + }; + static AchievementManager* GetInstance(); void Init(); ResponseType Login(const std::string& password); void LoginAsync(const std::string& password, const ResponseCallback& callback); bool IsLoggedIn() const; void LoadGameByFilenameAsync(const std::string& iso_path, const ResponseCallback& callback); + bool IsGameLoaded() const; void LoadUnlockData(const ResponseCallback& callback); void ActivateDeactivateAchievements(); @@ -68,6 +82,14 @@ public: u32 MemoryPeeker(u32 address, u32 num_bytes, void* ud); void AchievementEventHandler(const rc_runtime_event_t* runtime_event); + std::string GetPlayerDisplayName() const; + u32 GetPlayerScore() const; + std::string GetGameDisplayName() const; + PointSpread TallyScore() const; + rc_api_fetch_game_data_response_t* GetGameData(); + UnlockStatus GetUnlockStatus(AchievementId achievement_id) const; + void GetAchievementProgress(AchievementId achievement_id, u32* value, u32* target); + void CloseGame(); void Logout(); void Shutdown(); @@ -95,8 +117,6 @@ private: void HandleLeaderboardCanceledEvent(const rc_runtime_event_t* runtime_event); void HandleLeaderboardTriggeredEvent(const rc_runtime_event_t* runtime_event); - PointSpread TallyScore() const; - template ResponseType Request(RcRequest rc_request, RcResponse* rc_response, const std::function& init_request, @@ -106,24 +126,13 @@ private: Core::System* m_system{}; bool m_is_runtime_initialized = false; std::string m_display_name; + u32 m_player_score = 0; std::array m_game_hash{}; u32 m_game_id = 0; rc_api_fetch_game_data_response_t m_game_data{}; bool m_is_game_loaded = false; time_t m_last_ping_time = 0; - struct UnlockStatus - { - AchievementId game_data_index = 0; - enum class UnlockType - { - LOCKED, - SOFTCORE, - HARDCORE - } remote_unlock_status = UnlockType::LOCKED; - u32 session_unlock_count = 0; - u32 points = 0; - }; std::unordered_map m_unlock_map; Common::WorkQueueThread> m_queue; From ebe77f149f4db747347811f769cbb1866639bf51 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 2 Jun 2023 21:20:42 -0400 Subject: [PATCH 08/99] Added AchievementHeaderWidget to AchievementsWindow This widget displays a header on the AchievementsWindow dialog above the tabs that shows the currently logged in user (if there is one) and the game they are playing (if there is one). --- .../Achievements/AchievementHeaderWidget.cpp | 140 ++++++++++++++++++ .../Achievements/AchievementHeaderWidget.h | 42 ++++++ .../Achievements/AchievementsWindow.cpp | 5 + .../Achievements/AchievementsWindow.h | 2 + Source/Core/DolphinQt/CMakeLists.txt | 2 + Source/Core/DolphinQt/DolphinQt.vcxproj | 2 + 6 files changed, 193 insertions(+) create mode 100644 Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp create mode 100644 Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h diff --git a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp new file mode 100644 index 0000000000..4dc3e66538 --- /dev/null +++ b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp @@ -0,0 +1,140 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifdef USE_RETRO_ACHIEVEMENTS +#include "DolphinQt/Achievements/AchievementHeaderWidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "Core/AchievementManager.h" +#include "Core/Core.h" + +#include "DolphinQt/QtUtils/ModalMessageBox.h" +#include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SignalBlocking.h" +#include "DolphinQt/Settings.h" + +AchievementHeaderWidget::AchievementHeaderWidget(QWidget* parent) : QWidget(parent) +{ + m_user_name = new QLabel(); + m_user_points = new QLabel(); + m_game_name = new QLabel(); + m_game_points = new QLabel(); + m_game_progress_hard = new QProgressBar(); + m_game_progress_soft = new QProgressBar(); + m_rich_presence = new QLabel(); + + QVBoxLayout* m_user_right_col = new QVBoxLayout(); + m_user_right_col->addWidget(m_user_name); + m_user_right_col->addWidget(m_user_points); + QHBoxLayout* m_user_layout = new QHBoxLayout(); + // TODO: player badge goes here + m_user_layout->addLayout(m_user_right_col); + m_user_box = new QGroupBox(); + m_user_box->setLayout(m_user_layout); + + QVBoxLayout* m_game_right_col = new QVBoxLayout(); + m_game_right_col->addWidget(m_game_name); + m_game_right_col->addWidget(m_game_points); + m_game_right_col->addWidget(m_game_progress_hard); + m_game_right_col->addWidget(m_game_progress_soft); + QHBoxLayout* m_game_upper_row = new QHBoxLayout(); + // TODO: player badge and game badge go here + m_game_upper_row->addLayout(m_game_right_col); + QVBoxLayout* m_game_layout = new QVBoxLayout(); + m_game_layout->addLayout(m_game_upper_row); + m_game_layout->addWidget(m_rich_presence); + m_game_box = new QGroupBox(); + m_game_box->setLayout(m_game_layout); + + QVBoxLayout* m_total = new QVBoxLayout(); + m_total->addWidget(m_user_box); + m_total->addWidget(m_game_box); + + UpdateData(); + + m_total->setContentsMargins(0, 0, 0, 0); + m_total->setAlignment(Qt::AlignTop); + setLayout(m_total); +} + +void AchievementHeaderWidget::UpdateData() +{ + if (!AchievementManager::GetInstance()->IsLoggedIn()) + { + m_user_box->setVisible(false); + m_game_box->setVisible(false); + return; + } + + QString user_name = + QString::fromStdString(AchievementManager::GetInstance()->GetPlayerDisplayName()); + m_user_name->setText(user_name); + m_user_points->setText(tr("%1 points").arg(AchievementManager::GetInstance()->GetPlayerScore())); + + if (!AchievementManager::GetInstance()->IsGameLoaded()) + { + m_user_box->setVisible(true); + m_game_box->setVisible(false); + return; + } + + AchievementManager::PointSpread point_spread = AchievementManager::GetInstance()->TallyScore(); + m_game_name->setText( + QString::fromStdString(AchievementManager::GetInstance()->GetGameDisplayName())); + m_game_points->setText(GetPointsString(user_name, point_spread)); + m_game_progress_hard = new QProgressBar(); + m_game_progress_hard->setRange(0, point_spread.total_count); + m_game_progress_soft->setValue(point_spread.hard_unlocks); + m_game_progress_soft->setRange(0, point_spread.total_count); + m_game_progress_soft->setValue(point_spread.hard_unlocks + point_spread.soft_unlocks); + // TODO: RP needs a minor refactor to work here, will be a future PR + // m_rich_presence->setText(QString::fromStdString(AchievementManager::GetInstance()->GenerateRichPresence())); + // m_rich_presence->setVisible(Config::Get(Config::RA_RICH_PRESENCE_ENABLED)); + m_rich_presence->setText(QString{}); + m_rich_presence->setVisible(false); + + m_user_box->setVisible(false); + m_game_box->setVisible(true); +} + +QString +AchievementHeaderWidget::GetPointsString(const QString& user_name, + const AchievementManager::PointSpread& point_spread) const +{ + if (point_spread.soft_points > 0) + { + return tr("%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 hardcore)") + .arg(user_name) + .arg(point_spread.hard_unlocks + point_spread.soft_unlocks) + .arg(point_spread.total_count) + .arg(point_spread.hard_unlocks) + .arg(point_spread.hard_points + point_spread.soft_points) + .arg(point_spread.total_points) + .arg(point_spread.hard_points); + } + else + { + return tr("%1 has unlocked %2/%3 achievements worth %4/%5 points") + .arg(user_name) + .arg(point_spread.hard_unlocks) + .arg(point_spread.total_count) + .arg(point_spread.hard_points) + .arg(point_spread.total_points); + } +} + +#endif // USE_RETRO_ACHIEVEMENTS diff --git a/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h new file mode 100644 index 0000000000..b99457f2f1 --- /dev/null +++ b/Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.h @@ -0,0 +1,42 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#ifdef USE_RETRO_ACHIEVEMENTS +#include + +#include "Core/AchievementManager.h" + +class QGroupBox; +class QLabel; +class QProgressBar; +class QVBoxLayout; + +class AchievementHeaderWidget final : public QWidget +{ + Q_OBJECT +public: + explicit AchievementHeaderWidget(QWidget* parent); + void UpdateData(); + +private: + QString GetPointsString(const QString& user_name, + const AchievementManager::PointSpread& point_spread) const; + + QGroupBox* m_common_box; + QVBoxLayout* m_common_layout; + + QLabel* m_user_name; + QLabel* m_user_points; + QLabel* m_game_name; + QLabel* m_game_points; + QProgressBar* m_game_progress_hard; + QProgressBar* m_game_progress_soft; + QLabel* m_rich_presence; + + QGroupBox* m_user_box; + QGroupBox* m_game_box; +}; + +#endif // USE_RETRO_ACHIEVEMENTS diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp index b23843f75b..1d08ede223 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp @@ -8,6 +8,7 @@ #include #include +#include "DolphinQt/Achievements/AchievementHeaderWidget.h" #include "DolphinQt/Achievements/AchievementSettingsWidget.h" #include "DolphinQt/QtUtils/WrapInScrollArea.h" @@ -30,6 +31,7 @@ void AchievementsWindow::CreateMainLayout() { auto* layout = new QVBoxLayout(); + m_header_widget = new AchievementHeaderWidget(this); m_tab_widget = new QTabWidget(); m_tab_widget->addTab( GetWrappedWidget(new AchievementSettingsWidget(m_tab_widget, this), this, 125, 100), @@ -37,6 +39,7 @@ void AchievementsWindow::CreateMainLayout() m_button_box = new QDialogButtonBox(QDialogButtonBox::Close); + layout->addWidget(m_header_widget); layout->addWidget(m_tab_widget); layout->addWidget(m_button_box); @@ -50,6 +53,8 @@ void AchievementsWindow::ConnectWidgets() void AchievementsWindow::UpdateData() { + m_header_widget->UpdateData(); + m_header_widget->setVisible(AchievementManager::GetInstance()->IsLoggedIn()); update(); } diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.h b/Source/Core/DolphinQt/Achievements/AchievementsWindow.h index 9570e8127f..0e9a8bfdbe 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.h +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.h @@ -6,6 +6,7 @@ #ifdef USE_RETRO_ACHIEVEMENTS #include +class AchievementHeaderWidget; class QTabWidget; class QDialogButtonBox; @@ -21,6 +22,7 @@ private: void showEvent(QShowEvent* event); void ConnectWidgets(); + AchievementHeaderWidget* m_header_widget; QTabWidget* m_tab_widget; QDialogButtonBox* m_button_box; }; diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index e302287677..6ce4591cc6 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -27,6 +27,8 @@ add_executable(dolphin-emu CheatSearchWidget.h CheatsManager.cpp CheatsManager.h + Achievements/AchievementHeaderWidget.cpp + Achievements/AchievementHeaderWidget.h Achievements/AchievementSettingsWidget.cpp Achievements/AchievementSettingsWidget.h Achievements/AchievementsWindow.cpp diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 79b05b372b..1d6512692e 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -50,6 +50,7 @@ + @@ -256,6 +257,7 @@ + From 582042de1f80e68c72952e124fe18698d2cb494f Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 2 Jun 2023 21:25:01 -0400 Subject: [PATCH 09/99] Added AchievementProgressWidget to AchievementsWindow This widget is a tab in the AchievementsWindow that displays the player's current achievement progress: which achievements are locked or unlocked, and the progress of achievements that have progress metrics. --- .../AchievementProgressWidget.cpp | 124 ++++++++++++++++++ .../Achievements/AchievementProgressWidget.h | 34 +++++ .../Achievements/AchievementsWindow.cpp | 7 + .../Achievements/AchievementsWindow.h | 4 + Source/Core/DolphinQt/CMakeLists.txt | 2 + Source/Core/DolphinQt/DolphinQt.vcxproj | 2 + 6 files changed, 173 insertions(+) create mode 100644 Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp create mode 100644 Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h diff --git a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp new file mode 100644 index 0000000000..9f8c38bfe5 --- /dev/null +++ b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp @@ -0,0 +1,124 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifdef USE_RETRO_ACHIEVEMENTS +#include "DolphinQt/Achievements/AchievementProgressWidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "Core/AchievementManager.h" +#include "Core/Config/AchievementSettings.h" +#include "Core/Config/MainSettings.h" +#include "Core/Core.h" + +#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h" +#include "DolphinQt/QtUtils/ModalMessageBox.h" +#include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SignalBlocking.h" +#include "DolphinQt/Settings.h" + +AchievementProgressWidget::AchievementProgressWidget(QWidget* parent) : QWidget(parent) +{ + m_common_box = new QGroupBox(); + m_common_layout = new QVBoxLayout(); + + UpdateData(); + + m_common_box->setLayout(m_common_layout); + + auto* layout = new QVBoxLayout; + layout->setContentsMargins(0, 0, 0, 0); + layout->setAlignment(Qt::AlignTop); + layout->addWidget(m_common_box); + setLayout(layout); +} + +QGroupBox* +AchievementProgressWidget::CreateAchievementBox(const rc_api_achievement_definition_t* achievement) +{ + QLabel* a_title = new QLabel(QString::fromUtf8(achievement->title, strlen(achievement->title))); + QLabel* a_description = + new QLabel(QString::fromUtf8(achievement->description, strlen(achievement->description))); + QLabel* a_points = new QLabel(tr("%1 points").arg(achievement->points)); + QLabel* a_status = new QLabel(GetStatusString(achievement->id)); + QProgressBar* a_progress_bar = new QProgressBar(); + unsigned int value = 0; + unsigned int target = 0; + AchievementManager::GetInstance()->GetAchievementProgress(achievement->id, &value, &target); + if (target > 0) + { + a_progress_bar->setRange(0, target); + a_progress_bar->setValue(value); + } + else + { + a_progress_bar->setVisible(false); + } + + QVBoxLayout* a_col_right = new QVBoxLayout(); + a_col_right->addWidget(a_title); + a_col_right->addWidget(a_description); + a_col_right->addWidget(a_points); + a_col_right->addWidget(a_status); + a_col_right->addWidget(a_progress_bar); + QHBoxLayout* a_total = new QHBoxLayout(); + // TODO: achievement badge goes here + a_total->addLayout(a_col_right); + QGroupBox* a_group_box = new QGroupBox(); + a_group_box->setLayout(a_total); + return a_group_box; +} + +void AchievementProgressWidget::UpdateData() +{ + QLayoutItem* item; + while ((item = m_common_layout->layout()->takeAt(0)) != nullptr) + { + delete item->widget(); + delete item; + } + + const auto* game_data = AchievementManager::GetInstance()->GetGameData(); + for (u32 ix = 0; ix < game_data->num_achievements; ix++) + { + m_common_layout->addWidget(CreateAchievementBox(game_data->achievements + ix)); + } +} + +QString AchievementProgressWidget::GetStatusString(u32 achievement_id) const +{ + const auto unlock_status = AchievementManager::GetInstance()->GetUnlockStatus(achievement_id); + if (unlock_status.session_unlock_count > 0) + { + if (Config::Get(Config::RA_ENCORE_ENABLED)) + { + return tr("Unlocked %1 times this session").arg(unlock_status.session_unlock_count); + } + return tr("Unlocked this session"); + } + switch (unlock_status.remote_unlock_status) + { + case AchievementManager::UnlockStatus::UnlockType::LOCKED: + return tr("Locked"); + case AchievementManager::UnlockStatus::UnlockType::SOFTCORE: + return tr("Unlocked (Casual)"); + case AchievementManager::UnlockStatus::UnlockType::HARDCORE: + return tr("Unlocked"); + } + return {}; +} + +#endif // USE_RETRO_ACHIEVEMENTS diff --git a/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h new file mode 100644 index 0000000000..b1e09e40d8 --- /dev/null +++ b/Source/Core/DolphinQt/Achievements/AchievementProgressWidget.h @@ -0,0 +1,34 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#ifdef USE_RETRO_ACHIEVEMENTS +#include + +#include "Common/CommonTypes.h" + +class QCheckBox; +class QGroupBox; +class QLineEdit; +class QPushButton; +class QVBoxLayout; + +struct rc_api_achievement_definition_t; + +class AchievementProgressWidget final : public QWidget +{ + Q_OBJECT +public: + explicit AchievementProgressWidget(QWidget* parent); + void UpdateData(); + +private: + QGroupBox* CreateAchievementBox(const rc_api_achievement_definition_t* achievement); + QString GetStatusString(u32 achievement_id) const; + + QGroupBox* m_common_box; + QVBoxLayout* m_common_layout; +}; + +#endif // USE_RETRO_ACHIEVEMENTS diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp index 1d08ede223..451408fde5 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp @@ -9,6 +9,7 @@ #include #include "DolphinQt/Achievements/AchievementHeaderWidget.h" +#include "DolphinQt/Achievements/AchievementProgressWidget.h" #include "DolphinQt/Achievements/AchievementSettingsWidget.h" #include "DolphinQt/QtUtils/WrapInScrollArea.h" @@ -33,9 +34,12 @@ void AchievementsWindow::CreateMainLayout() m_header_widget = new AchievementHeaderWidget(this); m_tab_widget = new QTabWidget(); + m_progress_widget = new AchievementProgressWidget(m_tab_widget); m_tab_widget->addTab( GetWrappedWidget(new AchievementSettingsWidget(m_tab_widget, this), this, 125, 100), tr("Settings")); + m_tab_widget->addTab(GetWrappedWidget(m_progress_widget, this, 125, 100), tr("Progress")); + m_tab_widget->setTabVisible(1, AchievementManager::GetInstance()->IsGameLoaded()); m_button_box = new QDialogButtonBox(QDialogButtonBox::Close); @@ -55,6 +59,9 @@ void AchievementsWindow::UpdateData() { m_header_widget->UpdateData(); m_header_widget->setVisible(AchievementManager::GetInstance()->IsLoggedIn()); + // Settings tab handles its own updates ... indeed, that calls this + m_progress_widget->UpdateData(); + m_tab_widget->setTabVisible(1, AchievementManager::GetInstance()->IsGameLoaded()); update(); } diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.h b/Source/Core/DolphinQt/Achievements/AchievementsWindow.h index 0e9a8bfdbe..1d9f089836 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.h +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.h @@ -6,7 +6,10 @@ #ifdef USE_RETRO_ACHIEVEMENTS #include +#include "Core/AchievementManager.h" + class AchievementHeaderWidget; +class AchievementProgressWidget; class QTabWidget; class QDialogButtonBox; @@ -24,6 +27,7 @@ private: AchievementHeaderWidget* m_header_widget; QTabWidget* m_tab_widget; + AchievementProgressWidget* m_progress_widget; QDialogButtonBox* m_button_box; }; diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 6ce4591cc6..7087f03429 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -29,6 +29,8 @@ add_executable(dolphin-emu CheatsManager.h Achievements/AchievementHeaderWidget.cpp Achievements/AchievementHeaderWidget.h + Achievements/AchievementProgressWidget.cpp + Achievements/AchievementProgressWidget.h Achievements/AchievementSettingsWidget.cpp Achievements/AchievementSettingsWidget.h Achievements/AchievementsWindow.cpp diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 1d6512692e..ac769a10b9 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -51,6 +51,7 @@ + @@ -258,6 +259,7 @@ + From fbaeaf305bb713ca0a507713b132ee42f10a6e51 Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 2 Jun 2023 21:31:30 -0400 Subject: [PATCH 10/99] Add UpdateCallback to AchievementManager AchievementManager now has a SetUpdateCallback method for providing a single universal callback for anytime something important changes in the achievement state, such as logging in/out, game load/close, or events such as achievement unlocks. AchievementsWindow sets this callback in its own init to its UpdateData method so that the AchievementsWindow gets updated when one of these changes takes place. --- Source/Core/Core/AchievementManager.cpp | 27 +++++++++++++++++-- Source/Core/Core/AchievementManager.h | 3 +++ .../Achievements/AchievementsWindow.cpp | 3 +++ .../Achievements/AchievementsWindow.h | 4 ++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 27e82a8c55..407e0bed58 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -38,11 +38,20 @@ void AchievementManager::Init() } } +void AchievementManager::SetUpdateCallback(UpdateCallback callback) +{ + m_update_callback = std::move(callback); + m_update_callback(); +} + AchievementManager::ResponseType AchievementManager::Login(const std::string& password) { if (!m_is_runtime_initialized) return AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED; - return VerifyCredentials(password); + AchievementManager::ResponseType r_type = VerifyCredentials(password); + if (m_update_callback) + m_update_callback(); + return r_type; } void AchievementManager::LoginAsync(const std::string& password, const ResponseCallback& callback) @@ -52,7 +61,11 @@ void AchievementManager::LoginAsync(const std::string& password, const ResponseC callback(AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED); return; } - m_queue.EmplaceItem([this, password, callback] { callback(VerifyCredentials(password)); }); + m_queue.EmplaceItem([this, password, callback] { + callback(VerifyCredentials(password)); + if (m_update_callback) + m_update_callback(); + }); } bool AchievementManager::IsLoggedIn() const @@ -179,6 +192,8 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, // Reset this to zero so that RP immediately triggers on the first frame m_last_ping_time = 0; + if (m_update_callback) + m_update_callback(); callback(fetch_game_data_response); }); } @@ -199,6 +214,8 @@ void AchievementManager::LoadUnlockData(const ResponseCallback& callback) } callback(FetchUnlockData(false)); + if (m_update_callback) + m_update_callback(); }); } @@ -316,6 +333,8 @@ void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runti HandleLeaderboardTriggeredEvent(runtime_event); break; } + if (m_update_callback) + m_update_callback(); } std::string AchievementManager::GetPlayerDisplayName() const @@ -386,12 +405,16 @@ void AchievementManager::CloseGame() ActivateDeactivateAchievements(); ActivateDeactivateLeaderboards(); ActivateDeactivateRichPresence(); + if (m_update_callback) + m_update_callback(); } void AchievementManager::Logout() { CloseGame(); Config::SetBaseOrCurrent(Config::RA_API_TOKEN, ""); + if (m_update_callback) + m_update_callback(); } void AchievementManager::Shutdown() diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 00c2055920..9a4289612d 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -41,6 +41,7 @@ public: UNKNOWN_FAILURE }; using ResponseCallback = std::function; + using UpdateCallback = std::function; struct PointSpread { @@ -67,6 +68,7 @@ public: static AchievementManager* GetInstance(); void Init(); + void SetUpdateCallback(UpdateCallback callback); ResponseType Login(const std::string& password); void LoginAsync(const std::string& password, const ResponseCallback& callback); bool IsLoggedIn() const; @@ -125,6 +127,7 @@ private: rc_runtime_t m_runtime{}; Core::System* m_system{}; bool m_is_runtime_initialized = false; + UpdateCallback m_update_callback; std::string m_display_name; u32 m_player_score = 0; std::array m_game_hash{}; diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp index 451408fde5..40de94ee92 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp @@ -11,6 +11,7 @@ #include "DolphinQt/Achievements/AchievementHeaderWidget.h" #include "DolphinQt/Achievements/AchievementProgressWidget.h" #include "DolphinQt/Achievements/AchievementSettingsWidget.h" +#include "DolphinQt/QtUtils/QueueOnObject.h" #include "DolphinQt/QtUtils/WrapInScrollArea.h" AchievementsWindow::AchievementsWindow(QWidget* parent) : QDialog(parent) @@ -20,6 +21,8 @@ AchievementsWindow::AchievementsWindow(QWidget* parent) : QDialog(parent) CreateMainLayout(); ConnectWidgets(); + AchievementManager::GetInstance()->SetUpdateCallback( + [this] { QueueOnObject(this, &AchievementsWindow::UpdateData); }); } void AchievementsWindow::showEvent(QShowEvent* event) diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.h b/Source/Core/DolphinQt/Achievements/AchievementsWindow.h index 1d9f089836..d8407a3a17 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.h +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.h @@ -7,11 +7,13 @@ #include #include "Core/AchievementManager.h" +#include "DolphinQt/QtUtils/QueueOnObject.h" class AchievementHeaderWidget; class AchievementProgressWidget; -class QTabWidget; class QDialogButtonBox; +class QTabWidget; +class UpdateCallback; class AchievementsWindow : public QDialog { From ccc9d0e5ea12e33c06be1a695873b0fce56e1bff Mon Sep 17 00:00:00 2001 From: LillyJadeKatrin Date: Fri, 9 Jun 2023 17:05:52 -0400 Subject: [PATCH 11/99] Synchronized Achievement Window Expanded the use of the lock mutex already used for loading the player's existing unlock status to guard against races involving the Achievements dialog window reading from data AchievementManager might be in the process of updating. The lock has been exposed publicly and the AchievementsWindow uses it in its UpdateData method, and anywhere else that might modify data used to render that window has also been wrapped with it. --- Source/Core/Core/AchievementManager.cpp | 67 ++++++++++++------- Source/Core/Core/AchievementManager.h | 1 + .../Achievements/AchievementsWindow.cpp | 15 +++-- 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/Source/Core/Core/AchievementManager.cpp b/Source/Core/Core/AchievementManager.cpp index 407e0bed58..ef23dcf163 100644 --- a/Source/Core/Core/AchievementManager.cpp +++ b/Source/Core/Core/AchievementManager.cpp @@ -48,7 +48,11 @@ AchievementManager::ResponseType AchievementManager::Login(const std::string& pa { if (!m_is_runtime_initialized) return AchievementManager::ResponseType::MANAGER_NOT_INITIALIZED; - AchievementManager::ResponseType r_type = VerifyCredentials(password); + AchievementManager::ResponseType r_type = AchievementManager::ResponseType::UNKNOWN_FAILURE; + { + std::lock_guard lg{m_lock}; + r_type = VerifyCredentials(password); + } if (m_update_callback) m_update_callback(); return r_type; @@ -62,7 +66,10 @@ void AchievementManager::LoginAsync(const std::string& password, const ResponseC return; } m_queue.EmplaceItem([this, password, callback] { + { + std::lock_guard lg{m_lock}; callback(VerifyCredentials(password)); + } if (m_update_callback) m_update_callback(); }); @@ -154,11 +161,11 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, } const auto fetch_game_data_response = FetchGameData(); - m_is_game_loaded = fetch_game_data_response == ResponseType::SUCCESS; - if (!m_is_game_loaded) + if (fetch_game_data_response != ResponseType::SUCCESS) { OSD::AddMessage("Unable to retrieve data from RetroAchievements server.", OSD::Duration::VERY_LONG, OSD::Color::RED); + return; } // Claim the lock, then queue the fetch unlock data calls, then initialize the unlock map in @@ -167,6 +174,7 @@ void AchievementManager::LoadGameByFilenameAsync(const std::string& iso_path, // it. { std::lock_guard lg{m_lock}; + m_is_game_loaded = true; LoadUnlockData([](ResponseType r_type) {}); ActivateDeactivateAchievements(); PointSpread spread = TallyScore(); @@ -318,25 +326,33 @@ u32 AchievementManager::MemoryPeeker(u32 address, u32 num_bytes, void* ud) void AchievementManager::AchievementEventHandler(const rc_runtime_event_t* runtime_event) { - switch (runtime_event->type) { - case RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED: - HandleAchievementTriggeredEvent(runtime_event); - break; - case RC_RUNTIME_EVENT_LBOARD_STARTED: - HandleLeaderboardStartedEvent(runtime_event); - break; - case RC_RUNTIME_EVENT_LBOARD_CANCELED: - HandleLeaderboardCanceledEvent(runtime_event); - break; - case RC_RUNTIME_EVENT_LBOARD_TRIGGERED: - HandleLeaderboardTriggeredEvent(runtime_event); - break; + std::lock_guard lg{m_lock}; + switch (runtime_event->type) + { + case RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED: + HandleAchievementTriggeredEvent(runtime_event); + break; + case RC_RUNTIME_EVENT_LBOARD_STARTED: + HandleLeaderboardStartedEvent(runtime_event); + break; + case RC_RUNTIME_EVENT_LBOARD_CANCELED: + HandleLeaderboardCanceledEvent(runtime_event); + break; + case RC_RUNTIME_EVENT_LBOARD_TRIGGERED: + HandleLeaderboardTriggeredEvent(runtime_event); + break; + } } if (m_update_callback) m_update_callback(); } +std::recursive_mutex* AchievementManager::GetLock() +{ + return &m_lock; +} + std::string AchievementManager::GetPlayerDisplayName() const { return IsLoggedIn() ? m_display_name : ""; @@ -397,14 +413,17 @@ void AchievementManager::GetAchievementProgress(AchievementId achievement_id, u3 void AchievementManager::CloseGame() { - m_is_game_loaded = false; - m_game_id = 0; - m_queue.Cancel(); - m_unlock_map.clear(); - m_system = nullptr; - ActivateDeactivateAchievements(); - ActivateDeactivateLeaderboards(); - ActivateDeactivateRichPresence(); + { + std::lock_guard lg{m_lock}; + m_is_game_loaded = false; + m_game_id = 0; + m_queue.Cancel(); + m_unlock_map.clear(); + m_system = nullptr; + ActivateDeactivateAchievements(); + ActivateDeactivateLeaderboards(); + ActivateDeactivateRichPresence(); + } if (m_update_callback) m_update_callback(); } diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index 9a4289612d..14b6b0ec77 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -84,6 +84,7 @@ public: u32 MemoryPeeker(u32 address, u32 num_bytes, void* ud); void AchievementEventHandler(const rc_runtime_event_t* runtime_event); + std::recursive_mutex* GetLock(); std::string GetPlayerDisplayName() const; u32 GetPlayerScore() const; std::string GetGameDisplayName() const; diff --git a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp index 40de94ee92..d791d1b107 100644 --- a/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp +++ b/Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp @@ -4,6 +4,8 @@ #ifdef USE_RETRO_ACHIEVEMENTS #include "DolphinQt/Achievements/AchievementsWindow.h" +#include + #include #include #include @@ -60,11 +62,14 @@ void AchievementsWindow::ConnectWidgets() void AchievementsWindow::UpdateData() { - m_header_widget->UpdateData(); - m_header_widget->setVisible(AchievementManager::GetInstance()->IsLoggedIn()); - // Settings tab handles its own updates ... indeed, that calls this - m_progress_widget->UpdateData(); - m_tab_widget->setTabVisible(1, AchievementManager::GetInstance()->IsGameLoaded()); + { + std::lock_guard lg{*AchievementManager::GetInstance()->GetLock()}; + m_header_widget->UpdateData(); + m_header_widget->setVisible(AchievementManager::GetInstance()->IsLoggedIn()); + // Settings tab handles its own updates ... indeed, that calls this + m_progress_widget->UpdateData(); + m_tab_widget->setTabVisible(1, AchievementManager::GetInstance()->IsGameLoaded()); + } update(); } From 98c904918428f7f0d4a1d0f83decc02b257da709 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Tue, 13 Jun 2023 12:20:28 -0700 Subject: [PATCH 12/99] GekkoDisassembler: Remove unread variable m_sreg --- Source/Core/Common/GekkoDisassembler.cpp | 4 ---- Source/Core/Common/GekkoDisassembler.h | 1 - 2 files changed, 5 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index 17db752b7b..8a9bf73cd3 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -154,7 +154,6 @@ u32* GekkoDisassembler::m_iaddr = nullptr; std::string GekkoDisassembler::m_opcode; std::string GekkoDisassembler::m_operands; unsigned char GekkoDisassembler::m_flags = PPCF_ILLEGAL; -unsigned short GekkoDisassembler::m_sreg = 0; u32 GekkoDisassembler::m_displacement = 0; static u32 HelperRotateMask(int r, int mb, int me) @@ -927,9 +926,6 @@ void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg, unsigned c int d = (u32)(in & 0xffff); m_flags |= dmode; - m_sreg = (short)a; - // if (d >= 0x8000) - // d -= 0x10000; m_displacement = (u32)d; m_opcode = name; diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index b7a6e7bf5f..fa4b2d75b2 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -105,7 +105,6 @@ private: static std::string m_opcode; // Buffer for opcode, min. 10 chars. static std::string m_operands; // Operand buffer, min. 24 chars. static unsigned char m_flags; // Additional flags - static unsigned short m_sreg; // Register in load/store instructions static u32 m_displacement; // Branch- or load/store displacement }; } // namespace Common From c8e276c6f5eb58bf4542a0235bc332def2ea7de6 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Tue, 13 Jun 2023 12:59:46 -0700 Subject: [PATCH 13/99] GekkoDisassembler: Remove unread variable m_displacement --- Source/Core/Common/GekkoDisassembler.cpp | 7 ------- Source/Core/Common/GekkoDisassembler.h | 1 - 2 files changed, 8 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index 8a9bf73cd3..59ea32f170 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -154,7 +154,6 @@ u32* GekkoDisassembler::m_iaddr = nullptr; std::string GekkoDisassembler::m_opcode; std::string GekkoDisassembler::m_operands; unsigned char GekkoDisassembler::m_flags = PPCF_ILLEGAL; -u32 GekkoDisassembler::m_displacement = 0; static u32 HelperRotateMask(int r, int mb, int me) { @@ -392,7 +391,6 @@ std::string GekkoDisassembler::imm(u32 in, int uimm, int type, bool hex) { m_flags |= PPCF_UNSIGNED; } - m_displacement = i; switch (type) { @@ -582,8 +580,6 @@ void GekkoDisassembler::bc(u32 in) m_operands = fmt::format("{} ->0x{:08X}", m_operands, d); else m_operands = fmt::format("{} ->0x{:08X}", m_operands, *m_iaddr + d); - - m_displacement = d; } void GekkoDisassembler::bli(u32 in) @@ -599,8 +595,6 @@ void GekkoDisassembler::bli(u32 in) m_operands = fmt::format("->0x{:08X}", d); else m_operands = fmt::format("->0x{:08X}", *m_iaddr + d); - - m_displacement = d; } void GekkoDisassembler::mcrf(u32 in, std::string_view suffix) @@ -926,7 +920,6 @@ void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg, unsigned c int d = (u32)(in & 0xffff); m_flags |= dmode; - m_displacement = (u32)d; m_opcode = name; if (reg == 'r') diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index fa4b2d75b2..e18fd584f9 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -105,6 +105,5 @@ private: static std::string m_opcode; // Buffer for opcode, min. 10 chars. static std::string m_operands; // Operand buffer, min. 24 chars. static unsigned char m_flags; // Additional flags - static u32 m_displacement; // Branch- or load/store displacement }; } // namespace Common From a93e6e73972cb5ddd471c46282e2d14011d1b2d0 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 24 Jun 2023 02:02:53 -0500 Subject: [PATCH 14/99] VideoCommon: add support for allowing a TextureCache entry to be associated with multiple assets --- Source/Core/VideoCommon/TextureCacheBase.cpp | 78 +++++++++++++------- Source/Core/VideoCommon/TextureCacheBase.h | 11 +-- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index c26cbb5f4c..83fbf6b014 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -263,11 +263,16 @@ void TextureCacheBase::SetBackupConfig(const VideoConfig& config) bool TextureCacheBase::DidLinkedAssetsChange(const TCacheEntry& entry) { - if (!entry.linked_asset.m_asset) - return false; + for (const auto& cached_asset : entry.linked_game_texture_assets) + { + if (cached_asset.m_asset) + { + if (cached_asset.m_asset->GetLastLoadedTime() > cached_asset.m_cached_write_time) + return true; + } + } - const auto last_asset_write_time = entry.linked_asset.m_asset->GetLastLoadedTime(); - return last_asset_write_time > entry.linked_asset.m_cached_write_time; + return false; } RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const u8* palette, @@ -1590,8 +1595,8 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp InvalidateTexture(oldest_entry); } - VideoCommon::CachedAsset cached_texture_asset; - std::shared_ptr data = nullptr; + std::vector> cached_game_assets; + std::vector> data_for_assets; bool has_arbitrary_mipmaps = false; std::shared_ptr hires_texture; if (g_ActiveConfig.bHiresTextures) @@ -1599,31 +1604,37 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp hires_texture = HiresTexture::Search(texture_info); if (hires_texture) { - data = hires_texture->GetAsset()->GetData(); - cached_texture_asset = {hires_texture->GetAsset(), - hires_texture->GetAsset()->GetLastLoadedTime()}; + auto asset = hires_texture->GetAsset(); + const auto loaded_time = asset->GetLastLoadedTime(); + cached_game_assets.push_back( + VideoCommon::CachedAsset{std::move(asset), loaded_time}); has_arbitrary_mipmaps = hires_texture->HasArbitraryMipmaps(); - if (data) + } + } + + for (auto& cached_asset : cached_game_assets) + { + auto data = cached_asset.m_asset->GetData(); + if (data) + { + if (cached_asset.m_asset->Validate(texture_info.GetRawWidth(), texture_info.GetRawHeight())) { - if (!hires_texture->GetAsset()->Validate(texture_info.GetRawWidth(), - texture_info.GetRawHeight())) - { - data = nullptr; - } + data_for_assets.push_back(std::move(data)); } } } auto entry = CreateTextureEntry( TextureCreationInfo{base_hash, full_hash, bytes_per_block, palette_size}, texture_info, - textureCacheSafetyColorSampleSize, data.get(), has_arbitrary_mipmaps); - entry->linked_asset = std::move(cached_texture_asset); + textureCacheSafetyColorSampleSize, std::move(data_for_assets), has_arbitrary_mipmaps); + entry->linked_game_texture_assets = std::move(cached_game_assets); return entry; } RcTcacheEntry TextureCacheBase::CreateTextureEntry( const TextureCreationInfo& creation_info, const TextureInfo& texture_info, - const int safety_color_sample_size, const VideoCommon::CustomTextureData* custom_texture_data, + const int safety_color_sample_size, + std::vector> assets_data, const bool custom_arbitrary_mipmaps) { #ifdef __APPLE__ @@ -1633,20 +1644,33 @@ RcTcacheEntry TextureCacheBase::CreateTextureEntry( #endif RcTcacheEntry entry; - if (custom_texture_data && custom_texture_data->m_levels.size() >= 1) + if (!assets_data.empty()) { - const u32 texLevels = no_mips ? 1 : (u32)custom_texture_data->m_levels.size(); - const auto& first_level = custom_texture_data->m_levels[0]; - const TextureConfig config(first_level.width, first_level.height, texLevels, 1, 1, - first_level.format, 0); + const auto calculate_max_levels = [&]() { + const auto max_element = std::max_element( + assets_data.begin(), assets_data.end(), [](const auto& lhs, const auto& rhs) { + return lhs->m_levels.size() < rhs->m_levels.size(); + }); + return max_element->get()->m_levels.size(); + }; + const u32 texLevels = no_mips ? 1 : (u32)calculate_max_levels(); + const auto& first_level = assets_data[0]->m_levels[0]; + const TextureConfig config(first_level.width, first_level.height, texLevels, + static_cast(assets_data.size()), 1, first_level.format, 0); entry = AllocateCacheEntry(config); if (!entry) [[unlikely]] return entry; - for (u32 level_index = 0; level_index != texLevels; ++level_index) + for (u32 data_index = 0; data_index < static_cast(assets_data.size()); data_index++) { - const auto& level = custom_texture_data->m_levels[level_index]; - entry->texture->Load(level_index, level.width, level.height, level.row_length, - level.data.data(), level.data.size()); + const auto asset = assets_data[data_index]; + for (u32 level_index = 0; + level_index < std::min(texLevels, static_cast(asset->m_levels.size())); + ++level_index) + { + const auto& level = asset->m_levels[level_index]; + entry->texture->Load(level_index, level.width, level.height, level.row_length, + level.data.data(), level.data.size(), data_index); + } } entry->has_arbitrary_mips = custom_arbitrary_mipmaps; diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index f248d2b49f..db5e11ea29 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -167,7 +167,7 @@ struct TCacheEntry std::string texture_info_name = ""; - VideoCommon::CachedAsset linked_asset; + std::vector> linked_game_texture_assets; explicit TCacheEntry(std::unique_ptr tex, std::unique_ptr fb); @@ -346,10 +346,11 @@ private: void SetBackupConfig(const VideoConfig& config); - RcTcacheEntry CreateTextureEntry(const TextureCreationInfo& creation_info, - const TextureInfo& texture_info, int safety_color_sample_size, - const VideoCommon::CustomTextureData* custom_texture_data, - bool custom_arbitrary_mipmaps); + RcTcacheEntry + CreateTextureEntry(const TextureCreationInfo& creation_info, const TextureInfo& texture_info, + int safety_color_sample_size, + std::vector> assets_data, + bool custom_arbitrary_mipmaps); RcTcacheEntry GetXFBFromCache(u32 address, u32 width, u32 height, u32 stride); From 0539bb4a3ea4afed58c2a43a98c51baea760815d Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 2 Jul 2023 13:35:05 -0500 Subject: [PATCH 15/99] VideoCommon: call into graphics mods create texture callback, providing additional asset dependencies that trigger the texture to be reloaded --- .../Runtime/GraphicsModActionData.h | 9 ++++ Source/Core/VideoCommon/TextureCacheBase.cpp | 44 +++++++++++++++++++ Source/Core/VideoCommon/TextureCacheBase.h | 1 + 3 files changed, 54 insertions(+) diff --git a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h index 48de0e5368..2b1408dcc9 100644 --- a/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h +++ b/Source/Core/VideoCommon/GraphicsModSystem/Runtime/GraphicsModActionData.h @@ -4,9 +4,11 @@ #pragma once #include +#include #include "Common/CommonTypes.h" #include "Common/Matrix.h" +#include "VideoCommon/Assets/TextureAsset.h" namespace GraphicsModActionData { @@ -34,5 +36,12 @@ struct TextureLoad }; struct TextureCreate { + std::string_view texture_name; + u32 texture_width; + u32 texture_height; + std::vector>* custom_textures; + + // Dependencies needed to reload the texture and trigger this create again + std::vector>* additional_dependencies; }; } // namespace GraphicsModActionData diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 5dc00a9733..7ad97f94db 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -272,6 +272,15 @@ bool TextureCacheBase::DidLinkedAssetsChange(const TCacheEntry& entry) } } + for (const auto& cached_asset : entry.linked_asset_dependencies) + { + if (cached_asset.m_asset) + { + if (cached_asset.m_asset->GetLastLoadedTime() > cached_asset.m_cached_write_time) + return true; + } + } + return false; } @@ -1612,6 +1621,39 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp } } + std::vector> additional_dependencies; + + std::string texture_name = ""; + + if (g_ActiveConfig.bGraphicMods) + { + u32 height = texture_info.GetRawHeight(); + u32 width = texture_info.GetRawWidth(); + if (hires_texture) + { + auto asset = hires_texture->GetAsset(); + if (asset) + { + auto data = asset->GetData(); + if (data) + { + if (!data->m_levels.empty()) + { + height = data->m_levels[0].height; + width = data->m_levels[0].width; + } + } + } + } + texture_name = texture_info.CalculateTextureName().GetFullName(); + GraphicsModActionData::TextureCreate texture_create{ + texture_name, width, height, &cached_game_assets, &additional_dependencies}; + for (const auto& action : g_graphics_mod_manager->GetTextureCreateActions(texture_name)) + { + action->OnTextureCreate(&texture_create); + } + } + for (auto& cached_asset : cached_game_assets) { auto data = cached_asset.m_asset->GetData(); @@ -1628,6 +1670,8 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp TextureCreationInfo{base_hash, full_hash, bytes_per_block, palette_size}, texture_info, textureCacheSafetyColorSampleSize, std::move(data_for_assets), has_arbitrary_mipmaps); entry->linked_game_texture_assets = std::move(cached_game_assets); + entry->linked_asset_dependencies = std::move(additional_dependencies); + entry->texture_info_name = std::move(texture_name); return entry; } diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index db5e11ea29..65b0d2b469 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -168,6 +168,7 @@ struct TCacheEntry std::string texture_info_name = ""; std::vector> linked_game_texture_assets; + std::vector> linked_asset_dependencies; explicit TCacheEntry(std::unique_ptr tex, std::unique_ptr fb); From a2ad3ca6f72b15e89ccc2f52ba6b17fe62f78202 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 2 Jul 2023 13:58:07 -0500 Subject: [PATCH 16/99] VideoCommon: don't do pointer copies during graphics mod callback iteration --- Source/Core/VideoCommon/TextureCacheBase.cpp | 6 +++--- Source/Core/VideoCommon/VertexManagerBase.cpp | 2 +- Source/Core/VideoCommon/VertexShaderManager.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 5dc00a9733..5dea8e6e34 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -1322,7 +1322,7 @@ TCacheEntry* TextureCacheBase::LoadImpl(const TextureInfo& texture_info, bool fo entry->texture_info_name = texture_info.CalculateTextureName().GetFullName(); GraphicsModActionData::TextureLoad texture_load{entry->texture_info_name}; - for (const auto action : + for (const auto& action : g_graphics_mod_manager->GetTextureLoadActions(entry->texture_info_name)) { action->OnTextureLoad(&texture_load); @@ -2274,7 +2274,7 @@ void TextureCacheBase::CopyRenderTargetToTexture( info.m_texture_format = baseFormat; if (is_xfb_copy) { - for (const auto action : g_graphics_mod_manager->GetXFBActions(info)) + for (const auto& action : g_graphics_mod_manager->GetXFBActions(info)) { action->OnXFB(); } @@ -2283,7 +2283,7 @@ void TextureCacheBase::CopyRenderTargetToTexture( { bool skip = false; GraphicsModActionData::EFB efb{tex_w, tex_h, &skip, &scaled_tex_w, &scaled_tex_h}; - for (const auto action : g_graphics_mod_manager->GetEFBActions(info)) + for (const auto& action : g_graphics_mod_manager->GetEFBActions(info)) { action->OnEFB(&efb); } diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 768ac82fe7..0b184e1da9 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -566,7 +566,7 @@ void VertexManagerBase::Flush() { bool skip = false; GraphicsModActionData::DrawStarted draw_started{&skip}; - for (const auto action : g_graphics_mod_manager->GetDrawStartedActions(texture_name)) + for (const auto& action : g_graphics_mod_manager->GetDrawStartedActions(texture_name)) { action->OnDrawStarted(&draw_started); } diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp index 276b400ab3..41c06ad4ba 100644 --- a/Source/Core/VideoCommon/VertexShaderManager.cpp +++ b/Source/Core/VideoCommon/VertexShaderManager.cpp @@ -406,14 +406,14 @@ void VertexShaderManager::SetConstants(const std::vector& textures) std::vector projection_actions; if (g_ActiveConfig.bGraphicMods) { - for (const auto action : g_graphics_mod_manager->GetProjectionActions(xfmem.projection.type)) + for (const auto& action : g_graphics_mod_manager->GetProjectionActions(xfmem.projection.type)) { projection_actions.push_back(action); } for (const auto& texture : textures) { - for (const auto action : + for (const auto& action : g_graphics_mod_manager->GetProjectionTextureActions(xfmem.projection.type, texture)) { projection_actions.push_back(action); @@ -430,7 +430,7 @@ void VertexShaderManager::SetConstants(const std::vector& textures) auto corrected_matrix = LoadProjectionMatrix(); GraphicsModActionData::Projection projection{&corrected_matrix}; - for (auto action : projection_actions) + for (const auto& action : projection_actions) { action->OnProjection(&projection); } From 79a4b91d689ffa642846195f74002269ff2cae99 Mon Sep 17 00:00:00 2001 From: Joshua de Reeper Date: Sun, 2 Jul 2023 16:08:13 +0100 Subject: [PATCH 17/99] Skylander Portal: Simple List Fixes --- .../Core/Core/IOS/USB/Emulated/Skylander.cpp | 237 +++++++++--------- 1 file changed, 117 insertions(+), 120 deletions(-) diff --git a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp index f701ad4fe1..8d1fabeff2 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp +++ b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp @@ -111,9 +111,9 @@ const std::map, SkyData> list_skylanders = {{30, 0x0000}, {"Chop Chop", Game::SpyrosAdv, Element::Undead}}, {{30, 0x1801}, {"Series 2 Chop Chop", Game::Giants, Element::Undead}}, {{30, 0x2805}, {"Twin Blade Chop Chop", Game::SwapForce, Element::Undead}}, - {{30, 0x3810}, {"Eon's Elite Chop Chop"}}, + {{30, 0x3810}, {"Eon's Elite Chop Chop", Game::TrapTeam, Element::Undead}}, {{31, 0x0000}, {"Ghost Roaster", Game::SpyrosAdv, Element::Undead}}, - {{31, 0x4810}, {"Eon's Elite Ghost Roaster"}}, + {{31, 0x4810}, {"Eon's Elite Ghost Roaster", Game::Superchargers, Element::Undead}}, {{32, 0x0000}, {"Cynder", Game::SpyrosAdv, Element::Undead}}, {{32, 0x1801}, {"Series 2 Cynder", Game::Giants, Element::Undead}}, {{32, 0x2805}, {"Phantom Cynder", Game::SwapForce, Element::Undead}}, @@ -165,60 +165,60 @@ const std::map, SkyData> list_skylanders = {{205, 0x0000}, {"Sky Iron Shield", Game::SpyrosAdv}}, {{206, 0x0000}, {"Winged Boots", Game::SpyrosAdv}}, {{207, 0x0000}, {"Sparx the Dragonfly", Game::SpyrosAdv}}, - {{208, 0x0000}, {"Dragonfire Cannon", Game::SpyrosAdv}}, - {{208, 0x1602}, {"Golden Dragonfire Cannon", Game::SpyrosAdv}}, + {{208, 0x0000}, {"Dragonfire Cannon", Game::Giants}}, + {{208, 0x1602}, {"Golden Dragonfire Cannon", Game::Giants}}, {{209, 0x0000}, {"Scorpion Striker", Game::Giants}}, - {{210, 0x3002}, {"Biter's Bane", Game::TrapTeam}}, - {{210, 0x3008}, {"Sorcerous Skull", Game::TrapTeam}}, - {{210, 0x300B}, {"Axe of Illusion", Game::TrapTeam}}, - {{210, 0x300E}, {"Arcane Hourglass", Game::TrapTeam}}, - {{210, 0x3012}, {"Spell Slapper", Game::TrapTeam}}, - {{210, 0x3014}, {"Rune Rocket", Game::TrapTeam}}, - {{211, 0x3001}, {"Tidal Tiki", Game::TrapTeam}}, - {{211, 0x3002}, {"Wet Walter", Game::TrapTeam}}, - {{211, 0x3006}, {"Flood Flask", Game::TrapTeam}}, - {{211, 0x3406}, {"Legendary Flood Flask", Game::TrapTeam}}, - {{211, 0x3007}, {"Soaking Staff", Game::TrapTeam}}, - {{211, 0x300B}, {"Aqua Axe", Game::TrapTeam}}, - {{211, 0x3016}, {"Frost Helm", Game::TrapTeam}}, - {{212, 0x3003}, {"Breezy Bird", Game::TrapTeam}}, - {{212, 0x3006}, {"Drafty Decanter", Game::TrapTeam}}, - {{212, 0x300D}, {"Tempest Timer", Game::TrapTeam}}, - {{212, 0x3010}, {"Cloudy Cobra", Game::TrapTeam}}, - {{212, 0x3011}, {"Storm Warning", Game::TrapTeam}}, - {{212, 0x3018}, {"Cyclone Saber", Game::TrapTeam}}, - {{213, 0x3004}, {"Spirit Sphere", Game::TrapTeam}}, - {{213, 0x3404}, {"Legendary Spirit Sphere", Game::TrapTeam}}, - {{213, 0x3008}, {"Spectral Skull", Game::TrapTeam}}, - {{213, 0x3408}, {"Legendary Spectral Skull", Game::TrapTeam}}, - {{213, 0x300B}, {"Haunted Hatchet", Game::TrapTeam}}, - {{213, 0x300C}, {"Grim Gripper", Game::TrapTeam}}, - {{213, 0x3010}, {"Spooky Snake", Game::TrapTeam}}, - {{213, 0x3017}, {"Dream Piercer", Game::TrapTeam}}, - {{214, 0x3000}, {"Tech Totem", Game::TrapTeam}}, - {{214, 0x3007}, {"Automatic Angel", Game::TrapTeam}}, - {{214, 0x3009}, {"Factory Flower", Game::TrapTeam}}, - {{214, 0x300C}, {"Grabbing Gadget", Game::TrapTeam}}, - {{214, 0x3016}, {"Makers Mana", Game::TrapTeam}}, - {{214, 0x301A}, {"Topsy Techy", Game::TrapTeam}}, - {{215, 0x3005}, {"Eternal Flame", Game::TrapTeam}}, - {{215, 0x3009}, {"Fire Flower", Game::TrapTeam}}, - {{215, 0x3011}, {"Scorching Stopper", Game::TrapTeam}}, - {{215, 0x3012}, {"Searing Spinner", Game::TrapTeam}}, - {{215, 0x3017}, {"Spark Spear", Game::TrapTeam}}, - {{215, 0x301B}, {"Blazing Belch", Game::TrapTeam}}, - {{216, 0x3000}, {"Banded Boulder", Game::TrapTeam}}, - {{216, 0x3003}, {"Rock Hawk", Game::TrapTeam}}, - {{216, 0x300A}, {"Slag Hammer", Game::TrapTeam}}, - {{216, 0x300E}, {"Dust Of Time", Game::TrapTeam}}, - {{216, 0x3013}, {"Spinning Sandstorm", Game::TrapTeam}}, - {{216, 0x301A}, {"Rubble Trouble", Game::TrapTeam}}, - {{217, 0x3003}, {"Oak Eagle", Game::TrapTeam}}, - {{217, 0x3005}, {"Emerald Energy", Game::TrapTeam}}, - {{217, 0x300A}, {"Weed Whacker", Game::TrapTeam}}, - {{217, 0x3010}, {"Seed Serpent", Game::TrapTeam}}, - {{217, 0x3018}, {"Jade Blade", Game::TrapTeam}}, - {{217, 0x301B}, {"Shrub Shrieker", Game::TrapTeam}}, + {{210, 0x3002}, {"Biter's Bane", Game::TrapTeam, Element::Magic}}, + {{210, 0x3008}, {"Sorcerous Skull", Game::TrapTeam, Element::Magic}}, + {{210, 0x300B}, {"Axe of Illusion", Game::TrapTeam, Element::Magic}}, + {{210, 0x300E}, {"Arcane Hourglass", Game::TrapTeam, Element::Magic}}, + {{210, 0x3012}, {"Spell Slapper", Game::TrapTeam, Element::Magic}}, + {{210, 0x3014}, {"Rune Rocket", Game::TrapTeam, Element::Magic}}, + {{211, 0x3001}, {"Tidal Tiki", Game::TrapTeam, Element::Water}}, + {{211, 0x3002}, {"Wet Walter", Game::TrapTeam, Element::Water}}, + {{211, 0x3006}, {"Flood Flask", Game::TrapTeam, Element::Water}}, + {{211, 0x3406}, {"Legendary Flood Flask", Game::TrapTeam, Element::Water}}, + {{211, 0x3007}, {"Soaking Staff", Game::TrapTeam, Element::Water}}, + {{211, 0x300B}, {"Aqua Axe", Game::TrapTeam, Element::Water}}, + {{211, 0x3016}, {"Frost Helm", Game::TrapTeam, Element::Water}}, + {{212, 0x3003}, {"Breezy Bird", Game::TrapTeam, Element::Air}}, + {{212, 0x3006}, {"Drafty Decanter", Game::TrapTeam, Element::Air}}, + {{212, 0x300D}, {"Tempest Timer", Game::TrapTeam, Element::Air}}, + {{212, 0x3010}, {"Cloudy Cobra", Game::TrapTeam, Element::Air}}, + {{212, 0x3011}, {"Storm Warning", Game::TrapTeam, Element::Air}}, + {{212, 0x3018}, {"Cyclone Saber", Game::TrapTeam, Element::Air}}, + {{213, 0x3004}, {"Spirit Sphere", Game::TrapTeam, Element::Undead}}, + {{213, 0x3404}, {"Legendary Spirit Sphere", Game::TrapTeam, Element::Undead}}, + {{213, 0x3008}, {"Spectral Skull", Game::TrapTeam, Element::Undead}}, + {{213, 0x3408}, {"Legendary Spectral Skull", Game::TrapTeam, Element::Undead}}, + {{213, 0x300B}, {"Haunted Hatchet", Game::TrapTeam, Element::Undead}}, + {{213, 0x300C}, {"Grim Gripper", Game::TrapTeam, Element::Undead}}, + {{213, 0x3010}, {"Spooky Snake", Game::TrapTeam, Element::Undead}}, + {{213, 0x3017}, {"Dream Piercer", Game::TrapTeam, Element::Undead}}, + {{214, 0x3000}, {"Tech Totem", Game::TrapTeam, Element::Tech}}, + {{214, 0x3007}, {"Automatic Angel", Game::TrapTeam, Element::Tech}}, + {{214, 0x3009}, {"Factory Flower", Game::TrapTeam, Element::Tech}}, + {{214, 0x300C}, {"Grabbing Gadget", Game::TrapTeam, Element::Tech}}, + {{214, 0x3016}, {"Makers Mana", Game::TrapTeam, Element::Tech}}, + {{214, 0x301A}, {"Topsy Techy", Game::TrapTeam, Element::Tech}}, + {{215, 0x3005}, {"Eternal Flame", Game::TrapTeam, Element::Fire}}, + {{215, 0x3009}, {"Fire Flower", Game::TrapTeam, Element::Fire}}, + {{215, 0x3011}, {"Scorching Stopper", Game::TrapTeam, Element::Fire}}, + {{215, 0x3012}, {"Searing Spinner", Game::TrapTeam, Element::Fire}}, + {{215, 0x3017}, {"Spark Spear", Game::TrapTeam, Element::Fire}}, + {{215, 0x301B}, {"Blazing Belch", Game::TrapTeam, Element::Fire}}, + {{216, 0x3000}, {"Banded Boulder", Game::TrapTeam, Element::Earth}}, + {{216, 0x3003}, {"Rock Hawk", Game::TrapTeam, Element::Earth}}, + {{216, 0x300A}, {"Slag Hammer", Game::TrapTeam, Element::Earth}}, + {{216, 0x300E}, {"Dust Of Time", Game::TrapTeam, Element::Earth}}, + {{216, 0x3013}, {"Spinning Sandstorm", Game::TrapTeam, Element::Earth}}, + {{216, 0x301A}, {"Rubble Trouble", Game::TrapTeam, Element::Earth}}, + {{217, 0x3003}, {"Oak Eagle", Game::TrapTeam, Element::Life}}, + {{217, 0x3005}, {"Emerald Energy", Game::TrapTeam, Element::Life}}, + {{217, 0x300A}, {"Weed Whacker", Game::TrapTeam, Element::Life}}, + {{217, 0x3010}, {"Seed Serpent", Game::TrapTeam, Element::Life}}, + {{217, 0x3018}, {"Jade Blade", Game::TrapTeam, Element::Life}}, + {{217, 0x301B}, {"Shrub Shrieker", Game::TrapTeam, Element::Life}}, {{218, 0x3000}, {"Dark Dagger", Game::TrapTeam}}, {{218, 0x3014}, {"Shadow Spider", Game::TrapTeam}}, {{218, 0x301A}, {"Ghastly Grimace", Game::TrapTeam}}, @@ -232,11 +232,11 @@ const std::map, SkyData> list_skylanders = {{231, 0x0000}, {"Piggy Bank", Game::TrapTeam}}, {{232, 0x0000}, {"Rocket Ram", Game::TrapTeam}}, {{233, 0x0000}, {"Tiki Speaky", Game::TrapTeam}}, - {{300, 0x0000}, {"Dragon’s Peak", Game::TrapTeam}}, - {{301, 0x0000}, {"Empire of Ice", Game::TrapTeam}}, - {{302, 0x0000}, {"Pirate Seas", Game::TrapTeam}}, - {{303, 0x0000}, {"Darklight Crypt", Game::TrapTeam}}, - {{304, 0x0000}, {"Volcanic Vault", Game::TrapTeam}}, + {{300, 0x0000}, {"Dragon's Peak", Game::SpyrosAdv}}, + {{301, 0x0000}, {"Empire of Ice", Game::SpyrosAdv}}, + {{302, 0x0000}, {"Pirate Seas", Game::SpyrosAdv}}, + {{303, 0x0000}, {"Darklight Crypt", Game::SpyrosAdv}}, + {{304, 0x0000}, {"Volcanic Vault", Game::SpyrosAdv}}, {{305, 0x0000}, {"Mirror of Mystery", Game::TrapTeam}}, {{306, 0x0000}, {"Nightmare Express", Game::TrapTeam}}, {{307, 0x0000}, {"Sunscraper Spire", Game::TrapTeam}}, @@ -288,10 +288,10 @@ const std::map, SkyData> list_skylanders = {{479, 0x0000}, {"Short Cut", Game::TrapTeam, Element::Undead}}, {{480, 0x0000}, {"Bat Spin", Game::TrapTeam, Element::Undead}}, {{481, 0x0000}, {"Funny Bone", Game::TrapTeam, Element::Undead}}, - {{482, 0x0000}, {"Knight Light", Game::TrapTeam, Element::Other}}, - {{483, 0x0000}, {"Spotlight", Game::TrapTeam, Element::Other}}, - {{484, 0x0000}, {"Knight Mare", Game::TrapTeam, Element::Other}}, - {{485, 0x0000}, {"Blackout", Game::TrapTeam, Element::Other}}, + {{482, 0x0000}, {"Knight Light", Game::TrapTeam}}, + {{483, 0x0000}, {"Spotlight", Game::TrapTeam}}, + {{484, 0x0000}, {"Knight Mare", Game::TrapTeam}}, + {{485, 0x0000}, {"Blackout", Game::TrapTeam}}, {{502, 0x0000}, {"Bop", Game::TrapTeam, Element::Earth}}, {{505, 0x0000}, {"Terrabite", Game::SpyrosAdv, Element::Earth}}, {{506, 0x0000}, {"Breeze", Game::TrapTeam, Element::Air}}, @@ -390,52 +390,52 @@ const std::map, SkyData> list_skylanders = {{3013, 0x2206}, {"LightCore Grim Creeper", Game::SwapForce, Element::Undead}}, {{3014, 0x0000}, {"Rip Tide", Game::SwapForce, Element::Water}}, {{3015, 0x0000}, {"Punk Shock", Game::SwapForce, Element::Water}}, - {{3200, 0x0000}, {"Battle Hammer", Game::SwapForce, Element::Other}}, - {{3201, 0x0000}, {"Sky Diamond", Game::SwapForce, Element::Other}}, - {{3202, 0x0000}, {"Platinum Sheep", Game::SwapForce, Element::Other}}, - {{3203, 0x0000}, {"Groove Machine", Game::SwapForce, Element::Other}}, - {{3204, 0x0000}, {"UFO Hat", Game::SwapForce, Element::Other}}, - {{3300, 0x0000}, {"Sheep Wreck Island", Game::SwapForce, Element::Other}}, - {{3301, 0x0000}, {"Tower of Time", Game::SwapForce, Element::Other}}, - {{3302, 0x0000}, {"Fiery Forge", Game::SwapForce, Element::Other}}, - {{3303, 0x0000}, {"Arkeyan Crossbow", Game::SwapForce, Element::Other}}, - {{3220, 0x0000}, {"Jet Stream", Game::Superchargers, Element::Other}}, - {{3221, 0x0000}, {"Tomb Buggy", Game::Superchargers, Element::Other}}, - {{3222, 0x0000}, {"Reef Ripper", Game::Superchargers, Element::Other}}, - {{3223, 0x0000}, {"Burn Cycle", Game::Superchargers, Element::Other}}, - {{3224, 0x0000}, {"Hot Streak", Game::Superchargers, Element::Other}}, - {{3224, 0x4402}, {"Dark Hot Streak", Game::Superchargers, Element::Other}}, - {{3224, 0x4004}, {"E3 Hot Streak", Game::Superchargers, Element::Other}}, - {{3224, 0x441E}, {"Golden Hot Streak", Game::Superchargers, Element::Other}}, - {{3225, 0x0000}, {"Shark Tank", Game::Superchargers, Element::Other}}, - {{3226, 0x0000}, {"Thump Truck", Game::Superchargers, Element::Other}}, - {{3227, 0x0000}, {"Crypt Crusher", Game::Superchargers, Element::Other}}, - {{3228, 0x0000}, {"Stealth Stinger", Game::Superchargers, Element::Other}}, - {{3228, 0x4402}, {"Nitro Stealth Stinger", Game::Superchargers, Element::Other}}, - {{3231, 0x0000}, {"Dive Bomber", Game::Superchargers, Element::Other}}, - {{3231, 0x4402}, {"Spring Ahead Dive Bomber", Game::Superchargers, Element::Other}}, - {{3232, 0x0000}, {"Sky Slicer", Game::Superchargers, Element::Other}}, - {{3233, 0x0000}, {"Clown Cruiser (Nintendo Only)", Game::Superchargers, Element::Other}}, - {{3233, 0x4402}, {"Dark Clown Cruiser (Nintendo Only)", Game::Superchargers, Element::Other}}, - {{3234, 0x0000}, {"Gold Rusher", Game::Superchargers, Element::Other}}, - {{3234, 0x4402}, {"Power Blue Gold Rusher", Game::Superchargers, Element::Other}}, - {{3235, 0x0000}, {"Shield Striker", Game::Superchargers, Element::Other}}, - {{3236, 0x0000}, {"Sun Runner", Game::Superchargers, Element::Other}}, - {{3236, 0x4403}, {"Legendary Sun Runner", Game::Superchargers, Element::Other}}, - {{3237, 0x0000}, {"Sea Shadow", Game::Superchargers, Element::Other}}, - {{3237, 0x4402}, {"Dark Sea Shadow", Game::Superchargers, Element::Other}}, - {{3238, 0x0000}, {"Splatter Splasher", Game::Superchargers, Element::Other}}, - {{3238, 0x4402}, {"Power Blue Splatter Splasher", Game::Superchargers, Element::Other}}, - {{3239, 0x0000}, {"Soda Skimmer", Game::Superchargers, Element::Other}}, - {{3240, 0x0000}, {"Barrel Blaster (Nintendo Only)", Game::Superchargers, Element::Other}}, - {{3240, 0x4402}, {"Dark Barrel Blaster (Nintendo Only)", Game::Superchargers, Element::Other}}, - {{3239, 0x4402}, {"Nitro Soda Skimmer", Game::Superchargers, Element::Other}}, - {{3241, 0x0000}, {"Buzz Wing", Game::Superchargers, Element::Other}}, + {{3200, 0x0000}, {"Battle Hammer", Game::SwapForce}}, + {{3201, 0x0000}, {"Sky Diamond", Game::SwapForce}}, + {{3202, 0x0000}, {"Platinum Sheep", Game::SwapForce}}, + {{3203, 0x0000}, {"Groove Machine", Game::SwapForce}}, + {{3204, 0x0000}, {"UFO Hat", Game::SwapForce}}, + {{3220, 0x0000}, {"Jet Stream", Game::Superchargers}}, + {{3221, 0x0000}, {"Tomb Buggy", Game::Superchargers}}, + {{3222, 0x0000}, {"Reef Ripper", Game::Superchargers}}, + {{3223, 0x0000}, {"Burn Cycle", Game::Superchargers}}, + {{3224, 0x0000}, {"Hot Streak", Game::Superchargers}}, + {{3224, 0x4402}, {"Dark Hot Streak", Game::Superchargers}}, + {{3224, 0x4004}, {"E3 Hot Streak", Game::Superchargers}}, + {{3224, 0x441E}, {"Golden Hot Streak", Game::Superchargers}}, + {{3225, 0x0000}, {"Shark Tank", Game::Superchargers}}, + {{3226, 0x0000}, {"Thump Truck", Game::Superchargers}}, + {{3227, 0x0000}, {"Crypt Crusher", Game::Superchargers}}, + {{3228, 0x0000}, {"Stealth Stinger", Game::Superchargers}}, + {{3228, 0x4402}, {"Nitro Stealth Stinger", Game::Superchargers}}, + {{3231, 0x0000}, {"Dive Bomber", Game::Superchargers}}, + {{3231, 0x4402}, {"Spring Ahead Dive Bomber", Game::Superchargers}}, + {{3232, 0x0000}, {"Sky Slicer", Game::Superchargers}}, + {{3233, 0x0000}, {"Clown Cruiser", Game::Superchargers}}, + {{3233, 0x4402}, {"Dark Clown Cruiser", Game::Superchargers}}, + {{3234, 0x0000}, {"Gold Rusher", Game::Superchargers}}, + {{3234, 0x4402}, {"Power Blue Gold Rusher", Game::Superchargers}}, + {{3235, 0x0000}, {"Shield Striker", Game::Superchargers}}, + {{3236, 0x0000}, {"Sun Runner", Game::Superchargers}}, + {{3236, 0x4403}, {"Legendary Sun Runner", Game::Superchargers}}, + {{3237, 0x0000}, {"Sea Shadow", Game::Superchargers}}, + {{3237, 0x4402}, {"Dark Sea Shadow", Game::Superchargers}}, + {{3238, 0x0000}, {"Splatter Splasher", Game::Superchargers}}, + {{3238, 0x4402}, {"Power Blue Splatter Splasher", Game::Superchargers}}, + {{3239, 0x0000}, {"Soda Skimmer", Game::Superchargers}}, + {{3240, 0x0000}, {"Barrel Blaster", Game::Superchargers}}, + {{3240, 0x4402}, {"Dark Barrel Blaster", Game::Superchargers}}, + {{3239, 0x4402}, {"Nitro Soda Skimmer", Game::Superchargers}}, + {{3241, 0x0000}, {"Buzz Wing", Game::Superchargers}}, + {{3300, 0x0000}, {"Sheep Wreck Island", Game::SwapForce}}, + {{3301, 0x0000}, {"Tower of Time", Game::SwapForce}}, + {{3302, 0x0000}, {"Fiery Forge", Game::SwapForce}}, + {{3303, 0x0000}, {"Arkeyan Crossbow", Game::SwapForce}}, {{3400, 0x0000}, {"Fiesta", Game::Superchargers, Element::Undead}}, {{3400, 0x4515}, {"Frightful Fiesta", Game::Superchargers, Element::Undead}}, {{3401, 0x0000}, {"High Volt", Game::Superchargers, Element::Tech}}, {{3402, 0x0000}, {"Splat", Game::Superchargers, Element::Magic}}, - {{3402, 0x4502}, {"Power Blue Splat", Game::Superchargers, Element::Other}}, + {{3402, 0x4502}, {"Power Blue Splat", Game::Superchargers, Element::Magic}}, {{3406, 0x0000}, {"Stormblade", Game::Superchargers, Element::Air}}, {{3411, 0x0000}, {"Smash Hit", Game::Superchargers, Element::Earth}}, {{3411, 0x4502}, {"Steel Plated Smash Hit", Game::Superchargers, Element::Earth}}, @@ -454,24 +454,21 @@ const std::map, SkyData> list_skylanders = {{3420, 0x450E}, {"Birthday Bash Big Bubble Pop Fizz", Game::Superchargers, Element::Magic}}, {{3421, 0x0000}, {"Lava Lance Eruptor", Game::Superchargers, Element::Fire}}, {{3422, 0x0000}, {"Deep Dive Gill Grunt", Game::Superchargers, Element::Water}}, - {{3423, 0x0000}, - {"Turbo Charge Donkey Kong (Nintendo Only)", Game::Superchargers, Element::Life}}, - {{3423, 0x4502}, - {"Dark Turbo Charge Donkey Kong (Nintendo Only)", Game::Superchargers, Element::Life}}, - {{3424, 0x0000}, {"Hammer Slam Bowser (Nintendo Only)", Game::Superchargers, Element::Fire}}, - {{3424, 0x4502}, - {"Dark Hammer Slam Bowser (Nintendo Only)", Game::Superchargers, Element::Fire}}, + {{3423, 0x0000}, {"Turbo Charge Donkey Kong", Game::Superchargers, Element::Life}}, + {{3423, 0x4502}, {"Dark Turbo Charge Donkey Kong", Game::Superchargers, Element::Life}}, + {{3424, 0x0000}, {"Hammer Slam Bowser", Game::Superchargers, Element::Fire}}, + {{3424, 0x4502}, {"Dark Hammer Slam Bowser", Game::Superchargers, Element::Fire}}, {{3425, 0x0000}, {"Dive-Clops", Game::Superchargers, Element::Water}}, {{3425, 0x450E}, {"Missile-Tow Dive-Clops", Game::Superchargers, Element::Water}}, - {{3426, 0x0000}, {"Astroblast", Game::Superchargers, Element::Other}}, - {{3426, 0x4503}, {"Legendary Astroblast", Game::Superchargers, Element::Other}}, - {{3427, 0x0000}, {"Nightfall", Game::Superchargers, Element::Other}}, + {{3426, 0x0000}, {"Astroblast", Game::Superchargers}}, + {{3426, 0x4503}, {"Legendary Astroblast", Game::Superchargers}}, + {{3427, 0x0000}, {"Nightfall", Game::Superchargers}}, {{3428, 0x0000}, {"Thrillipede", Game::Superchargers, Element::Life}}, {{3428, 0x450D}, {"Eggcited Thrillipede", Game::Superchargers, Element::Life}}, - {{3500, 0x0000}, {"Sky Trophy", Game::Superchargers, Element::Other}}, - {{3501, 0x0000}, {"Land Trophy", Game::Superchargers, Element::Other}}, - {{3502, 0x0000}, {"Sea Trophy", Game::Superchargers, Element::Other}}, - {{3503, 0x0000}, {"Kaos Trophy", Game::Superchargers, Element::Other}}}; + {{3500, 0x0000}, {"Sky Trophy", Game::Superchargers}}, + {{3501, 0x0000}, {"Land Trophy", Game::Superchargers}}, + {{3502, 0x0000}, {"Sea Trophy", Game::Superchargers}}, + {{3503, 0x0000}, {"Kaos Trophy", Game::Superchargers}}}; SkylanderUSB::SkylanderUSB(EmulationKernel& ios, const std::string& device_name) : m_ios(ios) { From 54850e936c4fb3d78d6dfc627822a2c495262c1b Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 18 Jun 2023 14:31:01 -0700 Subject: [PATCH 18/99] Fix memory leak in libusb code --- Source/Core/InputCommon/GCAdapter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index a3853e9e6c..21a1255fb0 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -636,6 +636,7 @@ static void AddGCAdapter(libusb_device* device) } } } + libusb_free_config_descriptor(config); int size = 0; std::array payload = {0x13}; From afb5eff42685a0b5f2a91ed64237aaf7e2aa9468 Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 18 Jun 2023 14:28:26 -0700 Subject: [PATCH 19/99] Don't burn a CPU core and spam logs when GC Adapter fails --- Source/Core/InputCommon/GCAdapter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index 21a1255fb0..cacb73bc79 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -211,6 +211,10 @@ static void ReadThreadFunc() ERROR_LOG_FMT(CONTROLLERINTERFACE, "Read: libusb_interrupt_transfer failed: {}", LibusbUtils::ErrorWrap(error)); } + if (error == LIBUSB_ERROR_IO) + { + break; + } ProcessInputPayload(input_buffer.data(), payload_size); From 559a16da4999c1159bb4d594a969f13e77100a1c Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 18 Jun 2023 14:28:26 -0700 Subject: [PATCH 20/99] Reset GC adapter upon IO error after sleep-wake Fixes GC adapter breaking on sleep-wake on Linux and burning a full CPU core. This is cleaner than alternative approaches. --- Source/Core/InputCommon/GCAdapter.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index cacb73bc79..6088256a55 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -203,9 +203,8 @@ static void ReadThreadFunc() std::array input_buffer; int payload_size = 0; - const int error = - libusb_interrupt_transfer(s_handle, s_endpoint_in, input_buffer.data(), - int(input_buffer.size()), &payload_size, USB_TIMEOUT_MS); + int error = libusb_interrupt_transfer(s_handle, s_endpoint_in, input_buffer.data(), + int(input_buffer.size()), &payload_size, USB_TIMEOUT_MS); if (error != LIBUSB_SUCCESS) { ERROR_LOG_FMT(CONTROLLERINTERFACE, "Read: libusb_interrupt_transfer failed: {}", @@ -213,7 +212,16 @@ static void ReadThreadFunc() } if (error == LIBUSB_ERROR_IO) { - break; + // s_read_adapter_thread_running is cleared by the joiner, not the stopper. + + // Reset the device, which may trigger a replug. + error = libusb_reset_device(s_handle); + ERROR_LOG_FMT(CONTROLLERINTERFACE, "Read: libusb_reset_device: {}", + LibusbUtils::ErrorWrap(error)); + if (error != 0) + { + break; + } } ProcessInputPayload(input_buffer.data(), payload_size); From c893ccca58cb504b003b100880cc5074faf9e822 Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 2 Jul 2023 22:24:08 -0700 Subject: [PATCH 21/99] Workaround GC adapter detection breaking when reset fails --- Source/Core/InputCommon/GCAdapter.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index 6088256a55..bb1542988e 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -218,10 +218,9 @@ static void ReadThreadFunc() error = libusb_reset_device(s_handle); ERROR_LOG_FMT(CONTROLLERINTERFACE, "Read: libusb_reset_device: {}", LibusbUtils::ErrorWrap(error)); - if (error != 0) - { - break; - } + + // If error is nonzero, try fixing it next loop iteration. We can't easily return + // and cleanup program state without getting another thread to call Reset(). } ProcessInputPayload(input_buffer.data(), payload_size); From 5d0f1bd10b1af825a80ab78160fe7c9924e835e9 Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 2 Jul 2023 20:07:37 -0700 Subject: [PATCH 22/99] Switch libusb_config_descriptor to RAII type --- Source/Core/InputCommon/GCAdapter.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index bb1542988e..ec3c3a1fb3 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -625,8 +625,8 @@ static bool CheckDeviceAccess(libusb_device* device) static void AddGCAdapter(libusb_device* device) { - libusb_config_descriptor* config = nullptr; - if (const int error = libusb_get_config_descriptor(device, 0, &config); error != LIBUSB_SUCCESS) + auto [error, config] = LibusbUtils::MakeConfigDescriptor(device); + if (error != LIBUSB_SUCCESS) { WARN_LOG_FMT(CONTROLLERINTERFACE, "libusb_get_config_descriptor failed: {}", LibusbUtils::ErrorWrap(error)); @@ -647,13 +647,12 @@ static void AddGCAdapter(libusb_device* device) } } } - libusb_free_config_descriptor(config); + config.reset(); int size = 0; std::array payload = {0x13}; - const int error = - libusb_interrupt_transfer(s_handle, s_endpoint_out, payload.data(), - CONTROLER_OUTPUT_INIT_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); + error = libusb_interrupt_transfer(s_handle, s_endpoint_out, payload.data(), + CONTROLER_OUTPUT_INIT_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); if (error != LIBUSB_SUCCESS) { WARN_LOG_FMT(CONTROLLERINTERFACE, "AddGCAdapter: libusb_interrupt_transfer failed: {}", From c8df26554bc5433bff13aaff934d1539226577d7 Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Thu, 29 Jun 2023 22:50:01 -0700 Subject: [PATCH 23/99] Fix GC adapter not being detected when you enable controller in settings GCAdapter::UseAdapter() reads s_is_adapter_wanted, which gets initialized by config_guard.~ConfigChangeCallbackGuard(). So we must wait until after destroying the config guard to know whether we have any controllers set to GC Adapter. --- .../Core/DolphinQt/Config/GamecubeControllersWidget.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp index c27ab2e99f..38ea1e4e7f 100644 --- a/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp +++ b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp @@ -198,12 +198,11 @@ void GamecubeControllersWidget::SaveSettings() static_cast(i)); } } - - if (GCAdapter::UseAdapter()) - GCAdapter::StartScanThread(); - else - GCAdapter::StopScanThread(); } + if (GCAdapter::UseAdapter()) + GCAdapter::StartScanThread(); + else + GCAdapter::StopScanThread(); SConfig::GetInstance().SaveSettings(); } From d122492db7fab6f22ac6104789448cc4a65e2fec Mon Sep 17 00:00:00 2001 From: Amon Neander <138429719+MaverickAmon02@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:34:08 -0400 Subject: [PATCH 24/99] Fix unsafe netplay code in SI_DeviceGCController By misusing Config, this netplay-related code opened up a race condition between Config::OnConfigChanged() and SerialInterface::SerialInterfaceManager::UpdateDevices() that could cause iterator invalidation. --- Source/Core/Core/HW/SI/SI.cpp | 2 +- Source/Core/Core/HW/SI/SI.h | 2 +- .../Core/Core/HW/SI/SI_DeviceGCController.cpp | 20 ++----------------- .../Core/Core/HW/SI/SI_DeviceGCController.h | 7 ------- 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/Source/Core/Core/HW/SI/SI.cpp b/Source/Core/Core/HW/SI/SI.cpp index 1312c548bc..401d963ddd 100644 --- a/Source/Core/Core/HW/SI/SI.cpp +++ b/Source/Core/Core/HW/SI/SI.cpp @@ -568,7 +568,7 @@ void SerialInterfaceManager::UpdateDevices() NetPlay::SetSIPollBatching(false); } -SIDevices SerialInterfaceManager::GetDeviceType(int channel) +SIDevices SerialInterfaceManager::GetDeviceType(int channel) const { if (channel < 0 || channel >= MAX_SI_CHANNELS || !m_channel[channel].device) return SIDEVICE_NONE; diff --git a/Source/Core/Core/HW/SI/SI.h b/Source/Core/Core/HW/SI/SI.h index cedd5856cd..9bd9f707a2 100644 --- a/Source/Core/Core/HW/SI/SI.h +++ b/Source/Core/Core/HW/SI/SI.h @@ -63,7 +63,7 @@ public: void ChangeDevice(SIDevices device, int channel); - SIDevices GetDeviceType(int channel); + SIDevices GetDeviceType(int channel) const; u32 GetPollXLines(); diff --git a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp index 598c84678b..26a5b03c47 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp +++ b/Source/Core/Core/HW/SI/SI_DeviceGCController.cpp @@ -14,6 +14,7 @@ #include "Core/CoreTiming.h" #include "Core/HW/GCPad.h" #include "Core/HW/ProcessorInterface.h" +#include "Core/HW/SI/SI.h" #include "Core/HW/SI/SI_Device.h" #include "Core/HW/SystemTimers.h" #include "Core/Movie.h" @@ -36,14 +37,6 @@ CSIDevice_GCController::CSIDevice_GCController(Core::System& system, SIDevices d m_origin.origin_stick_y = GCPadStatus::MAIN_STICK_CENTER_Y; m_origin.substick_x = GCPadStatus::C_STICK_CENTER_X; m_origin.substick_y = GCPadStatus::C_STICK_CENTER_Y; - - m_config_changed_callback_id = Config::AddConfigChangedCallback([this] { RefreshConfig(); }); - RefreshConfig(); -} - -CSIDevice_GCController::~CSIDevice_GCController() -{ - Config::RemoveConfigChangedCallback(m_config_changed_callback_id); } int CSIDevice_GCController::RunBuffer(u8* buffer, int request_length) @@ -316,7 +309,7 @@ void CSIDevice_GCController::SendCommand(u32 command, u8 poll) if (pad_num < 4) { - const SIDevices device = m_config_si_devices[pad_num]; + const SIDevices device = m_system.GetSerialInterface().GetDeviceType(pad_num); if (type == 1) CSIDevice_GCController::Rumble(pad_num, 1.0, device); else @@ -346,15 +339,6 @@ void CSIDevice_GCController::DoState(PointerWrap& p) p.Do(m_last_button_combo); } -void CSIDevice_GCController::RefreshConfig() -{ - for (int i = 0; i < 4; ++i) - { - const SerialInterface::SIDevices device = Config::Get(Config::GetInfoForSIDevice(i)); - m_config_si_devices[i] = device; - } -} - CSIDevice_TaruKonga::CSIDevice_TaruKonga(Core::System& system, SIDevices device, int device_number) : CSIDevice_GCController(system, device, device_number) { diff --git a/Source/Core/Core/HW/SI/SI_DeviceGCController.h b/Source/Core/Core/HW/SI/SI_DeviceGCController.h index 809eaabd3b..43e3d7aabb 100644 --- a/Source/Core/Core/HW/SI/SI_DeviceGCController.h +++ b/Source/Core/Core/HW/SI/SI_DeviceGCController.h @@ -54,7 +54,6 @@ protected: public: // Constructor CSIDevice_GCController(Core::System& system, SIDevices device, int device_number); - ~CSIDevice_GCController() override; // Run the SI Buffer int RunBuffer(u8* buffer, int request_length) override; @@ -83,12 +82,6 @@ public: protected: void SetOrigin(const GCPadStatus& pad_status); - -private: - void RefreshConfig(); - - std::array m_config_si_devices{}; - size_t m_config_changed_callback_id; }; // "TaruKonga", the DK Bongo controller From 77511e8e7cc80cc82fa1edf206948f714413aac8 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 2 Jul 2023 21:27:24 -0500 Subject: [PATCH 25/99] VideoCommon: add material asset. A material is similar to other graphics engines where it provides data to be used in conjunction with a shader asset to generate a runtime AbstractShader --- Source/Core/DolphinLib.props | 2 + .../VideoCommon/Assets/CustomAssetLibrary.h | 4 + .../VideoCommon/Assets/CustomAssetLoader.cpp | 7 + .../VideoCommon/Assets/CustomAssetLoader.h | 5 + .../Assets/DirectFilesystemAssetLibrary.cpp | 56 ++++++ .../Assets/DirectFilesystemAssetLibrary.h | 1 + .../Core/VideoCommon/Assets/MaterialAsset.cpp | 166 ++++++++++++++++++ .../Core/VideoCommon/Assets/MaterialAsset.h | 61 +++++++ Source/Core/VideoCommon/CMakeLists.txt | 2 + 9 files changed, 304 insertions(+) create mode 100644 Source/Core/VideoCommon/Assets/MaterialAsset.cpp create mode 100644 Source/Core/VideoCommon/Assets/MaterialAsset.h diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 4ddf550edf..1b44f15ec4 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -637,6 +637,7 @@ + @@ -1253,6 +1254,7 @@ + diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h index 196372fab8..32e8020ae0 100644 --- a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h +++ b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h @@ -11,6 +11,7 @@ namespace VideoCommon { class CustomTextureData; +struct MaterialData; struct PixelShaderData; // This class provides functionality to load @@ -49,5 +50,8 @@ public: // Loads a pixel shader virtual LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) = 0; + + // Loads a material + virtual LoadInfo LoadMaterial(const AssetID& asset_id, MaterialData* data) = 0; }; } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp index ce76a368d2..f579a5eb4b 100644 --- a/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp +++ b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp @@ -97,4 +97,11 @@ CustomAssetLoader::LoadPixelShader(const CustomAssetLibrary::AssetID& asset_id, { return LoadOrCreateAsset(asset_id, m_pixel_shaders, std::move(library)); } + +std::shared_ptr +CustomAssetLoader::LoadMaterial(const CustomAssetLibrary::AssetID& asset_id, + std::shared_ptr library) +{ + return LoadOrCreateAsset(asset_id, m_materials, std::move(library)); +} } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLoader.h b/Source/Core/VideoCommon/Assets/CustomAssetLoader.h index cca83af960..fe86a40835 100644 --- a/Source/Core/VideoCommon/Assets/CustomAssetLoader.h +++ b/Source/Core/VideoCommon/Assets/CustomAssetLoader.h @@ -12,6 +12,7 @@ #include "Common/Flag.h" #include "Common/WorkQueueThread.h" #include "VideoCommon/Assets/CustomAsset.h" +#include "VideoCommon/Assets/MaterialAsset.h" #include "VideoCommon/Assets/ShaderAsset.h" #include "VideoCommon/Assets/TextureAsset.h" @@ -46,6 +47,9 @@ public: std::shared_ptr LoadPixelShader(const CustomAssetLibrary::AssetID& asset_id, std::shared_ptr library); + std::shared_ptr LoadMaterial(const CustomAssetLibrary::AssetID& asset_id, + std::shared_ptr library); + private: // TODO C++20: use a 'derived_from' concept against 'CustomAsset' when available template @@ -79,6 +83,7 @@ private: std::map> m_textures; std::map> m_game_textures; std::map> m_pixel_shaders; + std::map> m_materials; std::thread m_asset_monitor_thread; Common::Flag m_asset_monitor_thread_shutdown; diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp index c234b4088e..cc21549e54 100644 --- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp +++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp @@ -10,6 +10,7 @@ #include "Common/Logging/Log.h" #include "Common/StringUtil.h" #include "VideoCommon/Assets/CustomTextureData.h" +#include "VideoCommon/Assets/MaterialAsset.h" #include "VideoCommon/Assets/ShaderAsset.h" namespace VideoCommon @@ -144,6 +145,61 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadPixelShader(const return LoadInfo{approx_mem_size, GetLastAssetWriteTime(asset_id)}; } +CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMaterial(const AssetID& asset_id, + MaterialData* data) +{ + const auto asset_map = GetAssetMapForID(asset_id); + + // Material is expected to have one asset mapped + if (asset_map.empty() || asset_map.size() > 1) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' error - material expected to have one file mapped!", asset_id); + return {}; + } + const auto& asset_path = asset_map.begin()->second; + + std::string json_data; + if (!File::ReadFileToString(asset_path.string(), json_data)) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' error - material failed to load the json file '{}',", + asset_id, asset_path.string()); + return {}; + } + + picojson::value root; + const auto error = picojson::parse(root, json_data); + + if (!error.empty()) + { + ERROR_LOG_FMT( + VIDEO, + "Asset '{}' error - material failed to load the json file '{}', due to parse error: {}", + asset_id, asset_path.string(), error); + return {}; + } + if (!root.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' error - material failed to load the json file '{}', due to root not " + "being an object!", + asset_id, asset_path.string()); + return {}; + } + + const auto& root_obj = root.get(); + + if (!MaterialData::FromJson(asset_id, root_obj, data)) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' error - material failed to load the json file '{}', as material " + "json could not be parsed!", + asset_id, asset_path.string()); + return {}; + } + + return LoadInfo{json_data.size(), GetLastAssetWriteTime(asset_id)}; +} + CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const AssetID& asset_id, CustomTextureData* data) { diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h index 9a842c6988..eeedb42d68 100644 --- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h +++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.h @@ -23,6 +23,7 @@ public: LoadInfo LoadTexture(const AssetID& asset_id, CustomTextureData* data) override; LoadInfo LoadPixelShader(const AssetID& asset_id, PixelShaderData* data) override; + LoadInfo LoadMaterial(const AssetID& asset_id, MaterialData* data) override; // Gets the latest time from amongst all the files in the asset map TimeType GetLastAssetWriteTime(const AssetID& asset_id) const override; diff --git a/Source/Core/VideoCommon/Assets/MaterialAsset.cpp b/Source/Core/VideoCommon/Assets/MaterialAsset.cpp new file mode 100644 index 0000000000..c5e5718492 --- /dev/null +++ b/Source/Core/VideoCommon/Assets/MaterialAsset.cpp @@ -0,0 +1,166 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "VideoCommon/Assets/MaterialAsset.h" + +#include + +#include "Common/Logging/Log.h" +#include "Common/StringUtil.h" +#include "VideoCommon/Assets/CustomAssetLibrary.h" + +namespace VideoCommon +{ +namespace +{ +bool ParsePropertyValue(const CustomAssetLibrary::AssetID& asset_id, MaterialProperty::Type type, + const picojson::value& json_value, + std::optional* value) +{ + switch (type) + { + case MaterialProperty::Type::Type_TextureAsset: + { + if (json_value.is()) + { + *value = json_value.to_str(); + return true; + } + } + break; + }; + + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse the json, value is not valid for type '{}'", + asset_id, type); + return false; +} + +bool ParseMaterialProperties(const CustomAssetLibrary::AssetID& asset_id, + const picojson::array& values_data, + std::vector* material_property) +{ + for (const auto& value_data : values_data) + { + VideoCommon::MaterialProperty property; + if (!value_data.is()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse the json, value is not the right json type", + asset_id); + return false; + } + const auto& value_data_obj = value_data.get(); + + const auto type_iter = value_data_obj.find("type"); + if (type_iter == value_data_obj.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse the json, value entry 'type' not found", + asset_id); + return false; + } + if (!type_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse the json, value entry 'type' is not " + "the right json type", + asset_id); + return false; + } + std::string type = type_iter->second.to_str(); + Common::ToLower(&type); + if (type == "texture_asset") + { + property.m_type = MaterialProperty::Type::Type_TextureAsset; + } + else + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse the json, value entry 'type' is " + "an invalid option", + asset_id); + return false; + } + + const auto code_name_iter = value_data_obj.find("code_name"); + if (code_name_iter == value_data_obj.end()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse the json, value entry " + "'code_name' not found", + asset_id); + return false; + } + if (!code_name_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse the json, value entry 'code_name' is not " + "the right json type", + asset_id); + return false; + } + property.m_code_name = code_name_iter->second.to_str(); + + const auto value_iter = value_data_obj.find("value"); + if (value_iter != value_data_obj.end()) + { + if (!ParsePropertyValue(asset_id, property.m_type, value_iter->second, &property.m_value)) + return false; + } + + material_property->push_back(std::move(property)); + } + + return true; +} +} // namespace +bool MaterialData::FromJson(const CustomAssetLibrary::AssetID& asset_id, + const picojson::object& json, MaterialData* data) +{ + const auto values_iter = json.find("values"); + if (values_iter == json.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'values' not found", asset_id); + return false; + } + if (!values_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'values' is not the right json type", + asset_id); + return false; + } + const auto& values_array = values_iter->second.get(); + + if (!ParseMaterialProperties(asset_id, values_array, &data->properties)) + return false; + + const auto shader_asset_iter = json.find("shader_asset"); + if (shader_asset_iter == json.end()) + { + ERROR_LOG_FMT(VIDEO, "Asset '{}' failed to parse json, 'shader_asset' not found", asset_id); + return false; + } + if (!shader_asset_iter->second.is()) + { + ERROR_LOG_FMT(VIDEO, + "Asset '{}' failed to parse json, 'shader_asset' is not the right json type", + asset_id); + return false; + } + data->shader_asset = shader_asset_iter->second.to_str(); + + return true; +} + +CustomAssetLibrary::LoadInfo MaterialAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) +{ + auto potential_data = std::make_shared(); + const auto loaded_info = m_owning_library->LoadMaterial(asset_id, potential_data.get()); + if (loaded_info.m_bytes_loaded == 0) + return {}; + { + std::lock_guard lk(m_data_lock); + m_loaded = true; + m_data = std::move(potential_data); + } + return loaded_info; +} +} // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/MaterialAsset.h b/Source/Core/VideoCommon/Assets/MaterialAsset.h new file mode 100644 index 0000000000..498d9dae0f --- /dev/null +++ b/Source/Core/VideoCommon/Assets/MaterialAsset.h @@ -0,0 +1,61 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include + +#include + +#include "Common/CommonTypes.h" +#include "Common/EnumFormatter.h" +#include "VideoCommon/Assets/CustomAsset.h" + +namespace VideoCommon +{ +struct MaterialProperty +{ + using Value = std::variant; + enum class Type + { + Type_Undefined, + Type_TextureAsset, + Type_Max = Type_TextureAsset + }; + std::string m_code_name; + Type m_type = Type::Type_Undefined; + std::optional m_value; +}; + +struct MaterialData +{ + static bool FromJson(const CustomAssetLibrary::AssetID& asset_id, const picojson::object& json, + MaterialData* data); + std::string shader_asset; + std::vector properties; +}; + +// Much like Unity and Unreal materials, a Dolphin material does very little on its own +// Its sole purpose is to provide data (through properties) that are used in conjunction +// with a shader asset that is provided by name. It is up to user of this asset to +// use the two together to create the relevant runtime data +class MaterialAsset final : public CustomLoadableAsset +{ +public: + using CustomLoadableAsset::CustomLoadableAsset; + +private: + CustomAssetLibrary::LoadInfo LoadImpl(const CustomAssetLibrary::AssetID& asset_id) override; +}; + +} // namespace VideoCommon + +template <> +struct fmt::formatter + : EnumFormatter +{ + constexpr formatter() : EnumFormatter({"Undefined", "Texture"}) {} +}; diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 6f12cb80ba..ba3b67faba 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -18,6 +18,8 @@ add_library(videocommon Assets/CustomTextureData.h Assets/DirectFilesystemAssetLibrary.cpp Assets/DirectFilesystemAssetLibrary.h + Assets/MaterialAsset.cpp + Assets/MaterialAsset.h Assets/ShaderAsset.cpp Assets/ShaderAsset.h Assets/TextureAsset.cpp From 93c8db66d6ae7c97a19cf5f881638ec2fe95ee6b Mon Sep 17 00:00:00 2001 From: Joshua de Reeper Date: Mon, 10 Jul 2023 09:47:59 +0100 Subject: [PATCH 26/99] Skylanders: More List Fixes --- .../Core/Core/IOS/USB/Emulated/Skylander.cpp | 151 ++++++++++-------- 1 file changed, 80 insertions(+), 71 deletions(-) diff --git a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp index 8d1fabeff2..1163e9c83c 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp +++ b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp @@ -39,15 +39,15 @@ const std::map, SkyData> list_skylanders = {{6, 0x0000}, {"Dino Rang", Game::SpyrosAdv, Element::Earth}}, {{6, 0x4810}, {"Eon's Elite Dino Rang", Game::Superchargers, Element::Earth}}, {{7, 0x0000}, {"Prism Break", Game::SpyrosAdv, Element::Earth}}, + {{7, 0x1206}, {"LightCore Prism Break", Game::Giants, Element::Earth}}, {{7, 0x1801}, {"Series 2 Prism Break", Game::Giants, Element::Earth}}, {{7, 0x2805}, {"Hyper Beam Prism Break", Game::SwapForce, Element::Earth}}, - {{7, 0x1206}, {"LightCore Prism Break", Game::Giants, Element::Earth}}, {{8, 0x0000}, {"Sunburn", Game::SpyrosAdv, Element::Fire}}, {{9, 0x0000}, {"Eruptor", Game::SpyrosAdv, Element::Fire}}, + {{9, 0x1206}, {"LightCore Eruptor", Game::Giants, Element::Fire}}, {{9, 0x1801}, {"Series 2 Eruptor", Game::Giants, Element::Fire}}, {{9, 0x2C02}, {"Volcanic Eruptor", Game::SwapForce, Element::Fire}}, {{9, 0x2805}, {"Lava Barf Eruptor", Game::SwapForce, Element::Fire}}, - {{9, 0x1206}, {"LightCore Eruptor", Game::Giants, Element::Fire}}, {{9, 0x3810}, {"Eon's Elite Eruptor", Game::TrapTeam, Element::Fire}}, {{10, 0x0000}, {"Ignitor", Game::SpyrosAdv, Element::Fire}}, {{10, 0x1801}, {"Series 2 Ignitor", Game::Giants, Element::Fire}}, @@ -69,8 +69,8 @@ const std::map, SkyData> list_skylanders = {{15, 0x4810}, {"Eon's Elite Slam Bam", Game::Superchargers, Element::Water}}, {{16, 0x0000}, {"Spyro", Game::SpyrosAdv, Element::Magic}}, {{16, 0x1801}, {"Series 2 Spyro", Game::Giants, Element::Magic}}, - {{16, 0x2C02}, {"Dark Mega Ram Spyro", Game::SwapForce, Element::Magic}}, {{16, 0x2805}, {"Mega Ram Spyro", Game::SwapForce, Element::Magic}}, + {{16, 0x2C02}, {"Dark Mega Ram Spyro", Game::SwapForce, Element::Magic}}, {{16, 0x3810}, {"Eon's Elite Spyro", Game::TrapTeam, Element::Magic}}, {{17, 0x0000}, {"Voodood", Game::SpyrosAdv, Element::Magic}}, {{17, 0x4810}, {"Eon's Elite Voodood", Game::Superchargers, Element::Magic}}, @@ -79,12 +79,12 @@ const std::map, SkyData> list_skylanders = {{18, 0x1C02}, {"Royal Double Trouble", Game::Giants, Element::Magic}}, {{19, 0x0000}, {"Trigger Happy", Game::SpyrosAdv, Element::Tech}}, {{19, 0x1801}, {"Series 2 Trigger Happy", Game::Giants, Element::Tech}}, - {{19, 0x2C02}, {"Springtime Trigger Happy", Game::SwapForce, Element::Tech}}, {{19, 0x2805}, {"Big Bang Trigger Happy", Game::SwapForce, Element::Tech}}, + {{19, 0x2C02}, {"Springtime Trigger Happy", Game::SwapForce, Element::Tech}}, {{19, 0x3810}, {"Eon's Elite Trigger Happy", Game::TrapTeam, Element::Tech}}, {{20, 0x0000}, {"Drobot", Game::SpyrosAdv, Element::Tech}}, - {{20, 0x1801}, {"Series 2 Drobot", Game::Giants, Element::Tech}}, {{20, 0x1206}, {"LightCore Drobot", Game::Giants, Element::Tech}}, + {{20, 0x1801}, {"Series 2 Drobot", Game::Giants, Element::Tech}}, {{21, 0x0000}, {"Drill Seargeant", Game::SpyrosAdv, Element::Tech}}, {{21, 0x1801}, {"Series 2 Drill Seargeant", Game::Giants, Element::Tech}}, {{22, 0x0000}, {"Boomer", Game::SpyrosAdv, Element::Tech}}, @@ -98,16 +98,16 @@ const std::map, SkyData> list_skylanders = {{25, 0x4810}, {"Eon's Elite Zook", Game::Superchargers, Element::Life}}, {{26, 0x0000}, {"Stealth Elf", Game::SpyrosAdv, Element::Life}}, {{26, 0x1801}, {"Series 2 Stealth Elf", Game::Giants, Element::Life}}, - {{26, 0x2C02}, {"Dark Stealth Elf", Game::SwapForce, Element::Life}}, {{26, 0x1C03}, {"Legendary Stealth Elf", Game::Giants, Element::Life}}, + {{26, 0x2C02}, {"Dark Stealth Elf", Game::SwapForce, Element::Life}}, {{26, 0x2805}, {"Ninja Stealth Elf", Game::SwapForce, Element::Life}}, {{26, 0x3810}, {"Eon's Elite Stealth Elf", Game::TrapTeam, Element::Life}}, {{27, 0x0000}, {"Stump Smash", Game::SpyrosAdv, Element::Life}}, {{27, 0x1801}, {"Series 2 Stump Smash", Game::Giants, Element::Life}}, {{28, 0x0000}, {"Dark Spyro", Game::SpyrosAdv, Element::Magic}}, {{29, 0x0000}, {"Hex", Game::SpyrosAdv, Element::Undead}}, - {{29, 0x1801}, {"Series 2 Hex", Game::Giants, Element::Undead}}, {{29, 0x1206}, {"LightCore Hex", Game::Giants, Element::Undead}}, + {{29, 0x1801}, {"Series 2 Hex", Game::Giants, Element::Undead}}, {{30, 0x0000}, {"Chop Chop", Game::SpyrosAdv, Element::Undead}}, {{30, 0x1801}, {"Series 2 Chop Chop", Game::Giants, Element::Undead}}, {{30, 0x2805}, {"Twin Blade Chop Chop", Game::SwapForce, Element::Undead}}, @@ -118,10 +118,10 @@ const std::map, SkyData> list_skylanders = {{32, 0x1801}, {"Series 2 Cynder", Game::Giants, Element::Undead}}, {{32, 0x2805}, {"Phantom Cynder", Game::SwapForce, Element::Undead}}, {{100, 0x0000}, {"Jet Vac", Game::Giants, Element::Air}}, + {{100, 0x1206}, {"LightCore Jet Vac", Game::Giants, Element::Air}}, {{100, 0x1403}, {"Legendary Jet Vac", Game::Giants, Element::Air}}, {{100, 0x2805}, {"Turbo Jet Vac", Game::SwapForce, Element::Air}}, {{100, 0x3805}, {"Full Blast Jet Vac", Game::TrapTeam, Element::Air}}, - {{100, 0x1206}, {"LightCore Jet Vac", Game::Giants, Element::Air}}, {{101, 0x0000}, {"Swarm", Game::Giants, Element::Air}}, {{102, 0x0000}, {"Crusher", Game::Giants, Element::Earth}}, {{102, 0x1602}, {"Granite Crusher", Game::Giants, Element::Earth}}, @@ -133,16 +133,16 @@ const std::map, SkyData> list_skylanders = {{105, 0x1402}, {"Molten Hot Dog", Game::Giants, Element::Fire}}, {{105, 0x2805}, {"Fire Bone Hot Dog", Game::SwapForce, Element::Fire}}, {{106, 0x0000}, {"Chill", Game::Giants, Element::Water}}, - {{106, 0x1603}, {"Legendary Chill", Game::Giants, Element::Water}}, - {{106, 0x2805}, {"Blizzard Chill", Game::SwapForce, Element::Water}}, {{106, 0x1206}, {"LightCore Chill", Game::Giants, Element::Water}}, + {{106, 0x1603}, {"Legendary LightCore Chill", Game::Giants, Element::Water}}, + {{106, 0x2805}, {"Blizzard Chill", Game::SwapForce, Element::Water}}, {{107, 0x0000}, {"Thumpback", Game::Giants, Element::Water}}, {{108, 0x0000}, {"Pop Fizz", Game::Giants, Element::Magic}}, + {{108, 0x1206}, {"LightCore Pop Fizz", Game::Giants, Element::Magic}}, {{108, 0x1402}, {"Punch Pop Fizz", Game::Giants, Element::Magic}}, - {{108, 0x3C02}, {"Love Potion Pop Fizz", Game::TrapTeam, Element::Magic}}, {{108, 0x2805}, {"Super Gulp Pop Fizz", Game::SwapForce, Element::Magic}}, {{108, 0x3805}, {"Fizzy Frenzy Pop Fizz", Game::TrapTeam, Element::Magic}}, - {{108, 0x1206}, {"LightCore Pop Fizz", Game::Giants, Element::Magic}}, + {{108, 0x3C02}, {"Love Potion Pop Fizz", Game::TrapTeam, Element::Magic}}, {{109, 0x0000}, {"Ninjini", Game::Giants, Element::Magic}}, {{109, 0x1602}, {"Scarlet Ninjini", Game::Giants, Element::Magic}}, {{110, 0x0000}, {"Bouncer", Game::Giants, Element::Tech}}, @@ -152,8 +152,8 @@ const std::map, SkyData> list_skylanders = {{112, 0x0000}, {"Tree Rex", Game::Giants, Element::Life}}, {{112, 0x1602}, {"Gnarly Tree Rex", Game::Giants, Element::Life}}, {{113, 0x0000}, {"Shroomboom", Game::Giants, Element::Life}}, - {{113, 0x3805}, {"Sure Shot Shroomboom", Game::TrapTeam, Element::Life}}, {{113, 0x1206}, {"LightCore Shroomboom", Game::Giants, Element::Life}}, + {{113, 0x3805}, {"Sure Shot Shroomboom", Game::TrapTeam, Element::Life}}, {{114, 0x0000}, {"Eye Brawl", Game::Giants, Element::Undead}}, {{115, 0x0000}, {"Fright Rider", Game::Giants, Element::Undead}}, {{200, 0x0000}, {"Anvil Rain", Game::SpyrosAdv}}, @@ -167,7 +167,7 @@ const std::map, SkyData> list_skylanders = {{207, 0x0000}, {"Sparx the Dragonfly", Game::SpyrosAdv}}, {{208, 0x0000}, {"Dragonfire Cannon", Game::Giants}}, {{208, 0x1602}, {"Golden Dragonfire Cannon", Game::Giants}}, - {{209, 0x0000}, {"Scorpion Striker", Game::Giants}}, + {{209, 0x0000}, {"Scorpion Striker Catapult", Game::Giants}}, {{210, 0x3002}, {"Biter's Bane", Game::TrapTeam, Element::Magic}}, {{210, 0x3008}, {"Sorcerous Skull", Game::TrapTeam, Element::Magic}}, {{210, 0x300B}, {"Axe of Illusion", Game::TrapTeam, Element::Magic}}, @@ -292,25 +292,33 @@ const std::map, SkyData> list_skylanders = {{483, 0x0000}, {"Spotlight", Game::TrapTeam}}, {{484, 0x0000}, {"Knight Mare", Game::TrapTeam}}, {{485, 0x0000}, {"Blackout", Game::TrapTeam}}, - {{502, 0x0000}, {"Bop", Game::TrapTeam, Element::Earth}}, - {{505, 0x0000}, {"Terrabite", Game::SpyrosAdv, Element::Earth}}, - {{506, 0x0000}, {"Breeze", Game::TrapTeam, Element::Air}}, - {{508, 0x0000}, {"Pet Vac", Game::TrapTeam, Element::Air}}, - {{508, 0x3402}, {"Power Punch Pet Vac", Game::TrapTeam, Element::Air}}, - {{507, 0x0000}, {"Weeruptor", Game::TrapTeam, Element::Fire}}, - {{507, 0x3402}, {"Eggcellent Weeruptor", Game::TrapTeam, Element::Fire}}, - {{509, 0x0000}, {"Small Fry", Game::TrapTeam, Element::Fire}}, - {{510, 0x0000}, {"Drobit", Game::TrapTeam, Element::Fire}}, - {{519, 0x0000}, {"Trigger Snappy", Game::SpyrosAdv, Element::Tech}}, - {{526, 0x0000}, {"Whisper Elf", Game::SpyrosAdv, Element::Life}}, - {{540, 0x0000}, {"Barkley", Game::Giants, Element::Life}}, - {{540, 0x3402}, {"Gnarly Barkley", Game::Giants, Element::Life}}, - {{541, 0x0000}, {"Thumpling", Game::Giants, Element::Water}}, - {{514, 0x0000}, {"Gill Runt", Game::SpyrosAdv, Element::Water}}, - {{542, 0x0000}, {"Mini-Jini", Game::Giants, Element::Magic}}, - {{503, 0x0000}, {"Spry", Game::TrapTeam, Element::Magic}}, - {{504, 0x0000}, {"Hijinx", Game::TrapTeam, Element::Magic}}, - {{543, 0x0000}, {"Eye Small", Game::Giants, Element::Undead}}, + {{502, 0x0000}, {"Bop (Mini)", Game::TrapTeam, Element::Earth}}, + {{503, 0x0000}, {"Spry (Mini)", Game::TrapTeam, Element::Magic}}, + {{504, 0x0000}, {"Hijinx (Mini)", Game::TrapTeam, Element::Undead}}, + {{505, 0x0000}, {"Terrabite (Sidekick)", Game::SpyrosAdv, Element::Earth}}, + {{505, 0x3000}, {"Terrabite (Mini)", Game::TrapTeam, Element::Earth}}, + {{506, 0x0000}, {"Breeze (Mini)", Game::TrapTeam, Element::Air}}, + {{507, 0x0000}, {"Weeruptor (Mini)", Game::TrapTeam, Element::Fire}}, + {{507, 0x3402}, {"Eggcellent Weeruptor (Mini)", Game::TrapTeam, Element::Fire}}, + {{508, 0x0000}, {"Pet Vac (Mini)", Game::TrapTeam, Element::Air}}, + {{508, 0x3402}, {"Power Punch Pet Vac (Mini)", Game::TrapTeam, Element::Air}}, + {{509, 0x0000}, {"Small Fry (Mini)", Game::TrapTeam, Element::Fire}}, + {{510, 0x0000}, {"Drobit (Mini)", Game::TrapTeam, Element::Tech}}, + {{514, 0x0000}, {"Gill Runt (Sidekick)", Game::SpyrosAdv, Element::Water}}, + {{514, 0x3000}, {"Gill Runt (Mini)", Game::TrapTeam, Element::Water}}, + {{519, 0x0000}, {"Trigger Snappy (Sidekick)", Game::SpyrosAdv, Element::Tech}}, + {{519, 0x3000}, {"Trigger Snappy (Mini)", Game::TrapTeam, Element::Tech}}, + {{526, 0x0000}, {"Whisper Elf (Sidekick)", Game::SpyrosAdv, Element::Life}}, + {{526, 0x3000}, {"Whisper Elf (Mini)", Game::TrapTeam, Element::Life}}, + {{540, 0x0000}, {"Barkley (Sidekick)", Game::Giants, Element::Life}}, + {{540, 0x3000}, {"Barkley (Mini)", Game::TrapTeam, Element::Life}}, + {{540, 0x3402}, {"Gnarly Barkley (Mini)", Game::TrapTeam, Element::Life}}, + {{541, 0x0000}, {"Thumpling (Sidekick)", Game::Giants, Element::Water}}, + {{541, 0x3000}, {"Thumpling (Mini)", Game::TrapTeam, Element::Water}}, + {{542, 0x0000}, {"Mini-Jini (Sidekick)", Game::Giants, Element::Magic}}, + {{542, 0x3000}, {"Mini-Jini (Mini)", Game::TrapTeam, Element::Magic}}, + {{543, 0x0000}, {"Eye Small (Sidekick)", Game::Giants, Element::Undead}}, + {{543, 0x3000}, {"Eye Small (Mini)", Game::TrapTeam, Element::Undead}}, {{1000, 0x0000}, {"Boom Jet (Bottom)", Game::SwapForce, Element::Air}}, {{1001, 0x0000}, {"Free Ranger (Bottom)", Game::SwapForce, Element::Air}}, {{1001, 0x2403}, {"Legendary Free Ranger (Bottom)", Game::SwapForce, Element::Air}}, @@ -321,7 +329,7 @@ const std::map, SkyData> list_skylanders = {{1005, 0x0000}, {"Fire Kraken (Bottom)", Game::SwapForce, Element::Fire}}, {{1005, 0x2402}, {"Jade Fire Kraken (Bottom)", Game::SwapForce, Element::Fire}}, {{1006, 0x0000}, {"Stink Bomb (Bottom)", Game::SwapForce, Element::Life}}, - {{1007, 0x0000}, {"Grilla Drilla (Bottom)", Game::SwapForce, Element::Earth}}, + {{1007, 0x0000}, {"Grilla Drilla (Bottom)", Game::SwapForce, Element::Life}}, {{1008, 0x0000}, {"Hoot Loop (Bottom)", Game::SwapForce, Element::Magic}}, {{1008, 0x2402}, {"Enchanted Hoot Loop (Bottom)", Game::SwapForce, Element::Magic}}, {{1009, 0x0000}, {"Trap Shadow (Bottom)", Game::SwapForce, Element::Magic}}, @@ -339,8 +347,8 @@ const std::map, SkyData> list_skylanders = {{2000, 0x0000}, {"Boom Jet (Top)", Game::SwapForce, Element::Air}}, {{2001, 0x0000}, {"Free Ranger (Top)", Game::SwapForce, Element::Air}}, {{2001, 0x2403}, {"Legendary Free Ranger (Top)", Game::SwapForce, Element::Air}}, - {{2002, 0x0000}, {"Rubble Rouser (Top)", Game::SwapForce, Element::Air}}, - {{2003, 0x0000}, {"Doom Stone (Top)", Game::SwapForce, Element::Air}}, + {{2002, 0x0000}, {"Rubble Rouser (Top)", Game::SwapForce, Element::Earth}}, + {{2003, 0x0000}, {"Doom Stone (Top)", Game::SwapForce, Element::Earth}}, {{2004, 0x0000}, {"Blast Zone (Top)", Game::SwapForce, Element::Fire}}, {{2004, 0x2402}, {"Dark Blast Zone (Top)", Game::SwapForce, Element::Fire}}, {{2005, 0x0000}, {"Fire Kraken (Top)", Game::SwapForce, Element::Fire}}, @@ -362,7 +370,7 @@ const std::map, SkyData> list_skylanders = {{2015, 0x0000}, {"Wash Buckler (Top)", Game::SwapForce, Element::Water}}, {{2015, 0x2402}, {"Dark Wash Buckler (Top)", Game::SwapForce, Element::Water}}, {{3000, 0x0000}, {"Scratch", Game::SwapForce, Element::Air}}, - {{3001, 0x0000}, {"Pop Thorn", Game::SwapForce, Element::Magic}}, + {{3001, 0x0000}, {"Pop Thorn", Game::SwapForce, Element::Air}}, {{3002, 0x0000}, {"Slobber Tooth", Game::SwapForce, Element::Earth}}, {{3002, 0x2402}, {"Dark Slobber Tooth", Game::SwapForce, Element::Earth}}, {{3003, 0x0000}, {"Scorp", Game::SwapForce, Element::Earth}}, @@ -371,23 +379,23 @@ const std::map, SkyData> list_skylanders = {{3005, 0x0000}, {"Smolderdash", Game::SwapForce, Element::Fire}}, {{3005, 0x2206}, {"LightCore Smolderdash", Game::SwapForce, Element::Fire}}, {{3006, 0x0000}, {"Bumble Blast", Game::SwapForce, Element::Life}}, - {{3006, 0x2402}, {"Jolly Bumble Blast", Game::SwapForce, Element::Life}}, {{3006, 0x2206}, {"LightCore Bumble Blast", Game::SwapForce, Element::Life}}, + {{3006, 0x2402}, {"Jolly Bumble Blast", Game::SwapForce, Element::Life}}, {{3007, 0x0000}, {"Zoo Lou", Game::SwapForce, Element::Life}}, {{3007, 0x2403}, {"Legendary Zoo Lou", Game::SwapForce, Element::Life}}, {{3008, 0x0000}, {"Dune Bug", Game::SwapForce, Element::Magic}}, {{3009, 0x0000}, {"Star Strike", Game::SwapForce, Element::Magic}}, - {{3009, 0x2602}, {"Enchanted Star Strike", Game::SwapForce, Element::Magic}}, {{3009, 0x2206}, {"LightCore Star Strike", Game::SwapForce, Element::Magic}}, + {{3009, 0x2602}, {"Enchanted Star Strike", Game::SwapForce, Element::Magic}}, {{3010, 0x0000}, {"Countdown", Game::SwapForce, Element::Tech}}, - {{3010, 0x2402}, {"Kickoff Countdown", Game::SwapForce, Element::Tech}}, {{3010, 0x2206}, {"LightCore Countdown", Game::SwapForce, Element::Tech}}, + {{3010, 0x2402}, {"Kickoff Countdown", Game::SwapForce, Element::Tech}}, {{3011, 0x0000}, {"Wind Up", Game::SwapForce, Element::Tech}}, {{3011, 0x2404}, {"Gear Head VVind Up", Game::SwapForce, Element::Tech}}, {{3012, 0x0000}, {"Roller Brawl", Game::SwapForce, Element::Undead}}, {{3013, 0x0000}, {"Grim Creeper", Game::SwapForce, Element::Undead}}, - {{3013, 0x2603}, {"Legendary Grim Creeper", Game::SwapForce, Element::Undead}}, {{3013, 0x2206}, {"LightCore Grim Creeper", Game::SwapForce, Element::Undead}}, + {{3013, 0x2603}, {"Legendary Grim Creeper", Game::SwapForce, Element::Undead}}, {{3014, 0x0000}, {"Rip Tide", Game::SwapForce, Element::Water}}, {{3015, 0x0000}, {"Punk Shock", Game::SwapForce, Element::Water}}, {{3200, 0x0000}, {"Battle Hammer", Game::SwapForce}}, @@ -395,38 +403,38 @@ const std::map, SkyData> list_skylanders = {{3202, 0x0000}, {"Platinum Sheep", Game::SwapForce}}, {{3203, 0x0000}, {"Groove Machine", Game::SwapForce}}, {{3204, 0x0000}, {"UFO Hat", Game::SwapForce}}, - {{3220, 0x0000}, {"Jet Stream", Game::Superchargers}}, - {{3221, 0x0000}, {"Tomb Buggy", Game::Superchargers}}, - {{3222, 0x0000}, {"Reef Ripper", Game::Superchargers}}, - {{3223, 0x0000}, {"Burn Cycle", Game::Superchargers}}, - {{3224, 0x0000}, {"Hot Streak", Game::Superchargers}}, - {{3224, 0x4402}, {"Dark Hot Streak", Game::Superchargers}}, - {{3224, 0x4004}, {"E3 Hot Streak", Game::Superchargers}}, - {{3224, 0x441E}, {"Golden Hot Streak", Game::Superchargers}}, - {{3225, 0x0000}, {"Shark Tank", Game::Superchargers}}, - {{3226, 0x0000}, {"Thump Truck", Game::Superchargers}}, - {{3227, 0x0000}, {"Crypt Crusher", Game::Superchargers}}, - {{3228, 0x0000}, {"Stealth Stinger", Game::Superchargers}}, - {{3228, 0x4402}, {"Nitro Stealth Stinger", Game::Superchargers}}, - {{3231, 0x0000}, {"Dive Bomber", Game::Superchargers}}, - {{3231, 0x4402}, {"Spring Ahead Dive Bomber", Game::Superchargers}}, - {{3232, 0x0000}, {"Sky Slicer", Game::Superchargers}}, - {{3233, 0x0000}, {"Clown Cruiser", Game::Superchargers}}, - {{3233, 0x4402}, {"Dark Clown Cruiser", Game::Superchargers}}, - {{3234, 0x0000}, {"Gold Rusher", Game::Superchargers}}, - {{3234, 0x4402}, {"Power Blue Gold Rusher", Game::Superchargers}}, - {{3235, 0x0000}, {"Shield Striker", Game::Superchargers}}, + {{3220, 0x0000}, {"Jet Stream", Game::Superchargers, Element::Air}}, + {{3221, 0x0000}, {"Tomb Buggy", Game::Superchargers, Element::Undead}}, + {{3222, 0x0000}, {"Reef Ripper", Game::Superchargers, Element::Water}}, + {{3223, 0x0000}, {"Burn Cycle", Game::Superchargers, Element::Fire}}, + {{3224, 0x0000}, {"Hot Streak", Game::Superchargers, Element::Fire}}, + {{3224, 0x4004}, {"E3 Hot Streak", Game::Superchargers, Element::Fire}}, + {{3224, 0x4402}, {"Dark Hot Streak", Game::Superchargers, Element::Fire}}, + {{3224, 0x441E}, {"Golden Hot Streak", Game::Superchargers, Element::Fire}}, + {{3225, 0x0000}, {"Shark Tank", Game::Superchargers, Element::Earth}}, + {{3226, 0x0000}, {"Thump Truck", Game::Superchargers, Element::Earth}}, + {{3227, 0x0000}, {"Crypt Crusher", Game::Superchargers, Element::Undead}}, + {{3228, 0x0000}, {"Stealth Stinger", Game::Superchargers, Element::Life}}, + {{3228, 0x4402}, {"Nitro Stealth Stinger", Game::Superchargers, Element::Life}}, + {{3231, 0x0000}, {"Dive Bomber", Game::Superchargers, Element::Water}}, + {{3231, 0x4402}, {"Spring Ahead Dive Bomber", Game::Superchargers, Element::Water}}, + {{3232, 0x0000}, {"Sky Slicer", Game::Superchargers, Element::Air}}, + {{3233, 0x0000}, {"Clown Cruiser", Game::Superchargers, Element::Air}}, + {{3233, 0x4402}, {"Dark Clown Cruiser", Game::Superchargers, Element::Air}}, + {{3234, 0x0000}, {"Gold Rusher", Game::Superchargers, Element::Tech}}, + {{3234, 0x4402}, {"Power Blue Gold Rusher", Game::Superchargers, Element::Tech}}, + {{3235, 0x0000}, {"Shield Striker", Game::Superchargers, Element::Tech}}, {{3236, 0x0000}, {"Sun Runner", Game::Superchargers}}, {{3236, 0x4403}, {"Legendary Sun Runner", Game::Superchargers}}, {{3237, 0x0000}, {"Sea Shadow", Game::Superchargers}}, {{3237, 0x4402}, {"Dark Sea Shadow", Game::Superchargers}}, - {{3238, 0x0000}, {"Splatter Splasher", Game::Superchargers}}, - {{3238, 0x4402}, {"Power Blue Splatter Splasher", Game::Superchargers}}, - {{3239, 0x0000}, {"Soda Skimmer", Game::Superchargers}}, - {{3240, 0x0000}, {"Barrel Blaster", Game::Superchargers}}, - {{3240, 0x4402}, {"Dark Barrel Blaster", Game::Superchargers}}, - {{3239, 0x4402}, {"Nitro Soda Skimmer", Game::Superchargers}}, - {{3241, 0x0000}, {"Buzz Wing", Game::Superchargers}}, + {{3238, 0x0000}, {"Splatter Splasher", Game::Superchargers, Element::Magic}}, + {{3238, 0x4402}, {"Power Blue Splatter Splasher", Game::Superchargers, Element::Magic}}, + {{3239, 0x0000}, {"Soda Skimmer", Game::Superchargers, Element::Magic}}, + {{3239, 0x4402}, {"Nitro Soda Skimmer", Game::Superchargers, Element::Magic}}, + {{3240, 0x0000}, {"Barrel Blaster", Game::Superchargers, Element::Tech}}, + {{3240, 0x4402}, {"Dark Barrel Blaster", Game::Superchargers, Element::Tech}}, + {{3241, 0x0000}, {"Buzz Wing", Game::Superchargers, Element::Life}}, {{3300, 0x0000}, {"Sheep Wreck Island", Game::SwapForce}}, {{3301, 0x0000}, {"Tower of Time", Game::SwapForce}}, {{3302, 0x0000}, {"Fiery Forge", Game::SwapForce}}, @@ -437,6 +445,7 @@ const std::map, SkyData> list_skylanders = {{3402, 0x0000}, {"Splat", Game::Superchargers, Element::Magic}}, {{3402, 0x4502}, {"Power Blue Splat", Game::Superchargers, Element::Magic}}, {{3406, 0x0000}, {"Stormblade", Game::Superchargers, Element::Air}}, + {{3406, 0x4502}, {"Dark Stormblade", Game::Superchargers, Element::Air}}, {{3411, 0x0000}, {"Smash Hit", Game::Superchargers, Element::Earth}}, {{3411, 0x4502}, {"Steel Plated Smash Hit", Game::Superchargers, Element::Earth}}, {{3412, 0x0000}, {"Spitfire", Game::Superchargers, Element::Fire}}, @@ -448,8 +457,8 @@ const std::map, SkyData> list_skylanders = {{3415, 0x0000}, {"Super Shot Stealth Elf", Game::Superchargers, Element::Life}}, {{3415, 0x4502}, {"Dark Super Shot Stealth Elf", Game::Superchargers, Element::Life}}, {{3416, 0x0000}, {"Shark Shooter Terrafin", Game::Superchargers, Element::Earth}}, - {{3417, 0x0000}, {"Bone Bash Roller Brawl", Game::Superchargers, Element::Earth}}, - {{3417, 0x4503}, {"Legendary Bone Bash Roller Brawl", Game::Superchargers, Element::Earth}}, + {{3417, 0x0000}, {"Bone Bash Roller Brawl", Game::Superchargers, Element::Undead}}, + {{3417, 0x4503}, {"Legendary Bone Bash Roller Brawl", Game::Superchargers, Element::Undead}}, {{3420, 0x0000}, {"Big Bubble Pop Fizz", Game::Superchargers, Element::Magic}}, {{3420, 0x450E}, {"Birthday Bash Big Bubble Pop Fizz", Game::Superchargers, Element::Magic}}, {{3421, 0x0000}, {"Lava Lance Eruptor", Game::Superchargers, Element::Fire}}, From ad3b8b649b0f80e330144f69fcd2c184df916e27 Mon Sep 17 00:00:00 2001 From: Benjamin Mugnier Date: Tue, 11 Jul 2023 20:48:31 +0200 Subject: [PATCH 27/99] readme: Add '--recursive' to git submodule command Not doing so results in the following error : CMake Error at Externals/cubeb/CMakeLists.txt:30 (message): Could not find sanitizers-cmake: run git submodule update --init --recursive in base git checkout As the advice is correct, update readme with the correct command. --- Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index 197d4040f8..7fecf65cfd 100644 --- a/Readme.md +++ b/Readme.md @@ -46,7 +46,7 @@ installed when building. Make sure to pull submodules before building: ```sh -git submodule update --init +git submodule update --init --recursive ``` The "Release" solution configuration includes performance optimizations for the best user experience but complicates debugging Dolphin. @@ -63,7 +63,7 @@ to install any missing packages yourself. You may refer to the [wiki](https://gi Make sure to pull submodules before building: ```sh -git submodule update --init +git submodule update --init --recursive ``` ### macOS Build Steps: @@ -128,7 +128,7 @@ Android dev environment set up, see [AndroidSetup.md](AndroidSetup.md). Make sure to pull submodules before building: ```sh -git submodule update --init +git submodule update --init --recursive ``` If using Android Studio, import the Gradle project located in `./Source/Android`. From 5acebc71c47893ead1b449863a4c58199c89d53d Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 11 Jul 2023 22:41:51 +0200 Subject: [PATCH 28/99] D3D: Remove Windows 7 mention in logic ops warning Dolphin no longer supports Windows 7, so the fact that there are (were?) more people who use Windows 7 than who use a GPU that doesn't support the required feature is no longer relevant. --- Source/Core/VideoBackends/D3D/D3DMain.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/D3DMain.cpp b/Source/Core/VideoBackends/D3D/D3DMain.cpp index 5ea3014c6c..9a25c1abde 100644 --- a/Source/Core/VideoBackends/D3D/D3DMain.cpp +++ b/Source/Core/VideoBackends/D3D/D3DMain.cpp @@ -42,7 +42,7 @@ std::optional VideoBackend::GetWarningMessage() const { std::optional result; - // If user is on Win7, show a warning about partial DX11.1 support + // If relevant, show a warning about partial DX11.1 support // This is being called BEFORE FillBackendInfo is called for this backend, // so query for logic op support manually bool supportsLogicOp = false; @@ -54,10 +54,11 @@ std::optional VideoBackend::GetWarningMessage() const if (!supportsLogicOp) { - result = _trans("Direct3D 11 renderer requires support for features not supported by your " - "system configuration. This is most likely because you are using Windows 7. " - "You may still use this backend, but you might encounter graphical artifacts." - "\n\nDo you really want to switch to Direct3D 11? If unsure, select 'No'."); + result = _trans("The Direct3D 11 renderer requires support for features not supported by your " + "system configuration. You may still use this backend, but you will encounter " + "graphical artifacts in certain games.\n" + "\n" + "Do you really want to switch to Direct3D 11? If unsure, select 'No'."); } return result; From 92be54d57a977f3abe7de8f08da3bb3eca452b7b Mon Sep 17 00:00:00 2001 From: Sepalani Date: Wed, 12 Jul 2023 19:18:03 +0400 Subject: [PATCH 29/99] Common/CommonFuncs: Add StrErrorWrapper function --- Source/Core/Common/CommonFuncs.cpp | 38 ++++++++++++++++++------------ Source/Core/Common/CommonFuncs.h | 3 +++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Source/Core/Common/CommonFuncs.cpp b/Source/Core/Common/CommonFuncs.cpp index 4fdefa3a67..a1e93455a2 100644 --- a/Source/Core/Common/CommonFuncs.cpp +++ b/Source/Core/Common/CommonFuncs.cpp @@ -17,27 +17,35 @@ namespace Common { constexpr size_t BUFFER_SIZE = 256; +// There are two variants of strerror_r. The XSI version stores the message to the passed-in +// buffer and returns an int (0 on success). The GNU version returns a pointer to the message, +// which might have been stored in the passed-in buffer or might be a static string. +// +// This function might change the errno value. +// +// References: +// https://www.gnu.org/software/gnulib/manual/html_node/strerror_005fr.html +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror_r.html +// https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib-strerror-r.html +const char* StrErrorWrapper(int error, char* buffer, std::size_t length) +{ + // We check defines in order to figure out which variant is in use. +#if (defined(__GLIBC__) || __ANDROID_API__ >= 23) && \ + (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) + return strerror_r(error, buffer, length); +#else + const int error_code = strerror_r(error, buffer, length); + return error_code == 0 ? buffer : ""; +#endif +} + // Wrapper function to get last strerror(errno) string. // This function might change the error code. std::string LastStrerrorString() { char error_message[BUFFER_SIZE]; - // There are two variants of strerror_r. The XSI version stores the message to the passed-in - // buffer and returns an int (0 on success). The GNU version returns a pointer to the message, - // which might have been stored in the passed-in buffer or might be a static string. - - // We check defines in order to figure out variant is in use, and we store the returned value - // to a variable so that we'll get a compile-time check that our assumption was correct. - -#if (defined(__GLIBC__) || __ANDROID_API__ >= 23) && \ - (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) - const char* str = strerror_r(errno, error_message, BUFFER_SIZE); - return std::string(str); -#else - int error_code = strerror_r(errno, error_message, BUFFER_SIZE); - return error_code == 0 ? std::string(error_message) : ""; -#endif + return StrErrorWrapper(errno, error_message, BUFFER_SIZE); } #ifdef _WIN32 diff --git a/Source/Core/Common/CommonFuncs.h b/Source/Core/Common/CommonFuncs.h index cd8dbe94ac..4dac076c04 100644 --- a/Source/Core/Common/CommonFuncs.h +++ b/Source/Core/Common/CommonFuncs.h @@ -41,6 +41,9 @@ __declspec(dllimport) void __stdcall DebugBreak(void); namespace Common { +// strerror_r wrapper to handle XSI and GNU versions. +const char* StrErrorWrapper(int error, char* buffer, std::size_t length); + // Wrapper function to get last strerror(errno) string. // This function might change the error code. std::string LastStrerrorString(); From cbb76c1d4fbccbe08d28a2a26cfe92c507982e43 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Wed, 12 Jul 2023 19:29:35 +0400 Subject: [PATCH 30/99] Common/Network: Use StrErrorWrapper --- Source/Core/Common/Network.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Source/Core/Common/Network.cpp b/Source/Core/Common/Network.cpp index a5e56b74d2..f859a8d438 100644 --- a/Source/Core/Common/Network.cpp +++ b/Source/Core/Common/Network.cpp @@ -19,6 +19,7 @@ #include #include "Common/BitUtils.h" +#include "Common/CommonFuncs.h" #include "Common/Random.h" #include "Common/StringUtil.h" @@ -551,23 +552,14 @@ const char* DecodeNetworkError(s32 error_code) { thread_local char buffer[1024]; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(ANDROID) || \ - defined(__APPLE__) -#define IS_BSD_STRERROR -#endif - #ifdef _WIN32 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), nullptr); return buffer; -#elif defined(IS_BSD_STRERROR) || \ - ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) - strerror_r(error_code, buffer, sizeof(buffer)); - return buffer; #else - return strerror_r(error_code, buffer, sizeof(buffer)); + return Common::StrErrorWrapper(error_code, buffer, sizeof(buffer)); #endif } From c4978edaf6dbef81903f84ce0b3ef45b270fa926 Mon Sep 17 00:00:00 2001 From: Upfoldian Date: Thu, 13 Jul 2023 21:33:36 +1000 Subject: [PATCH 31/99] Fixed a bug where in the extremely unlikely change that HostIDs collide, a new HostID is generated. --- Source/Core/Common/TraversalServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/TraversalServer.cpp b/Source/Core/Common/TraversalServer.cpp index b9b05519fa..a3d28d1bab 100644 --- a/Source/Core/Common/TraversalServer.cpp +++ b/Source/Core/Common/TraversalServer.cpp @@ -312,9 +312,9 @@ static void HandlePacket(Common::TraversalPacket* packet, sockaddr_in6* addr) Common::TraversalInetAddress* iaddr{}; // not that there is any significant change of // duplication, but... - GetRandomHostId(&hostId); while (true) { + GetRandomHostId(&hostId); auto r = EvictFind(connectedClients, hostId); if (!r.found) { From 17f2072e1c9221aa38bc9f653ce792b2745f0d91 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 14 Jul 2023 04:20:42 +0200 Subject: [PATCH 32/99] UnitTests: Enable cluster check in FileSystemTest.GetDirectoryStats. --- Source/UnitTests/Core/IOS/FS/FileSystemTest.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/UnitTests/Core/IOS/FS/FileSystemTest.cpp b/Source/UnitTests/Core/IOS/FS/FileSystemTest.cpp index 5442a66eab..b1e6997e34 100644 --- a/Source/UnitTests/Core/IOS/FS/FileSystemTest.cpp +++ b/Source/UnitTests/Core/IOS/FS/FileSystemTest.cpp @@ -269,8 +269,7 @@ TEST_F(FileSystemTest, GetDirectoryStats) file->Write(std::vector(20).data(), 20); } // The file should now take up one cluster. - // TODO: uncomment after the FS code is fixed. - // check_stats(1u, 2u); + check_stats(1u, 2u); } // Files need to be explicitly created using CreateFile or CreateDirectory. From 0d9e027a0b54ff8c4a3be2ce3b743eb98b2d35bc Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 14 Jul 2023 04:13:31 +0200 Subject: [PATCH 33/99] IOS/FS: Move NAND size related constants to FileSystem.h. That way they're available for calculating NAND stats to display to the user. This also adds a few more constants. --- Source/Core/Core/IOS/FS/FileSystem.h | 27 ++++++++++++++++++++++ Source/Core/Core/IOS/FS/HostBackend/FS.cpp | 15 ------------ 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Source/Core/Core/IOS/FS/FileSystem.h b/Source/Core/Core/IOS/FS/FileSystem.h index 581df6fbee..f02d2eb350 100644 --- a/Source/Core/Core/IOS/FS/FileSystem.h +++ b/Source/Core/Core/IOS/FS/FileSystem.h @@ -107,6 +107,33 @@ struct Metadata u16 fst_index; }; +// size of a single cluster in the NAND in bytes +constexpr u16 CLUSTER_SIZE = 16384; + +// total number of clusters available in the NAND +constexpr u16 TOTAL_CLUSTERS = 0x7ec0; + +// number of clusters reserved for bad blocks and similar, not accessible to normal writes +constexpr u16 RESERVED_CLUSTERS = 0x0300; + +// number of clusters actually usable by the file system +constexpr u16 USABLE_CLUSTERS = TOTAL_CLUSTERS - RESERVED_CLUSTERS; + +// size of a single 'block' as defined by the Wii System Menu in clusters +constexpr u16 CLUSTERS_PER_BLOCK = 8; + +// total number of user-accessible blocks in the NAND +constexpr u16 USER_BLOCKS = 2176; + +// total number of user-accessible clusters in the NAND +constexpr u16 USER_CLUSTERS = USER_BLOCKS * CLUSTERS_PER_BLOCK; + +// the inverse of that, the amount of usable clusters reserved for system files +constexpr u16 SYSTEM_CLUSTERS = USABLE_CLUSTERS - USER_CLUSTERS; + +// total number of inodes available in the NAND +constexpr u16 TOTAL_INODES = 0x17ff; + struct NandStats { u32 cluster_size; diff --git a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp index f09cadb7c8..8c832b2934 100644 --- a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp +++ b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp @@ -29,21 +29,6 @@ namespace IOS::HLE::FS { constexpr u32 BUFFER_CHUNK_SIZE = 65536; -// size of a single cluster in the NAND -constexpr u16 CLUSTER_SIZE = 16384; - -// total number of clusters available in the NAND -constexpr u16 TOTAL_CLUSTERS = 0x7ec0; - -// number of clusters reserved for bad blocks and similar, not accessible to normal writes -constexpr u16 RESERVED_CLUSTERS = 0x0300; - -// number of clusters actually usable by the file system -constexpr u16 USABLE_CLUSTERS = TOTAL_CLUSTERS - RESERVED_CLUSTERS; - -// total number of inodes available in the NAND -constexpr u16 TOTAL_INODES = 0x17ff; - HostFileSystem::HostFilename HostFileSystem::BuildFilename(const std::string& wii_path) const { for (const auto& redirect : m_nand_redirects) From efae5827f211c41778e8d0c66623655488fdd1fd Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 14 Jul 2023 04:16:56 +0200 Subject: [PATCH 34/99] IOS/FS: Implement GetExtendedDirectoryStats(). Behaves like GetDirectoryStats() but doesn't clamp to the Wii limits, so we can tell the user exactly how overfull their NAND is. --- Source/Core/Core/IOS/FS/FileSystem.h | 11 +++++++++++ Source/Core/Core/IOS/FS/HostBackend/FS.cpp | 21 ++++++++++++++++----- Source/Core/Core/IOS/FS/HostBackend/FS.h | 1 + 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/IOS/FS/FileSystem.h b/Source/Core/Core/IOS/FS/FileSystem.h index f02d2eb350..c0f59c2137 100644 --- a/Source/Core/Core/IOS/FS/FileSystem.h +++ b/Source/Core/Core/IOS/FS/FileSystem.h @@ -151,6 +151,14 @@ struct DirectoryStats u32 used_inodes; }; +// Not a real Wii data struct, but useful for calculating how full the user's NAND is even if it's +// way larger than it should be. +struct ExtendedDirectoryStats +{ + u64 used_clusters; + u64 used_inodes; +}; + struct FileStatus { u32 offset; @@ -279,6 +287,9 @@ public: /// Get usage information about a directory (used cluster and inode counts). virtual Result GetDirectoryStats(const std::string& path) = 0; + /// Like GetDirectoryStats() but not limited to the actual 512 MB NAND limit. + virtual Result GetExtendedDirectoryStats(const std::string& path) = 0; + virtual void SetNandRedirects(std::vector nand_redirects) = 0; }; diff --git a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp index 8c832b2934..a916ffba81 100644 --- a/Source/Core/Core/IOS/FS/HostBackend/FS.cpp +++ b/Source/Core/Core/IOS/FS/HostBackend/FS.cpp @@ -803,11 +803,24 @@ Result HostFileSystem::GetNandStats() } Result HostFileSystem::GetDirectoryStats(const std::string& wii_path) +{ + const auto result = GetExtendedDirectoryStats(wii_path); + if (!result) + return result.Error(); + + DirectoryStats stats{}; + stats.used_inodes = static_cast(std::min(result->used_inodes, TOTAL_INODES)); + stats.used_clusters = static_cast(std::min(result->used_clusters, USABLE_CLUSTERS)); + return stats; +} + +Result +HostFileSystem::GetExtendedDirectoryStats(const std::string& wii_path) { if (!IsValidPath(wii_path)) return ResultCode::Invalid; - DirectoryStats stats{}; + ExtendedDirectoryStats stats{}; std::string path(BuildFilename(wii_path).host_path); File::FileInfo info(path); if (!info.Exists()) @@ -820,10 +833,8 @@ Result HostFileSystem::GetDirectoryStats(const std::string& wii_ FixupDirectoryEntries(&parent_dir, wii_path == "/"); // add one for the folder itself - stats.used_inodes = static_cast(std::min(1 + parent_dir.size, TOTAL_INODES)); - - const u64 clusters = ComputeUsedClusters(parent_dir); - stats.used_clusters = static_cast(std::min(clusters, USABLE_CLUSTERS)); + stats.used_inodes = 1 + parent_dir.size; + stats.used_clusters = ComputeUsedClusters(parent_dir); } else { diff --git a/Source/Core/Core/IOS/FS/HostBackend/FS.h b/Source/Core/Core/IOS/FS/HostBackend/FS.h index 1248c06736..3c68a59495 100644 --- a/Source/Core/Core/IOS/FS/HostBackend/FS.h +++ b/Source/Core/Core/IOS/FS/HostBackend/FS.h @@ -55,6 +55,7 @@ public: Result GetNandStats() override; Result GetDirectoryStats(const std::string& path) override; + Result GetExtendedDirectoryStats(const std::string& path) override; void SetNandRedirects(std::vector nand_redirects) override; From cd5aebe5ac47ea305644ab62bebd057dbaa170d3 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 14 Jul 2023 05:10:18 +0200 Subject: [PATCH 35/99] Qt: Add file size stats to NAND Check. --- Source/Core/Core/WiiUtils.cpp | 28 ++++++++++++++++++++++ Source/Core/Core/WiiUtils.h | 4 ++++ Source/Core/DolphinQt/MenuBar.cpp | 39 ++++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/WiiUtils.cpp b/Source/Core/Core/WiiUtils.cpp index 30225febfb..92c2c19a0d 100644 --- a/Source/Core/Core/WiiUtils.cpp +++ b/Source/Core/Core/WiiUtils.cpp @@ -961,6 +961,34 @@ static NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios, bool repair) } } + // Get some storage stats. + const auto fs = ios.GetFS(); + const auto root_stats = fs->GetExtendedDirectoryStats("/"); + + // The Wii System Menu's save/channel management only considers a specific subset of the Wii NAND + // user-accessible and will only use those folders when calculating the amount of free blocks it + // displays. This can have weird side-effects where the other parts of the NAND contain more data + // than reserved and it will display free blocks even though there isn't any space left. To avoid + // confusion, report the 'user' and 'system' data separately to the user. + u64 used_clusters_user = 0; + u64 used_inodes_user = 0; + for (std::string user_path : {"/meta", "/ticket", "/title/00010000", "/title/00010001", + "/title/00010003", "/title/00010004", "/title/00010005", + "/title/00010006", "/title/00010007", "/shared2/title"}) + { + const auto dir_stats = fs->GetExtendedDirectoryStats(user_path); + if (dir_stats) + { + used_clusters_user += dir_stats->used_clusters; + used_inodes_user += dir_stats->used_inodes; + } + } + + result.used_clusters_user = used_clusters_user; + result.used_clusters_system = root_stats ? (root_stats->used_clusters - used_clusters_user) : 0; + result.used_inodes_user = used_inodes_user; + result.used_inodes_system = root_stats ? (root_stats->used_inodes - used_inodes_user) : 0; + return result; } diff --git a/Source/Core/Core/WiiUtils.h b/Source/Core/Core/WiiUtils.h index ae2d7c85e0..c8f86d7253 100644 --- a/Source/Core/Core/WiiUtils.h +++ b/Source/Core/Core/WiiUtils.h @@ -101,6 +101,10 @@ struct NANDCheckResult { bool bad = false; std::unordered_set titles_to_remove; + u64 used_clusters_user = 0; + u64 used_clusters_system = 0; + u64 used_inodes_user = 0; + u64 used_inodes_system = 0; }; NANDCheckResult CheckNAND(IOS::HLE::Kernel& ios); bool RepairNAND(IOS::HLE::Kernel& ios); diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index b0989fae66..37562a738c 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -15,6 +15,7 @@ #include #include +#include "Common/Align.h" #include "Common/CommonPaths.h" #include "Common/FileUtil.h" #include "Common/StringUtil.h" @@ -32,6 +33,7 @@ #include "Core/HW/WiiSave.h" #include "Core/HW/Wiimote.h" #include "Core/IOS/ES/ES.h" +#include "Core/IOS/FS/FileSystem.h" #include "Core/IOS/IOS.h" #include "Core/IOS/USB/Bluetooth/BTEmu.h" #include "Core/Movie.h" @@ -1137,7 +1139,42 @@ void MenuBar::CheckNAND() WiiUtils::NANDCheckResult result = WiiUtils::CheckNAND(ios); if (!result.bad) { - ModalMessageBox::information(this, tr("NAND Check"), tr("No issues have been detected.")); + const bool overfull = result.used_clusters_user > IOS::HLE::FS::USER_CLUSTERS || + result.used_clusters_system > IOS::HLE::FS::SYSTEM_CLUSTERS; + const QString user_cluster_message = + tr("The user-accessible part of your NAND contains %1 blocks (%2 KiB) " + "of data, out of an allowed maximum of %3 blocks (%4 KiB).") + .arg(Common::AlignUp(result.used_clusters_user, IOS::HLE::FS::CLUSTERS_PER_BLOCK) / + IOS::HLE::FS::CLUSTERS_PER_BLOCK) + .arg((result.used_clusters_user * IOS::HLE::FS::CLUSTER_SIZE) / 1024) + .arg(IOS::HLE::FS::USER_CLUSTERS / IOS::HLE::FS::CLUSTERS_PER_BLOCK) + .arg((IOS::HLE::FS::USER_CLUSTERS * IOS::HLE::FS::CLUSTER_SIZE) / 1024); + const QString system_cluster_message = + tr("The system-reserved part of your NAND contains %1 blocks (%2 KiB) " + "of data, out of an allowed maximum of %3 blocks (%4 KiB).") + .arg(Common::AlignUp(result.used_clusters_system, IOS::HLE::FS::CLUSTERS_PER_BLOCK) / + IOS::HLE::FS::CLUSTERS_PER_BLOCK) + .arg((result.used_clusters_system * IOS::HLE::FS::CLUSTER_SIZE) / 1024) + .arg(IOS::HLE::FS::SYSTEM_CLUSTERS / IOS::HLE::FS::CLUSTERS_PER_BLOCK) + .arg((IOS::HLE::FS::SYSTEM_CLUSTERS * IOS::HLE::FS::CLUSTER_SIZE) / 1024); + + if (overfull) + { + ModalMessageBox::warning(this, tr("NAND Check"), + QStringLiteral("%1

%2

%3") + .arg(tr("Your NAND contains more data than allowed. Wii " + "software may behave incorrectly or not allow saving.")) + .arg(user_cluster_message) + .arg(system_cluster_message)); + } + else + { + ModalMessageBox::information(this, tr("NAND Check"), + QStringLiteral("%1

%2

%3") + .arg(tr("No issues have been detected.")) + .arg(user_cluster_message) + .arg(system_cluster_message)); + } return; } From 6dad8f837285c32720efa8fcd28de4d197f27611 Mon Sep 17 00:00:00 2001 From: Jeremy Newton Date: Mon, 10 Apr 2023 17:49:38 -0400 Subject: [PATCH 36/99] Allow shared zlib-ng --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed6c64a2fa..ee44d04458 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -676,7 +676,7 @@ dolphin_make_imported_target_if_missing(LibLZMA::LibLZMA LIBLZMA) dolphin_find_optional_system_library_pkgconfig(ZSTD libzstd>=1.4.0 zstd::zstd Externals/zstd) -add_subdirectory(Externals/zlib-ng) +dolphin_find_optional_system_library_pkgconfig(ZLIB zlib-ng ZLIB::ZLIB Externals/zlib-ng) dolphin_find_optional_system_library_pkgconfig(MINIZIP minizip>=3.0.0 minizip::minizip Externals/minizip) From 5740be15f9fe5c6a009f097b9089970f3f78682a Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 16 Jul 2023 12:56:03 -0500 Subject: [PATCH 37/99] VideoCommon: initialize load info variables --- Source/Core/VideoCommon/Assets/CustomAssetLibrary.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h index 32e8020ae0..6eec276620 100644 --- a/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h +++ b/Source/Core/VideoCommon/Assets/CustomAssetLibrary.h @@ -34,8 +34,8 @@ public: struct LoadInfo { - std::size_t m_bytes_loaded; - CustomAssetLibrary::TimeType m_load_time; + std::size_t m_bytes_loaded = 0; + CustomAssetLibrary::TimeType m_load_time = {}; }; // Loads a texture, if there are no levels, bytes loaded will be empty From d7e79683cc4164d7246ef4974cf35f01b439d175 Mon Sep 17 00:00:00 2001 From: "Mateus B. Cassiano" Date: Sun, 16 Jul 2023 16:48:08 -0400 Subject: [PATCH 38/99] Qt: Color Correction window fixes --- .../Graphics/ColorCorrectionConfigWindow.cpp | 114 ++++++++++-------- .../Graphics/ColorCorrectionConfigWindow.h | 10 +- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp b/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp index 44f6850990..2dbd10d2da 100644 --- a/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp @@ -1,4 +1,4 @@ -// Copyright 2018 Dolphin Emulator Project +// Copyright 2023 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h" @@ -8,12 +8,14 @@ #include #include #include +#include #include "Core/Config/GraphicsSettings.h" #include "DolphinQt/Config/ConfigControls/ConfigBool.h" #include "DolphinQt/Config/ConfigControls/ConfigChoice.h" #include "DolphinQt/Config/ConfigControls/ConfigFloatSlider.h" +#include "DolphinQt/QtUtils/WrapInScrollArea.h" #include "VideoCommon/VideoConfig.h" @@ -29,35 +31,38 @@ ColorCorrectionConfigWindow::ColorCorrectionConfigWindow(QWidget* parent) : QDia void ColorCorrectionConfigWindow::Create() { static const char TR_COLOR_SPACE_CORRECTION_DESCRIPTION[] = QT_TR_NOOP( - "Converts the colors to the color spaces that GC/Wii were meant to work with to sRGB/Rec.709." - "

There's no way of knowing what exact color space games were meant for," - "
given there were multiple standards and most games didn't acknowledge them," - "
so it's not correct to assume a format from the game disc region." - "
Just pick the one that looks more natural to you," - " or match it with the region the game was developed in." - "

HDR output is required to show all the colors from the PAL and NTSC-J color spaces." - "

If unsure, leave this unchecked."); - static const char TR_GAME_GAMMA_DESCRIPTION[] = - QT_TR_NOOP("NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8." - "
None of the two were necessarily followed by games or TVs. 2.35 is a good " - "generic value for all regions." - "
If a game allows you to chose a gamma value, match it here."); + "Converts the colors from the color spaces that GC/Wii were meant to work with to " + "sRGB/Rec.709.

There's no way of knowing what exact color space games were meant for, " + "given there were multiple standards and most games didn't acknowledge them, so it's not " + "correct to assume a format from the game disc region. Just pick the one that looks more " + "natural to you, or match it with the region the game was developed in.

HDR output is " + "required to show all the colors from the PAL and NTSC-J color " + "spaces.

If unsure, leave this unchecked."); + static const char TR_GAME_GAMMA_DESCRIPTION[] = QT_TR_NOOP( + "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the two were " + "necessarily followed by games or TVs.
2.35 is a good generic value for all " + "regions.

If a game allows you to chose a gamma value, match it " + "here.

If unsure, leave this at 2.35."); static const char TR_GAMMA_CORRECTION_DESCRIPTION[] = QT_TR_NOOP( - "Converts the gamma from what the game targeted to what your current SDR display targets." - "
Monitors often target sRGB. TVs often target 2.2." - "

If unsure, leave this unchecked."); + "Converts the gamma from what the game targeted to what your current SDR display " + "targets.
Monitors often target sRGB. TVs often target 2.2.

If " + "unsure, leave this unchecked."); + static const char TR_HDR_PAPER_WHITE_NITS_DESCRIPTION[] = QT_TR_NOOP( + "Controls the base luminance of a paper white surface in nits. Useful for adjusting to " + "different environmental lighting conditions when using a HDR display.

HDR output is " + "required for this setting to take effect.

If unsure, leave this at " + "200."); // Color Space: auto* const color_space_box = new QGroupBox(tr("Color Space")); auto* const color_space_layout = new QGridLayout(); - color_space_layout->setVerticalSpacing(7); color_space_layout->setColumnStretch(1, 1); color_space_box->setLayout(color_space_layout); m_correct_color_space = new ConfigBool(tr("Correct Color Space"), Config::GFX_CC_CORRECT_COLOR_SPACE); - color_space_layout->addWidget(m_correct_color_space, 0, 0); + color_space_layout->addWidget(m_correct_color_space, 0, 0, 1, 2); m_correct_color_space->SetDescription(tr(TR_COLOR_SPACE_CORRECTION_DESCRIPTION)); // "ColorCorrectionRegion" @@ -65,7 +70,7 @@ void ColorCorrectionConfigWindow::Create() tr("PAL (EBU)")}; m_game_color_space = new ConfigChoice(game_color_space_enum, Config::GFX_CC_GAME_COLOR_SPACE); - color_space_layout->addWidget(new QLabel(tr("Game Color Space")), 1, 0); + color_space_layout->addWidget(new QLabel(tr("Game Color Space:")), 1, 0); color_space_layout->addWidget(m_game_color_space, 1, 1); m_game_color_space->setEnabled(m_correct_color_space->isChecked()); @@ -74,72 +79,85 @@ void ColorCorrectionConfigWindow::Create() auto* const gamma_box = new QGroupBox(tr("Gamma")); auto* const gamma_layout = new QGridLayout(); - gamma_layout->setVerticalSpacing(7); - gamma_layout->setColumnStretch(1, 1); gamma_box->setLayout(gamma_layout); m_game_gamma = new ConfigFloatSlider(Config::GFX_CC_GAME_GAMMA_MIN, Config::GFX_CC_GAME_GAMMA_MAX, Config::GFX_CC_GAME_GAMMA, 0.01f); - gamma_layout->addWidget(new QLabel(tr("Game Gamma")), 0, 0); + gamma_layout->addWidget(new QLabel(tr("Game Gamma:")), 0, 0); gamma_layout->addWidget(m_game_gamma, 0, 1); + m_game_gamma->SetTitle(tr("Game Gamma")); m_game_gamma->SetDescription(tr(TR_GAME_GAMMA_DESCRIPTION)); m_game_gamma_value = new QLabel(); gamma_layout->addWidget(m_game_gamma_value, 0, 2); m_correct_gamma = new ConfigBool(tr("Correct SDR Gamma"), Config::GFX_CC_CORRECT_GAMMA); - gamma_layout->addWidget(m_correct_gamma, 1, 0); + gamma_layout->addWidget(m_correct_gamma, 1, 0, 1, 2); m_correct_gamma->SetDescription(tr(TR_GAMMA_CORRECTION_DESCRIPTION)); - m_sdr_display_gamma_srgb = - new ConfigBool(tr("SDR Display Gamma sRGB"), Config::GFX_CC_SDR_DISPLAY_GAMMA_SRGB); - gamma_layout->addWidget(m_sdr_display_gamma_srgb, 2, 0); + auto* const gamma_target_box = new QGroupBox(tr("SDR Display Gamma Target")); + auto* const gamma_target_layout = new QGridLayout(); + gamma_target_box->setLayout(gamma_target_layout); + m_sdr_display_target_srgb = new QRadioButton(tr("sRGB")); + m_sdr_display_target_custom = new QRadioButton(tr("Custom:")); m_sdr_display_custom_gamma = new ConfigFloatSlider(Config::GFX_CC_DISPLAY_GAMMA_MIN, Config::GFX_CC_DISPLAY_GAMMA_MAX, Config::GFX_CC_SDR_DISPLAY_CUSTOM_GAMMA, 0.01f); - gamma_layout->addWidget(new QLabel(tr("SDR Display Custom Gamma")), 3, 0); - gamma_layout->addWidget(m_sdr_display_custom_gamma, 3, 1); m_sdr_display_custom_gamma_value = new QLabel(); - gamma_layout->addWidget(m_sdr_display_custom_gamma_value, 3, 2); - m_sdr_display_gamma_srgb->setEnabled(m_correct_gamma->isChecked()); + gamma_target_layout->addWidget(m_sdr_display_target_srgb, 0, 0); + gamma_target_layout->addWidget(m_sdr_display_target_custom, 1, 0); + gamma_target_layout->addWidget(m_sdr_display_custom_gamma, 1, 1); + gamma_target_layout->addWidget(m_sdr_display_custom_gamma_value, 1, 2); + + gamma_layout->addWidget(gamma_target_box, 2, 0, 1, 3); + + m_sdr_display_target_srgb->setEnabled(m_correct_gamma->isChecked()); + m_sdr_display_target_srgb->setChecked(Config::Get(Config::GFX_CC_SDR_DISPLAY_GAMMA_SRGB)); + + m_sdr_display_target_custom->setEnabled(m_correct_gamma->isChecked()); + m_sdr_display_target_custom->setChecked(!m_sdr_display_target_srgb->isChecked()); + m_sdr_display_custom_gamma->setEnabled(m_correct_gamma->isChecked() && - !m_sdr_display_gamma_srgb->isChecked()); - m_game_gamma_value->setText(QString::asprintf("%f", m_game_gamma->GetValue())); + m_sdr_display_target_custom->isChecked()); + + m_game_gamma_value->setText(QString::asprintf("%.2f", m_game_gamma->GetValue())); m_sdr_display_custom_gamma_value->setText( - QString::asprintf("%f", m_sdr_display_custom_gamma->GetValue())); + QString::asprintf("%.2f", m_sdr_display_custom_gamma->GetValue())); // HDR: auto* const hdr_box = new QGroupBox(tr("HDR")); auto* const hdr_layout = new QGridLayout(); - hdr_layout->setVerticalSpacing(7); - hdr_layout->setColumnStretch(1, 1); hdr_box->setLayout(hdr_layout); m_hdr_paper_white_nits = new ConfigFloatSlider(Config::GFX_CC_HDR_PAPER_WHITE_NITS_MIN, Config::GFX_CC_HDR_PAPER_WHITE_NITS_MAX, Config::GFX_CC_HDR_PAPER_WHITE_NITS, 1.f); - hdr_layout->addWidget(new QLabel(tr("HDR Paper White Nits")), 0, 0); + hdr_layout->addWidget(new QLabel(tr("HDR Paper White Nits:")), 0, 0); hdr_layout->addWidget(m_hdr_paper_white_nits, 0, 1); + m_hdr_paper_white_nits->SetTitle(tr("HDR Paper White Nits")); + m_hdr_paper_white_nits->SetDescription(tr(TR_HDR_PAPER_WHITE_NITS_DESCRIPTION)); m_hdr_paper_white_nits_value = new QLabel(); hdr_layout->addWidget(m_hdr_paper_white_nits_value, 0, 2); m_hdr_paper_white_nits_value->setText( - QString::asprintf("%f", m_hdr_paper_white_nits->GetValue())); + QString::asprintf("%.0f", m_hdr_paper_white_nits->GetValue())); // Other: m_button_box = new QDialogButtonBox(QDialogButtonBox::Close); auto* layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); layout->setAlignment(Qt::AlignTop); layout->addWidget(color_space_box); layout->addWidget(gamma_box); layout->addWidget(hdr_box); + layout->addStretch(); layout->addWidget(m_button_box); + setLayout(layout); + WrapInScrollArea(this, layout); } void ColorCorrectionConfigWindow::ConnectWidgets() @@ -148,7 +166,7 @@ void ColorCorrectionConfigWindow::ConnectWidgets() [this] { m_game_color_space->setEnabled(m_correct_color_space->isChecked()); }); connect(m_game_gamma, &ConfigFloatSlider::valueChanged, this, [this] { - m_game_gamma_value->setText(QString::asprintf("%f", m_game_gamma->GetValue())); + m_game_gamma_value->setText(QString::asprintf("%.2f", m_game_gamma->GetValue())); }); connect(m_correct_gamma, &QCheckBox::toggled, this, [this] { @@ -157,24 +175,26 @@ void ColorCorrectionConfigWindow::ConnectWidgets() // For the moment we leave this enabled even when we are outputting in HDR // (which means they'd have no influence on the final image), // mostly because we don't have a simple way to determine if HDR is engaged from here - m_sdr_display_gamma_srgb->setEnabled(m_correct_gamma->isChecked()); + m_sdr_display_target_srgb->setEnabled(m_correct_gamma->isChecked()); + m_sdr_display_target_custom->setEnabled(m_correct_gamma->isChecked()); m_sdr_display_custom_gamma->setEnabled(m_correct_gamma->isChecked() && - !m_sdr_display_gamma_srgb->isChecked()); + m_sdr_display_target_custom->isChecked()); }); - connect(m_sdr_display_gamma_srgb, &QCheckBox::toggled, this, [this] { - m_sdr_display_custom_gamma->setEnabled(m_correct_gamma->isChecked() && - !m_sdr_display_gamma_srgb->isChecked()); + connect(m_sdr_display_target_srgb, &QRadioButton::toggled, this, [this] { + Config::SetBaseOrCurrent(Config::GFX_CC_SDR_DISPLAY_GAMMA_SRGB, + m_sdr_display_target_srgb->isChecked()); + m_sdr_display_custom_gamma->setEnabled(!m_sdr_display_target_srgb->isChecked()); }); connect(m_sdr_display_custom_gamma, &ConfigFloatSlider::valueChanged, this, [this] { m_sdr_display_custom_gamma_value->setText( - QString::asprintf("%f", m_sdr_display_custom_gamma->GetValue())); + QString::asprintf("%.2f", m_sdr_display_custom_gamma->GetValue())); }); connect(m_hdr_paper_white_nits, &ConfigFloatSlider::valueChanged, this, [this] { m_hdr_paper_white_nits_value->setText( - QString::asprintf("%f", m_hdr_paper_white_nits->GetValue())); + QString::asprintf("%.0f", m_hdr_paper_white_nits->GetValue())); }); connect(m_button_box, &QDialogButtonBox::rejected, this, &QDialog::reject); diff --git a/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h b/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h index bcc27ce1c8..b87ed6cb91 100644 --- a/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h +++ b/Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.h @@ -1,16 +1,17 @@ -// Copyright 2018 Dolphin Emulator Project +// Copyright 2023 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include -class QWidget; -class QLabel; class ConfigBool; class ConfigChoice; class ConfigFloatSlider; class QDialogButtonBox; +class QLabel; +class QRadioButton; +class QWidget; class ColorCorrectionConfigWindow final : public QDialog { @@ -27,7 +28,8 @@ private: ConfigFloatSlider* m_game_gamma; QLabel* m_game_gamma_value; ConfigBool* m_correct_gamma; - ConfigBool* m_sdr_display_gamma_srgb; + QRadioButton* m_sdr_display_target_srgb; + QRadioButton* m_sdr_display_target_custom; ConfigFloatSlider* m_sdr_display_custom_gamma; QLabel* m_sdr_display_custom_gamma_value; ConfigFloatSlider* m_hdr_paper_white_nits; From 79f202ea5cfa6c10d3c822a1143943fa34fce173 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 16 Jul 2023 19:44:15 -0500 Subject: [PATCH 39/99] VideoCommon: fix some compiler warnings for CustomAsset. FreeBSD compiler complained about a defaulted move constructor due to the mutex being implicitly deleted. Additionally, the const owning library deleted the copy constructor. --- Source/Core/VideoCommon/Assets/CustomAsset.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoCommon/Assets/CustomAsset.h b/Source/Core/VideoCommon/Assets/CustomAsset.h index 9a11a49365..ea4a182932 100644 --- a/Source/Core/VideoCommon/Assets/CustomAsset.h +++ b/Source/Core/VideoCommon/Assets/CustomAsset.h @@ -20,10 +20,10 @@ public: CustomAsset(std::shared_ptr library, const CustomAssetLibrary::AssetID& asset_id); virtual ~CustomAsset() = default; - CustomAsset(const CustomAsset&) = default; - CustomAsset(CustomAsset&&) = default; - CustomAsset& operator=(const CustomAsset&) = default; - CustomAsset& operator=(CustomAsset&&) = default; + CustomAsset(const CustomAsset&) = delete; + CustomAsset(CustomAsset&&) = delete; + CustomAsset& operator=(const CustomAsset&) = delete; + CustomAsset& operator=(CustomAsset&&) = delete; // Loads the asset from the library returning a pass/fail result bool Load(); From 70b3db93e086e2b0edad9be2202006fffed949ca Mon Sep 17 00:00:00 2001 From: mitaclaw <140017135+mitaclaw@users.noreply.github.com> Date: Wed, 19 Jul 2023 14:15:42 -0700 Subject: [PATCH 40/99] Announce RSCRATCH clobbering in Jit64 when profiling is enabled --- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 6090ce9112..313b840132 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -469,6 +469,7 @@ bool Jit64::Cleanup() Imm32(js.downcountAmount)); MOV(64, MDisp(RSCRATCH2, offsetof(JitBlock::ProfileData, ticCounter)), R(RSCRATCH)); ABI_PopRegistersAndAdjustStack({}, 0); + did_something = true; } return did_something; From 84e8516341c87b86a8e5bc0a2e37c931c83b3b3a Mon Sep 17 00:00:00 2001 From: Sketch <75850871+noahpistilli@users.noreply.github.com> Date: Wed, 19 Jul 2023 18:30:40 -0400 Subject: [PATCH 41/99] Add Forecast Channel buffer patch --- Data/Sys/GameSettings/HAF.ini | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Data/Sys/GameSettings/HAF.ini b/Data/Sys/GameSettings/HAF.ini index 07bda4ea93..b6296a9819 100644 --- a/Data/Sys/GameSettings/HAF.ini +++ b/Data/Sys/GameSettings/HAF.ini @@ -1,5 +1,24 @@ # HAFE01, HAFJ01, HAFP01 - Forecast Channel +[OnFrame_Enabled] +$BufferPatch + +[OnFrame] +$BufferPatch +0x8000AA9E:word:0x00000008 +0x8000AAC6:word:0x00007000 +0x8000AAD0:dword:0x3C600001 +0x8000AE08:dword:0x3C000001 +0x8000AE06:word:0x00000008 +0x8000AE0E:word:0x00007000 +0x8000AEEE:word:0x00000008 +0x8000AEFE:word:0x00007000 +0x8000AF5A:word:0x00000008 +0x8000AF6A:word:0x00007000 +0x8000AFEC:dword:0x3CC00001 +0x8000B08E:word:0x00000008 +0x8000B09E:word:0x00007000 + [WC24Patch] $Main weather.wapp.wii.com:fore.wiilink24.com:1 From f7e78742cf2c1d5dae1f0158422384a71b32fc3d Mon Sep 17 00:00:00 2001 From: iwubcode Date: Wed, 19 Jul 2023 23:44:41 -0500 Subject: [PATCH 42/99] VideoCommon: skip the texture dump if the texture is using a custom texture, regardless of whether or not it is loaded yet --- Source/Core/VideoCommon/TextureCacheBase.cpp | 13 ++++++++----- Source/Core/VideoCommon/TextureCacheBase.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 2fd0a4b284..37dadba967 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -1607,6 +1607,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp std::vector> cached_game_assets; std::vector> data_for_assets; bool has_arbitrary_mipmaps = false; + bool skip_texture_dump = false; std::shared_ptr hires_texture; if (g_ActiveConfig.bHiresTextures) { @@ -1618,6 +1619,7 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp cached_game_assets.push_back( VideoCommon::CachedAsset{std::move(asset), loaded_time}); has_arbitrary_mipmaps = hires_texture->HasArbitraryMipmaps(); + skip_texture_dump = true; } } @@ -1666,9 +1668,10 @@ RcTcacheEntry TextureCacheBase::GetTexture(const int textureCacheSafetyColorSamp } } - auto entry = CreateTextureEntry( - TextureCreationInfo{base_hash, full_hash, bytes_per_block, palette_size}, texture_info, - textureCacheSafetyColorSampleSize, std::move(data_for_assets), has_arbitrary_mipmaps); + auto entry = + CreateTextureEntry(TextureCreationInfo{base_hash, full_hash, bytes_per_block, palette_size}, + texture_info, textureCacheSafetyColorSampleSize, + std::move(data_for_assets), has_arbitrary_mipmaps, skip_texture_dump); entry->linked_game_texture_assets = std::move(cached_game_assets); entry->linked_asset_dependencies = std::move(additional_dependencies); entry->texture_info_name = std::move(texture_name); @@ -1679,7 +1682,7 @@ RcTcacheEntry TextureCacheBase::CreateTextureEntry( const TextureCreationInfo& creation_info, const TextureInfo& texture_info, const int safety_color_sample_size, std::vector> assets_data, - const bool custom_arbitrary_mipmaps) + const bool custom_arbitrary_mipmaps, bool skip_texture_dump) { #ifdef __APPLE__ const bool no_mips = g_ActiveConfig.bNoMipmapping; @@ -1828,7 +1831,7 @@ RcTcacheEntry TextureCacheBase::CreateTextureEntry( entry->has_arbitrary_mips = arbitrary_mip_detector.HasArbitraryMipmaps(dst_buffer); - if (g_ActiveConfig.bDumpTextures) + if (g_ActiveConfig.bDumpTextures && !skip_texture_dump) { const std::string basename = texture_info.CalculateTextureName().GetFullName(); for (u32 level = 0; level < texLevels; ++level) diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h index 65b0d2b469..3592535a65 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.h +++ b/Source/Core/VideoCommon/TextureCacheBase.h @@ -351,7 +351,7 @@ private: CreateTextureEntry(const TextureCreationInfo& creation_info, const TextureInfo& texture_info, int safety_color_sample_size, std::vector> assets_data, - bool custom_arbitrary_mipmaps); + bool custom_arbitrary_mipmaps, bool skip_texture_dump); RcTcacheEntry GetXFBFromCache(u32 address, u32 width, u32 height, u32 stride); From eba5291ec765742b576ab882c72631f4ea075bc6 Mon Sep 17 00:00:00 2001 From: Mandar1jn Date: Wed, 19 Jul 2023 22:16:13 +0200 Subject: [PATCH 43/99] Skylanders: Update J command documentation I initially thought the 0x01 side was both sides (equavalent to just C. However, this turned out to be something I forgot I implemented in my personal interface. 0x01 does not seem to change any colors. Recently discovered how exactly the last 2 bytes of the J command for timing data --- Source/Core/Core/IOS/USB/Emulated/Skylander.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp index 8d1fabeff2..2838f848ae 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp +++ b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp @@ -668,18 +668,13 @@ int SkylanderUSB::SubmitTransfer(std::unique_ptr cmd) // Sided color // The 2nd byte is the side // 0x00: right - // 0x01: left and right // 0x02: left // The 3rd, 4th and 5th bytes are red, green and blue - // The 6th byte is unknown. Observed values are 0x00, 0x0D and 0xF4 - - // The 7th byte is the fade duration. Exact value-time corrolation unknown. Observed values - // are 0x00, 0x01 and 0x07. Custom commands show that the higher this value the longer the - // duration. - - // Empty J response is sent after the fade is completed. + // The 6th and 7th bytes form a little-endian short for how long the fade duration should be + // in milliseconds. + // For example, 500 milliseconds becomes 0xF4, 0x01 if (cmd->length == 7) { control_response = {buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]}; From 2569d10b3d94a8c0af68f7206f50bd1e46026247 Mon Sep 17 00:00:00 2001 From: SketchMaster2001 Date: Thu, 20 Jul 2023 20:58:58 -0400 Subject: [PATCH 44/99] Add Enable WiiLink checkbox to Android GUI --- .../dolphinemu/features/settings/model/BooleanSetting.kt | 1 + .../features/settings/ui/SettingsFragmentPresenter.kt | 8 ++++++++ Source/Android/app/src/main/res/values/strings.xml | 2 ++ 3 files changed, 11 insertions(+) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt index 80060f61dd..60042ceb8e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt @@ -128,6 +128,7 @@ enum class BooleanSetting( "EnableSaveStates", false ), + MAIN_WII_WIILINK_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableWiiLink", false), MAIN_DSP_JIT(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "EnableJIT", true), MAIN_EXPAND_TO_CUTOUT_AREA( Settings.FILE_DOLPHIN, diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index 8e3761cb0a..59858193df 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -712,6 +712,14 @@ class SettingsFragmentPresenter( R.string.wii_screensaver_description ) ) + sl.add( + SwitchSetting( + context, + BooleanSetting.MAIN_WII_WIILINK_ENABLE, + R.string.wii_enable_wiilink, + R.string.wii_enable_wiilink_description + ) + ) sl.add( SingleChoiceSetting( context, diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 0276eaba0f..9145d10af0 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -92,6 +92,8 @@ Changes refresh rate from 50 Hz to 60 Hz in PAL games that support it. Enable Screen Saver Dims the screen after five minutes of inactivity. + Enable WiiConnect24 via WiiLink + Enables the WiiLink service for WiiConnect24 channels. Read the Terms of Service at https://www.wiilink24.com/tos Sound Insert SD Card Supports SD and SDHC. Default size is 128 MB. From e892b7f1ac426fdc8a3ac1fa28026b86cc06279b Mon Sep 17 00:00:00 2001 From: iwubcode Date: Fri, 21 Jul 2023 19:09:40 -0500 Subject: [PATCH 45/99] VideoBackends: add support for cube maps for OGL, Vulkan, and D3D --- Source/Core/VideoBackends/D3D/DXTexture.cpp | 4 +- .../Core/VideoBackends/D3D12/DX12Context.cpp | 3 +- .../Core/VideoBackends/D3D12/DX12Texture.cpp | 29 +++++++--- Source/Core/VideoBackends/OGL/OGLTexture.cpp | 57 +++++++++++++++---- Source/Core/VideoBackends/OGL/OGLTexture.h | 4 +- .../Core/VideoBackends/Vulkan/VKTexture.cpp | 6 +- Source/Core/VideoCommon/TextureConfig.h | 2 + 7 files changed, 81 insertions(+), 24 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/DXTexture.cpp b/Source/Core/VideoBackends/D3D/DXTexture.cpp index c20a8d9204..7a260eae4a 100644 --- a/Source/Core/VideoBackends/D3D/DXTexture.cpp +++ b/Source/Core/VideoBackends/D3D/DXTexture.cpp @@ -46,7 +46,8 @@ std::unique_ptr DXTexture::Create(const TextureConfig& config, std::s bindflags |= D3D11_BIND_UNORDERED_ACCESS; CD3D11_TEXTURE2D_DESC desc(tex_format, config.width, config.height, config.layers, config.levels, - bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0, 0); + bindflags, D3D11_USAGE_DEFAULT, 0, config.samples, 0, + config.IsCubeMap() ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0); ComPtr d3d_texture; HRESULT hr = D3D::device->CreateTexture2D(&desc, nullptr, d3d_texture.GetAddressOf()); if (FAILED(hr)) @@ -90,6 +91,7 @@ bool DXTexture::CreateSRV() { const CD3D11_SHADER_RESOURCE_VIEW_DESC desc( m_texture.Get(), + m_config.IsCubeMap() ? D3D11_SRV_DIMENSION_TEXTURECUBE : m_config.IsMultisampled() ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY : D3D11_SRV_DIMENSION_TEXTURE2DARRAY, D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), 0, m_config.levels, 0, diff --git a/Source/Core/VideoBackends/D3D12/DX12Context.cpp b/Source/Core/VideoBackends/D3D12/DX12Context.cpp index bf156b2fdb..dd8630ac3b 100644 --- a/Source/Core/VideoBackends/D3D12/DX12Context.cpp +++ b/Source/Core/VideoBackends/D3D12/DX12Context.cpp @@ -88,7 +88,8 @@ std::vector DXContext::GetAAModes(u32 adapter_index) bool DXContext::SupportsTextureFormat(DXGI_FORMAT format) { - constexpr u32 required = D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE; + constexpr u32 required = D3D12_FORMAT_SUPPORT1_TEXTURE2D | D3D12_FORMAT_SUPPORT1_TEXTURECUBE | + D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE; D3D12_FEATURE_DATA_FORMAT_SUPPORT support = {format}; return SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &support, diff --git a/Source/Core/VideoBackends/D3D12/DX12Texture.cpp b/Source/Core/VideoBackends/D3D12/DX12Texture.cpp index f20c37354b..a51fe7ff38 100644 --- a/Source/Core/VideoBackends/D3D12/DX12Texture.cpp +++ b/Source/Core/VideoBackends/D3D12/DX12Texture.cpp @@ -165,19 +165,30 @@ bool DXTexture::CreateSRVDescriptor() return false; } - D3D12_SHADER_RESOURCE_VIEW_DESC desc = {D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), - m_config.IsMultisampled() ? - D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY : - D3D12_SRV_DIMENSION_TEXTURE2DARRAY, - D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING}; - if (m_config.IsMultisampled()) + D3D12_SHADER_RESOURCE_VIEW_DESC desc = { + D3DCommon::GetSRVFormatForAbstractFormat(m_config.format), + m_config.IsCubeMap() ? D3D12_SRV_DIMENSION_TEXTURECUBE : + m_config.IsMultisampled() ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY : + D3D12_SRV_DIMENSION_TEXTURE2DARRAY, + D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING}; + + if (m_config.IsCubeMap()) { - desc.Texture2DMSArray.ArraySize = m_config.layers; + desc.TextureCube.MostDetailedMip = 0; + desc.TextureCube.MipLevels = m_config.levels; + desc.TextureCube.ResourceMinLODClamp = 0.0f; } else { - desc.Texture2DArray.MipLevels = m_config.levels; - desc.Texture2DArray.ArraySize = m_config.layers; + if (m_config.IsMultisampled()) + { + desc.Texture2DMSArray.ArraySize = m_config.layers; + } + else + { + desc.Texture2DArray.MipLevels = m_config.levels; + desc.Texture2DArray.ArraySize = m_config.layers; + } } g_dx_context->GetDevice()->CreateShaderResourceView(m_resource.Get(), &desc, m_srv_descriptor.cpu_handle); diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.cpp b/Source/Core/VideoBackends/OGL/OGLTexture.cpp index f8894a365b..70c38d14ff 100644 --- a/Source/Core/VideoBackends/OGL/OGLTexture.cpp +++ b/Source/Core/VideoBackends/OGL/OGLTexture.cpp @@ -140,7 +140,11 @@ OGLTexture::OGLTexture(const TextureConfig& tex_config, std::string_view name) glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, m_config.levels - 1); GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, true); - if (tex_config.IsMultisampled()) + if (g_ogl_config.bSupportsTextureStorage && m_config.IsCubeMap()) + { + glTexStorage2D(target, m_config.levels, gl_internal_format, m_config.width, m_config.height); + } + else if (tex_config.IsMultisampled()) { ASSERT(g_ogl_config.bSupportsMSAA); if (g_ogl_config.SupportedMultisampleTexStorage != MultisampleTexStorageType::TexStorageNone) @@ -267,29 +271,62 @@ void OGLTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8 GLenum gl_internal_format = GetGLInternalFormatForTextureFormat(m_config.format, false); if (IsCompressedFormat(m_config.format)) { - if (g_ogl_config.bSupportsTextureStorage) + if (m_config.IsCubeMap()) { - glCompressedTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_internal_format, - static_cast(buffer_size), buffer); + if (g_ogl_config.bSupportsTextureStorage) + { + glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, 0, 0, width, + height, gl_internal_format, static_cast(buffer_size), + buffer); + } + else + { + glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, gl_internal_format, + width, height, 0, static_cast(buffer_size), buffer); + } } else { - glCompressedTexImage3D(target, level, gl_internal_format, width, height, 1, 0, - static_cast(buffer_size), buffer); + if (g_ogl_config.bSupportsTextureStorage) + { + glCompressedTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_internal_format, + static_cast(buffer_size), buffer); + } + else + { + glCompressedTexImage3D(target, level, gl_internal_format, width, height, 1, 0, + static_cast(buffer_size), buffer); + } } } else { GLenum gl_format = GetGLFormatForTextureFormat(m_config.format); GLenum gl_type = GetGLTypeForTextureFormat(m_config.format); - if (g_ogl_config.bSupportsTextureStorage) + if (m_config.IsCubeMap()) { - glTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_format, gl_type, buffer); + if (g_ogl_config.bSupportsTextureStorage) + { + glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, 0, 0, width, height, + gl_format, gl_type, buffer); + } + else + { + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer, level, gl_internal_format, width, + height, 0, gl_format, gl_type, buffer); + } } else { - glTexImage3D(target, level, gl_internal_format, width, height, 1, 0, gl_format, gl_type, - buffer); + if (g_ogl_config.bSupportsTextureStorage) + { + glTexSubImage3D(target, level, 0, 0, layer, width, height, 1, gl_format, gl_type, buffer); + } + else + { + glTexImage3D(target, level, gl_internal_format, width, height, 1, 0, gl_format, gl_type, + buffer); + } } } diff --git a/Source/Core/VideoBackends/OGL/OGLTexture.h b/Source/Core/VideoBackends/OGL/OGLTexture.h index 53d9d7f589..91879a6564 100644 --- a/Source/Core/VideoBackends/OGL/OGLTexture.h +++ b/Source/Core/VideoBackends/OGL/OGLTexture.h @@ -34,7 +34,9 @@ public: GLuint GetGLTextureId() const { return m_texId; } GLenum GetGLTarget() const { - return IsMultisampled() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY; + return m_config.IsCubeMap() ? GL_TEXTURE_CUBE_MAP : + IsMultisampled() ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : + GL_TEXTURE_2D_ARRAY; } static GLenum GetGLInternalFormatForTextureFormat(AbstractTextureFormat format, bool storage); GLenum GetGLFormatForImageTexture() const; diff --git a/Source/Core/VideoBackends/Vulkan/VKTexture.cpp b/Source/Core/VideoBackends/Vulkan/VKTexture.cpp index f8923b4edc..e80ce4f2f7 100644 --- a/Source/Core/VideoBackends/Vulkan/VKTexture.cpp +++ b/Source/Core/VideoBackends/Vulkan/VKTexture.cpp @@ -70,7 +70,8 @@ std::unique_ptr VKTexture::Create(const TextureConfig& tex_config, st VkImageCreateInfo image_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, nullptr, - 0, + tex_config.IsCubeMap() ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : + static_cast(0), VK_IMAGE_TYPE_2D, GetVkFormatForHostTextureFormat(tex_config.format), {tex_config.width, tex_config.height, 1}, @@ -106,7 +107,8 @@ std::unique_ptr VKTexture::Create(const TextureConfig& tex_config, st std::unique_ptr texture = std::make_unique( tex_config, alloc, image, name, VK_IMAGE_LAYOUT_UNDEFINED, ComputeImageLayout::Undefined); - if (!texture->CreateView(VK_IMAGE_VIEW_TYPE_2D_ARRAY)) + if (!texture->CreateView(tex_config.IsCubeMap() ? VK_IMAGE_VIEW_TYPE_CUBE : + VK_IMAGE_VIEW_TYPE_2D_ARRAY)) return nullptr; return texture; diff --git a/Source/Core/VideoCommon/TextureConfig.h b/Source/Core/VideoCommon/TextureConfig.h index c076ff85c0..75d7387f17 100644 --- a/Source/Core/VideoCommon/TextureConfig.h +++ b/Source/Core/VideoCommon/TextureConfig.h @@ -39,6 +39,7 @@ enum AbstractTextureFlag : u32 { AbstractTextureFlag_RenderTarget = (1 << 0), // Texture is used as a framebuffer. AbstractTextureFlag_ComputeImage = (1 << 1), // Texture is used as a compute image. + AbstractTextureFlag_CubeMap = (1 << 2), // Texture is used as a cube map. }; struct TextureConfig @@ -61,6 +62,7 @@ struct TextureConfig bool IsMultisampled() const { return samples > 1; } bool IsRenderTarget() const { return (flags & AbstractTextureFlag_RenderTarget) != 0; } bool IsComputeImage() const { return (flags & AbstractTextureFlag_ComputeImage) != 0; } + bool IsCubeMap() const { return (flags & AbstractTextureFlag_CubeMap) != 0; } u32 width = 0; u32 height = 0; From fd742443396dd8d7ef458cecc629d9772396a4b6 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Fri, 21 Jul 2023 20:13:27 -0500 Subject: [PATCH 46/99] VideoCommon: add custom texture message to provide a dirty means of debugging whether custom textures are installed correctly --- Source/Core/VideoCommon/HiresTextures.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp index 27fc75ec4d..c70e5523f8 100644 --- a/Source/Core/VideoCommon/HiresTextures.cpp +++ b/Source/Core/VideoCommon/HiresTextures.cpp @@ -147,6 +147,17 @@ void HiresTexture::Update() texture_directory); } } + + if (g_ActiveConfig.bCacheHiresTextures) + { + OSD::AddMessage(fmt::format("Loading '{}' custom textures", s_hires_texture_cache.size()), + 10000); + } + else + { + OSD::AddMessage( + fmt::format("Found '{}' custom textures", s_hires_texture_id_to_arbmipmap.size()), 10000); + } } void HiresTexture::Clear() From 6f55e443653de856a8e0b235d8c4eeac1faf855d Mon Sep 17 00:00:00 2001 From: Sketch <75850871+SketchMaster2001@users.noreply.github.com> Date: Sat, 27 May 2023 21:37:33 -0400 Subject: [PATCH 47/99] Update libcurl to 8.1.2 --- .gitmodules | 3 + Externals/curl/CMakeLists.txt | 64 +- Externals/curl/curl | 1 + Externals/curl/curl.vcxproj | 679 +- Externals/curl/{lib => }/curl_config.h | 8 +- Externals/curl/exports.props | 2 +- Externals/curl/include/README | 55 - Externals/curl/include/curl/Makefile.am | 53 - Externals/curl/include/curl/Makefile.in | 707 -- Externals/curl/include/curl/curl.h | 2439 ------ Externals/curl/include/curl/curlbuild.h | 586 -- Externals/curl/include/curl/curlbuild.h.cmake | 197 - Externals/curl/include/curl/curlbuild.h.in | 197 - Externals/curl/include/curl/curlrules.h | 262 - Externals/curl/include/curl/curlver.h | 77 - Externals/curl/include/curl/easy.h | 102 - Externals/curl/include/curl/mprintf.h | 50 - Externals/curl/include/curl/multi.h | 435 -- Externals/curl/include/curl/stdcheaders.h | 33 - Externals/curl/include/curl/typecheck-gcc.h | 622 -- Externals/curl/lib/CMakeLists.txt | 18 - Externals/curl/lib/amigaos.c | 77 - Externals/curl/lib/amigaos.h | 39 - Externals/curl/lib/arpa_telnet.h | 104 - Externals/curl/lib/asyn-ares.c | 691 -- Externals/curl/lib/asyn-thread.c | 697 -- Externals/curl/lib/asyn.h | 168 - Externals/curl/lib/base64.c | 315 - Externals/curl/lib/checksrc.pl | 493 -- Externals/curl/lib/config-amigaos.h | 166 - Externals/curl/lib/config-dos.h | 181 - Externals/curl/lib/config-mac.h | 125 - Externals/curl/lib/config-os400.h | 563 -- Externals/curl/lib/config-riscos.h | 513 -- Externals/curl/lib/config-symbian.h | 811 -- Externals/curl/lib/config-tpf.h | 772 -- Externals/curl/lib/config-vxworks.h | 928 --- Externals/curl/lib/config-win32.h | 725 -- Externals/curl/lib/config-win32ce.h | 448 -- Externals/curl/lib/conncache.c | 370 - Externals/curl/lib/conncache.h | 68 - Externals/curl/lib/connect.c | 1416 ---- Externals/curl/lib/connect.h | 124 - Externals/curl/lib/content_encoding.c | 435 -- Externals/curl/lib/content_encoding.h | 48 - Externals/curl/lib/cookie.c | 1393 ---- Externals/curl/lib/cookie.h | 104 - Externals/curl/lib/curl_addrinfo.c | 565 -- Externals/curl/lib/curl_addrinfo.h | 102 - Externals/curl/lib/curl_base64.h | 35 - Externals/curl/lib/curl_config.h.cmake | 985 --- Externals/curl/lib/curl_config.h.in | 1048 --- Externals/curl/lib/curl_des.c | 63 - Externals/curl/lib/curl_des.h | 34 - Externals/curl/lib/curl_endian.c | 236 - Externals/curl/lib/curl_endian.h | 70 - Externals/curl/lib/curl_fnmatch.c | 426 -- Externals/curl/lib/curl_fnmatch.h | 44 - Externals/curl/lib/curl_gethostname.c | 100 - Externals/curl/lib/curl_gethostname.h | 31 - Externals/curl/lib/curl_gssapi.c | 131 - Externals/curl/lib/curl_gssapi.h | 75 - Externals/curl/lib/curl_hmac.h | 67 - Externals/curl/lib/curl_ldap.h | 35 - Externals/curl/lib/curl_md4.h | 35 - Externals/curl/lib/curl_md5.h | 63 - Externals/curl/lib/curl_memory.h | 156 - Externals/curl/lib/curl_memrchr.c | 61 - Externals/curl/lib/curl_memrchr.h | 44 - Externals/curl/lib/curl_multibyte.c | 84 - Externals/curl/lib/curl_multibyte.h | 92 - Externals/curl/lib/curl_ntlm_core.c | 761 -- Externals/curl/lib/curl_ntlm_core.h | 106 - Externals/curl/lib/curl_ntlm_wb.c | 430 -- Externals/curl/lib/curl_ntlm_wb.h | 38 - Externals/curl/lib/curl_printf.h | 56 - Externals/curl/lib/curl_rtmp.c | 306 - Externals/curl/lib/curl_rtmp.h | 33 - Externals/curl/lib/curl_sasl.c | 617 -- Externals/curl/lib/curl_sasl.h | 143 - Externals/curl/lib/curl_sec.h | 51 - Externals/curl/lib/curl_setup.h | 740 -- Externals/curl/lib/curl_setup_once.h | 551 -- Externals/curl/lib/curl_sspi.c | 258 - Externals/curl/lib/curl_sspi.h | 350 - Externals/curl/lib/curl_threads.c | 138 - Externals/curl/lib/curl_threads.h | 62 - Externals/curl/lib/curlx.h | 118 - Externals/curl/lib/dict.c | 279 - Externals/curl/lib/dict.h | 29 - Externals/curl/lib/dotdot.c | 179 - Externals/curl/lib/dotdot.h | 25 - Externals/curl/lib/easy.c | 1140 --- Externals/curl/lib/easyif.h | 33 - Externals/curl/lib/escape.c | 230 - Externals/curl/lib/escape.h | 33 - Externals/curl/lib/file.c | 593 -- Externals/curl/lib/file.h | 41 - Externals/curl/lib/fileinfo.c | 50 - Externals/curl/lib/fileinfo.h | 33 - Externals/curl/lib/firefox-db2pem.sh | 54 - Externals/curl/lib/formdata.c | 1586 ---- Externals/curl/lib/formdata.h | 98 - Externals/curl/lib/ftp.c | 4615 ------------ Externals/curl/lib/ftp.h | 159 - Externals/curl/lib/ftplistparser.c | 1028 --- Externals/curl/lib/ftplistparser.h | 41 - Externals/curl/lib/getenv.c | 53 - Externals/curl/lib/getinfo.c | 402 - Externals/curl/lib/getinfo.h | 27 - Externals/curl/lib/gopher.c | 167 - Externals/curl/lib/gopher.h | 29 - Externals/curl/lib/hash.c | 390 - Externals/curl/lib/hash.h | 100 - Externals/curl/lib/hmac.c | 132 - Externals/curl/lib/hostasyn.c | 153 - Externals/curl/lib/hostcheck.c | 147 - Externals/curl/lib/hostcheck.h | 32 - Externals/curl/lib/hostip.c | 881 --- Externals/curl/lib/hostip.h | 250 - Externals/curl/lib/hostip4.c | 307 - Externals/curl/lib/hostip6.c | 222 - Externals/curl/lib/hostsyn.c | 107 - Externals/curl/lib/http.c | 3766 ---------- Externals/curl/lib/http.h | 253 - Externals/curl/lib/http2.c | 1982 ----- Externals/curl/lib/http2.h | 67 - Externals/curl/lib/http_chunks.c | 381 - Externals/curl/lib/http_chunks.h | 91 - Externals/curl/lib/http_digest.c | 178 - Externals/curl/lib/http_digest.h | 42 - Externals/curl/lib/http_negotiate.c | 133 - Externals/curl/lib/http_negotiate.h | 38 - Externals/curl/lib/http_ntlm.c | 238 - Externals/curl/lib/http_ntlm.h | 40 - Externals/curl/lib/http_proxy.c | 605 -- Externals/curl/lib/http_proxy.h | 42 - Externals/curl/lib/idn_win32.c | 111 - Externals/curl/lib/if2ip.c | 272 - Externals/curl/lib/if2ip.h | 83 - Externals/curl/lib/imap.c | 2132 ------ Externals/curl/lib/imap.h | 96 - Externals/curl/lib/inet_ntop.c | 197 - Externals/curl/lib/inet_ntop.h | 38 - Externals/curl/lib/inet_pton.c | 234 - Externals/curl/lib/inet_pton.h | 37 - Externals/curl/lib/krb5.c | 332 - Externals/curl/lib/ldap.c | 1012 --- Externals/curl/lib/libcurl.plist | 35 - Externals/curl/lib/libcurl.rc | 63 - Externals/curl/lib/libcurl.vers.in | 13 - Externals/curl/lib/llist.c | 214 - Externals/curl/lib/llist.h | 57 - Externals/curl/lib/makefile.amiga | 21 - Externals/curl/lib/makefile.dj | 73 - Externals/curl/lib/md4.c | 304 - Externals/curl/lib/md5.c | 562 -- Externals/curl/lib/memdebug.c | 488 -- Externals/curl/lib/memdebug.h | 173 - Externals/curl/lib/mk-ca-bundle.pl | 499 -- Externals/curl/lib/mk-ca-bundle.vbs | 286 - Externals/curl/lib/mprintf.c | 1160 --- Externals/curl/lib/multi.c | 3118 -------- Externals/curl/lib/multihandle.h | 152 - Externals/curl/lib/multiif.h | 97 - Externals/curl/lib/netrc.c | 203 - Externals/curl/lib/netrc.h | 36 - Externals/curl/lib/non-ascii.c | 338 - Externals/curl/lib/non-ascii.h | 63 - Externals/curl/lib/nonblock.c | 91 - Externals/curl/lib/nonblock.h | 31 - Externals/curl/lib/nwlib.c | 325 - Externals/curl/lib/nwos.c | 88 - Externals/curl/lib/objnames-test08.sh | 217 - Externals/curl/lib/objnames-test10.sh | 217 - Externals/curl/lib/objnames.inc | 107 - Externals/curl/lib/openldap.c | 711 -- Externals/curl/lib/parsedate.c | 583 -- Externals/curl/lib/parsedate.h | 31 - Externals/curl/lib/pingpong.c | 507 -- Externals/curl/lib/pingpong.h | 150 - Externals/curl/lib/pipeline.c | 434 -- Externals/curl/lib/pipeline.h | 56 - Externals/curl/lib/pop3.c | 1613 ---- Externals/curl/lib/pop3.h | 95 - Externals/curl/lib/progress.c | 492 -- Externals/curl/lib/progress.h | 73 - Externals/curl/lib/rawstr.c | 148 - Externals/curl/lib/rawstr.h | 47 - Externals/curl/lib/rtsp.c | 825 --- Externals/curl/lib/rtsp.h | 69 - Externals/curl/lib/security.c | 580 -- Externals/curl/lib/select.c | 578 -- Externals/curl/lib/select.h | 114 - Externals/curl/lib/sendf.c | 826 --- Externals/curl/lib/sendf.h | 92 - Externals/curl/lib/setup-os400.h | 223 - Externals/curl/lib/setup-vms.h | 442 -- Externals/curl/lib/share.c | 247 - Externals/curl/lib/share.h | 61 - Externals/curl/lib/sigpipe.h | 78 - Externals/curl/lib/slist.c | 145 - Externals/curl/lib/slist.h | 40 - Externals/curl/lib/smb.c | 978 --- Externals/curl/lib/smb.h | 271 - Externals/curl/lib/smtp.c | 1674 ----- Externals/curl/lib/smtp.h | 91 - Externals/curl/lib/sockaddr.h | 43 - Externals/curl/lib/socks.c | 755 -- Externals/curl/lib/socks.h | 77 - Externals/curl/lib/socks_gssapi.c | 524 -- Externals/curl/lib/socks_sspi.c | 602 -- Externals/curl/lib/speedcheck.c | 74 - Externals/curl/lib/speedcheck.h | 33 - Externals/curl/lib/splay.c | 288 - Externals/curl/lib/splay.h | 66 - Externals/curl/lib/ssh.c | 3454 --------- Externals/curl/lib/ssh.h | 198 - Externals/curl/lib/strdup.c | 77 - Externals/curl/lib/strdup.h | 31 - Externals/curl/lib/strequal.c | 79 - Externals/curl/lib/strequal.h | 31 - Externals/curl/lib/strerror.c | 1145 --- Externals/curl/lib/strerror.h | 37 - Externals/curl/lib/strtok.c | 66 - Externals/curl/lib/strtok.h | 34 - Externals/curl/lib/strtoofft.c | 188 - Externals/curl/lib/strtoofft.h | 75 - Externals/curl/lib/system_win32.c | 130 - Externals/curl/lib/system_win32.h | 39 - Externals/curl/lib/telnet.c | 1677 ----- Externals/curl/lib/telnet.h | 29 - Externals/curl/lib/tftp.c | 1379 ---- Externals/curl/lib/tftp.h | 29 - Externals/curl/lib/timeval.c | 150 - Externals/curl/lib/timeval.h | 58 - Externals/curl/lib/transfer.c | 1993 ----- Externals/curl/lib/transfer.h | 72 - Externals/curl/lib/url.c | 6588 ----------------- Externals/curl/lib/url.h | 80 - Externals/curl/lib/urldata.h | 1759 ----- Externals/curl/lib/vauth/cleartext.c | 157 - Externals/curl/lib/vauth/cram.c | 138 - Externals/curl/lib/vauth/digest.c | 883 --- Externals/curl/lib/vauth/digest.h | 43 - Externals/curl/lib/vauth/digest_sspi.c | 527 -- Externals/curl/lib/vauth/krb5_gssapi.c | 387 - Externals/curl/lib/vauth/krb5_sspi.c | 496 -- Externals/curl/lib/vauth/ntlm.c | 842 --- Externals/curl/lib/vauth/ntlm.h | 143 - Externals/curl/lib/vauth/ntlm_sspi.c | 314 - Externals/curl/lib/vauth/oauth2.c | 86 - Externals/curl/lib/vauth/spnego_gssapi.c | 260 - Externals/curl/lib/vauth/spnego_sspi.c | 297 - Externals/curl/lib/vauth/vauth.c | 106 - Externals/curl/lib/vauth/vauth.h | 189 - Externals/curl/lib/version.c | 396 - Externals/curl/lib/vtls/axtls.c | 690 -- Externals/curl/lib/vtls/axtls.h | 71 - Externals/curl/lib/vtls/cyassl.c | 902 --- Externals/curl/lib/vtls/cyassl.h | 92 - Externals/curl/lib/vtls/darwinssl.c | 2490 ------- Externals/curl/lib/vtls/darwinssl.h | 76 - Externals/curl/lib/vtls/gskit.c | 1069 --- Externals/curl/lib/vtls/gskit.h | 71 - Externals/curl/lib/vtls/gtls.c | 1627 ---- Externals/curl/lib/vtls/gtls.h | 91 - Externals/curl/lib/vtls/mbedtls.c | 866 --- Externals/curl/lib/vtls/mbedtls.h | 80 - Externals/curl/lib/vtls/nss.c | 2081 ------ Externals/curl/lib/vtls/nssg.h | 105 - Externals/curl/lib/vtls/openssl.c | 3188 -------- Externals/curl/lib/vtls/openssl.h | 123 - Externals/curl/lib/vtls/polarssl.c | 814 -- Externals/curl/lib/vtls/polarssl.h | 81 - Externals/curl/lib/vtls/polarssl_threadlock.c | 153 - Externals/curl/lib/vtls/polarssl_threadlock.h | 53 - Externals/curl/lib/vtls/schannel.c | 1623 ---- Externals/curl/lib/vtls/schannel.h | 118 - Externals/curl/lib/vtls/vtls.c | 993 --- Externals/curl/lib/vtls/vtls.h | 159 - Externals/curl/lib/warnless.c | 543 -- Externals/curl/lib/warnless.h | 113 - Externals/curl/lib/wildcard.c | 69 - Externals/curl/lib/wildcard.h | 58 - Externals/curl/lib/x509asn1.c | 1185 --- Externals/curl/lib/x509asn1.h | 132 - Source/VSProps/Base.Dolphin.props | 2 + 288 files changed, 417 insertions(+), 121479 deletions(-) create mode 160000 Externals/curl/curl rename Externals/curl/{lib => }/curl_config.h (99%) delete mode 100644 Externals/curl/include/README delete mode 100644 Externals/curl/include/curl/Makefile.am delete mode 100644 Externals/curl/include/curl/Makefile.in delete mode 100644 Externals/curl/include/curl/curl.h delete mode 100644 Externals/curl/include/curl/curlbuild.h delete mode 100644 Externals/curl/include/curl/curlbuild.h.cmake delete mode 100644 Externals/curl/include/curl/curlbuild.h.in delete mode 100644 Externals/curl/include/curl/curlrules.h delete mode 100644 Externals/curl/include/curl/curlver.h delete mode 100644 Externals/curl/include/curl/easy.h delete mode 100644 Externals/curl/include/curl/mprintf.h delete mode 100644 Externals/curl/include/curl/multi.h delete mode 100644 Externals/curl/include/curl/stdcheaders.h delete mode 100644 Externals/curl/include/curl/typecheck-gcc.h delete mode 100644 Externals/curl/lib/CMakeLists.txt delete mode 100644 Externals/curl/lib/amigaos.c delete mode 100644 Externals/curl/lib/amigaos.h delete mode 100644 Externals/curl/lib/arpa_telnet.h delete mode 100644 Externals/curl/lib/asyn-ares.c delete mode 100644 Externals/curl/lib/asyn-thread.c delete mode 100644 Externals/curl/lib/asyn.h delete mode 100644 Externals/curl/lib/base64.c delete mode 100755 Externals/curl/lib/checksrc.pl delete mode 100644 Externals/curl/lib/config-amigaos.h delete mode 100644 Externals/curl/lib/config-dos.h delete mode 100644 Externals/curl/lib/config-mac.h delete mode 100644 Externals/curl/lib/config-os400.h delete mode 100644 Externals/curl/lib/config-riscos.h delete mode 100644 Externals/curl/lib/config-symbian.h delete mode 100644 Externals/curl/lib/config-tpf.h delete mode 100644 Externals/curl/lib/config-vxworks.h delete mode 100644 Externals/curl/lib/config-win32.h delete mode 100644 Externals/curl/lib/config-win32ce.h delete mode 100644 Externals/curl/lib/conncache.c delete mode 100644 Externals/curl/lib/conncache.h delete mode 100644 Externals/curl/lib/connect.c delete mode 100644 Externals/curl/lib/connect.h delete mode 100644 Externals/curl/lib/content_encoding.c delete mode 100644 Externals/curl/lib/content_encoding.h delete mode 100644 Externals/curl/lib/cookie.c delete mode 100644 Externals/curl/lib/cookie.h delete mode 100644 Externals/curl/lib/curl_addrinfo.c delete mode 100644 Externals/curl/lib/curl_addrinfo.h delete mode 100644 Externals/curl/lib/curl_base64.h delete mode 100644 Externals/curl/lib/curl_config.h.cmake delete mode 100644 Externals/curl/lib/curl_config.h.in delete mode 100644 Externals/curl/lib/curl_des.c delete mode 100644 Externals/curl/lib/curl_des.h delete mode 100644 Externals/curl/lib/curl_endian.c delete mode 100644 Externals/curl/lib/curl_endian.h delete mode 100644 Externals/curl/lib/curl_fnmatch.c delete mode 100644 Externals/curl/lib/curl_fnmatch.h delete mode 100644 Externals/curl/lib/curl_gethostname.c delete mode 100644 Externals/curl/lib/curl_gethostname.h delete mode 100644 Externals/curl/lib/curl_gssapi.c delete mode 100644 Externals/curl/lib/curl_gssapi.h delete mode 100644 Externals/curl/lib/curl_hmac.h delete mode 100644 Externals/curl/lib/curl_ldap.h delete mode 100644 Externals/curl/lib/curl_md4.h delete mode 100644 Externals/curl/lib/curl_md5.h delete mode 100644 Externals/curl/lib/curl_memory.h delete mode 100644 Externals/curl/lib/curl_memrchr.c delete mode 100644 Externals/curl/lib/curl_memrchr.h delete mode 100644 Externals/curl/lib/curl_multibyte.c delete mode 100644 Externals/curl/lib/curl_multibyte.h delete mode 100644 Externals/curl/lib/curl_ntlm_core.c delete mode 100644 Externals/curl/lib/curl_ntlm_core.h delete mode 100644 Externals/curl/lib/curl_ntlm_wb.c delete mode 100644 Externals/curl/lib/curl_ntlm_wb.h delete mode 100644 Externals/curl/lib/curl_printf.h delete mode 100644 Externals/curl/lib/curl_rtmp.c delete mode 100644 Externals/curl/lib/curl_rtmp.h delete mode 100644 Externals/curl/lib/curl_sasl.c delete mode 100644 Externals/curl/lib/curl_sasl.h delete mode 100644 Externals/curl/lib/curl_sec.h delete mode 100644 Externals/curl/lib/curl_setup.h delete mode 100644 Externals/curl/lib/curl_setup_once.h delete mode 100644 Externals/curl/lib/curl_sspi.c delete mode 100644 Externals/curl/lib/curl_sspi.h delete mode 100644 Externals/curl/lib/curl_threads.c delete mode 100644 Externals/curl/lib/curl_threads.h delete mode 100644 Externals/curl/lib/curlx.h delete mode 100644 Externals/curl/lib/dict.c delete mode 100644 Externals/curl/lib/dict.h delete mode 100644 Externals/curl/lib/dotdot.c delete mode 100644 Externals/curl/lib/dotdot.h delete mode 100644 Externals/curl/lib/easy.c delete mode 100644 Externals/curl/lib/easyif.h delete mode 100644 Externals/curl/lib/escape.c delete mode 100644 Externals/curl/lib/escape.h delete mode 100644 Externals/curl/lib/file.c delete mode 100644 Externals/curl/lib/file.h delete mode 100644 Externals/curl/lib/fileinfo.c delete mode 100644 Externals/curl/lib/fileinfo.h delete mode 100644 Externals/curl/lib/firefox-db2pem.sh delete mode 100644 Externals/curl/lib/formdata.c delete mode 100644 Externals/curl/lib/formdata.h delete mode 100644 Externals/curl/lib/ftp.c delete mode 100644 Externals/curl/lib/ftp.h delete mode 100644 Externals/curl/lib/ftplistparser.c delete mode 100644 Externals/curl/lib/ftplistparser.h delete mode 100644 Externals/curl/lib/getenv.c delete mode 100644 Externals/curl/lib/getinfo.c delete mode 100644 Externals/curl/lib/getinfo.h delete mode 100644 Externals/curl/lib/gopher.c delete mode 100644 Externals/curl/lib/gopher.h delete mode 100644 Externals/curl/lib/hash.c delete mode 100644 Externals/curl/lib/hash.h delete mode 100644 Externals/curl/lib/hmac.c delete mode 100644 Externals/curl/lib/hostasyn.c delete mode 100644 Externals/curl/lib/hostcheck.c delete mode 100644 Externals/curl/lib/hostcheck.h delete mode 100644 Externals/curl/lib/hostip.c delete mode 100644 Externals/curl/lib/hostip.h delete mode 100644 Externals/curl/lib/hostip4.c delete mode 100644 Externals/curl/lib/hostip6.c delete mode 100644 Externals/curl/lib/hostsyn.c delete mode 100644 Externals/curl/lib/http.c delete mode 100644 Externals/curl/lib/http.h delete mode 100644 Externals/curl/lib/http2.c delete mode 100644 Externals/curl/lib/http2.h delete mode 100644 Externals/curl/lib/http_chunks.c delete mode 100644 Externals/curl/lib/http_chunks.h delete mode 100644 Externals/curl/lib/http_digest.c delete mode 100644 Externals/curl/lib/http_digest.h delete mode 100644 Externals/curl/lib/http_negotiate.c delete mode 100644 Externals/curl/lib/http_negotiate.h delete mode 100644 Externals/curl/lib/http_ntlm.c delete mode 100644 Externals/curl/lib/http_ntlm.h delete mode 100644 Externals/curl/lib/http_proxy.c delete mode 100644 Externals/curl/lib/http_proxy.h delete mode 100644 Externals/curl/lib/idn_win32.c delete mode 100644 Externals/curl/lib/if2ip.c delete mode 100644 Externals/curl/lib/if2ip.h delete mode 100644 Externals/curl/lib/imap.c delete mode 100644 Externals/curl/lib/imap.h delete mode 100644 Externals/curl/lib/inet_ntop.c delete mode 100644 Externals/curl/lib/inet_ntop.h delete mode 100644 Externals/curl/lib/inet_pton.c delete mode 100644 Externals/curl/lib/inet_pton.h delete mode 100644 Externals/curl/lib/krb5.c delete mode 100644 Externals/curl/lib/ldap.c delete mode 100644 Externals/curl/lib/libcurl.plist delete mode 100644 Externals/curl/lib/libcurl.rc delete mode 100644 Externals/curl/lib/libcurl.vers.in delete mode 100644 Externals/curl/lib/llist.c delete mode 100644 Externals/curl/lib/llist.h delete mode 100644 Externals/curl/lib/makefile.amiga delete mode 100644 Externals/curl/lib/makefile.dj delete mode 100644 Externals/curl/lib/md4.c delete mode 100644 Externals/curl/lib/md5.c delete mode 100644 Externals/curl/lib/memdebug.c delete mode 100644 Externals/curl/lib/memdebug.h delete mode 100755 Externals/curl/lib/mk-ca-bundle.pl delete mode 100755 Externals/curl/lib/mk-ca-bundle.vbs delete mode 100644 Externals/curl/lib/mprintf.c delete mode 100644 Externals/curl/lib/multi.c delete mode 100644 Externals/curl/lib/multihandle.h delete mode 100644 Externals/curl/lib/multiif.h delete mode 100644 Externals/curl/lib/netrc.c delete mode 100644 Externals/curl/lib/netrc.h delete mode 100644 Externals/curl/lib/non-ascii.c delete mode 100644 Externals/curl/lib/non-ascii.h delete mode 100644 Externals/curl/lib/nonblock.c delete mode 100644 Externals/curl/lib/nonblock.h delete mode 100644 Externals/curl/lib/nwlib.c delete mode 100644 Externals/curl/lib/nwos.c delete mode 100755 Externals/curl/lib/objnames-test08.sh delete mode 100755 Externals/curl/lib/objnames-test10.sh delete mode 100644 Externals/curl/lib/objnames.inc delete mode 100644 Externals/curl/lib/openldap.c delete mode 100644 Externals/curl/lib/parsedate.c delete mode 100644 Externals/curl/lib/parsedate.h delete mode 100644 Externals/curl/lib/pingpong.c delete mode 100644 Externals/curl/lib/pingpong.h delete mode 100644 Externals/curl/lib/pipeline.c delete mode 100644 Externals/curl/lib/pipeline.h delete mode 100644 Externals/curl/lib/pop3.c delete mode 100644 Externals/curl/lib/pop3.h delete mode 100644 Externals/curl/lib/progress.c delete mode 100644 Externals/curl/lib/progress.h delete mode 100644 Externals/curl/lib/rawstr.c delete mode 100644 Externals/curl/lib/rawstr.h delete mode 100644 Externals/curl/lib/rtsp.c delete mode 100644 Externals/curl/lib/rtsp.h delete mode 100644 Externals/curl/lib/security.c delete mode 100644 Externals/curl/lib/select.c delete mode 100644 Externals/curl/lib/select.h delete mode 100644 Externals/curl/lib/sendf.c delete mode 100644 Externals/curl/lib/sendf.h delete mode 100644 Externals/curl/lib/setup-os400.h delete mode 100644 Externals/curl/lib/setup-vms.h delete mode 100644 Externals/curl/lib/share.c delete mode 100644 Externals/curl/lib/share.h delete mode 100644 Externals/curl/lib/sigpipe.h delete mode 100644 Externals/curl/lib/slist.c delete mode 100644 Externals/curl/lib/slist.h delete mode 100644 Externals/curl/lib/smb.c delete mode 100644 Externals/curl/lib/smb.h delete mode 100644 Externals/curl/lib/smtp.c delete mode 100644 Externals/curl/lib/smtp.h delete mode 100644 Externals/curl/lib/sockaddr.h delete mode 100644 Externals/curl/lib/socks.c delete mode 100644 Externals/curl/lib/socks.h delete mode 100644 Externals/curl/lib/socks_gssapi.c delete mode 100644 Externals/curl/lib/socks_sspi.c delete mode 100644 Externals/curl/lib/speedcheck.c delete mode 100644 Externals/curl/lib/speedcheck.h delete mode 100644 Externals/curl/lib/splay.c delete mode 100644 Externals/curl/lib/splay.h delete mode 100644 Externals/curl/lib/ssh.c delete mode 100644 Externals/curl/lib/ssh.h delete mode 100644 Externals/curl/lib/strdup.c delete mode 100644 Externals/curl/lib/strdup.h delete mode 100644 Externals/curl/lib/strequal.c delete mode 100644 Externals/curl/lib/strequal.h delete mode 100644 Externals/curl/lib/strerror.c delete mode 100644 Externals/curl/lib/strerror.h delete mode 100644 Externals/curl/lib/strtok.c delete mode 100644 Externals/curl/lib/strtok.h delete mode 100644 Externals/curl/lib/strtoofft.c delete mode 100644 Externals/curl/lib/strtoofft.h delete mode 100644 Externals/curl/lib/system_win32.c delete mode 100644 Externals/curl/lib/system_win32.h delete mode 100644 Externals/curl/lib/telnet.c delete mode 100644 Externals/curl/lib/telnet.h delete mode 100644 Externals/curl/lib/tftp.c delete mode 100644 Externals/curl/lib/tftp.h delete mode 100644 Externals/curl/lib/timeval.c delete mode 100644 Externals/curl/lib/timeval.h delete mode 100644 Externals/curl/lib/transfer.c delete mode 100644 Externals/curl/lib/transfer.h delete mode 100644 Externals/curl/lib/url.c delete mode 100644 Externals/curl/lib/url.h delete mode 100644 Externals/curl/lib/urldata.h delete mode 100644 Externals/curl/lib/vauth/cleartext.c delete mode 100644 Externals/curl/lib/vauth/cram.c delete mode 100644 Externals/curl/lib/vauth/digest.c delete mode 100644 Externals/curl/lib/vauth/digest.h delete mode 100644 Externals/curl/lib/vauth/digest_sspi.c delete mode 100644 Externals/curl/lib/vauth/krb5_gssapi.c delete mode 100644 Externals/curl/lib/vauth/krb5_sspi.c delete mode 100644 Externals/curl/lib/vauth/ntlm.c delete mode 100644 Externals/curl/lib/vauth/ntlm.h delete mode 100644 Externals/curl/lib/vauth/ntlm_sspi.c delete mode 100644 Externals/curl/lib/vauth/oauth2.c delete mode 100644 Externals/curl/lib/vauth/spnego_gssapi.c delete mode 100644 Externals/curl/lib/vauth/spnego_sspi.c delete mode 100644 Externals/curl/lib/vauth/vauth.c delete mode 100644 Externals/curl/lib/vauth/vauth.h delete mode 100644 Externals/curl/lib/version.c delete mode 100644 Externals/curl/lib/vtls/axtls.c delete mode 100644 Externals/curl/lib/vtls/axtls.h delete mode 100644 Externals/curl/lib/vtls/cyassl.c delete mode 100644 Externals/curl/lib/vtls/cyassl.h delete mode 100644 Externals/curl/lib/vtls/darwinssl.c delete mode 100644 Externals/curl/lib/vtls/darwinssl.h delete mode 100644 Externals/curl/lib/vtls/gskit.c delete mode 100644 Externals/curl/lib/vtls/gskit.h delete mode 100644 Externals/curl/lib/vtls/gtls.c delete mode 100644 Externals/curl/lib/vtls/gtls.h delete mode 100644 Externals/curl/lib/vtls/mbedtls.c delete mode 100644 Externals/curl/lib/vtls/mbedtls.h delete mode 100644 Externals/curl/lib/vtls/nss.c delete mode 100644 Externals/curl/lib/vtls/nssg.h delete mode 100644 Externals/curl/lib/vtls/openssl.c delete mode 100644 Externals/curl/lib/vtls/openssl.h delete mode 100644 Externals/curl/lib/vtls/polarssl.c delete mode 100644 Externals/curl/lib/vtls/polarssl.h delete mode 100644 Externals/curl/lib/vtls/polarssl_threadlock.c delete mode 100644 Externals/curl/lib/vtls/polarssl_threadlock.h delete mode 100644 Externals/curl/lib/vtls/schannel.c delete mode 100644 Externals/curl/lib/vtls/schannel.h delete mode 100644 Externals/curl/lib/vtls/vtls.c delete mode 100644 Externals/curl/lib/vtls/vtls.h delete mode 100644 Externals/curl/lib/warnless.c delete mode 100644 Externals/curl/lib/warnless.h delete mode 100644 Externals/curl/lib/wildcard.c delete mode 100644 Externals/curl/lib/wildcard.h delete mode 100644 Externals/curl/lib/x509asn1.c delete mode 100644 Externals/curl/lib/x509asn1.h diff --git a/.gitmodules b/.gitmodules index 09ed6b807a..0e07cdfb67 100644 --- a/.gitmodules +++ b/.gitmodules @@ -57,3 +57,6 @@ [submodule "Externals/libadrenotools"] path = Externals/libadrenotools url = https://github.com/bylaws/libadrenotools.git +[submodule "Externals/curl/curl"] + path = Externals/curl/curl + url = https://github.com/curl/curl.git diff --git a/Externals/curl/CMakeLists.txt b/Externals/curl/CMakeLists.txt index 96351c4120..1d01b5a872 100644 --- a/Externals/curl/CMakeLists.txt +++ b/Externals/curl/CMakeLists.txt @@ -1,2 +1,62 @@ -include_directories(include/) -add_subdirectory(lib) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/curl/include) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/curl/lib) + +set(CURL_LIBS MbedTLS::mbedtls zlibstatic) +if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + set(use_core_foundation ON) + + find_library(SYSTEMCONFIGURATION_FRAMEWORK "SystemConfiguration") + if(NOT SYSTEMCONFIGURATION_FRAMEWORK) + message(FATAL_ERROR "SystemConfiguration framework not found") + endif() + + list(APPEND CURL_LIBS "-framework SystemConfiguration") +endif() + +file(GLOB SRCS curl/lib/*.c curl/lib/vauth/*.c curl/lib/vquic/*.c curl/lib/vssh/*.c curl/lib/vtls/*.c) +add_library( + curl + STATIC + curl/include/curl/curl.h + ${SRCS} +) + +set(SEARCH_CA_BUNDLE_PATHS + /etc/ssl/certs/ca-certificates.crt + /etc/pki/tls/certs/ca-bundle.crt + /usr/share/ssl/certs/ca-bundle.crt + /usr/local/share/certs/ca-root-nss.crt + /etc/ssl/cert.pem) + +foreach(SEARCH_CA_BUNDLE_PATH ${SEARCH_CA_BUNDLE_PATHS}) + if(EXISTS "${SEARCH_CA_BUNDLE_PATH}") + message(STATUS "Found CA bundle: ${SEARCH_CA_BUNDLE_PATH}") + set(CURL_CA_BUNDLE "${SEARCH_CA_BUNDLE_PATH}") + set(CURL_CA_BUNDLE_SET TRUE) + break() + endif() +endforeach() + +if(NOT CURL_CA_PATH_SET) + if(EXISTS "/etc/ssl/certs") + set(CURL_CA_PATH "/etc/ssl/certs") + set(CURL_CA_PATH_SET TRUE) + endif() +endif() + +dolphin_disable_warnings_msvc(curl) +target_link_libraries(curl ${CURL_LIBS}) +target_include_directories(curl PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/curl/include") +target_compile_definitions(curl PRIVATE "BUILDING_LIBCURL=1") +if (WIN32) + target_compile_definitions(curl PUBLIC "CURL_STATICLIB=1" "CURL_DISABLE_LDAP" "USE_WINDOWS_SSPI" "USE_SCHANNEL") + target_link_libraries(curl Crypt32.lib) +else() + target_compile_definitions(curl PUBLIC "CURL_STATICLIB=1" "USE_MBEDTLS=1" "HAVE_CONFIG_H=1" "CURL_DISABLE_LDAP") + if (CURL_CA_PATH_SET) + target_compile_definitions(curl PUBLIC CURL_CA_PATH="${CURL_CA_PATH}") + endif() +endif() + +add_library(CURL::libcurl ALIAS curl) diff --git a/Externals/curl/curl b/Externals/curl/curl new file mode 160000 index 0000000000..7ab9d43720 --- /dev/null +++ b/Externals/curl/curl @@ -0,0 +1 @@ +Subproject commit 7ab9d43720bc34d9aa351c7ca683c1668ebf8335 diff --git a/Externals/curl/curl.vcxproj b/Externals/curl/curl.vcxproj index 351f05831b..0628edc0b4 100644 --- a/Externals/curl/curl.vcxproj +++ b/Externals/curl/curl.vcxproj @@ -1,4 +1,4 @@ - + @@ -17,345 +17,354 @@ - include;lib;%(AdditionalIncludeDirectories) - CURL_STATICLIB;CURL_DISABLE_LDAP;USE_WINDOWS_SSPI;USE_SCHANNEL;%(PreprocessorDefinitions) + curl\include;curl\lib;%(AdditionalIncludeDirectories) + BUILDING_LIBCURL;CURL_STATICLIB;CURL_DISABLE_LDAP;USE_WINDOWS_SSPI;USE_SCHANNEL;%(PreprocessorDefinitions) - - true - - - true - - - - - - - true - - - - - - - - - true - - - - - - true - - - true - - - - - - - - - - - - - - - - - - - - - true - - - - - true - - - true - - - - - - - - - - true - - - - - - - true - - - true - - - - true - - - - true - - - - - - true - - - - true - - - true - - - true - - - - - - - - - - true - - - - - - - - - - true - - - - - - true - - - - - - - true - - - - - - - - - - - - - true - - - - true - - - - - true - - - - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - true - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Externals/curl/lib/curl_config.h b/Externals/curl/curl_config.h similarity index 99% rename from Externals/curl/lib/curl_config.h rename to Externals/curl/curl_config.h index 5f119939ad..5d660437c5 100644 --- a/Externals/curl/lib/curl_config.h +++ b/Externals/curl/curl_config.h @@ -1,8 +1,6 @@ /* lib/curl_config.h. Generated from curl_config.h.in by configure. */ /* lib/curl_config.h.in. Generated from configure.ac by autoheader. */ -/* Location of default ca bundle */ -#define CURL_CA_BUNDLE "/etc/ssl/certs/ca-certificates.crt" /* define "1" to use built in CA store of SSL library */ /* #undef CURL_CA_FALLBACK */ @@ -860,7 +858,7 @@ #define RETSIGTYPE void /* Define to the type qualifier of arg 5 for select. */ -#define SELECT_QUAL_ARG5 +#define SELECT_QUAL_ARG5 /* Define to the type of arg 1 for select. */ #define SELECT_TYPE_ARG1 int @@ -958,6 +956,8 @@ /* if mbedTLS is enabled */ #define USE_MBEDTLS 1 +#define SIZEOF_CURL_OFF_T 8 + /* Define to enable metalink support */ /* #undef USE_METALINK */ @@ -1046,4 +1046,4 @@ /* #undef size_t */ /* the signed version of size_t */ -/* #undef ssize_t */ +/* #undef ssize_t */ \ No newline at end of file diff --git a/Externals/curl/exports.props b/Externals/curl/exports.props index 1f5167cbd1..f78f55e3fe 100644 --- a/Externals/curl/exports.props +++ b/Externals/curl/exports.props @@ -2,7 +2,7 @@ - $(ExternalsDir)curl\include;%(AdditionalIncludeDirectories) + $(ExternalsDir)curl\curl\include;%(AdditionalIncludeDirectories) CURL_STATICLIB;%(PreprocessorDefinitions) diff --git a/Externals/curl/include/README b/Externals/curl/include/README deleted file mode 100644 index 3e52a1d0a6..0000000000 --- a/Externals/curl/include/README +++ /dev/null @@ -1,55 +0,0 @@ - _ _ ____ _ - ___| | | | _ \| | - / __| | | | |_) | | - | (__| |_| | _ <| |___ - \___|\___/|_| \_\_____| - -Include files for libcurl, external users. - -They're all placed in the curl subdirectory here for better fit in any kind -of environment. You must include files from here using... - - #include - -... style and point the compiler's include path to the directory holding the -curl subdirectory. It makes it more likely to survive future modifications. - -NOTE FOR LIBCURL HACKERS - -The following notes apply to libcurl version 7.19.0 and later. - -* The distributed curl/curlbuild.h file is only intended to be used on systems - which can not run the also distributed configure script. - -* The distributed curlbuild.h file is generated as a copy of curlbuild.h.dist - when the libcurl source code distribution archive file is originally created. - -* If you check out from git on a non-configure platform, you must run the - appropriate buildconf* script to set up curlbuild.h and other local files - before being able of compiling the library. - -* On systems capable of running the configure script, the configure process - will overwrite the distributed include/curl/curlbuild.h file with one that - is suitable and specific to the library being configured and built, which - is generated from the include/curl/curlbuild.h.in template file. - -* If you intend to distribute an already compiled libcurl library you _MUST_ - also distribute along with it the generated curl/curlbuild.h which has been - used to compile it. Otherwise the library will be of no use for the users of - the library that you have built. It is _your_ responsibility to provide this - file. No one at the cURL project can know how you have built the library. - -* File curl/curlbuild.h includes platform and configuration dependent info, - and must not be modified by anyone. Configure script generates it for you. - -* We cannot assume anything else but very basic compiler features being - present. While libcurl requires an ANSI C compiler to build, some of the - earlier ANSI compilers clearly can't deal with some preprocessor operators. - -* Newlines must remain unix-style for older compilers' sake. - -* Comments must be written in the old-style /* unnested C-fashion */ - -To figure out how to do good and portable checks for features, operating -systems or specific hardwarare, a very good resource is Bjorn Reese's -collection at http://predef.sf.net/ diff --git a/Externals/curl/include/curl/Makefile.am b/Externals/curl/include/curl/Makefile.am deleted file mode 100644 index 7c924fcb5a..0000000000 --- a/Externals/curl/include/curl/Makefile.am +++ /dev/null @@ -1,53 +0,0 @@ -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -########################################################################### -pkginclude_HEADERS = \ - curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ - typecheck-gcc.h curlbuild.h curlrules.h - -pkgincludedir= $(includedir)/curl - -# curlbuild.h does not exist in the git tree. When the original libcurl -# source code distribution archive file is created, curlbuild.h.dist is -# renamed to curlbuild.h and included in the tarball so that it can be -# used directly on non-configure systems. -# -# The distributed curlbuild.h will be overwritten on configure systems -# when the configure script runs, with one that is suitable and specific -# to the library being configured and built. -# -# curlbuild.h.in is the distributed template file from which the configure -# script creates curlbuild.h at library configuration time, overwiting the -# one included in the distribution archive. -# -# curlbuild.h.dist is not included in the source code distribution archive. - -EXTRA_DIST = curlbuild.h.in - -DISTCLEANFILES = curlbuild.h - -checksrc: - @@PERL@ $(top_srcdir)/lib/checksrc.pl -Wcurlbuild.h -D$(top_srcdir)/include/curl $(pkginclude_HEADERS) $(EXTRA_DIST) - -if CURLDEBUG -# for debug builds, we scan the sources on all regular make invokes -all-local: checksrc -endif diff --git a/Externals/curl/include/curl/Makefile.in b/Externals/curl/include/curl/Makefile.in deleted file mode 100644 index dc790db563..0000000000 --- a/Externals/curl/include/curl/Makefile.in +++ /dev/null @@ -1,707 +0,0 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2014 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = { \ - if test -z '$(MAKELEVEL)'; then \ - false; \ - elif test -n '$(MAKE_HOST)'; then \ - true; \ - elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ - true; \ - else \ - false; \ - fi; \ -} -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -subdir = include/curl -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/curl-compilers.m4 \ - $(top_srcdir)/m4/curl-confopts.m4 \ - $(top_srcdir)/m4/curl-functions.m4 \ - $(top_srcdir)/m4/curl-openssl.m4 \ - $(top_srcdir)/m4/curl-override.m4 \ - $(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/xc-am-iface.m4 \ - $(top_srcdir)/m4/xc-cc-check.m4 \ - $(top_srcdir)/m4/xc-lt-iface.m4 \ - $(top_srcdir)/m4/xc-translit.m4 \ - $(top_srcdir)/m4/xc-val-flgs.m4 \ - $(top_srcdir)/m4/zz40-xc-ovr.m4 \ - $(top_srcdir)/m4/zz50-xc-ovr.m4 \ - $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \ - $(am__DIST_COMMON) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/lib/curl_config.h curlbuild.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -SOURCES = -DIST_SOURCES = -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(pkgincludedir)" -HEADERS = $(pkginclude_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)curlbuild.h.in -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/curlbuild.h.in -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -pkgincludedir = $(includedir)/curl -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ -CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@ -CURLVERSION = @CURLVERSION@ -CURL_CA_BUNDLE = @CURL_CA_BUNDLE@ -CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@ -CURL_DISABLE_DICT = @CURL_DISABLE_DICT@ -CURL_DISABLE_FILE = @CURL_DISABLE_FILE@ -CURL_DISABLE_FTP = @CURL_DISABLE_FTP@ -CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@ -CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@ -CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@ -CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@ -CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@ -CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@ -CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@ -CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@ -CURL_DISABLE_SMB = @CURL_DISABLE_SMB@ -CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@ -CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@ -CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@ -CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@ -CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@ -CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -ENABLE_SHARED = @ENABLE_SHARED@ -ENABLE_STATIC = @ENABLE_STATIC@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GREP = @GREP@ -HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@ -HAVE_LDAP_SSL = @HAVE_LDAP_SSL@ -HAVE_LIBZ = @HAVE_LIBZ@ -HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@ -IDN_ENABLED = @IDN_ENABLED@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -IPV6_ENABLED = @IPV6_ENABLED@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBCURL_LIBS = @LIBCURL_LIBS@ -LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@ -LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@ -LIBMETALINK_LIBS = @LIBMETALINK_LIBS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBOBJS = @LTLIBOBJS@ -LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MANOPT = @MANOPT@ -MKDIR_P = @MKDIR_P@ -NM = @NM@ -NMEDIT = @NMEDIT@ -NROFF = @NROFF@ -NSS_LIBS = @NSS_LIBS@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PERL = @PERL@ -PKGADD_NAME = @PKGADD_NAME@ -PKGADD_PKG = @PKGADD_PKG@ -PKGADD_VENDOR = @PKGADD_VENDOR@ -PKGCONFIG = @PKGCONFIG@ -RANDOM_FILE = @RANDOM_FILE@ -RANLIB = @RANLIB@ -REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SSL_ENABLED = @SSL_ENABLED@ -SSL_LIBS = @SSL_LIBS@ -STRIP = @STRIP@ -SUPPORT_FEATURES = @SUPPORT_FEATURES@ -SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@ -USE_ARES = @USE_ARES@ -USE_AXTLS = @USE_AXTLS@ -USE_CYASSL = @USE_CYASSL@ -USE_DARWINSSL = @USE_DARWINSSL@ -USE_GNUTLS = @USE_GNUTLS@ -USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@ -USE_LIBRTMP = @USE_LIBRTMP@ -USE_LIBSSH2 = @USE_LIBSSH2@ -USE_MBEDTLS = @USE_MBEDTLS@ -USE_NGHTTP2 = @USE_NGHTTP2@ -USE_NSS = @USE_NSS@ -USE_OPENLDAP = @USE_OPENLDAP@ -USE_POLARSSL = @USE_POLARSSL@ -USE_SCHANNEL = @USE_SCHANNEL@ -USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@ -USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@ -VERSION = @VERSION@ -VERSIONNUM = @VERSIONNUM@ -ZLIB_LIBS = @ZLIB_LIBS@ -ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -libext = @libext@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -runstatedir = @runstatedir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ - -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -########################################################################### -pkginclude_HEADERS = \ - curl.h curlver.h easy.h mprintf.h stdcheaders.h multi.h \ - typecheck-gcc.h curlbuild.h curlrules.h - - -# curlbuild.h does not exist in the git tree. When the original libcurl -# source code distribution archive file is created, curlbuild.h.dist is -# renamed to curlbuild.h and included in the tarball so that it can be -# used directly on non-configure systems. -# -# The distributed curlbuild.h will be overwritten on configure systems -# when the configure script runs, with one that is suitable and specific -# to the library being configured and built. -# -# curlbuild.h.in is the distributed template file from which the configure -# script creates curlbuild.h at library configuration time, overwiting the -# one included in the distribution archive. -# -# curlbuild.h.dist is not included in the source code distribution archive. -EXTRA_DIST = curlbuild.h.in -DISTCLEANFILES = curlbuild.h -all: curlbuild.h - $(MAKE) $(AM_MAKEFLAGS) all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/curl/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu include/curl/Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -curlbuild.h: stamp-h2 - @test -f $@ || rm -f stamp-h2 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2 - -stamp-h2: $(srcdir)/curlbuild.h.in $(top_builddir)/config.status - @rm -f stamp-h2 - cd $(top_builddir) && $(SHELL) ./config.status include/curl/curlbuild.h - -distclean-hdr: - -rm -f curlbuild.h stamp-h2 - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-pkgincludeHEADERS: $(pkginclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ - done - -uninstall-pkgincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -@CURLDEBUG_FALSE@all-local: -all-am: Makefile $(HEADERS) curlbuild.h all-local -installdirs: - for dir in "$(DESTDIR)$(pkgincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic distclean-hdr distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-pkgincludeHEADERS - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-pkgincludeHEADERS - -.MAKE: all install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am all-local check check-am clean \ - clean-generic clean-libtool cscopelist-am ctags ctags-am \ - distclean distclean-generic distclean-hdr distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-pkgincludeHEADERS \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-pkgincludeHEADERS - -.PRECIOUS: Makefile - - -checksrc: - @@PERL@ $(top_srcdir)/lib/checksrc.pl -Wcurlbuild.h -D$(top_srcdir)/include/curl $(pkginclude_HEADERS) $(EXTRA_DIST) - -# for debug builds, we scan the sources on all regular make invokes -@CURLDEBUG_TRUE@all-local: checksrc - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/Externals/curl/include/curl/curl.h b/Externals/curl/include/curl/curl.h deleted file mode 100644 index 57e716b3ef..0000000000 --- a/Externals/curl/include/curl/curl.h +++ /dev/null @@ -1,2439 +0,0 @@ -#ifndef __CURL_CURL_H -#define __CURL_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * If you have libcurl problems, all docs and details are found here: - * https://curl.haxx.se/libcurl/ - * - * curl-library mailing list subscription and unsubscription web interface: - * https://cool.haxx.se/mailman/listinfo/curl-library/ - */ - -#include "curlver.h" /* libcurl version defines */ -#include "curlbuild.h" /* libcurl build definitions */ -#include "curlrules.h" /* libcurl rules enforcement */ - -/* - * Define WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__)) && \ - !defined(WIN32) && !defined(__SYMBIAN32__) -#define WIN32 -#endif - -#include -#include - -#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) -/* Needed for __FreeBSD_version symbol definition */ -#include -#endif - -/* The include stuff here below is mainly for time_t! */ -#include -#include - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ - defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) -/* The check above prevents the winsock2 inclusion if winsock.h already was - included, since they can't co-exist without problems */ -#include -#include -#endif -#endif - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on systems that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) -#include -#endif - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#include -#endif - -#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) -#include -#endif - -#ifdef __BEOS__ -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURL; - -/* - * libcurl external API function linkage decorations. - */ - -#ifdef CURL_STATICLIB -# define CURL_EXTERN -#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) -# if defined(BUILDING_LIBCURL) -# define CURL_EXTERN __declspec(dllexport) -# else -# define CURL_EXTERN __declspec(dllimport) -# endif -#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) -# define CURL_EXTERN CURL_EXTERN_SYMBOL -#else -# define CURL_EXTERN -#endif - -#ifndef curl_socket_typedef -/* socket typedef */ -#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD -1 -#endif -#define curl_socket_typedef -#endif /* curl_socket_typedef */ - -struct curl_httppost { - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field, see also - CURL_HTTPPOST_LARGE */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist* contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ - -/* specified content is a file name */ -#define CURL_HTTPPOST_FILENAME (1<<0) -/* specified content is a file name */ -#define CURL_HTTPPOST_READFILE (1<<1) -/* name is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRNAME (1<<2) -/* contents is only stored pointer do not free in formfree */ -#define CURL_HTTPPOST_PTRCONTENTS (1<<3) -/* upload file from buffer */ -#define CURL_HTTPPOST_BUFFER (1<<4) -/* upload file from pointer contents */ -#define CURL_HTTPPOST_PTRBUFFER (1<<5) -/* upload file contents by using the regular read callback to get the data and - pass the given pointer as custom pointer */ -#define CURL_HTTPPOST_CALLBACK (1<<6) -/* use size in 'contentlen', added in 7.46.0 */ -#define CURL_HTTPPOST_LARGE (1<<7) - - char *showfilename; /* The file name to show. If not set, the - actual file name will be used (if this - is a file part) */ - void *userp; /* custom pointer used for - HTTPPOST_CALLBACK posts */ - curl_off_t contentlen; /* alternative length of contents - field. Used if CURL_HTTPPOST_LARGE is - set. Added in 7.46.0 */ -}; - -/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered - deprecated but was the only choice up until 7.31.0 */ -typedef int (*curl_progress_callback)(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - -/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in - 7.32.0, it avoids floating point and provides more detailed information. */ -typedef int (*curl_xferinfo_callback)(void *clientp, - curl_off_t dltotal, - curl_off_t dlnow, - curl_off_t ultotal, - curl_off_t ulnow); - -#ifndef CURL_MAX_WRITE_SIZE - /* Tests have proven that 20K is a very bad buffer size for uploads on - Windows, while 16K for some odd reason performed a lot better. - We do the ifndef check to allow this value to easier be changed at build - time for those who feel adventurous. The practical minimum is about - 400 bytes since libcurl uses a buffer of this size as a scratch area - (unrelated to network send operations). */ -#define CURL_MAX_WRITE_SIZE 16384 -#endif - -#ifndef CURL_MAX_HTTP_HEADER -/* The only reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause reallocs - infinitely */ -#define CURL_MAX_HTTP_HEADER (100*1024) -#endif - -/* This is a magic return code for the write callback that, when returned, - will signal libcurl to pause receiving on the current transfer. */ -#define CURL_WRITEFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - - - -/* enumeration of file types */ -typedef enum { - CURLFILETYPE_FILE = 0, - CURLFILETYPE_DIRECTORY, - CURLFILETYPE_SYMLINK, - CURLFILETYPE_DEVICE_BLOCK, - CURLFILETYPE_DEVICE_CHAR, - CURLFILETYPE_NAMEDPIPE, - CURLFILETYPE_SOCKET, - CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ - - CURLFILETYPE_UNKNOWN /* should never occur */ -} curlfiletype; - -#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) -#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) -#define CURLFINFOFLAG_KNOWN_TIME (1<<2) -#define CURLFINFOFLAG_KNOWN_PERM (1<<3) -#define CURLFINFOFLAG_KNOWN_UID (1<<4) -#define CURLFINFOFLAG_KNOWN_GID (1<<5) -#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) -#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) - -/* Content of this structure depends on information which is known and is - achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man - page for callbacks returning this structure -- some fields are mandatory, - some others are optional. The FLAG field has special meaning. */ -struct curl_fileinfo { - char *filename; - curlfiletype filetype; - time_t time; - unsigned int perm; - int uid; - int gid; - curl_off_t size; - long int hardlinks; - - struct { - /* If some of these fields is not NULL, it is a pointer to b_data. */ - char *time; - char *perm; - char *user; - char *group; - char *target; /* pointer to the target filename of a symlink */ - } strings; - - unsigned int flags; - - /* used internally */ - char * b_data; - size_t b_size; - size_t b_used; -}; - -/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ -#define CURL_CHUNK_BGN_FUNC_OK 0 -#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ -#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ - -/* if splitting of data transfer is enabled, this callback is called before - download of an individual chunk started. Note that parameter "remains" works - only for FTP wildcard downloading (for now), otherwise is not used */ -typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, - void *ptr, - int remains); - -/* return codes for CURLOPT_CHUNK_END_FUNCTION */ -#define CURL_CHUNK_END_FUNC_OK 0 -#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ - -/* If splitting of data transfer is enabled this callback is called after - download of an individual chunk finished. - Note! After this callback was set then it have to be called FOR ALL chunks. - Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. - This is the reason why we don't need "transfer_info" parameter in this - callback and we are not interested in "remains" parameter too. */ -typedef long (*curl_chunk_end_callback)(void *ptr); - -/* return codes for FNMATCHFUNCTION */ -#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ -#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ -#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ - -/* callback type for wildcard downloading pattern matching. If the - string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ -typedef int (*curl_fnmatch_callback)(void *ptr, - const char *pattern, - const char *string); - -/* These are the return codes for the seek callbacks */ -#define CURL_SEEKFUNC_OK 0 -#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ -#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so - libcurl might try other means instead */ -typedef int (*curl_seek_callback)(void *instream, - curl_off_t offset, - int origin); /* 'whence' */ - -/* This is a return code for the read callback that, when returned, will - signal libcurl to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -/* This is a return code for the read callback that, when returned, will - signal libcurl to pause sending data on the current transfer. */ -#define CURL_READFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - -typedef enum { - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ - CURLSOCKTYPE_LAST /* never use */ -} curlsocktype; - -/* The return code from the sockopt_callback can signal information back - to libcurl: */ -#define CURL_SOCKOPT_OK 0 -#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return - CURLE_ABORTED_BY_CALLBACK */ -#define CURL_SOCKOPT_ALREADY_CONNECTED 2 - -typedef int (*curl_sockopt_callback)(void *clientp, - curl_socket_t curlfd, - curlsocktype purpose); - -struct curl_sockaddr { - int family; - int socktype; - int protocol; - unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it - turned really ugly and painful on the systems that - lack this type */ - struct sockaddr addr; -}; - -typedef curl_socket_t -(*curl_opensocket_callback)(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *address); - -typedef int -(*curl_closesocket_callback)(void *clientp, curl_socket_t item); - -typedef enum { - CURLIOE_OK, /* I/O operation successful */ - CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ - CURLIOE_FAILRESTART, /* failed to restart the read */ - CURLIOE_LAST /* never use */ -} curlioerr; - -typedef enum { - CURLIOCMD_NOP, /* no operation */ - CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ - CURLIOCMD_LAST /* never use */ -} curliocmd; - -typedef curlioerr (*curl_ioctl_callback)(CURL *handle, - int cmd, - void *clientp); - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -#define CURL_DID_MEMORY_FUNC_TYPEDEFS -#endif - -/* the kind of data that is passed to information_callback*/ -typedef enum { - CURLINFO_TEXT = 0, - CURLINFO_HEADER_IN, /* 1 */ - CURLINFO_HEADER_OUT, /* 2 */ - CURLINFO_DATA_IN, /* 3 */ - CURLINFO_DATA_OUT, /* 4 */ - CURLINFO_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - CURLINFO_END -} curl_infotype; - -typedef int (*curl_debug_callback) - (CURL *handle, /* the handle/transfer this concerns */ - curl_infotype type, /* what kind of data */ - char *data, /* points to the data */ - size_t size, /* size of the data pointed to */ - void *userptr); /* whatever the user please */ - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum { - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for - 7.17.0, reused in April 2011 for 7.21.5] */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server - due to lack of access - when login fails - this is not returned. */ - CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for - 7.15.4, reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server - [was obsoleted in August 2007 for 7.17.0, - reused in Dec 2011 for 7.24.0]*/ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. - [was obsoleted in August 2007 for 7.17.0, - reused in July 2014 for 7.38.0] */ - CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_OBSOLETE20, /* 20 - NOT USED */ - CURLE_QUOTE_ERROR, /* 21 - quote command failure */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_OBSOLETE24, /* 24 - NOT USED */ - CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ - CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error - instead of a memory allocation error if CURL_DOES_CONVERSIONS - is defined - */ - CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ - CURLE_OBSOLETE29, /* 29 - NOT USED */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_OBSOLETE32, /* 32 - NOT USED */ - CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ - CURLE_HTTP_POST_ERROR, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_FUNCTION_NOT_FOUND, /* 41 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_OBSOLETE44, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ - CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_SEND_ERROR, /* 55 - failed sending network data */ - CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - CURLE_OBSOLETE57, /* 57 - NOT IN USE */ - CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ - CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ - CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ - CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind - that failed */ - CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ - CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not - accepted and we failed to login */ - CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ - CURLE_TFTP_PERM, /* 69 - permission problem on server */ - CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ - CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ - CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ - CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ - CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_CONV_FAILED, /* 75 - conversion failed */ - CURLE_CONV_REQD, /* 76 - caller must register conversion - callbacks using curl_easy_setopt options - CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOPT_CONV_TO_NETWORK_FUNCTION, and - CURLOPT_CONV_FROM_UTF8_FUNCTION */ - CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing - or wrong format */ - CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ - CURLE_SSH, /* 79 - error from the SSH layer, somewhat - generic so the error message will be of - interest when this has happened */ - - CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL - connection */ - CURLE_AGAIN, /* 81 - socket is not ready for send/recv, - wait till it's ready and try again (Added - in 7.18.2) */ - CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or - wrong format (Added in 7.19.0) */ - CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in - 7.19.0) */ - CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ - CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ - CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ - CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ - CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ - CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the - session will be queued */ - CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not - match */ - CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ - CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer - */ - CURL_LAST /* never use! */ -} CURLcode; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Previously obsolete error code re-used in 7.38.0 */ -#define CURLE_OBSOLETE16 CURLE_HTTP2 - -/* Previously obsolete error codes re-used in 7.24.0 */ -#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED -#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT - -/* compatibility with older names */ -#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING - -/* The following were added in 7.21.5, April 2011 */ -#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION - -/* The following were added in 7.17.1 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.17.0 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ -#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 -#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 -#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 -#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 -#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 -#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 -#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 -#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 -#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 -#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 -#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 -#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN - -#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED -#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE -#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR -#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL -#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS -#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR -#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED - -/* The following were added earlier */ - -#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT - -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED -#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED - -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME - -/* This was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -/* Provide defines for really old option names */ -#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ -#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ -#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA - -/* Since long deprecated options with no code in the lib that does anything - with them. */ -#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 -#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 - -#endif /*!CURL_NO_OLDIES*/ - -/* This prototype applies to all conversion callbacks */ -typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an - OpenSSL SSL_CTX */ - void *userptr); - -typedef enum { - CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use - CONNECT HTTP/1.1 */ - CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT - HTTP/1.0 */ - CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already - in 7.10 */ - CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ - CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ - CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the - host name rather than the IP address. added - in 7.18.0 */ -} curl_proxytype; /* this enum was added in 7.10 */ - -/* - * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: - * - * CURLAUTH_NONE - No HTTP authentication - * CURLAUTH_BASIC - HTTP Basic authentication (default) - * CURLAUTH_DIGEST - HTTP Digest authentication - * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication - * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) - * CURLAUTH_NTLM - HTTP NTLM authentication - * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour - * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper - * CURLAUTH_ONLY - Use together with a single other type to force no - * authentication or just that single type - * CURLAUTH_ANY - All fine types set - * CURLAUTH_ANYSAFE - All fine types except Basic - */ - -#define CURLAUTH_NONE ((unsigned long)0) -#define CURLAUTH_BASIC (((unsigned long)1)<<0) -#define CURLAUTH_DIGEST (((unsigned long)1)<<1) -#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) -/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ -#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE -#define CURLAUTH_NTLM (((unsigned long)1)<<3) -#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) -#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) -#define CURLAUTH_ONLY (((unsigned long)1)<<31) -#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) -#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) - -#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ -#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ -#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ -#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ -#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ -#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ -#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ -#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY - -#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ -#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ -#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ - -#define CURL_ERROR_SIZE 256 - -enum curl_khtype { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS -}; - -struct curl_khkey { - const char *key; /* points to a zero-terminated string encoded with base64 - if len is zero, otherwise to the "raw" data */ - size_t len; - enum curl_khtype keytype; -}; - -/* this is the set of return values expected from the curl_sshkeycallback - callback */ -enum curl_khstat { - CURLKHSTAT_FINE_ADD_TO_FILE, - CURLKHSTAT_FINE, - CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so - this causes a CURLE_DEFER error but otherwise the - connection will be left intact etc */ - CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ -}; - -/* this is the set of status codes pass in to the callback */ -enum curl_khmatch { - CURLKHMATCH_OK, /* match */ - CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ - CURLKHMATCH_MISSING, /* no matching host/key found */ - CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ -}; - -typedef int - (*curl_sshkeycallback) (CURL *easy, /* easy handle */ - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch, /* libcurl's view on the keys */ - void *clientp); /* custom pointer passed from app */ - -/* parameter for the CURLOPT_USE_SSL option */ -typedef enum { - CURLUSESSL_NONE, /* do not attempt to use SSL */ - CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ - CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ - CURLUSESSL_ALL, /* SSL for all communication or fail */ - CURLUSESSL_LAST /* not an option, never use */ -} curl_usessl; - -/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ - -/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the - name of improving interoperability with older servers. Some SSL libraries - have introduced work-arounds for this flaw but those work-arounds sometimes - make the SSL communication fail. To regain functionality with those broken - servers, a user can this way allow the vulnerability back. */ -#define CURLSSLOPT_ALLOW_BEAST (1<<0) - -/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those - SSL backends where such behavior is present. */ -#define CURLSSLOPT_NO_REVOKE (1<<1) - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2009 */ - -#define CURLFTPSSL_NONE CURLUSESSL_NONE -#define CURLFTPSSL_TRY CURLUSESSL_TRY -#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL -#define CURLFTPSSL_ALL CURLUSESSL_ALL -#define CURLFTPSSL_LAST CURLUSESSL_LAST -#define curl_ftpssl curl_usessl -#endif /*!CURL_NO_OLDIES*/ - -/* parameter for the CURLOPT_FTP_SSL_CCC option */ -typedef enum { - CURLFTPSSL_CCC_NONE, /* do not send CCC */ - CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ - CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ - CURLFTPSSL_CCC_LAST /* not an option, never use */ -} curl_ftpccc; - -/* parameter for the CURLOPT_FTPSSLAUTH option */ -typedef enum { - CURLFTPAUTH_DEFAULT, /* let libcurl decide */ - CURLFTPAUTH_SSL, /* use "AUTH SSL" */ - CURLFTPAUTH_TLS, /* use "AUTH TLS" */ - CURLFTPAUTH_LAST /* not an option, never use */ -} curl_ftpauth; - -/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ -typedef enum { - CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ - CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD - again if MKD succeeded, for SFTP this does - similar magic */ - CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD - again even if MKD failed! */ - CURLFTP_CREATE_DIR_LAST /* not an option, never use */ -} curl_ftpcreatedir; - -/* parameter for the CURLOPT_FTP_FILEMETHOD option */ -typedef enum { - CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ - CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ - CURLFTPMETHOD_NOCWD, /* no CWD at all */ - CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ - CURLFTPMETHOD_LAST /* not an option, never use */ -} curl_ftpmethod; - -/* bitmask defines for CURLOPT_HEADEROPT */ -#define CURLHEADER_UNIFIED 0 -#define CURLHEADER_SEPARATE (1<<0) - -/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ -#define CURLPROTO_HTTP (1<<0) -#define CURLPROTO_HTTPS (1<<1) -#define CURLPROTO_FTP (1<<2) -#define CURLPROTO_FTPS (1<<3) -#define CURLPROTO_SCP (1<<4) -#define CURLPROTO_SFTP (1<<5) -#define CURLPROTO_TELNET (1<<6) -#define CURLPROTO_LDAP (1<<7) -#define CURLPROTO_LDAPS (1<<8) -#define CURLPROTO_DICT (1<<9) -#define CURLPROTO_FILE (1<<10) -#define CURLPROTO_TFTP (1<<11) -#define CURLPROTO_IMAP (1<<12) -#define CURLPROTO_IMAPS (1<<13) -#define CURLPROTO_POP3 (1<<14) -#define CURLPROTO_POP3S (1<<15) -#define CURLPROTO_SMTP (1<<16) -#define CURLPROTO_SMTPS (1<<17) -#define CURLPROTO_RTSP (1<<18) -#define CURLPROTO_RTMP (1<<19) -#define CURLPROTO_RTMPT (1<<20) -#define CURLPROTO_RTMPE (1<<21) -#define CURLPROTO_RTMPTE (1<<22) -#define CURLPROTO_RTMPS (1<<23) -#define CURLPROTO_RTMPTS (1<<24) -#define CURLPROTO_GOPHER (1<<25) -#define CURLPROTO_SMB (1<<26) -#define CURLPROTO_SMBS (1<<27) -#define CURLPROTO_ALL (~0) /* enable everything */ - -/* long may be 32 or 64 bits, but we should never depend on anything else - but 32 */ -#define CURLOPTTYPE_LONG 0 -#define CURLOPTTYPE_OBJECTPOINT 10000 -#define CURLOPTTYPE_STRINGPOINT 10000 -#define CURLOPTTYPE_FUNCTIONPOINT 20000 -#define CURLOPTTYPE_OFF_T 30000 - -/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the - string options from the header file */ - -/* name is uppercase CURLOPT_, - type is one of the defined CURLOPTTYPE_ - number is unique identifier */ -#ifdef CINIT -#undef CINIT -#endif - -#ifdef CURL_ISOCPP -#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLOPT_/**/name = type + number -#endif - -/* - * This macro-mania below setups the CURLOPT_[what] enum, to be used with - * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] - * word. - */ - -typedef enum { - /* This is the FILE * or void * the regular output should be written to. */ - CINIT(WRITEDATA, OBJECTPOINT, 1), - - /* The full URL to get/put */ - CINIT(URL, STRINGPOINT, 2), - - /* Port number to connect to, if other than default. */ - CINIT(PORT, LONG, 3), - - /* Name of proxy to use. */ - CINIT(PROXY, STRINGPOINT, 4), - - /* "user:password;options" to use when fetching. */ - CINIT(USERPWD, STRINGPOINT, 5), - - /* "user:password" to use with proxy. */ - CINIT(PROXYUSERPWD, STRINGPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CINIT(RANGE, STRINGPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CINIT(READDATA, OBJECTPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. If this is not used, error messages go to stderr instead: */ - CINIT(ERRORBUFFER, OBJECTPOINT, 10), - - /* Function that will be called to store the output (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), - - /* Function that will be called to read the input (instead of fread). The - * parameters will use fread() syntax, make sure to follow them. */ - CINIT(READFUNCTION, FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CINIT(TIMEOUT, LONG, 13), - - /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was successful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CINIT(INFILESIZE, LONG, 14), - - /* POST static input fields. */ - CINIT(POSTFIELDS, OBJECTPOINT, 15), - - /* Set the referrer page (needed by some CGIs) */ - CINIT(REFERER, STRINGPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CINIT(FTPPORT, STRINGPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CINIT(USERAGENT, STRINGPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CINIT(LOW_SPEED_LIMIT, LONG, 19), - - /* Set the "low speed time" */ - CINIT(LOW_SPEED_TIME, LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CINIT(RESUME_FROM, LONG, 21), - - /* Set cookie in request: */ - CINIT(COOKIE, STRINGPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind. This - list is also used for RTSP (in spite of its name) */ - CINIT(HTTPHEADER, OBJECTPOINT, 23), - - /* This points to a linked list of post entries, struct curl_httppost */ - CINIT(HTTPPOST, OBJECTPOINT, 24), - - /* name of the file keeping your private SSL-certificate */ - CINIT(SSLCERT, STRINGPOINT, 25), - - /* password for the SSL or SSH private key */ - CINIT(KEYPASSWD, STRINGPOINT, 26), - - /* send TYPE parameter? */ - CINIT(CRLF, LONG, 27), - - /* send linked-list of QUOTE commands */ - CINIT(QUOTE, OBJECTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is simply passed to the callback unmodified */ - CINIT(HEADERDATA, OBJECTPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CINIT(COOKIEFILE, STRINGPOINT, 31), - - /* What version to specifically try to use. - See CURL_SSLVERSION defines below. */ - CINIT(SSLVERSION, LONG, 32), - - /* What kind of HTTP time condition to use, see defines */ - CINIT(TIMECONDITION, LONG, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CINIT(TIMEVALUE, LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CINIT(CUSTOMREQUEST, STRINGPOINT, 36), - - /* FILE handle to use instead of stderr */ - CINIT(STDERR, OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CINIT(POSTQUOTE, OBJECTPOINT, 39), - - CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ - - CINIT(VERBOSE, LONG, 41), /* talk a lot */ - CINIT(HEADER, LONG, 42), /* throw the header out too */ - CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ - CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ - CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ - CINIT(UPLOAD, LONG, 46), /* this is an upload */ - CINIT(POST, LONG, 47), /* HTTP POST method */ - CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ - - CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ - - /* Specify whether to read the user+password from the .netrc or the URL. - * This must be one of the CURL_NETRC_* enums below. */ - CINIT(NETRC, LONG, 51), - - CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ - - CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ - CINIT(PUT, LONG, 54), /* HTTP PUT */ - - /* 55 = OBSOLETE */ - - /* DEPRECATED - * Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), - - /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION - callbacks */ - CINIT(PROGRESSDATA, OBJECTPOINT, 57), -#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA - - /* We want the referrer field set automatically when following locations */ - CINIT(AUTOREFERER, LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CINIT(PROXYPORT, LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CINIT(POSTFIELDSIZE, LONG, 60), - - /* tunnel non-http operations through a HTTP proxy */ - CINIT(HTTPPROXYTUNNEL, LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CINIT(INTERFACE, STRINGPOINT, 62), - - /* Set the krb4/5 security level, this also enables krb4/5 awareness. This - * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string - * is set but doesn't match one of these, 'private' will be used. */ - CINIT(KRBLEVEL, STRINGPOINT, 63), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CINIT(SSL_VERIFYPEER, LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAINFO, STRINGPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CINIT(MAXREDIRS, LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CINIT(FILETIME, LONG, 69), - - /* This points to a linked list of telnet options */ - CINIT(TELNETOPTIONS, OBJECTPOINT, 70), - - /* Max amount of cached alive connections */ - CINIT(MAXCONNECTS, LONG, 71), - - CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ - - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you're absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CINIT(FRESH_CONNECT, LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be re-used - when done. Do not use this unless you're absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CINIT(FORBID_REUSE, LONG, 75), - - /* Set to a file name that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CINIT(RANDOM_FILE, STRINGPOINT, 76), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CINIT(EGDSOCKET, STRINGPOINT, 77), - - /* Time-out connect operations after this amount of seconds, if connects are - OK within this time, then fine... This only aborts the connect phase. */ - CINIT(CONNECTTIMEOUT, LONG, 78), - - /* Function that will be called to store headers (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CINIT(HTTPGET, LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CINIT(SSL_VERIFYHOST, LONG, 81), - - /* Specify which file name to write all known cookies in after completed - operation. Set file name to "-" (dash) to make it go to stdout. */ - CINIT(COOKIEJAR, STRINGPOINT, 82), - - /* Specify which SSL ciphers to use */ - CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CINIT(HTTP_VERSION, LONG, 84), - - /* Specifically switch on or off the FTP engine's use of the EPSV command. By - default, that one will always be attempted before the more traditional - PASV command. */ - CINIT(FTP_USE_EPSV, LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CINIT(SSLCERTTYPE, STRINGPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CINIT(SSLKEY, STRINGPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CINIT(SSLKEYTYPE, STRINGPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CINIT(SSLENGINE, STRINGPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CINIT(SSLENGINE_DEFAULT, LONG, 90), - - /* Non-zero value means to use the global dns cache */ - CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ - - /* DNS cache timeout */ - CINIT(DNS_CACHE_TIMEOUT, LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands */ - CINIT(PREQUOTE, OBJECTPOINT, 93), - - /* set the debug function */ - CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CINIT(DEBUGDATA, OBJECTPOINT, 95), - - /* mark this as start of a cookie session */ - CINIT(COOKIESESSION, LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAPATH, STRINGPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CINIT(BUFFERSIZE, LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CINIT(NOSIGNAL, LONG, 99), - - /* Provide a CURLShare for mutexing non-ts data */ - CINIT(SHARE, OBJECTPOINT, 100), - - /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ - CINIT(PROXYTYPE, LONG, 101), - - /* Set the Accept-Encoding string. Use this to tell a server you would like - the response to be compressed. Before 7.21.6, this was known as - CURLOPT_ENCODING */ - CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), - - /* Set pointer to private data */ - CINIT(PRIVATE, OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CINIT(HTTP200ALIASES, OBJECTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentially send off the name - and password to whatever host the server decides. */ - CINIT(UNRESTRICTED_AUTH, LONG, 105), - - /* Specifically switch on or off the FTP engine's use of the EPRT command ( - it also disables the LPRT attempt). By default, those ones will always be - attempted before the good old traditional PORT command. */ - CINIT(FTP_USE_EPRT, LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(HTTPAUTH, LONG, 107), - - /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx - in second argument. The function must be matching the - curl_ssl_ctx_callback proto. */ - CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server. - In 7.19.4 we introduced the convenience enums for this option using the - CURLFTP_CREATE_DIR prefix. - */ - CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(PROXYAUTH, LONG, 111), - - /* FTP option that changes the timeout, in seconds, associated with - getting a response. This is different from transfer timeout time and - essentially places a demand on the FTP server to acknowledge commands - in a timely manner. */ - CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), -#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to resolve names to those IP versions only. This only has - affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CINIT(IPRESOLVE, LONG, 113), - - /* Set this option to limit the size of a file that will be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CINIT(MAXFILESIZE, LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CINIT(INFILESIZE_LARGE, OFF_T, 115), - - /* Sets the continuation offset. There is also a LONG version of this; - * look above for RESUME_FROM. - */ - CINIT(RESUME_FROM_LARGE, OFF_T, 116), - - /* Sets the maximum size of data that will be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CINIT(MAXFILESIZE_LARGE, OFF_T, 117), - - /* Set this option to the file name of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl will do - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CINIT(NETRC_FILE, STRINGPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLUSESSL_TRY - try using SSL, proceed anyway otherwise - CURLUSESSL_CONTROL - SSL for the control connection or fail - CURLUSESSL_ALL - SSL for all communication or fail - */ - CINIT(USE_SSL, LONG, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CINIT(TCP_NODELAY, LONG, 121), - - /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 123 OBSOLETE. Gone in 7.16.0 */ - /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 127 OBSOLETE. Gone in 7.16.0 */ - /* 128 OBSOLETE. Gone in 7.16.0 */ - - /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option - can be used to change libcurl's default action which is to first try - "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK - response has been received. - - Available parameters are: - CURLFTPAUTH_DEFAULT - let libcurl decide - CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS - CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL - */ - CINIT(FTPSSLAUTH, LONG, 129), - - CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), - CINIT(IOCTLDATA, OBJECTPOINT, 131), - - /* 132 OBSOLETE. Gone in 7.16.0 */ - /* 133 OBSOLETE. Gone in 7.16.0 */ - - /* zero terminated string for pass on to the FTP server when asked for - "account" info */ - CINIT(FTP_ACCOUNT, STRINGPOINT, 134), - - /* feed cookie into cookie engine */ - CINIT(COOKIELIST, STRINGPOINT, 135), - - /* ignore Content-Length */ - CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), - - /* Set to non-zero to skip the IP address received in a 227 PASV FTP server - response. Typically used for FTP-SSL purposes but is not restricted to - that. libcurl will then instead use the same IP address it used for the - control connection. */ - CINIT(FTP_SKIP_PASV_IP, LONG, 137), - - /* Select "file method" to use when doing FTP, see the curl_ftpmethod - above. */ - CINIT(FTP_FILEMETHOD, LONG, 138), - - /* Local port number to bind the socket to */ - CINIT(LOCALPORT, LONG, 139), - - /* Number of ports to try, including the first one set with LOCALPORT. - Thus, setting it to 1 will make no additional attempts but the first. - */ - CINIT(LOCALPORTRANGE, LONG, 140), - - /* no transfer, set up connection and let application use the socket by - extracting it with CURLINFO_LASTSOCKET */ - CINIT(CONNECT_ONLY, LONG, 141), - - /* Function that will be called to convert from the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), - - /* Function that will be called to convert to the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), - - /* Function that will be called to convert from UTF8 - (instead of using the iconv calls in libcurl) - Note that this is used only for SSL certificate processing */ - CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), - - /* if the connection proceeds too quickly then need to slow it down */ - /* limit-rate: maximum number of bytes per second to send or receive */ - CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), - CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), - - /* Pointer to command string to send if USER/PASS fails. */ - CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), - - /* callback function for setting socket options */ - CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), - CINIT(SOCKOPTDATA, OBJECTPOINT, 149), - - /* set to 0 to disable session ID re-use for this transfer, default is - enabled (== 1) */ - CINIT(SSL_SESSIONID_CACHE, LONG, 150), - - /* allowed SSH authentication methods */ - CINIT(SSH_AUTH_TYPES, LONG, 151), - - /* Used by scp/sftp to do public/private key authentication */ - CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), - CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), - - /* Send CCC (Clear Command Channel) after authentication */ - CINIT(FTP_SSL_CCC, LONG, 154), - - /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CINIT(TIMEOUT_MS, LONG, 155), - CINIT(CONNECTTIMEOUT_MS, LONG, 156), - - /* set to zero to disable the libcurl's decoding and thus pass the raw body - data to the application even when it is encoded/compressed */ - CINIT(HTTP_TRANSFER_DECODING, LONG, 157), - CINIT(HTTP_CONTENT_DECODING, LONG, 158), - - /* Permission used when creating new files and directories on the remote - server for protocols that support it, SFTP/SCP/FILE */ - CINIT(NEW_FILE_PERMS, LONG, 159), - CINIT(NEW_DIRECTORY_PERMS, LONG, 160), - - /* Set the behaviour of POST when redirecting. Values must be set to one - of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CINIT(POSTREDIR, LONG, 161), - - /* used by scp/sftp to verify the host's public key */ - CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), - - /* Callback function for opening socket (instead of socket(2)). Optionally, - callback is able change the address or refuse to connect returning - CURL_SOCKET_BAD. The callback should have type - curl_opensocket_callback */ - CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), - CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), - - /* POST volatile input fields. */ - CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), - - /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CINIT(PROXY_TRANSFER_MODE, LONG, 166), - - /* Callback function for seeking in the input stream */ - CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), - CINIT(SEEKDATA, OBJECTPOINT, 168), - - /* CRL file */ - CINIT(CRLFILE, STRINGPOINT, 169), - - /* Issuer certificate */ - CINIT(ISSUERCERT, STRINGPOINT, 170), - - /* (IPv6) Address scope */ - CINIT(ADDRESS_SCOPE, LONG, 171), - - /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. */ - CINIT(CERTINFO, LONG, 172), - - /* "name" and "pwd" to use when fetching. */ - CINIT(USERNAME, STRINGPOINT, 173), - CINIT(PASSWORD, STRINGPOINT, 174), - - /* "name" and "pwd" to use with Proxy when fetching. */ - CINIT(PROXYUSERNAME, STRINGPOINT, 175), - CINIT(PROXYPASSWORD, STRINGPOINT, 176), - - /* Comma separated list of hostnames defining no-proxy zones. These should - match both hostnames directly, and hostnames within a domain. For - example, local.com will match local.com and www.local.com, but NOT - notlocal.com or www.notlocal.com. For compatibility with other - implementations of this, .local.com will be considered to be the same as - local.com. A single * is the only valid wildcard, and effectively - disables the use of proxy. */ - CINIT(NOPROXY, STRINGPOINT, 177), - - /* block size for TFTP transfers */ - CINIT(TFTP_BLKSIZE, LONG, 178), - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), - - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - CINIT(PROTOCOLS, LONG, 181), - - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. Defaults - to all protocols except FILE and SCP. */ - CINIT(REDIR_PROTOCOLS, LONG, 182), - - /* set the SSH knownhost file name to use */ - CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), - - /* set the SSH host key callback custom pointer */ - CINIT(SSH_KEYDATA, OBJECTPOINT, 185), - - /* set the SMTP mail originator */ - CINIT(MAIL_FROM, STRINGPOINT, 186), - - /* set the list of SMTP mail receiver(s) */ - CINIT(MAIL_RCPT, OBJECTPOINT, 187), - - /* FTP: send PRET before PASV */ - CINIT(FTP_USE_PRET, LONG, 188), - - /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CINIT(RTSP_REQUEST, LONG, 189), - - /* The RTSP session identifier */ - CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), - - /* The RTSP stream URI */ - CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), - - /* The Transport: header to use in RTSP requests */ - CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), - - /* Manually initialize the client RTSP CSeq for this handle */ - CINIT(RTSP_CLIENT_CSEQ, LONG, 193), - - /* Manually initialize the server RTSP CSeq for this handle */ - CINIT(RTSP_SERVER_CSEQ, LONG, 194), - - /* The stream to pass to INTERLEAVEFUNCTION. */ - CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), - - /* Let the application define a custom write method for RTP data */ - CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), - - /* Turn on wildcard matching */ - CINIT(WILDCARDMATCH, LONG, 197), - - /* Directory matching callback called before downloading of an - individual file (chunk) started */ - CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), - - /* Directory matching callback called after the file (chunk) - was downloaded, or skipped */ - CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), - - /* Change match (fnmatch-like) callback for wildcard matching */ - CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), - - /* Let the application define custom chunk data pointer */ - CINIT(CHUNK_DATA, OBJECTPOINT, 201), - - /* FNMATCH_FUNCTION user pointer */ - CINIT(FNMATCH_DATA, OBJECTPOINT, 202), - - /* send linked-list of name:port:address sets */ - CINIT(RESOLVE, OBJECTPOINT, 203), - - /* Set a username for authenticated TLS */ - CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), - - /* Set a password for authenticated TLS */ - CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), - - /* Set authentication type for authenticated TLS */ - CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), - - /* Set to 1 to enable the "TE:" header in HTTP requests to ask for - compressed transfer-encoded responses. Set to 0 to disable the use of TE: - in outgoing requests. The current default is 0, but it might change in a - future libcurl release. - - libcurl will ask for the compressed methods it knows of, and if that - isn't any, it will not ask for transfer-encoding at all even if this - option is set to 1. - - */ - CINIT(TRANSFER_ENCODING, LONG, 207), - - /* Callback function for closing socket (instead of close(2)). The callback - should have type curl_closesocket_callback */ - CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), - CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), - - /* allow GSSAPI credential delegation */ - CINIT(GSSAPI_DELEGATION, LONG, 210), - - /* Set the name servers to use for DNS resolution */ - CINIT(DNS_SERVERS, STRINGPOINT, 211), - - /* Time-out accept operations (currently for FTP only) after this amount - of miliseconds. */ - CINIT(ACCEPTTIMEOUT_MS, LONG, 212), - - /* Set TCP keepalive */ - CINIT(TCP_KEEPALIVE, LONG, 213), - - /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ - CINIT(TCP_KEEPIDLE, LONG, 214), - CINIT(TCP_KEEPINTVL, LONG, 215), - - /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ - CINIT(SSL_OPTIONS, LONG, 216), - - /* Set the SMTP auth originator */ - CINIT(MAIL_AUTH, STRINGPOINT, 217), - - /* Enable/disable SASL initial response */ - CINIT(SASL_IR, LONG, 218), - - /* Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_xferinfo_callback - * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ - CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), - - /* The XOAUTH2 bearer token */ - CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), - - /* Set the interface string to use as outgoing network - * interface for DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_INTERFACE, STRINGPOINT, 221), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), - - /* Set the local IPv4 address to use for outgoing DNS requests. - * Only supported by the c-ares DNS backend */ - CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), - - /* Set authentication options directly */ - CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), - - /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ - CINIT(SSL_ENABLE_NPN, LONG, 225), - - /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ - CINIT(SSL_ENABLE_ALPN, LONG, 226), - - /* Time to wait for a response to a HTTP request containing an - * Expect: 100-continue header before sending the data anyway. */ - CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), - - /* This points to a linked list of headers used for proxy requests only, - struct curl_slist kind */ - CINIT(PROXYHEADER, OBJECTPOINT, 228), - - /* Pass in a bitmask of "header options" */ - CINIT(HEADEROPT, LONG, 229), - - /* The public key in DER form used to validate the peer public key - this option is used only if SSL_VERIFYPEER is true */ - CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), - - /* Path to Unix domain socket */ - CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), - - /* Set if we should verify the certificate status. */ - CINIT(SSL_VERIFYSTATUS, LONG, 232), - - /* Set if we should enable TLS false start. */ - CINIT(SSL_FALSESTART, LONG, 233), - - /* Do not squash dot-dot sequences */ - CINIT(PATH_AS_IS, LONG, 234), - - /* Proxy Service Name */ - CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), - - /* Service Name */ - CINIT(SERVICE_NAME, STRINGPOINT, 236), - - /* Wait/don't wait for pipe/mutex to clarify */ - CINIT(PIPEWAIT, LONG, 237), - - /* Set the protocol used when curl is given a URL without a protocol */ - CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), - - /* Set stream weight, 1 - 256 (default is 16) */ - CINIT(STREAM_WEIGHT, LONG, 239), - - /* Set stream dependency on another CURL handle */ - CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), - - /* Set E-xclusive stream dependency on another CURL handle */ - CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), - - /* Do not send any tftp option requests to the server */ - CINIT(TFTP_NO_OPTIONS, LONG, 242), - - /* Linked-list of host:port:connect-to-host:connect-to-port, - overrides the URL's host:port (only for the network layer) */ - CINIT(CONNECT_TO, OBJECTPOINT, 243), - - /* Set TCP Fast Open */ - CINIT(TCP_FASTOPEN, LONG, 244), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2011 */ - -/* This was added in version 7.19.1 */ -#define CURLOPT_POST301 CURLOPT_POSTREDIR - -/* These are scheduled to disappear by 2009 */ - -/* The following were added in 7.17.0 */ -#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_FTPAPPEND CURLOPT_APPEND -#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY -#define CURLOPT_FTP_SSL CURLOPT_USE_SSL - -/* The following were added earlier */ - -#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - - - /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ - - /* three convenient "aliases" that follow the name scheme better */ -#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER - - /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ -enum { - CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd - like the library to choose the best possible - for us! */ - CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ - CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ - CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ - CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 - Upgrade */ - - CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ -}; - -/* Convenience definition simple because the name of the version is HTTP/2 and - not 2.0. The 2_0 version of the enum name was set while the version was - still planned to be 2.0 and we stick to it for compatibility. */ -#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 - -/* - * Public API enums for RTSP requests - */ -enum { - CURL_RTSPREQ_NONE, /* first in list */ - CURL_RTSPREQ_OPTIONS, - CURL_RTSPREQ_DESCRIBE, - CURL_RTSPREQ_ANNOUNCE, - CURL_RTSPREQ_SETUP, - CURL_RTSPREQ_PLAY, - CURL_RTSPREQ_PAUSE, - CURL_RTSPREQ_TEARDOWN, - CURL_RTSPREQ_GET_PARAMETER, - CURL_RTSPREQ_SET_PARAMETER, - CURL_RTSPREQ_RECORD, - CURL_RTSPREQ_RECEIVE, - CURL_RTSPREQ_LAST /* last in list */ -}; - - /* These enums are for use with the CURLOPT_NETRC option. */ -enum CURL_NETRC_OPTION { - CURL_NETRC_IGNORED, /* The .netrc will never be read. - * This is the default. */ - CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred - * to one in the .netrc. */ - CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. - * Unless one is set programmatically, the .netrc - * will be queried. */ - CURL_NETRC_LAST -}; - -enum { - CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, /* TLS 1.x */ - CURL_SSLVERSION_SSLv2, - CURL_SSLVERSION_SSLv3, - CURL_SSLVERSION_TLSv1_0, - CURL_SSLVERSION_TLSv1_1, - CURL_SSLVERSION_TLSv1_2, - - CURL_SSLVERSION_LAST /* never use, keep last */ -}; - -enum CURL_TLSAUTH { - CURL_TLSAUTH_NONE, - CURL_TLSAUTH_SRP, - CURL_TLSAUTH_LAST /* never use, keep last */ -}; - -/* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 - can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 - | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ - -#define CURL_REDIR_GET_ALL 0 -#define CURL_REDIR_POST_301 1 -#define CURL_REDIR_POST_302 2 -#define CURL_REDIR_POST_303 4 -#define CURL_REDIR_POST_ALL \ - (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) - -typedef enum { - CURL_TIMECOND_NONE, - - CURL_TIMECOND_IFMODSINCE, - CURL_TIMECOND_IFUNMODSINCE, - CURL_TIMECOND_LASTMOD, - - CURL_TIMECOND_LAST -} curl_TimeCond; - - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - libcurl, see lib/README.curlx for details */ -CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); -CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); - -/* name is uppercase CURLFORM_ */ -#ifdef CFINIT -#undef CFINIT -#endif - -#ifdef CURL_ISOCPP -#define CFINIT(name) CURLFORM_ ## name -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define CFINIT(name) CURLFORM_/**/name -#endif - -typedef enum { - CFINIT(NOTHING), /********* the first one is unused ************/ - - /* */ - CFINIT(COPYNAME), - CFINIT(PTRNAME), - CFINIT(NAMELENGTH), - CFINIT(COPYCONTENTS), - CFINIT(PTRCONTENTS), - CFINIT(CONTENTSLENGTH), - CFINIT(FILECONTENT), - CFINIT(ARRAY), - CFINIT(OBSOLETE), - CFINIT(FILE), - - CFINIT(BUFFER), - CFINIT(BUFFERPTR), - CFINIT(BUFFERLENGTH), - - CFINIT(CONTENTTYPE), - CFINIT(CONTENTHEADER), - CFINIT(FILENAME), - CFINIT(END), - CFINIT(OBSOLETE2), - - CFINIT(STREAM), - CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ - - CURLFORM_LASTENTRY /* the last unused */ -} CURLformoption; - -#undef CFINIT /* done */ - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms { - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum { - CURL_FORMADD_OK, /* first, no error */ - - CURL_FORMADD_MEMORY, - CURL_FORMADD_OPTION_TWICE, - CURL_FORMADD_NULL, - CURL_FORMADD_UNKNOWN_OPTION, - CURL_FORMADD_INCOMPLETE, - CURL_FORMADD_ILLEGAL_ARRAY, - CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanced function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * callback function for curl_formget() - * The void *arg pointer will be the one passed as second argument to - * curl_formget(). - * The character buffer passed to it must not be freed. - * Should return the buffer length passed to it as the argument "len" on - * success. - */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, - size_t len); - -/* - * NAME curl_formget() - * - * DESCRIPTION - * - * Serialize a curl_httppost struct built with curl_formadd(). - * Accepts a void pointer as second argument which will be passed to - * the curl_formget_callback function. - * Returns 0 on success. - */ -CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append); -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -CURL_EXTERN void curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -CURL_EXTERN char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ascii string of the libcurl version. - */ -CURL_EXTERN char *curl_version(void); - -/* - * NAME curl_easy_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -CURL_EXTERN char *curl_easy_escape(CURL *handle, - const char *string, - int length); - -/* the previous version: */ -CURL_EXTERN char *curl_escape(const char *string, - int length); - - -/* - * NAME curl_easy_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - * Conversion Note: On non-ASCII platforms the ASCII %XX codes are - * converted into the host encoding. - */ -CURL_EXTERN char *curl_easy_unescape(CURL *handle, - const char *string, - int length, - int *outlength); - -/* the previous version */ -CURL_EXTERN char *curl_unescape(const char *string, - int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -CURL_EXTERN void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl and before any call of other libcurl functions. - * - * This function is not thread-safe! - */ -CURL_EXTERN CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for mis-use of the curl library etc. User registered - * callback routines with be invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURL_EXTERN CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -CURL_EXTERN void curl_global_cleanup(void); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist { - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it will be created - * first. Returns the new list, after appending. - */ -CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, - const char *); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -CURL_EXTERN void curl_slist_free_all(struct curl_slist *); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is unused - * and should be set to NULL. - */ -CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); - -/* info about the certificate chain, only for OpenSSL builds. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -struct curl_certinfo { - int num_of_certs; /* number of certificates with information */ - struct curl_slist **certinfo; /* for each index in this array, there's a - linked list with textual information in the - format "name: value" */ -}; - -/* enum for the different supported SSL backends */ -typedef enum { - CURLSSLBACKEND_NONE = 0, - CURLSSLBACKEND_OPENSSL = 1, - CURLSSLBACKEND_GNUTLS = 2, - CURLSSLBACKEND_NSS = 3, - CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ - CURLSSLBACKEND_GSKIT = 5, - CURLSSLBACKEND_POLARSSL = 6, - CURLSSLBACKEND_CYASSL = 7, - CURLSSLBACKEND_SCHANNEL = 8, - CURLSSLBACKEND_DARWINSSL = 9, - CURLSSLBACKEND_AXTLS = 10, - CURLSSLBACKEND_MBEDTLS = 11 -} curl_sslbackend; - -/* aliases for library clones and renames */ -#define CURLSSLBACKEND_LIBRESSL 1 -#define CURLSSLBACKEND_BORINGSSL 1 -#define CURLSSLBACKEND_WOLFSSL 6 - -/* Information about the SSL library used and the respective internal SSL - handle, which can be used to obtain further information regarding the - connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ -struct curl_tlssessioninfo { - curl_sslbackend backend; - void *internals; -}; - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_SLIST 0x400000 -#define CURLINFO_SOCKET 0x500000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum { - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, - CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, - CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, - CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, - CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, - CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, - CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, - CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, - CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, - CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_SLIST + 34, - CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, - CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, - CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, - CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, - CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, - CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, - CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, - CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, - CURLINFO_TLS_SESSION = CURLINFO_SLIST + 43, - CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, - CURLINFO_TLS_SSL_PTR = CURLINFO_SLIST + 45, - /* Fill in new entries below here! */ - - CURLINFO_LASTONE = 45 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum { - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1<<0) -#define CURL_GLOBAL_WIN32 (1<<1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL -#define CURL_GLOBAL_ACK_EINTR (1<<2) - - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum { - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internally to say that - * the locking is just made to change the internal state of the share - * itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum { - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - -typedef void CURLSH; - -typedef enum { - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* 4 out of memory */ - CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum { - CURLSHOPT_NONE, /* don't use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURL_EXTERN CURLSH *curl_share_init(void); -CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); -CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum { - CURLVERSION_FIRST, - CURLVERSION_SECOND, - CURLVERSION_THIRD, - CURLVERSION_FOURTH, - CURLVERSION_LAST /* never actually use this */ -} CURLversion; - -/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by - basically all programs ever that want to get version information. It is - meant to be a built-in version number for what kind of struct the caller - expects. If the struct ever changes, we redefine the NOW to another enum - from above. */ -#define CURLVERSION_NOW CURLVERSION_FOURTH - -typedef struct { - CURLversion age; /* age of the returned struct */ - const char *version; /* LIBCURL_VERSION */ - unsigned int version_num; /* LIBCURL_VERSION_NUM */ - const char *host; /* OS/host/cpu/machine when configured */ - int features; /* bitmask, see defines below */ - const char *ssl_version; /* human readable string */ - long ssl_version_num; /* not used anymore, always 0 */ - const char *libz_version; /* human readable string */ - /* protocols is terminated by an entry with a NULL protoname */ - const char * const *protocols; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was added in CURLVERSION_THIRD */ - const char *libidn; - - /* These field were added in CURLVERSION_FOURTH */ - - /* Same as '_libiconv_version' if built with HAVE_ICONV */ - int iconv_ver_num; - - const char *libssh_version; /* human readable string */ - -} curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported - (deprecated) */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported - (deprecated) */ -#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ -#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are - supported */ -#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ -#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ -#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ -#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper - is suported */ -#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ -#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ -#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ -#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ -#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used - for cookie domain verification */ - - /* - * NAME curl_version_info() - * - * DESCRIPTION - * - * This function returns a pointer to a static copy of the version info - * struct. See above. - */ -CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_easy_strerror(CURLcode); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_share_strerror(CURLSHcode); - -/* - * NAME curl_easy_pause() - * - * DESCRIPTION - * - * The curl_easy_pause function pauses or unpauses transfers. Select the new - * state by setting the bitmask, use the convenience defines below. - * - */ -CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); - -#define CURLPAUSE_RECV (1<<0) -#define CURLPAUSE_RECV_CONT (0) - -#define CURLPAUSE_SEND (1<<2) -#define CURLPAUSE_SEND_CONT (0) - -#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) -#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) - -#ifdef __cplusplus -} -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" - -/* the typechecker doesn't work in C++ (yet) */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ - !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) -#include "typecheck-gcc.h" -#else -#if defined(__STDC__) && (__STDC__ >= 1) -/* This preprocessor magic that replaces a call with the exact same call is - only done to make sure application authors pass exactly three arguments - to these functions. */ -#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) -#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) -#endif /* __STDC__ >= 1 */ -#endif /* gcc >= 4.3 && !__cplusplus */ - -#endif /* __CURL_CURL_H */ diff --git a/Externals/curl/include/curl/curlbuild.h b/Externals/curl/include/curl/curlbuild.h deleted file mode 100644 index ae95095fa5..0000000000 --- a/Externals/curl/include/curl/curlbuild.h +++ /dev/null @@ -1,586 +0,0 @@ -#ifndef __CURL_CURLBUILD_H -#define __CURL_CURLBUILD_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * See file include/curl/curlbuild.h.in, run configure, and forget - * that this file exists it is only used for non-configure systems. - * But you can keep reading if you want ;-) - * - */ - -/* ================================================================ */ -/* NOTES FOR NON-CONFIGURE SYSTEMS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * If you think that something actually needs to be changed, adjusted - * or fixed in this file, then, report it on the libcurl development - * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ - * - * Try to keep one section per platform, compiler and architecture, - * otherwise, if an existing section is reused for a different one and - * later on the original is adjusted, probably the piggybacking one can - * be adversely changed. - * - * In order to differentiate between platforms/compilers/architectures - * use only compiler built in predefined preprocessor symbols. - * - * This header file shall only export symbols which are 'curl' or 'CURL' - * prefixed, otherwise public name space would be polluted. - * - * NOTE 2: - * ------- - * - * For any given platform/compiler curl_off_t must be typedef'ed to a - * 64-bit wide signed integral data type. The width of this data type - * must remain constant and independent of any possible large file - * support settings. - * - * As an exception to the above, curl_off_t shall be typedef'ed to a - * 32-bit wide signed integral data type if there is no 64-bit type. - * - * As a general rule, curl_off_t shall not be mapped to off_t. This - * rule shall only be violated if off_t is the only 64-bit data type - * available and the size of off_t is independent of large file support - * settings. Keep your build on the safe side avoiding an off_t gating. - * If you have a 64-bit off_t then take for sure that another 64-bit - * data type exists, dig deeper and you will find it. - * - * NOTE 3: - * ------- - * - * Right now you might be staring at file include/curl/curlbuild.h.dist or - * at file include/curl/curlbuild.h, this is due to the following reason: - * file include/curl/curlbuild.h.dist is renamed to include/curl/curlbuild.h - * when the libcurl source code distribution archive file is created. - * - * File include/curl/curlbuild.h.dist is not included in the distribution - * archive. File include/curl/curlbuild.h is not present in the git tree. - * - * The distributed include/curl/curlbuild.h file is only intended to be used - * on systems which can not run the also distributed configure script. - * - * On systems capable of running the configure script, the configure process - * will overwrite the distributed include/curl/curlbuild.h file with one that - * is suitable and specific to the library being configured and built, which - * is generated from the include/curl/curlbuild.h.in template file. - * - * If you check out from git on a non-configure platform, you must run the - * appropriate buildconf* script to set up curlbuild.h and other local files. - * - */ - -/* ================================================================ */ -/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ -/* ================================================================ */ - -#ifdef CURL_SIZEOF_LONG -# error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T -# error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_SOCKLEN_T -# error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_OFF_T -# error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_T -# error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_TU -# error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined -#endif - -#ifdef CURL_FORMAT_OFF_T -# error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_OFF_T -# error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_T -# error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_TU -# error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined -#endif - -/* ================================================================ */ -/* EXTERNAL INTERFACE SETTINGS FOR NON-CONFIGURE SYSTEMS ONLY */ -/* ================================================================ */ - -#if defined(__DJGPP__) || defined(__GO32__) -# if defined(__DJGPP__) && (__DJGPP__ > 1) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# else -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__SALFORDC__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__BORLANDC__) -# if (__BORLANDC__ < 0x520) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_FORMAT_OFF_T "%I64d" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__TURBOC__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__WATCOMC__) -# if defined(__386__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_FORMAT_OFF_T "%I64d" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__POCC__) -# if (__POCC__ < 280) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# elif defined(_MSC_VER) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_FORMAT_OFF_T "%I64d" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__LCC__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__SYMBIAN32__) -# if defined(__EABI__) /* Treat all ARM compilers equally */ -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__CW32__) -# pragma longlong on -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__VC32__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__MWERKS__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(_WIN32_WCE) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_FORMAT_OFF_T "%I64d" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__MINGW32__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_FORMAT_OFF_T "%I64d" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__VMS) -# if defined(__VAX) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T unsigned int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -#elif defined(__OS400__) -# if defined(__ILEC400__) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(__MVS__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_ILP32) -# define CURL_SIZEOF_LONG 4 -# elif defined(_LP64) -# define CURL_SIZEOF_LONG 8 -# endif -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(__370__) -# if defined(__IBMC__) || defined(__IBMCPP__) -# if defined(_ILP32) -# define CURL_SIZEOF_LONG 4 -# elif defined(_LP64) -# define CURL_SIZEOF_LONG 8 -# endif -# if defined(_LONG_LONG) -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(_LP64) -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# else -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 -# endif - -#elif defined(TPF) -# define CURL_SIZEOF_LONG 8 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -/* ===================================== */ -/* KEEP MSVC THE PENULTIMATE ENTRY */ -/* ===================================== */ - -#elif defined(_MSC_VER) -# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T __int64 -# define CURL_FORMAT_CURL_OFF_T "I64d" -# define CURL_FORMAT_CURL_OFF_TU "I64u" -# define CURL_FORMAT_OFF_T "%I64d" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T i64 -# define CURL_SUFFIX_CURL_OFF_TU ui64 -# else -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 4 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T int -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -/* ===================================== */ -/* KEEP GENERIC GCC THE LAST ENTRY */ -/* ===================================== */ - -#elif defined(__GNUC__) -# if !defined(__LP64__) && (defined(__ILP32__) || \ - defined(__i386__) || defined(__ppc__) || defined(__arm__) || \ - defined(__sparc__) || defined(__mips__) || defined(__sh__)) -# define CURL_SIZEOF_LONG 4 -# define CURL_TYPEOF_CURL_OFF_T long long -# define CURL_FORMAT_CURL_OFF_T "lld" -# define CURL_FORMAT_CURL_OFF_TU "llu" -# define CURL_FORMAT_OFF_T "%lld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T LL -# define CURL_SUFFIX_CURL_OFF_TU ULL -# elif defined(__LP64__) || \ - defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) -# define CURL_SIZEOF_LONG 8 -# define CURL_TYPEOF_CURL_OFF_T long -# define CURL_FORMAT_CURL_OFF_T "ld" -# define CURL_FORMAT_CURL_OFF_TU "lu" -# define CURL_FORMAT_OFF_T "%ld" -# define CURL_SIZEOF_CURL_OFF_T 8 -# define CURL_SUFFIX_CURL_OFF_T L -# define CURL_SUFFIX_CURL_OFF_TU UL -# endif -# define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t -# define CURL_SIZEOF_CURL_SOCKLEN_T 4 -# define CURL_PULL_SYS_TYPES_H 1 -# define CURL_PULL_SYS_SOCKET_H 1 - -#else -# error "Unknown non-configure build target!" - Error Compilation_aborted_Unknown_non_configure_build_target -#endif - -/* CURL_PULL_SYS_TYPES_H is defined above when inclusion of header file */ -/* sys/types.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* CURL_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ -/* sys/socket.h is required here to properly make type definitions below. */ -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* Data type definition of curl_socklen_t. */ - -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T - typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; -#endif - -/* Data type definition of curl_off_t. */ - -#ifdef CURL_TYPEOF_CURL_OFF_T - typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; -#endif - -#endif /* __CURL_CURLBUILD_H */ diff --git a/Externals/curl/include/curl/curlbuild.h.cmake b/Externals/curl/include/curl/curlbuild.h.cmake deleted file mode 100644 index bbb31a9408..0000000000 --- a/Externals/curl/include/curl/curlbuild.h.cmake +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef __CURL_CURLBUILD_H -#define __CURL_CURLBUILD_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * If you think that something actually needs to be changed, adjusted - * or fixed in this file, then, report it on the libcurl development - * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ - * - * This header file shall only export symbols which are 'curl' or 'CURL' - * prefixed, otherwise public name space would be polluted. - * - * NOTE 2: - * ------- - * - * Right now you might be staring at file include/curl/curlbuild.h.in or - * at file include/curl/curlbuild.h, this is due to the following reason: - * - * On systems capable of running the configure script, the configure process - * will overwrite the distributed include/curl/curlbuild.h file with one that - * is suitable and specific to the library being configured and built, which - * is generated from the include/curl/curlbuild.h.in template file. - * - */ - -/* ================================================================ */ -/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ -/* ================================================================ */ - -#ifdef CURL_SIZEOF_LONG -#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T -#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_SOCKLEN_T -#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_OFF_T -#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_T -#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_TU -#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined -#endif - -#ifdef CURL_FORMAT_OFF_T -#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_OFF_T -#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_T -#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_TU -#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined -#endif - -/* ================================================================ */ -/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ -/* ================================================================ */ - -/* Configure process defines this to 1 when it finds out that system */ -/* header file ws2tcpip.h must be included by the external interface. */ -#cmakedefine CURL_PULL_WS2TCPIP_H -#ifdef CURL_PULL_WS2TCPIP_H -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/types.h must be included by the external interface. */ -#cmakedefine CURL_PULL_SYS_TYPES_H -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file stdint.h must be included by the external interface. */ -#cmakedefine CURL_PULL_STDINT_H -#ifdef CURL_PULL_STDINT_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file inttypes.h must be included by the external interface. */ -#cmakedefine CURL_PULL_INTTYPES_H -#ifdef CURL_PULL_INTTYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/socket.h must be included by the external interface. */ -#cmakedefine CURL_PULL_SYS_SOCKET_H -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/poll.h must be included by the external interface. */ -#cmakedefine CURL_PULL_SYS_POLL_H -#ifdef CURL_PULL_SYS_POLL_H -# include -#endif - -/* The size of `long', as computed by sizeof. */ -#define CURL_SIZEOF_LONG ${CURL_SIZEOF_LONG} - -/* Integral data type used for curl_socklen_t. */ -#define CURL_TYPEOF_CURL_SOCKLEN_T ${CURL_TYPEOF_CURL_SOCKLEN_T} - -/* The size of `curl_socklen_t', as computed by sizeof. */ -#define CURL_SIZEOF_CURL_SOCKLEN_T ${CURL_SIZEOF_CURL_SOCKLEN_T} - -/* Data type definition of curl_socklen_t. */ -typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; - -/* Signed integral data type used for curl_off_t. */ -#define CURL_TYPEOF_CURL_OFF_T ${CURL_TYPEOF_CURL_OFF_T} - -/* Data type definition of curl_off_t. */ -typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; - -/* curl_off_t formatting string directive without "%" conversion specifier. */ -#define CURL_FORMAT_CURL_OFF_T "${CURL_FORMAT_CURL_OFF_T}" - -/* unsigned curl_off_t formatting string without "%" conversion specifier. */ -#define CURL_FORMAT_CURL_OFF_TU "${CURL_FORMAT_CURL_OFF_TU}" - -/* curl_off_t formatting string directive with "%" conversion specifier. */ -#define CURL_FORMAT_OFF_T "${CURL_FORMAT_OFF_T}" - -/* The size of `curl_off_t', as computed by sizeof. */ -#define CURL_SIZEOF_CURL_OFF_T ${CURL_SIZEOF_CURL_OFF_T} - -/* curl_off_t constant suffix. */ -#define CURL_SUFFIX_CURL_OFF_T ${CURL_SUFFIX_CURL_OFF_T} - -/* unsigned curl_off_t constant suffix. */ -#define CURL_SUFFIX_CURL_OFF_TU ${CURL_SUFFIX_CURL_OFF_TU} - -#endif /* __CURL_CURLBUILD_H */ diff --git a/Externals/curl/include/curl/curlbuild.h.in b/Externals/curl/include/curl/curlbuild.h.in deleted file mode 100644 index ffab356709..0000000000 --- a/Externals/curl/include/curl/curlbuild.h.in +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef __CURL_CURLBUILD_H -#define __CURL_CURLBUILD_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * If you think that something actually needs to be changed, adjusted - * or fixed in this file, then, report it on the libcurl development - * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ - * - * This header file shall only export symbols which are 'curl' or 'CURL' - * prefixed, otherwise public name space would be polluted. - * - * NOTE 2: - * ------- - * - * Right now you might be staring at file include/curl/curlbuild.h.in or - * at file include/curl/curlbuild.h, this is due to the following reason: - * - * On systems capable of running the configure script, the configure process - * will overwrite the distributed include/curl/curlbuild.h file with one that - * is suitable and specific to the library being configured and built, which - * is generated from the include/curl/curlbuild.h.in template file. - * - */ - -/* ================================================================ */ -/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ -/* ================================================================ */ - -#ifdef CURL_SIZEOF_LONG -#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T -#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_SOCKLEN_T -#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_OFF_T -#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_T -#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_TU -#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined -#endif - -#ifdef CURL_FORMAT_OFF_T -#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_OFF_T -#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_T -#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_TU -#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined -#endif - -/* ================================================================ */ -/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ -/* ================================================================ */ - -/* Configure process defines this to 1 when it finds out that system */ -/* header file ws2tcpip.h must be included by the external interface. */ -#undef CURL_PULL_WS2TCPIP_H -#ifdef CURL_PULL_WS2TCPIP_H -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/types.h must be included by the external interface. */ -#undef CURL_PULL_SYS_TYPES_H -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file stdint.h must be included by the external interface. */ -#undef CURL_PULL_STDINT_H -#ifdef CURL_PULL_STDINT_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file inttypes.h must be included by the external interface. */ -#undef CURL_PULL_INTTYPES_H -#ifdef CURL_PULL_INTTYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/socket.h must be included by the external interface. */ -#undef CURL_PULL_SYS_SOCKET_H -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/poll.h must be included by the external interface. */ -#undef CURL_PULL_SYS_POLL_H -#ifdef CURL_PULL_SYS_POLL_H -# include -#endif - -/* The size of `long', as computed by sizeof. */ -#undef CURL_SIZEOF_LONG - -/* Integral data type used for curl_socklen_t. */ -#undef CURL_TYPEOF_CURL_SOCKLEN_T - -/* The size of `curl_socklen_t', as computed by sizeof. */ -#undef CURL_SIZEOF_CURL_SOCKLEN_T - -/* Data type definition of curl_socklen_t. */ -typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; - -/* Signed integral data type used for curl_off_t. */ -#undef CURL_TYPEOF_CURL_OFF_T - -/* Data type definition of curl_off_t. */ -typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; - -/* curl_off_t formatting string directive without "%" conversion specifier. */ -#undef CURL_FORMAT_CURL_OFF_T - -/* unsigned curl_off_t formatting string without "%" conversion specifier. */ -#undef CURL_FORMAT_CURL_OFF_TU - -/* curl_off_t formatting string directive with "%" conversion specifier. */ -#undef CURL_FORMAT_OFF_T - -/* The size of `curl_off_t', as computed by sizeof. */ -#undef CURL_SIZEOF_CURL_OFF_T - -/* curl_off_t constant suffix. */ -#undef CURL_SUFFIX_CURL_OFF_T - -/* unsigned curl_off_t constant suffix. */ -#undef CURL_SUFFIX_CURL_OFF_TU - -#endif /* __CURL_CURLBUILD_H */ diff --git a/Externals/curl/include/curl/curlrules.h b/Externals/curl/include/curl/curlrules.h deleted file mode 100644 index 55d21f68f1..0000000000 --- a/Externals/curl/include/curl/curlrules.h +++ /dev/null @@ -1,262 +0,0 @@ -#ifndef __CURL_CURLRULES_H -#define __CURL_CURLRULES_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* COMPILE TIME SANITY CHECKS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * All checks done in this file are intentionally placed in a public - * header file which is pulled by curl/curl.h when an application is - * being built using an already built libcurl library. Additionally - * this file is also included and used when building the library. - * - * If compilation fails on this file it is certainly sure that the - * problem is elsewhere. It could be a problem in the curlbuild.h - * header file, or simply that you are using different compilation - * settings than those used to build the library. - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * Do not deactivate any check, these are done to make sure that the - * library is properly built and used. - * - * You can find further help on the libcurl development mailing list: - * https://cool.haxx.se/mailman/listinfo/curl-library/ - * - * NOTE 2 - * ------ - * - * Some of the following compile time checks are based on the fact - * that the dimension of a constant array can not be a negative one. - * In this way if the compile time verification fails, the compilation - * will fail issuing an error. The error description wording is compiler - * dependent but it will be quite similar to one of the following: - * - * "negative subscript or subscript is too large" - * "array must have at least one element" - * "-1 is an illegal array size" - * "size of array is negative" - * - * If you are building an application which tries to use an already - * built libcurl library and you are getting this kind of errors on - * this file, it is a clear indication that there is a mismatch between - * how the library was built and how you are trying to use it for your - * application. Your already compiled or binary library provider is the - * only one who can give you the details you need to properly use it. - */ - -/* - * Verify that some macros are actually defined. - */ - -#ifndef CURL_SIZEOF_LONG -# error "CURL_SIZEOF_LONG definition is missing!" - Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing -#endif - -#ifndef CURL_TYPEOF_CURL_SOCKLEN_T -# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" - Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing -#endif - -#ifndef CURL_SIZEOF_CURL_SOCKLEN_T -# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" - Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing -#endif - -#ifndef CURL_TYPEOF_CURL_OFF_T -# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_FORMAT_CURL_OFF_T -# error "CURL_FORMAT_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_FORMAT_CURL_OFF_TU -# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" - Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing -#endif - -#ifndef CURL_FORMAT_OFF_T -# error "CURL_FORMAT_OFF_T definition is missing!" - Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing -#endif - -#ifndef CURL_SIZEOF_CURL_OFF_T -# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_SUFFIX_CURL_OFF_T -# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_SUFFIX_CURL_OFF_TU -# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" - Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing -#endif - -/* - * Macros private to this header file. - */ - -#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 - -#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 - -/* - * Verify that the size previously defined and expected for long - * is the same as the one reported by sizeof() at compile time. - */ - -typedef char - __curl_rule_01__ - [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; - -/* - * Verify that the size previously defined and expected for - * curl_off_t is actually the the same as the one reported - * by sizeof() at compile time. - */ - -typedef char - __curl_rule_02__ - [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; - -/* - * Verify at compile time that the size of curl_off_t as reported - * by sizeof() is greater or equal than the one reported for long - * for the current compilation. - */ - -typedef char - __curl_rule_03__ - [CurlchkszGE(curl_off_t, long)]; - -/* - * Verify that the size previously defined and expected for - * curl_socklen_t is actually the the same as the one reported - * by sizeof() at compile time. - */ - -typedef char - __curl_rule_04__ - [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; - -/* - * Verify at compile time that the size of curl_socklen_t as reported - * by sizeof() is greater or equal than the one reported for int for - * the current compilation. - */ - -typedef char - __curl_rule_05__ - [CurlchkszGE(curl_socklen_t, int)]; - -/* ================================================================ */ -/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ -/* ================================================================ */ - -/* - * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow - * these to be visible and exported by the external libcurl interface API, - * while also making them visible to the library internals, simply including - * curl_setup.h, without actually needing to include curl.h internally. - * If some day this section would grow big enough, all this should be moved - * to its own header file. - */ - -/* - * Figure out if we can use the ## preprocessor operator, which is supported - * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ - * or __cplusplus so we need to carefully check for them too. - */ - -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ - defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ - defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ - defined(__ILEC400__) - /* This compiler is believed to have an ISO compatible preprocessor */ -#define CURL_ISOCPP -#else - /* This compiler is believed NOT to have an ISO compatible preprocessor */ -#undef CURL_ISOCPP -#endif - -/* - * Macros for minimum-width signed and unsigned curl_off_t integer constants. - */ - -#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) -# define __CURL_OFF_T_C_HLPR2(x) x -# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) -#else -# ifdef CURL_ISOCPP -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix -# else -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix -# endif -# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) -#endif - -/* - * Get rid of macros private to this header file. - */ - -#undef CurlchkszEQ -#undef CurlchkszGE - -/* - * Get rid of macros not intended to exist beyond this point. - */ - -#undef CURL_PULL_WS2TCPIP_H -#undef CURL_PULL_SYS_TYPES_H -#undef CURL_PULL_SYS_SOCKET_H -#undef CURL_PULL_SYS_POLL_H -#undef CURL_PULL_STDINT_H -#undef CURL_PULL_INTTYPES_H - -#undef CURL_TYPEOF_CURL_SOCKLEN_T -#undef CURL_TYPEOF_CURL_OFF_T - -#ifdef CURL_NO_OLDIES -#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ -#endif - -#endif /* __CURL_CURLRULES_H */ diff --git a/Externals/curl/include/curl/curlver.h b/Externals/curl/include/curl/curlver.h deleted file mode 100644 index 4e0bc22c88..0000000000 --- a/Externals/curl/include/curl/curlver.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef __CURL_CURLVER_H -#define __CURL_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2016 Daniel Stenberg, ." - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "7.49.1" - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 49 -#define LIBCURL_VERSION_PATCH 1 - -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparions by programs. The LIBCURL_VERSION_NUM define will - always follow this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal (using 8 bits each). All three numbers are always represented - using two digits. 1.2 would appear as "0x010200" while version 9.11.7 - appears as "0x090b07". - - This 6-digit (24 bits) hexadecimal number does not show pre-release number, - and it is always a greater number in a more recent release. It makes - comparisons with greater than and less than work. - - Note: This define is the full hex number and _does not_ use the - CURL_VERSION_BITS() macro since curl's own configure script greps for it - and needs it to contain the full number. -*/ -#define LIBCURL_VERSION_NUM 0x073101 - -/* - * This is the date and time when the full source package was created. The - * timestamp is not stored in git, as the timestamp is properly set in the - * tarballs by the maketgz script. - * - * The format of the date should follow this template: - * - * "Mon Feb 12 11:35:33 UTC 2007" - */ -#define LIBCURL_TIMESTAMP "Mon May 30 06:15:46 UTC 2016" - -#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) -#define CURL_AT_LEAST_VERSION(x,y,z) \ - (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) - -#endif /* __CURL_CURLVER_H */ diff --git a/Externals/curl/include/curl/easy.h b/Externals/curl/include/curl/easy.h deleted file mode 100644 index afc766cd2d..0000000000 --- a/Externals/curl/include/curl/easy.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __CURL_EASY_H -#define __CURL_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN CURL *curl_easy_init(void); -CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); -CURL_EXTERN void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. The - * third argument MUST be a pointer to a long, a pointer to a char * or a - * pointer to a double (as the documentation describes elsewhere). The data - * pointed to will be filled in accordingly and can be relied upon only if the - * function returns CURLE_OK. This function is intended to get used *AFTER* a - * performed transfer, all results from this function are undefined until the - * transfer is completed. - */ -CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistent connections cannot - * be transferred. It is useful in multithreaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a CURL handle to the default values. This puts back the - * handle to the same state as it was in when it was just created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -CURL_EXTERN void curl_easy_reset(CURL *curl); - -/* - * NAME curl_easy_recv() - * - * DESCRIPTION - * - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, - size_t *n); - -/* - * NAME curl_easy_send() - * - * DESCRIPTION - * - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, - size_t buflen, size_t *n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Externals/curl/include/curl/mprintf.h b/Externals/curl/include/curl/mprintf.h deleted file mode 100644 index e20f546e19..0000000000 --- a/Externals/curl/include/curl/mprintf.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __CURL_MPRINTF_H -#define __CURL_MPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include -#include /* needed for FILE */ -#include "curl.h" /* for CURL_EXTERN */ - -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN int curl_mprintf(const char *format, ...); -CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); -CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); -CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, - const char *format, ...); -CURL_EXTERN int curl_mvprintf(const char *format, va_list args); -CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); -CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); -CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, - const char *format, va_list args); -CURL_EXTERN char *curl_maprintf(const char *format, ...); -CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); - -#ifdef __cplusplus -} -#endif - -#endif /* __CURL_MPRINTF_H */ diff --git a/Externals/curl/include/curl/multi.h b/Externals/curl/include/curl/multi.h deleted file mode 100644 index 0fbbd96f09..0000000000 --- a/Externals/curl/include/curl/multi.h +++ /dev/null @@ -1,435 +0,0 @@ -#ifndef __CURL_MULTI_H -#define __CURL_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* - This is an "external" header file. Don't give away any internals here! - - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ - -/* - * This header file should not really need to include "curl.h" since curl.h - * itself includes this file and we expect user applications to do #include - * without the need for especially including multi.h. - * - * For some reason we added this include here at one point, and rather than to - * break existing (wrongly written) libcurl applications, we leave it as-is - * but with this warning attached. - */ -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURLM; - -typedef enum { - CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or - curl_multi_socket*() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ - CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ - CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was - attempted to get added - again */ - CURLM_LAST -} CURLMcode; - -/* just to make code nicer when using curl_multi_socket() you can now check - for CURLM_CALL_MULTI_SOCKET too in the same style it works for - curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ -#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM - -/* bitmask bits for CURLMOPT_PIPELINING */ -#define CURLPIPE_NOTHING 0L -#define CURLPIPE_HTTP1 1L -#define CURLPIPE_MULTIPLEX 2L - -typedef enum { - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg { - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* Based on poll(2) structure and values. - * We don't use pollfd and POLL* constants explicitly - * to cover platforms without poll(). */ -#define CURL_WAIT_POLLIN 0x0001 -#define CURL_WAIT_POLLPRI 0x0002 -#define CURL_WAIT_POLLOUT 0x0004 - -struct curl_waitfd { - curl_socket_t fd; - short events; - short revents; /* not supported yet */ -}; - -/* - * Name: curl_multi_init() - * - * Desc: inititalize multi-style curl usage - * - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURL_EXTERN CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle); - - /* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - -/* - * Name: curl_multi_wait() - * - * Desc: Poll on all fds within a CURLM set as well as any - * additional fds passed to the function. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret); - - /* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there's data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called just in case. It returns - * the number of handles that still transfer data in the second - * argument's integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. - */ -CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, - int *running_handles); - - /* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles will be if this function is called - * in the middle of a transfer. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there's any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or just the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function will return a new struct each - * time, until a special "end of msgs" struct is returned as a signal - * that there is no more to get at this point. - * - * The data the returned pointer points to will not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic informations. If more involved information is wanted, - * we will provide the particular "transfer handle" in that struct - * and that should/could/would be used in subsequent - * curl_easy_getinfo() calls (or similar). The point being that we - * must never expose complex structs to applications, as then we'll - * undoubtably get backwards compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, - int *msgs_in_queue); - -/* - * Name: curl_multi_strerror() - * - * Desc: The curl_multi_strerror function may be used to turn a CURLMcode - * value into the equivalent human readable error string. This is - * useful for printing meaningful error messages. - * - * Returns: A pointer to a zero-terminated error message. - */ -CURL_EXTERN const char *curl_multi_strerror(CURLMcode); - -/* - * Name: curl_multi_socket() and - * curl_multi_socket_all() - * - * Desc: An alternative version of curl_multi_perform() that allows the - * application to pass in one of the file descriptors that have been - * detected to have "action" on them and let libcurl perform. - * See man page for details. - */ -#define CURL_POLL_NONE 0 -#define CURL_POLL_IN 1 -#define CURL_POLL_OUT 2 -#define CURL_POLL_INOUT 3 -#define CURL_POLL_REMOVE 4 - -#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD - -#define CURL_CSELECT_IN 0x01 -#define CURL_CSELECT_OUT 0x02 -#define CURL_CSELECT_ERR 0x04 - -typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp); /* private socket - pointer */ -/* - * Name: curl_multi_timer_callback - * - * Desc: Called by libcurl whenever the library detects a change in the - * maximum number of milliseconds the app is allowed to wait before - * curl_multi_socket() or curl_multi_perform() must be called - * (to allow libcurl's timed events to take place). - * - * Returns: The callback should return zero. - */ -typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp); /* private callback - pointer */ - -CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, - curl_socket_t s, - int ev_bitmask, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, - int *running_handles); - -#ifndef CURL_ALLOW_OLD_MULTI_SOCKET -/* This macro below was added in 7.16.3 to push users who recompile to use - the new curl_multi_socket_action() instead of the old curl_multi_socket() -*/ -#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) -#endif - -/* - * Name: curl_multi_timeout() - * - * Desc: Returns the maximum number of milliseconds the app is allowed to - * wait before curl_multi_socket() or curl_multi_perform() must be - * called (to allow libcurl's timed events to take place). - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, - long *milliseconds); - -#undef CINIT /* re-using the same name as in curl.h */ - -#ifdef CURL_ISOCPP -#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLMOPT_/**/name = type + number -#endif - -typedef enum { - /* This is the socket callback function pointer */ - CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), - - /* This is the argument passed to the socket callback */ - CINIT(SOCKETDATA, OBJECTPOINT, 2), - - /* set to 1 to enable pipelining for this multi handle */ - CINIT(PIPELINING, LONG, 3), - - /* This is the timer callback function pointer */ - CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), - - /* This is the argument passed to the timer callback */ - CINIT(TIMERDATA, OBJECTPOINT, 5), - - /* maximum number of entries in the connection cache */ - CINIT(MAXCONNECTS, LONG, 6), - - /* maximum number of (pipelining) connections to one host */ - CINIT(MAX_HOST_CONNECTIONS, LONG, 7), - - /* maximum number of requests in a pipeline */ - CINIT(MAX_PIPELINE_LENGTH, LONG, 8), - - /* a connection with a content-length longer than this - will not be considered for pipelining */ - CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), - - /* a connection with a chunk length longer than this - will not be considered for pipelining */ - CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), - - /* a list of site names(+port) that are blacklisted from - pipelining */ - CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), - - /* a list of server types that are blacklisted from - pipelining */ - CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), - - /* maximum number of open connections in total */ - CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), - - /* This is the server push callback function pointer */ - CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), - - /* This is the argument passed to the server push callback */ - CINIT(PUSHDATA, OBJECTPOINT, 15), - - CURLMOPT_LASTENTRY /* the last unused */ -} CURLMoption; - - -/* - * Name: curl_multi_setopt() - * - * Desc: Sets options for the multi handle. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, - CURLMoption option, ...); - - -/* - * Name: curl_multi_assign() - * - * Desc: This function sets an association in the multi handle between the - * given socket and a private pointer of the application. This is - * (only) useful for curl_multi_socket uses. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, - curl_socket_t sockfd, void *sockp); - - -/* - * Name: curl_push_callback - * - * Desc: This callback gets called when a new stream is being pushed by the - * server. It approves or denies the new stream. - * - * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. - */ -#define CURL_PUSH_OK 0 -#define CURL_PUSH_DENY 1 - -struct curl_pushheaders; /* forward declaration only */ - -CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, - size_t num); -CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, - const char *name); - -typedef int (*curl_push_callback)(CURL *parent, - CURL *easy, - size_t num_headers, - struct curl_pushheaders *headers, - void *userp); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/Externals/curl/include/curl/stdcheaders.h b/Externals/curl/include/curl/stdcheaders.h deleted file mode 100644 index 6f0f7f3435..0000000000 --- a/Externals/curl/include/curl/stdcheaders.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __STDC_HEADERS_H -#define __STDC_HEADERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -size_t fread (void *, size_t, size_t, FILE *); -size_t fwrite (const void *, size_t, size_t, FILE *); - -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); - -#endif /* __STDC_HEADERS_H */ diff --git a/Externals/curl/include/curl/typecheck-gcc.h b/Externals/curl/include/curl/typecheck-gcc.h deleted file mode 100644 index 6ec8bcfd4f..0000000000 --- a/Externals/curl/include/curl/typecheck-gcc.h +++ /dev/null @@ -1,622 +0,0 @@ -#ifndef __CURL_TYPECHECK_GCC_H -#define __CURL_TYPECHECK_GCC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* wraps curl_easy_setopt() with typechecking */ - -/* To add a new kind of warning, add an - * if(_curl_is_sometype_option(_curl_opt)) - * if(!_curl_is_sometype(value)) - * _curl_easy_setopt_err_sometype(); - * block and define _curl_is_sometype_option, _curl_is_sometype and - * _curl_easy_setopt_err_sometype below - * - * NOTE: We use two nested 'if' statements here instead of the && operator, in - * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x - * when compiling with -Wlogical-op. - * - * To add an option that uses the same type as an existing option, you'll just - * need to extend the appropriate _curl_*_option macro - */ -#define curl_easy_setopt(handle, option, value) \ -__extension__ ({ \ - __typeof__ (option) _curl_opt = option; \ - if(__builtin_constant_p(_curl_opt)) { \ - if(_curl_is_long_option(_curl_opt)) \ - if(!_curl_is_long(value)) \ - _curl_easy_setopt_err_long(); \ - if(_curl_is_off_t_option(_curl_opt)) \ - if(!_curl_is_off_t(value)) \ - _curl_easy_setopt_err_curl_off_t(); \ - if(_curl_is_string_option(_curl_opt)) \ - if(!_curl_is_string(value)) \ - _curl_easy_setopt_err_string(); \ - if(_curl_is_write_cb_option(_curl_opt)) \ - if(!_curl_is_write_cb(value)) \ - _curl_easy_setopt_err_write_callback(); \ - if((_curl_opt) == CURLOPT_READFUNCTION) \ - if(!_curl_is_read_cb(value)) \ - _curl_easy_setopt_err_read_cb(); \ - if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ - if(!_curl_is_ioctl_cb(value)) \ - _curl_easy_setopt_err_ioctl_cb(); \ - if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ - if(!_curl_is_sockopt_cb(value)) \ - _curl_easy_setopt_err_sockopt_cb(); \ - if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ - if(!_curl_is_opensocket_cb(value)) \ - _curl_easy_setopt_err_opensocket_cb(); \ - if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ - if(!_curl_is_progress_cb(value)) \ - _curl_easy_setopt_err_progress_cb(); \ - if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ - if(!_curl_is_debug_cb(value)) \ - _curl_easy_setopt_err_debug_cb(); \ - if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ - if(!_curl_is_ssl_ctx_cb(value)) \ - _curl_easy_setopt_err_ssl_ctx_cb(); \ - if(_curl_is_conv_cb_option(_curl_opt)) \ - if(!_curl_is_conv_cb(value)) \ - _curl_easy_setopt_err_conv_cb(); \ - if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ - if(!_curl_is_seek_cb(value)) \ - _curl_easy_setopt_err_seek_cb(); \ - if(_curl_is_cb_data_option(_curl_opt)) \ - if(!_curl_is_cb_data(value)) \ - _curl_easy_setopt_err_cb_data(); \ - if((_curl_opt) == CURLOPT_ERRORBUFFER) \ - if(!_curl_is_error_buffer(value)) \ - _curl_easy_setopt_err_error_buffer(); \ - if((_curl_opt) == CURLOPT_STDERR) \ - if(!_curl_is_FILE(value)) \ - _curl_easy_setopt_err_FILE(); \ - if(_curl_is_postfields_option(_curl_opt)) \ - if(!_curl_is_postfields(value)) \ - _curl_easy_setopt_err_postfields(); \ - if((_curl_opt) == CURLOPT_HTTPPOST) \ - if(!_curl_is_arr((value), struct curl_httppost)) \ - _curl_easy_setopt_err_curl_httpost(); \ - if(_curl_is_slist_option(_curl_opt)) \ - if(!_curl_is_arr((value), struct curl_slist)) \ - _curl_easy_setopt_err_curl_slist(); \ - if((_curl_opt) == CURLOPT_SHARE) \ - if(!_curl_is_ptr((value), CURLSH)) \ - _curl_easy_setopt_err_CURLSH(); \ - } \ - curl_easy_setopt(handle, _curl_opt, value); \ -}) - -/* wraps curl_easy_getinfo() with typechecking */ -/* FIXME: don't allow const pointers */ -#define curl_easy_getinfo(handle, info, arg) \ -__extension__ ({ \ - __typeof__ (info) _curl_info = info; \ - if(__builtin_constant_p(_curl_info)) { \ - if(_curl_is_string_info(_curl_info)) \ - if(!_curl_is_arr((arg), char *)) \ - _curl_easy_getinfo_err_string(); \ - if(_curl_is_long_info(_curl_info)) \ - if(!_curl_is_arr((arg), long)) \ - _curl_easy_getinfo_err_long(); \ - if(_curl_is_double_info(_curl_info)) \ - if(!_curl_is_arr((arg), double)) \ - _curl_easy_getinfo_err_double(); \ - if(_curl_is_slist_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_slist *)) \ - _curl_easy_getinfo_err_curl_slist(); \ - } \ - curl_easy_getinfo(handle, _curl_info, arg); \ -}) - -/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), - * for now just make sure that the functions are called with three - * arguments - */ -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) - - -/* the actual warnings, triggered by calling the _curl_easy_setopt_err* - * functions */ - -/* To define a new warning, use _CURL_WARNING(identifier, "message") */ -#define _CURL_WARNING(id, message) \ - static void __attribute__((__warning__(message))) \ - __attribute__((__unused__)) __attribute__((__noinline__)) \ - id(void) { __asm__(""); } - -_CURL_WARNING(_curl_easy_setopt_err_long, - "curl_easy_setopt expects a long argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, - "curl_easy_setopt expects a curl_off_t argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_string, - "curl_easy_setopt expects a " - "string (char* or char[]) argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_write_callback, - "curl_easy_setopt expects a curl_write_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_read_cb, - "curl_easy_setopt expects a curl_read_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, - "curl_easy_setopt expects a curl_ioctl_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, - "curl_easy_setopt expects a curl_sockopt_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, - "curl_easy_setopt expects a " - "curl_opensocket_callback argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_progress_cb, - "curl_easy_setopt expects a curl_progress_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_debug_cb, - "curl_easy_setopt expects a curl_debug_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, - "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_conv_cb, - "curl_easy_setopt expects a curl_conv_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_seek_cb, - "curl_easy_setopt expects a curl_seek_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_cb_data, - "curl_easy_setopt expects a " - "private data pointer as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_error_buffer, - "curl_easy_setopt expects a " - "char buffer of CURL_ERROR_SIZE as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_FILE, - "curl_easy_setopt expects a FILE* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_postfields, - "curl_easy_setopt expects a void* or char* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, - "curl_easy_setopt expects a struct curl_httppost* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_slist, - "curl_easy_setopt expects a struct curl_slist* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_CURLSH, - "curl_easy_setopt expects a CURLSH* argument for this option") - -_CURL_WARNING(_curl_easy_getinfo_err_string, - "curl_easy_getinfo expects a pointer to char * for this info") -_CURL_WARNING(_curl_easy_getinfo_err_long, - "curl_easy_getinfo expects a pointer to long for this info") -_CURL_WARNING(_curl_easy_getinfo_err_double, - "curl_easy_getinfo expects a pointer to double for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, - "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") - -/* groups of curl_easy_setops options that take the same type of argument */ - -/* To add a new option to one of the groups, just add - * (option) == CURLOPT_SOMETHING - * to the or-expression. If the option takes a long or curl_off_t, you don't - * have to do anything - */ - -/* evaluates to true if option takes a long argument */ -#define _curl_is_long_option(option) \ - (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) - -#define _curl_is_off_t_option(option) \ - ((option) > CURLOPTTYPE_OFF_T) - -/* evaluates to true if option takes a char* argument */ -#define _curl_is_string_option(option) \ - ((option) == CURLOPT_ACCEPT_ENCODING || \ - (option) == CURLOPT_CAINFO || \ - (option) == CURLOPT_CAPATH || \ - (option) == CURLOPT_COOKIE || \ - (option) == CURLOPT_COOKIEFILE || \ - (option) == CURLOPT_COOKIEJAR || \ - (option) == CURLOPT_COOKIELIST || \ - (option) == CURLOPT_CRLFILE || \ - (option) == CURLOPT_CUSTOMREQUEST || \ - (option) == CURLOPT_DEFAULT_PROTOCOL || \ - (option) == CURLOPT_DNS_INTERFACE || \ - (option) == CURLOPT_DNS_LOCAL_IP4 || \ - (option) == CURLOPT_DNS_LOCAL_IP6 || \ - (option) == CURLOPT_DNS_SERVERS || \ - (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_FTPPORT || \ - (option) == CURLOPT_FTP_ACCOUNT || \ - (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ - (option) == CURLOPT_INTERFACE || \ - (option) == CURLOPT_ISSUERCERT || \ - (option) == CURLOPT_KEYPASSWD || \ - (option) == CURLOPT_KRBLEVEL || \ - (option) == CURLOPT_LOGIN_OPTIONS || \ - (option) == CURLOPT_MAIL_AUTH || \ - (option) == CURLOPT_MAIL_FROM || \ - (option) == CURLOPT_NETRC_FILE || \ - (option) == CURLOPT_NOPROXY || \ - (option) == CURLOPT_PASSWORD || \ - (option) == CURLOPT_PINNEDPUBLICKEY || \ - (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYUSERPWD || \ - (option) == CURLOPT_PROXY_SERVICE_NAME || \ - (option) == CURLOPT_RANDOM_FILE || \ - (option) == CURLOPT_RANGE || \ - (option) == CURLOPT_REFERER || \ - (option) == CURLOPT_RTSP_SESSION_ID || \ - (option) == CURLOPT_RTSP_STREAM_URI || \ - (option) == CURLOPT_RTSP_TRANSPORT || \ - (option) == CURLOPT_SERVICE_NAME || \ - (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ - (option) == CURLOPT_SSH_KNOWNHOSTS || \ - (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ - (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ - (option) == CURLOPT_SSLCERT || \ - (option) == CURLOPT_SSLCERTTYPE || \ - (option) == CURLOPT_SSLENGINE || \ - (option) == CURLOPT_SSLKEY || \ - (option) == CURLOPT_SSLKEYTYPE || \ - (option) == CURLOPT_SSL_CIPHER_LIST || \ - (option) == CURLOPT_TLSAUTH_PASSWORD || \ - (option) == CURLOPT_TLSAUTH_TYPE || \ - (option) == CURLOPT_TLSAUTH_USERNAME || \ - (option) == CURLOPT_UNIX_SOCKET_PATH || \ - (option) == CURLOPT_URL || \ - (option) == CURLOPT_USERAGENT || \ - (option) == CURLOPT_USERNAME || \ - (option) == CURLOPT_USERPWD || \ - (option) == CURLOPT_XOAUTH2_BEARER || \ - 0) - -/* evaluates to true if option takes a curl_write_callback argument */ -#define _curl_is_write_cb_option(option) \ - ((option) == CURLOPT_HEADERFUNCTION || \ - (option) == CURLOPT_WRITEFUNCTION) - -/* evaluates to true if option takes a curl_conv_callback argument */ -#define _curl_is_conv_cb_option(option) \ - ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) - -/* evaluates to true if option takes a data argument to pass to a callback */ -#define _curl_is_cb_data_option(option) \ - ((option) == CURLOPT_CHUNK_DATA || \ - (option) == CURLOPT_CLOSESOCKETDATA || \ - (option) == CURLOPT_DEBUGDATA || \ - (option) == CURLOPT_FNMATCH_DATA || \ - (option) == CURLOPT_HEADERDATA || \ - (option) == CURLOPT_INTERLEAVEDATA || \ - (option) == CURLOPT_IOCTLDATA || \ - (option) == CURLOPT_OPENSOCKETDATA || \ - (option) == CURLOPT_PRIVATE || \ - (option) == CURLOPT_PROGRESSDATA || \ - (option) == CURLOPT_READDATA || \ - (option) == CURLOPT_SEEKDATA || \ - (option) == CURLOPT_SOCKOPTDATA || \ - (option) == CURLOPT_SSH_KEYDATA || \ - (option) == CURLOPT_SSL_CTX_DATA || \ - (option) == CURLOPT_WRITEDATA || \ - 0) - -/* evaluates to true if option takes a POST data argument (void* or char*) */ -#define _curl_is_postfields_option(option) \ - ((option) == CURLOPT_POSTFIELDS || \ - (option) == CURLOPT_COPYPOSTFIELDS || \ - 0) - -/* evaluates to true if option takes a struct curl_slist * argument */ -#define _curl_is_slist_option(option) \ - ((option) == CURLOPT_HTTP200ALIASES || \ - (option) == CURLOPT_HTTPHEADER || \ - (option) == CURLOPT_MAIL_RCPT || \ - (option) == CURLOPT_POSTQUOTE || \ - (option) == CURLOPT_PREQUOTE || \ - (option) == CURLOPT_PROXYHEADER || \ - (option) == CURLOPT_QUOTE || \ - (option) == CURLOPT_RESOLVE || \ - (option) == CURLOPT_TELNETOPTIONS || \ - 0) - -/* groups of curl_easy_getinfo infos that take the same type of argument */ - -/* evaluates to true if info expects a pointer to char * argument */ -#define _curl_is_string_info(info) \ - (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) - -/* evaluates to true if info expects a pointer to long argument */ -#define _curl_is_long_info(info) \ - (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) - -/* evaluates to true if info expects a pointer to double argument */ -#define _curl_is_double_info(info) \ - (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) - -/* true if info expects a pointer to struct curl_slist * argument */ -#define _curl_is_slist_info(info) \ - (CURLINFO_SLIST < (info)) - - -/* typecheck helpers -- check whether given expression has requested type*/ - -/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, - * otherwise define a new macro. Search for __builtin_types_compatible_p - * in the GCC manual. - * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is - * the actual expression passed to the curl_easy_setopt macro. This - * means that you can only apply the sizeof and __typeof__ operators, no - * == or whatsoever. - */ - -/* XXX: should evaluate to true iff expr is a pointer */ -#define _curl_is_any_ptr(expr) \ - (sizeof(expr) == sizeof(void*)) - -/* evaluates to true if expr is NULL */ -/* XXX: must not evaluate expr, so this check is not accurate */ -#define _curl_is_NULL(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) - -/* evaluates to true if expr is type*, const type* or NULL */ -#define _curl_is_ptr(expr, type) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type *) || \ - __builtin_types_compatible_p(__typeof__(expr), const type *)) - -/* evaluates to true if expr is one of type[], type*, NULL or const type* */ -#define _curl_is_arr(expr, type) \ - (_curl_is_ptr((expr), type) || \ - __builtin_types_compatible_p(__typeof__(expr), type [])) - -/* evaluates to true if expr is a string */ -#define _curl_is_string(expr) \ - (_curl_is_arr((expr), char) || \ - _curl_is_arr((expr), signed char) || \ - _curl_is_arr((expr), unsigned char)) - -/* evaluates to true if expr is a long (no matter the signedness) - * XXX: for now, int is also accepted (and therefore short and char, which - * are promoted to int when passed to a variadic function) */ -#define _curl_is_long(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), long) || \ - __builtin_types_compatible_p(__typeof__(expr), signed long) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ - __builtin_types_compatible_p(__typeof__(expr), int) || \ - __builtin_types_compatible_p(__typeof__(expr), signed int) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ - __builtin_types_compatible_p(__typeof__(expr), short) || \ - __builtin_types_compatible_p(__typeof__(expr), signed short) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ - __builtin_types_compatible_p(__typeof__(expr), char) || \ - __builtin_types_compatible_p(__typeof__(expr), signed char) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned char)) - -/* evaluates to true if expr is of type curl_off_t */ -#define _curl_is_off_t(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) - -/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ -/* XXX: also check size of an char[] array? */ -#define _curl_is_error_buffer(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), char *) || \ - __builtin_types_compatible_p(__typeof__(expr), char[])) - -/* evaluates to true if expr is of type (const) void* or (const) FILE* */ -#if 0 -#define _curl_is_cb_data(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_ptr((expr), FILE)) -#else /* be less strict */ -#define _curl_is_cb_data(expr) \ - _curl_is_any_ptr(expr) -#endif - -/* evaluates to true if expr is of type FILE* */ -#define _curl_is_FILE(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), FILE *)) - -/* evaluates to true if expr can be passed as POST data (void* or char*) */ -#define _curl_is_postfields(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_arr((expr), char)) - -/* FIXME: the whole callback checking is messy... - * The idea is to tolerate char vs. void and const vs. not const - * pointers in arguments at least - */ -/* helper: __builtin_types_compatible_p distinguishes between functions and - * function pointers, hide it */ -#define _curl_callback_compatible(func, type) \ - (__builtin_types_compatible_p(__typeof__(func), type) || \ - __builtin_types_compatible_p(__typeof__(func), type*)) - -/* evaluates to true if expr is of type curl_read_callback or "similar" */ -#define _curl_is_read_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ - _curl_callback_compatible((expr), _curl_read_callback1) || \ - _curl_callback_compatible((expr), _curl_read_callback2) || \ - _curl_callback_compatible((expr), _curl_read_callback3) || \ - _curl_callback_compatible((expr), _curl_read_callback4) || \ - _curl_callback_compatible((expr), _curl_read_callback5) || \ - _curl_callback_compatible((expr), _curl_read_callback6)) -typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*); -typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*); -typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*); -typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*); -typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*); -typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*); - -/* evaluates to true if expr is of type curl_write_callback or "similar" */ -#define _curl_is_write_cb(expr) \ - (_curl_is_read_cb(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ - _curl_callback_compatible((expr), _curl_write_callback1) || \ - _curl_callback_compatible((expr), _curl_write_callback2) || \ - _curl_callback_compatible((expr), _curl_write_callback3) || \ - _curl_callback_compatible((expr), _curl_write_callback4) || \ - _curl_callback_compatible((expr), _curl_write_callback5) || \ - _curl_callback_compatible((expr), _curl_write_callback6)) -typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*); -typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, - const void*); -typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*); -typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*); -typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, - const void*); -typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*); - -/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ -#define _curl_is_ioctl_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback4)) -typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*); -typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*); -typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*); -typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*); - -/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ -#define _curl_is_sockopt_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback2)) -typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); -typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, - curlsocktype); - -/* evaluates to true if expr is of type curl_opensocket_callback or - "similar" */ -#define _curl_is_opensocket_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ - _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback4)) -typedef curl_socket_t (_curl_opensocket_callback1) - (void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback2) - (void *, curlsocktype, const struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback3) - (const void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback4) - (const void *, curlsocktype, const struct curl_sockaddr *); - -/* evaluates to true if expr is of type curl_progress_callback or "similar" */ -#define _curl_is_progress_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ - _curl_callback_compatible((expr), _curl_progress_callback1) || \ - _curl_callback_compatible((expr), _curl_progress_callback2)) -typedef int (_curl_progress_callback1)(void *, - double, double, double, double); -typedef int (_curl_progress_callback2)(const void *, - double, double, double, double); - -/* evaluates to true if expr is of type curl_debug_callback or "similar" */ -#define _curl_is_debug_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ - _curl_callback_compatible((expr), _curl_debug_callback1) || \ - _curl_callback_compatible((expr), _curl_debug_callback2) || \ - _curl_callback_compatible((expr), _curl_debug_callback3) || \ - _curl_callback_compatible((expr), _curl_debug_callback4) || \ - _curl_callback_compatible((expr), _curl_debug_callback5) || \ - _curl_callback_compatible((expr), _curl_debug_callback6) || \ - _curl_callback_compatible((expr), _curl_debug_callback7) || \ - _curl_callback_compatible((expr), _curl_debug_callback8)) -typedef int (_curl_debug_callback1) (CURL *, - curl_infotype, char *, size_t, void *); -typedef int (_curl_debug_callback2) (CURL *, - curl_infotype, char *, size_t, const void *); -typedef int (_curl_debug_callback3) (CURL *, - curl_infotype, const char *, size_t, void *); -typedef int (_curl_debug_callback4) (CURL *, - curl_infotype, const char *, size_t, const void *); -typedef int (_curl_debug_callback5) (CURL *, - curl_infotype, unsigned char *, size_t, void *); -typedef int (_curl_debug_callback6) (CURL *, - curl_infotype, unsigned char *, size_t, const void *); -typedef int (_curl_debug_callback7) (CURL *, - curl_infotype, const unsigned char *, size_t, void *); -typedef int (_curl_debug_callback8) (CURL *, - curl_infotype, const unsigned char *, size_t, const void *); - -/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ -/* this is getting even messier... */ -#define _curl_is_ssl_ctx_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) -typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); -typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); -#ifdef HEADER_SSL_H -/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX - * this will of course break if we're included before OpenSSL headers... - */ -typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); -typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, - const void *); -#else -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; -#endif - -/* evaluates to true if expr is of type curl_conv_callback or "similar" */ -#define _curl_is_conv_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ - _curl_callback_compatible((expr), _curl_conv_callback1) || \ - _curl_callback_compatible((expr), _curl_conv_callback2) || \ - _curl_callback_compatible((expr), _curl_conv_callback3) || \ - _curl_callback_compatible((expr), _curl_conv_callback4)) -typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); -typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); -typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); -typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); - -/* evaluates to true if expr is of type curl_seek_callback or "similar" */ -#define _curl_is_seek_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ - _curl_callback_compatible((expr), _curl_seek_callback1) || \ - _curl_callback_compatible((expr), _curl_seek_callback2)) -typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); -typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); - - -#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/Externals/curl/lib/CMakeLists.txt b/Externals/curl/lib/CMakeLists.txt deleted file mode 100644 index 3679575463..0000000000 --- a/Externals/curl/lib/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -if(CMAKE_SYSTEM_NAME MATCHES "Windows") - add_definitions(-DUSE_SCHANNEL -DUSE_WINDOWS_SSPI) -else() - add_definitions(-DHAVE_CONFIG_H) -endif() - -file(GLOB SRCS *.c vauth/*.c vtls/*.c) -add_library( - curl - STATIC - ${SRCS} - ) -dolphin_disable_warnings_msvc(curl) - -target_include_directories(curl PRIVATE . INTERFACE ../include) -target_link_libraries(curl MbedTLS::mbedtls zlibstatic) -target_compile_definitions(curl PUBLIC CURL_STATICLIB PRIVATE CURL_DISABLE_LDAP) -add_library(CURL::libcurl ALIAS curl) diff --git a/Externals/curl/lib/amigaos.c b/Externals/curl/lib/amigaos.c deleted file mode 100644 index 5591d22209..0000000000 --- a/Externals/curl/lib/amigaos.c +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(__AMIGA__) && !defined(__ixemul__) - -#include - -#include "amigaos.h" - -struct Library *SocketBase = NULL; -extern int errno, h_errno; - -#ifdef __libnix__ -#include -void __request(const char *msg); -#else -# define __request(msg) Printf(msg "\n\a") -#endif - -void Curl_amiga_cleanup() -{ - if(SocketBase) { - CloseLibrary(SocketBase); - SocketBase = NULL; - } -} - -bool Curl_amiga_init() -{ - if(!SocketBase) - SocketBase = OpenLibrary("bsdsocket.library", 4); - - if(!SocketBase) { - __request("No TCP/IP Stack running!"); - return FALSE; - } - - if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno, - SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL", - TAG_DONE)) { - __request("SocketBaseTags ERROR"); - return FALSE; - } - -#ifndef __libnix__ - atexit(Curl_amiga_cleanup); -#endif - - return TRUE; -} - -#ifdef __libnix__ -ADD2EXIT(Curl_amiga_cleanup, -50); -#endif - -#endif /* __AMIGA__ && ! __ixemul__ */ diff --git a/Externals/curl/lib/amigaos.h b/Externals/curl/lib/amigaos.h deleted file mode 100644 index 02bee16107..0000000000 --- a/Externals/curl/lib/amigaos.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_AMIGAOS_H -#define HEADER_CURL_AMIGAOS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(__AMIGA__) && !defined(__ixemul__) - -bool Curl_amiga_init(); -void Curl_amiga_cleanup(); - -#else - -#define Curl_amiga_init() 1 -#define Curl_amiga_cleanup() Curl_nop_stmt - -#endif - -#endif /* HEADER_CURL_AMIGAOS_H */ - diff --git a/Externals/curl/lib/arpa_telnet.h b/Externals/curl/lib/arpa_telnet.h deleted file mode 100644 index ec238729dd..0000000000 --- a/Externals/curl/lib/arpa_telnet.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef HEADER_CURL_ARPA_TELNET_H -#define HEADER_CURL_ARPA_TELNET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifndef CURL_DISABLE_TELNET -/* - * Telnet option defines. Add more here if in need. - */ -#define CURL_TELOPT_BINARY 0 /* binary 8bit data */ -#define CURL_TELOPT_ECHO 1 /* just echo! */ -#define CURL_TELOPT_SGA 3 /* Suppress Go Ahead */ -#define CURL_TELOPT_EXOPL 255 /* EXtended OPtions List */ -#define CURL_TELOPT_TTYPE 24 /* Terminal TYPE */ -#define CURL_TELOPT_NAWS 31 /* Negotiate About Window Size */ -#define CURL_TELOPT_XDISPLOC 35 /* X DISPlay LOCation */ - -#define CURL_TELOPT_NEW_ENVIRON 39 /* NEW ENVIRONment variables */ -#define CURL_NEW_ENV_VAR 0 -#define CURL_NEW_ENV_VALUE 1 - -/* - * The telnet options represented as strings - */ -static const char * const telnetoptions[]= -{ - "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", - "NAME", "STATUS", "TIMING MARK", "RCTE", - "NAOL", "NAOP", "NAOCRD", "NAOHTS", - "NAOHTD", "NAOFFD", "NAOVTS", "NAOVTD", - "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", - "DE TERMINAL", "SUPDUP", "SUPDUP OUTPUT", "SEND LOCATION", - "TERM TYPE", "END OF RECORD", "TACACS UID", "OUTPUT MARKING", - "TTYLOC", "3270 REGIME", "X3 PAD", "NAWS", - "TERM SPEED", "LFLOW", "LINEMODE", "XDISPLOC", - "OLD-ENVIRON", "AUTHENTICATION", "ENCRYPT", "NEW-ENVIRON" -}; - -#define CURL_TELOPT_MAXIMUM CURL_TELOPT_NEW_ENVIRON - -#define CURL_TELOPT_OK(x) ((x) <= CURL_TELOPT_MAXIMUM) -#define CURL_TELOPT(x) telnetoptions[x] - -#define CURL_NTELOPTS 40 - -/* - * First some defines - */ -#define CURL_xEOF 236 /* End Of File */ -#define CURL_SE 240 /* Sub negotiation End */ -#define CURL_NOP 241 /* No OPeration */ -#define CURL_DM 242 /* Data Mark */ -#define CURL_GA 249 /* Go Ahead, reverse the line */ -#define CURL_SB 250 /* SuBnegotiation */ -#define CURL_WILL 251 /* Our side WILL use this option */ -#define CURL_WONT 252 /* Our side WON'T use this option */ -#define CURL_DO 253 /* DO use this option! */ -#define CURL_DONT 254 /* DON'T use this option! */ -#define CURL_IAC 255 /* Interpret As Command */ - -/* - * Then those numbers represented as strings: - */ -static const char * const telnetcmds[]= -{ - "EOF", "SUSP", "ABORT", "EOR", "SE", - "NOP", "DMARK", "BRK", "IP", "AO", - "AYT", "EC", "EL", "GA", "SB", - "WILL", "WONT", "DO", "DONT", "IAC" -}; - -#define CURL_TELCMD_MINIMUM CURL_xEOF /* the first one */ -#define CURL_TELCMD_MAXIMUM CURL_IAC /* surprise, 255 is the last one! ;-) */ - -#define CURL_TELQUAL_IS 0 -#define CURL_TELQUAL_SEND 1 -#define CURL_TELQUAL_INFO 2 -#define CURL_TELQUAL_NAME 3 - -#define CURL_TELCMD_OK(x) ( ((unsigned int)(x) >= CURL_TELCMD_MINIMUM) && \ - ((unsigned int)(x) <= CURL_TELCMD_MAXIMUM) ) -#define CURL_TELCMD(x) telnetcmds[(x)-CURL_TELCMD_MINIMUM] - -#endif /* CURL_DISABLE_TELNET */ - -#endif /* HEADER_CURL_ARPA_TELNET_H */ diff --git a/Externals/curl/lib/asyn-ares.c b/Externals/curl/lib/asyn-ares.c deleted file mode 100644 index 51f61dee12..0000000000 --- a/Externals/curl/lib/asyn-ares.c +++ /dev/null @@ -1,691 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_LIMITS_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_PROCESS_H -#include -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -/*********************************************************************** - * Only for ares-enabled builds - * And only for functions that fulfill the asynch resolver backend API - * as defined in asyn.h, nothing else belongs in this file! - **********************************************************************/ - -#ifdef CURLRES_ARES - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "multiif.h" -#include "inet_pton.h" -#include "connect.h" -#include "select.h" -#include "progress.h" - -# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ - (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) -# define CARES_STATICLIB -# endif -# include -# include /* really old c-ares didn't include this by - itself */ - -#if ARES_VERSION >= 0x010500 -/* c-ares 1.5.0 or later, the callback proto is modified */ -#define HAVE_CARES_CALLBACK_TIMEOUTS 1 -#endif - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -struct ResolverResults { - int num_pending; /* number of ares_gethostbyname() requests */ - Curl_addrinfo *temp_ai; /* intermediary result while fetching c-ares parts */ - int last_status; -}; - -/* - * Curl_resolver_global_init() - the generic low-level asynchronous name - * resolve API. Called from curl_global_init() to initialize global resolver - * environment. Initializes ares library. - */ -int Curl_resolver_global_init(void) -{ -#ifdef CARES_HAVE_ARES_LIBRARY_INIT - if(ares_library_init(ARES_LIB_INIT_ALL)) { - return CURLE_FAILED_INIT; - } -#endif - return CURLE_OK; -} - -/* - * Curl_resolver_global_cleanup() - * - * Called from curl_global_cleanup() to destroy global resolver environment. - * Deinitializes ares library. - */ -void Curl_resolver_global_cleanup(void) -{ -#ifdef CARES_HAVE_ARES_LIBRARY_CLEANUP - ares_library_cleanup(); -#endif -} - -/* - * Curl_resolver_init() - * - * Called from curl_easy_init() -> Curl_open() to initialize resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Fills the passed pointer by the initialized ares_channel. - */ -CURLcode Curl_resolver_init(void **resolver) -{ - int status = ares_init((ares_channel*)resolver); - if(status != ARES_SUCCESS) { - if(status == ARES_ENOMEM) - return CURLE_OUT_OF_MEMORY; - else - return CURLE_FAILED_INIT; - } - return CURLE_OK; - /* make sure that all other returns from this function should destroy the - ares channel before returning error! */ -} - -/* - * Curl_resolver_cleanup() - * - * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Destroys the ares channel. - */ -void Curl_resolver_cleanup(void *resolver) -{ - ares_destroy((ares_channel)resolver); -} - -/* - * Curl_resolver_duphandle() - * - * Called from curl_easy_duphandle() to duplicate resolver URL-state specific - * environment ('resolver' member of the UrlState structure). Duplicates the - * 'from' ares channel and passes the resulting channel to the 'to' pointer. - */ -int Curl_resolver_duphandle(void **to, void *from) -{ - /* Clone the ares channel for the new handle */ - if(ARES_SUCCESS != ares_dup((ares_channel*)to, (ares_channel)from)) - return CURLE_FAILED_INIT; - return CURLE_OK; -} - -static void destroy_async_data (struct Curl_async *async); - -/* - * Cancel all possibly still on-going resolves for this connection. - */ -void Curl_resolver_cancel(struct connectdata *conn) -{ - if(conn->data && conn->data->state.resolver) - ares_cancel((ares_channel)conn->data->state.resolver); - destroy_async_data(&conn->async); -} - -/* - * destroy_async_data() cleans up async resolver data. - */ -static void destroy_async_data (struct Curl_async *async) -{ - free(async->hostname); - - if(async->os_specific) { - struct ResolverResults *res = (struct ResolverResults *)async->os_specific; - if(res) { - if(res->temp_ai) { - Curl_freeaddrinfo(res->temp_ai); - res->temp_ai = NULL; - } - free(res); - } - async->os_specific = NULL; - } - - async->hostname = NULL; -} - -/* - * Curl_resolver_getsock() is called when someone from the outside world - * (using curl_multi_fdset()) wants to get our fd_set setup and we're talking - * with ares. The caller must make sure that this function is only called when - * we have a working ares channel. - * - * Returns: sockets-in-use-bitmap - */ - -int Curl_resolver_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) - -{ - struct timeval maxtime; - struct timeval timebuf; - struct timeval *timeout; - long milli; - int max = ares_getsock((ares_channel)conn->data->state.resolver, - (ares_socket_t *)socks, numsocks); - - maxtime.tv_sec = CURL_TIMEOUT_RESOLVE; - maxtime.tv_usec = 0; - - timeout = ares_timeout((ares_channel)conn->data->state.resolver, &maxtime, - &timebuf); - milli = (timeout->tv_sec * 1000) + (timeout->tv_usec/1000); - if(milli == 0) - milli += 10; - Curl_expire_latest(conn->data, milli); - - return max; -} - -/* - * waitperform() - * - * 1) Ask ares what sockets it currently plays with, then - * 2) wait for the timeout period to check for action on ares' sockets. - * 3) tell ares to act on all the sockets marked as "with action" - * - * return number of sockets it worked on - */ - -static int waitperform(struct connectdata *conn, int timeout_ms) -{ - struct SessionHandle *data = conn->data; - int nfds; - int bitmask; - ares_socket_t socks[ARES_GETSOCK_MAXNUM]; - struct pollfd pfd[ARES_GETSOCK_MAXNUM]; - int i; - int num = 0; - - bitmask = ares_getsock((ares_channel)data->state.resolver, socks, - ARES_GETSOCK_MAXNUM); - - for(i=0; i < ARES_GETSOCK_MAXNUM; i++) { - pfd[i].events = 0; - pfd[i].revents = 0; - if(ARES_GETSOCK_READABLE(bitmask, i)) { - pfd[i].fd = socks[i]; - pfd[i].events |= POLLRDNORM|POLLIN; - } - if(ARES_GETSOCK_WRITABLE(bitmask, i)) { - pfd[i].fd = socks[i]; - pfd[i].events |= POLLWRNORM|POLLOUT; - } - if(pfd[i].events != 0) - num++; - else - break; - } - - if(num) - nfds = Curl_poll(pfd, num, timeout_ms); - else - nfds = 0; - - if(!nfds) - /* Call ares_process() unconditonally here, even if we simply timed out - above, as otherwise the ares name resolve won't timeout! */ - ares_process_fd((ares_channel)data->state.resolver, ARES_SOCKET_BAD, - ARES_SOCKET_BAD); - else { - /* move through the descriptors and ask for processing on them */ - for(i=0; i < num; i++) - ares_process_fd((ares_channel)data->state.resolver, - pfd[i].revents & (POLLRDNORM|POLLIN)? - pfd[i].fd:ARES_SOCKET_BAD, - pfd[i].revents & (POLLWRNORM|POLLOUT)? - pfd[i].fd:ARES_SOCKET_BAD); - } - return nfds; -} - -/* - * Curl_resolver_is_resolved() is called repeatedly to check if a previous - * name resolve request has completed. It should also make sure to time-out if - * the operation seems to take too long. - * - * Returns normal CURLcode errors. - */ -CURLcode Curl_resolver_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns) -{ - struct SessionHandle *data = conn->data; - struct ResolverResults *res = (struct ResolverResults *) - conn->async.os_specific; - CURLcode result = CURLE_OK; - - *dns = NULL; - - waitperform(conn, 0); - - if(res && !res->num_pending) { - (void)Curl_addrinfo_callback(conn, res->last_status, res->temp_ai); - /* temp_ai ownership is moved to the connection, so we need not free-up - them */ - res->temp_ai = NULL; - if(!conn->async.dns) { - failf(data, "Could not resolve: %s (%s)", - conn->async.hostname, ares_strerror(conn->async.status)); - result = conn->bits.proxy?CURLE_COULDNT_RESOLVE_PROXY: - CURLE_COULDNT_RESOLVE_HOST; - } - else - *dns = conn->async.dns; - - destroy_async_data(&conn->async); - } - - return result; -} - -/* - * Curl_resolver_wait_resolv() - * - * waits for a resolve to finish. This function should be avoided since using - * this risk getting the multi interface to "hang". - * - * If 'entry' is non-NULL, make it point to the resolved dns entry - * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and - * CURLE_OPERATION_TIMEDOUT if a time-out occurred. - */ -CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - long timeout; - struct timeval now = Curl_tvnow(); - struct Curl_dns_entry *temp_entry; - - timeout = Curl_timeleft(data, &now, TRUE); - if(!timeout) - timeout = CURL_TIMEOUT_RESOLVE * 1000; /* default name resolve timeout */ - - /* Wait for the name resolve query to complete. */ - for(;;) { - struct timeval *tvp, tv, store; - long timediff; - int itimeout; - int timeout_ms; - - itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout; - - store.tv_sec = itimeout/1000; - store.tv_usec = (itimeout%1000)*1000; - - tvp = ares_timeout((ares_channel)data->state.resolver, &store, &tv); - - /* use the timeout period ares returned to us above if less than one - second is left, otherwise just use 1000ms to make sure the progress - callback gets called frequent enough */ - if(!tvp->tv_sec) - timeout_ms = (int)(tvp->tv_usec/1000); - else - timeout_ms = 1000; - - waitperform(conn, timeout_ms); - Curl_resolver_is_resolved(conn, &temp_entry); - - if(conn->async.done) - break; - - if(Curl_pgrsUpdate(conn)) { - result = CURLE_ABORTED_BY_CALLBACK; - timeout = -1; /* trigger the cancel below */ - } - else { - struct timeval now2 = Curl_tvnow(); - timediff = Curl_tvdiff(now2, now); /* spent time */ - timeout -= timediff?timediff:1; /* always deduct at least 1 */ - now = now2; /* for next loop */ - } - - if(timeout < 0) { - /* our timeout, so we cancel the ares operation */ - ares_cancel((ares_channel)data->state.resolver); - break; - } - } - - /* Operation complete, if the lookup was successful we now have the entry - in the cache. */ - if(entry) - *entry = conn->async.dns; - - if(result) - /* close the connection, since we can't return failure here without - cleaning up this connection properly. - TODO: remove this action from here, it is not a name resolver decision. - */ - connclose(conn, "c-ares resolve failed"); - - return result; -} - -/* Connects results to the list */ -static void compound_results(struct ResolverResults *res, - Curl_addrinfo *ai) -{ - Curl_addrinfo *ai_tail; - if(!ai) - return; - ai_tail = ai; - - while(ai_tail->ai_next) - ai_tail = ai_tail->ai_next; - - /* Add the new results to the list of old results. */ - ai_tail->ai_next = res->temp_ai; - res->temp_ai = ai; -} - -/* - * ares_query_completed_cb() is the callback that ares will call when - * the host query initiated by ares_gethostbyname() from Curl_getaddrinfo(), - * when using ares, is completed either successfully or with failure. - */ -static void query_completed_cb(void *arg, /* (struct connectdata *) */ - int status, -#ifdef HAVE_CARES_CALLBACK_TIMEOUTS - int timeouts, -#endif - struct hostent *hostent) -{ - struct connectdata *conn = (struct connectdata *)arg; - struct ResolverResults *res; - -#ifdef HAVE_CARES_CALLBACK_TIMEOUTS - (void)timeouts; /* ignored */ -#endif - - if(ARES_EDESTRUCTION == status) - /* when this ares handle is getting destroyed, the 'arg' pointer may not - be valid so only defer it when we know the 'status' says its fine! */ - return; - - res = (struct ResolverResults *)conn->async.os_specific; - res->num_pending--; - - if(CURL_ASYNC_SUCCESS == status) { - Curl_addrinfo *ai = Curl_he2ai(hostent, conn->async.port); - if(ai) { - compound_results(res, ai); - } - } - /* A successful result overwrites any previous error */ - if(res->last_status != ARES_SUCCESS) - res->last_status = status; -} - -/* - * Curl_resolver_getaddrinfo() - when using ares - * - * Returns name information about the given hostname and port number. If - * successful, the 'hostent' is returned and the forth argument will point to - * memory we need to free after use. That memory *MUST* be freed with - * Curl_freeaddrinfo(), nothing else. - */ -Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) -{ - char *bufp; - struct SessionHandle *data = conn->data; - struct in_addr in; - int family = PF_INET; -#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ - struct in6_addr in6; -#endif /* CURLRES_IPV6 */ - - *waitp = 0; /* default to synchronous response */ - - /* First check if this is an IPv4 address string */ - if(Curl_inet_pton(AF_INET, hostname, &in) > 0) { - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(AF_INET, &in, hostname, port); - } - -#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ - /* Otherwise, check if this is an IPv6 address string */ - if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0) - /* This must be an IPv6 address literal. */ - return Curl_ip2addr(AF_INET6, &in6, hostname, port); - - switch(conn->ip_version) { - default: -#if ARES_VERSION >= 0x010601 - family = PF_UNSPEC; /* supported by c-ares since 1.6.1, so for older - c-ares versions this just falls through and defaults - to PF_INET */ - break; -#endif - case CURL_IPRESOLVE_V4: - family = PF_INET; - break; - case CURL_IPRESOLVE_V6: - family = PF_INET6; - break; - } -#endif /* CURLRES_IPV6 */ - - bufp = strdup(hostname); - if(bufp) { - struct ResolverResults *res = NULL; - free(conn->async.hostname); - conn->async.hostname = bufp; - conn->async.port = port; - conn->async.done = FALSE; /* not done */ - conn->async.status = 0; /* clear */ - conn->async.dns = NULL; /* clear */ - res = calloc(sizeof(struct ResolverResults), 1); - if(!res) { - free(conn->async.hostname); - conn->async.hostname = NULL; - return NULL; - } - conn->async.os_specific = res; - - /* initial status - failed */ - res->last_status = ARES_ENOTFOUND; -#ifdef ENABLE_IPV6 /* CURLRES_IPV6 */ - if(family == PF_UNSPEC) { - if(Curl_ipv6works()) { - res->num_pending = 2; - - /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname((ares_channel)data->state.resolver, hostname, - PF_INET, query_completed_cb, conn); - ares_gethostbyname((ares_channel)data->state.resolver, hostname, - PF_INET6, query_completed_cb, conn); - } - else { - res->num_pending = 1; - - /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname((ares_channel)data->state.resolver, hostname, - PF_INET, query_completed_cb, conn); - } - } - else -#endif /* CURLRES_IPV6 */ - { - res->num_pending = 1; - - /* areschannel is already setup in the Curl_open() function */ - ares_gethostbyname((ares_channel)data->state.resolver, hostname, family, - query_completed_cb, conn); - } - - *waitp = 1; /* expect asynchronous response */ - } - return NULL; /* no struct yet */ -} - -CURLcode Curl_set_dns_servers(struct SessionHandle *data, - char *servers) -{ - CURLcode result = CURLE_NOT_BUILT_IN; - int ares_result; - - /* If server is NULL or empty, this would purge all DNS servers - * from ares library, which will cause any and all queries to fail. - * So, just return OK if none are configured and don't actually make - * any changes to c-ares. This lets c-ares use it's defaults, which - * it gets from the OS (for instance from /etc/resolv.conf on Linux). - */ - if(!(servers && servers[0])) - return CURLE_OK; - -#if (ARES_VERSION >= 0x010704) - ares_result = ares_set_servers_csv(data->state.resolver, servers); - switch(ares_result) { - case ARES_SUCCESS: - result = CURLE_OK; - break; - case ARES_ENOMEM: - result = CURLE_OUT_OF_MEMORY; - break; - case ARES_ENOTINITIALIZED: - case ARES_ENODATA: - case ARES_EBADSTR: - default: - result = CURLE_BAD_FUNCTION_ARGUMENT; - break; - } -#else /* too old c-ares version! */ - (void)data; - (void)(ares_result); -#endif - return result; -} - -CURLcode Curl_set_dns_interface(struct SessionHandle *data, - const char *interf) -{ -#if (ARES_VERSION >= 0x010704) - if(!interf) - interf = ""; - - ares_set_local_dev((ares_channel)data->state.resolver, interf); - - return CURLE_OK; -#else /* c-ares version too old! */ - (void)data; - (void)interf; - return CURLE_NOT_BUILT_IN; -#endif -} - -CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data, - const char *local_ip4) -{ -#if (ARES_VERSION >= 0x010704) - struct in_addr a4; - - if((!local_ip4) || (local_ip4[0] == 0)) { - a4.s_addr = 0; /* disabled: do not bind to a specific address */ - } - else { - if(Curl_inet_pton(AF_INET, local_ip4, &a4) != 1) { - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - - ares_set_local_ip4((ares_channel)data->state.resolver, ntohl(a4.s_addr)); - - return CURLE_OK; -#else /* c-ares version too old! */ - (void)data; - (void)local_ip4; - return CURLE_NOT_BUILT_IN; -#endif -} - -CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data, - const char *local_ip6) -{ -#if (ARES_VERSION >= 0x010704) && defined(ENABLE_IPV6) - unsigned char a6[INET6_ADDRSTRLEN]; - - if((!local_ip6) || (local_ip6[0] == 0)) { - /* disabled: do not bind to a specific address */ - memset(a6, 0, sizeof(a6)); - } - else { - if(Curl_inet_pton(AF_INET6, local_ip6, a6) != 1) { - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } - - ares_set_local_ip6((ares_channel)data->state.resolver, a6); - - return CURLE_OK; -#else /* c-ares version too old! */ - (void)data; - (void)local_ip6; - return CURLE_NOT_BUILT_IN; -#endif -} -#endif /* CURLRES_ARES */ diff --git a/Externals/curl/lib/asyn-thread.c b/Externals/curl/lib/asyn-thread.c deleted file mode 100644 index 81caedb091..0000000000 --- a/Externals/curl/lib/asyn-thread.c +++ /dev/null @@ -1,697 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#if defined(USE_THREADS_POSIX) -# ifdef HAVE_PTHREAD_H -# include -# endif -#elif defined(USE_THREADS_WIN32) -# ifdef HAVE_PROCESS_H -# include -# endif -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#ifdef HAVE_GETADDRINFO -# define RESOLVER_ENOMEM EAI_MEMORY -#else -# define RESOLVER_ENOMEM ENOMEM -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "multiif.h" -#include "inet_pton.h" -#include "inet_ntop.h" -#include "curl_threads.h" -#include "connect.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/*********************************************************************** - * Only for threaded name resolves builds - **********************************************************************/ -#ifdef CURLRES_THREADED - -/* - * Curl_resolver_global_init() - * Called from curl_global_init() to initialize global resolver environment. - * Does nothing here. - */ -int Curl_resolver_global_init(void) -{ - return CURLE_OK; -} - -/* - * Curl_resolver_global_cleanup() - * Called from curl_global_cleanup() to destroy global resolver environment. - * Does nothing here. - */ -void Curl_resolver_global_cleanup(void) -{ -} - -/* - * Curl_resolver_init() - * Called from curl_easy_init() -> Curl_open() to initialize resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Does nothing here. - */ -CURLcode Curl_resolver_init(void **resolver) -{ - (void)resolver; - return CURLE_OK; -} - -/* - * Curl_resolver_cleanup() - * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Does nothing here. - */ -void Curl_resolver_cleanup(void *resolver) -{ - (void)resolver; -} - -/* - * Curl_resolver_duphandle() - * Called from curl_easy_duphandle() to duplicate resolver URL state-specific - * environment ('resolver' member of the UrlState structure). Does nothing - * here. - */ -int Curl_resolver_duphandle(void **to, void *from) -{ - (void)to; - (void)from; - return CURLE_OK; -} - -static void destroy_async_data(struct Curl_async *); - -/* - * Cancel all possibly still on-going resolves for this connection. - */ -void Curl_resolver_cancel(struct connectdata *conn) -{ - destroy_async_data(&conn->async); -} - -/* This function is used to init a threaded resolve */ -static bool init_resolve_thread(struct connectdata *conn, - const char *hostname, int port, - const struct addrinfo *hints); - - -/* Data for synchronization between resolver thread and its parent */ -struct thread_sync_data { - curl_mutex_t * mtx; - int done; - - char * hostname; /* hostname to resolve, Curl_async.hostname - duplicate */ - int port; - int sock_error; - Curl_addrinfo *res; -#ifdef HAVE_GETADDRINFO - struct addrinfo hints; -#endif - struct thread_data *td; /* for thread-self cleanup */ -}; - -struct thread_data { - curl_thread_t thread_hnd; - unsigned int poll_interval; - long interval_end; - struct thread_sync_data tsd; -}; - -static struct thread_sync_data *conn_thread_sync_data(struct connectdata *conn) -{ - return &(((struct thread_data *)conn->async.os_specific)->tsd); -} - -#define CONN_THREAD_SYNC_DATA(conn) &(((conn)->async.os_specific)->tsd); - -/* Destroy resolver thread synchronization data */ -static -void destroy_thread_sync_data(struct thread_sync_data * tsd) -{ - if(tsd->mtx) { - Curl_mutex_destroy(tsd->mtx); - free(tsd->mtx); - } - - free(tsd->hostname); - - if(tsd->res) - Curl_freeaddrinfo(tsd->res); - - memset(tsd, 0, sizeof(*tsd)); -} - -/* Initialize resolver thread synchronization data */ -static -int init_thread_sync_data(struct thread_data * td, - const char * hostname, - int port, - const struct addrinfo *hints) -{ - struct thread_sync_data *tsd = &td->tsd; - - memset(tsd, 0, sizeof(*tsd)); - - tsd->td = td; - tsd->port = port; -#ifdef HAVE_GETADDRINFO - DEBUGASSERT(hints); - tsd->hints = *hints; -#else - (void) hints; -#endif - - tsd->mtx = malloc(sizeof(curl_mutex_t)); - if(tsd->mtx == NULL) - goto err_exit; - - Curl_mutex_init(tsd->mtx); - - tsd->sock_error = CURL_ASYNC_SUCCESS; - - /* Copying hostname string because original can be destroyed by parent - * thread during gethostbyname execution. - */ - tsd->hostname = strdup(hostname); - if(!tsd->hostname) - goto err_exit; - - return 1; - - err_exit: - /* Memory allocation failed */ - destroy_thread_sync_data(tsd); - return 0; -} - -static int getaddrinfo_complete(struct connectdata *conn) -{ - struct thread_sync_data *tsd = conn_thread_sync_data(conn); - int rc; - - rc = Curl_addrinfo_callback(conn, tsd->sock_error, tsd->res); - /* The tsd->res structure has been copied to async.dns and perhaps the DNS - cache. Set our copy to NULL so destroy_thread_sync_data doesn't free it. - */ - tsd->res = NULL; - - return rc; -} - - -#ifdef HAVE_GETADDRINFO - -/* - * getaddrinfo_thread() resolves a name and then exits. - * - * For builds without ARES, but with ENABLE_IPV6, create a resolver thread - * and wait on it. - */ -static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg) -{ - struct thread_sync_data *tsd = (struct thread_sync_data*)arg; - struct thread_data *td = tsd->td; - char service[12]; - int rc; - - snprintf(service, sizeof(service), "%d", tsd->port); - - rc = Curl_getaddrinfo_ex(tsd->hostname, service, &tsd->hints, &tsd->res); - - if(rc != 0) { - tsd->sock_error = SOCKERRNO?SOCKERRNO:rc; - if(tsd->sock_error == 0) - tsd->sock_error = RESOLVER_ENOMEM; - } - - Curl_mutex_acquire(tsd->mtx); - if(tsd->done) { - /* too late, gotta clean up the mess */ - Curl_mutex_release(tsd->mtx); - destroy_thread_sync_data(tsd); - free(td); - } - else { - tsd->done = 1; - Curl_mutex_release(tsd->mtx); - } - - return 0; -} - -#else /* HAVE_GETADDRINFO */ - -/* - * gethostbyname_thread() resolves a name and then exits. - */ -static unsigned int CURL_STDCALL gethostbyname_thread (void *arg) -{ - struct thread_sync_data *tsd = (struct thread_sync_data *)arg; - struct thread_data *td = tsd->td; - - tsd->res = Curl_ipv4_resolve_r(tsd->hostname, tsd->port); - - if(!tsd->res) { - tsd->sock_error = SOCKERRNO; - if(tsd->sock_error == 0) - tsd->sock_error = RESOLVER_ENOMEM; - } - - Curl_mutex_acquire(tsd->mtx); - if(tsd->done) { - /* too late, gotta clean up the mess */ - Curl_mutex_release(tsd->mtx); - destroy_thread_sync_data(tsd); - free(td); - } - else { - tsd->done = 1; - Curl_mutex_release(tsd->mtx); - } - - return 0; -} - -#endif /* HAVE_GETADDRINFO */ - -/* - * destroy_async_data() cleans up async resolver data and thread handle. - */ -static void destroy_async_data (struct Curl_async *async) -{ - if(async->os_specific) { - struct thread_data *td = (struct thread_data*) async->os_specific; - int done; - - /* - * if the thread is still blocking in the resolve syscall, detach it and - * let the thread do the cleanup... - */ - Curl_mutex_acquire(td->tsd.mtx); - done = td->tsd.done; - td->tsd.done = 1; - Curl_mutex_release(td->tsd.mtx); - - if(!done) { - Curl_thread_destroy(td->thread_hnd); - } - else { - if(td->thread_hnd != curl_thread_t_null) - Curl_thread_join(&td->thread_hnd); - - destroy_thread_sync_data(&td->tsd); - - free(async->os_specific); - } - } - async->os_specific = NULL; - - free(async->hostname); - async->hostname = NULL; -} - -/* - * init_resolve_thread() starts a new thread that performs the actual - * resolve. This function returns before the resolve is done. - * - * Returns FALSE in case of failure, otherwise TRUE. - */ -static bool init_resolve_thread (struct connectdata *conn, - const char *hostname, int port, - const struct addrinfo *hints) -{ - struct thread_data *td = calloc(1, sizeof(struct thread_data)); - int err = RESOLVER_ENOMEM; - - conn->async.os_specific = (void*) td; - if(!td) - goto err_exit; - - conn->async.port = port; - conn->async.done = FALSE; - conn->async.status = 0; - conn->async.dns = NULL; - td->thread_hnd = curl_thread_t_null; - - if(!init_thread_sync_data(td, hostname, port, hints)) - goto err_exit; - - free(conn->async.hostname); - conn->async.hostname = strdup(hostname); - if(!conn->async.hostname) - goto err_exit; - -#ifdef HAVE_GETADDRINFO - td->thread_hnd = Curl_thread_create(getaddrinfo_thread, &td->tsd); -#else - td->thread_hnd = Curl_thread_create(gethostbyname_thread, &td->tsd); -#endif - - if(!td->thread_hnd) { -#ifndef _WIN32_WCE - err = errno; -#endif - goto err_exit; - } - - return TRUE; - - err_exit: - destroy_async_data(&conn->async); - - SET_ERRNO(err); - - return FALSE; -} - -/* - * resolver_error() calls failf() with the appropriate message after a resolve - * error - */ - -static CURLcode resolver_error(struct connectdata *conn) -{ - const char *host_or_proxy; - CURLcode result; - - if(conn->bits.httpproxy) { - host_or_proxy = "proxy"; - result = CURLE_COULDNT_RESOLVE_PROXY; - } - else { - host_or_proxy = "host"; - result = CURLE_COULDNT_RESOLVE_HOST; - } - - failf(conn->data, "Could not resolve %s: %s", host_or_proxy, - conn->async.hostname); - - return result; -} - -/* - * Curl_resolver_wait_resolv() - * - * waits for a resolve to finish. This function should be avoided since using - * this risk getting the multi interface to "hang". - * - * If 'entry' is non-NULL, make it point to the resolved dns entry - * - * This is the version for resolves-in-a-thread. - */ -CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - CURLcode result = CURLE_OK; - - DEBUGASSERT(conn && td); - - /* wait for the thread to resolve the name */ - if(Curl_thread_join(&td->thread_hnd)) - result = getaddrinfo_complete(conn); - else - DEBUGASSERT(0); - - conn->async.done = TRUE; - - if(entry) - *entry = conn->async.dns; - - if(!conn->async.dns) - /* a name was not resolved, report error */ - result = resolver_error(conn); - - destroy_async_data(&conn->async); - - if(!conn->async.dns) - connclose(conn, "asynch resolve failed"); - - return result; -} - -/* - * Curl_resolver_is_resolved() is called repeatedly to check if a previous - * name resolve request has completed. It should also make sure to time-out if - * the operation seems to take too long. - */ -CURLcode Curl_resolver_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **entry) -{ - struct SessionHandle *data = conn->data; - struct thread_data *td = (struct thread_data*) conn->async.os_specific; - int done = 0; - - *entry = NULL; - - if(!td) { - DEBUGASSERT(td); - return CURLE_COULDNT_RESOLVE_HOST; - } - - Curl_mutex_acquire(td->tsd.mtx); - done = td->tsd.done; - Curl_mutex_release(td->tsd.mtx); - - if(done) { - getaddrinfo_complete(conn); - - if(!conn->async.dns) { - CURLcode result = resolver_error(conn); - destroy_async_data(&conn->async); - return result; - } - destroy_async_data(&conn->async); - *entry = conn->async.dns; - } - else { - /* poll for name lookup done with exponential backoff up to 250ms */ - long elapsed = Curl_tvdiff(Curl_tvnow(), data->progress.t_startsingle); - if(elapsed < 0) - elapsed = 0; - - if(td->poll_interval == 0) - /* Start at 1ms poll interval */ - td->poll_interval = 1; - else if(elapsed >= td->interval_end) - /* Back-off exponentially if last interval expired */ - td->poll_interval *= 2; - - if(td->poll_interval > 250) - td->poll_interval = 250; - - td->interval_end = elapsed + td->poll_interval; - Curl_expire(conn->data, td->poll_interval); - } - - return CURLE_OK; -} - -int Curl_resolver_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - (void)conn; - (void)socks; - (void)numsocks; - return 0; -} - -#ifndef HAVE_GETADDRINFO -/* - * Curl_getaddrinfo() - for platforms without getaddrinfo - */ -Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) -{ - struct in_addr in; - - *waitp = 0; /* default to synchronous response */ - - if(Curl_inet_pton(AF_INET, hostname, &in) > 0) - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(AF_INET, &in, hostname, port); - - /* fire up a new resolver thread! */ - if(init_resolve_thread(conn, hostname, port, NULL)) { - *waitp = 1; /* expect asynchronous response */ - return NULL; - } - - /* fall-back to blocking version */ - return Curl_ipv4_resolve_r(hostname, port); -} - -#else /* !HAVE_GETADDRINFO */ - -/* - * Curl_resolver_getaddrinfo() - for getaddrinfo - */ -Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) -{ - struct addrinfo hints; - struct in_addr in; - Curl_addrinfo *res; - int error; - char sbuf[12]; - int pf = PF_INET; -#ifdef CURLRES_IPV6 - struct in6_addr in6; -#endif /* CURLRES_IPV6 */ - - *waitp = 0; /* default to synchronous response */ - - /* First check if this is an IPv4 address string */ - if(Curl_inet_pton(AF_INET, hostname, &in) > 0) - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(AF_INET, &in, hostname, port); - -#ifdef CURLRES_IPV6 - /* check if this is an IPv6 address string */ - if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0) - /* This is an IPv6 address literal */ - return Curl_ip2addr(AF_INET6, &in6, hostname, port); - - /* - * Check if a limited name resolve has been requested. - */ - switch(conn->ip_version) { - case CURL_IPRESOLVE_V4: - pf = PF_INET; - break; - case CURL_IPRESOLVE_V6: - pf = PF_INET6; - break; - default: - pf = PF_UNSPEC; - break; - } - - if((pf != PF_INET) && !Curl_ipv6works()) - /* The stack seems to be a non-IPv6 one */ - pf = PF_INET; - -#endif /* CURLRES_IPV6 */ - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = pf; - hints.ai_socktype = conn->socktype; - - snprintf(sbuf, sizeof(sbuf), "%d", port); - - /* fire up a new resolver thread! */ - if(init_resolve_thread(conn, hostname, port, &hints)) { - *waitp = 1; /* expect asynchronous response */ - return NULL; - } - - /* fall-back to blocking version */ - infof(conn->data, "init_resolve_thread() failed for %s; %s\n", - hostname, Curl_strerror(conn, ERRNO)); - - error = Curl_getaddrinfo_ex(hostname, sbuf, &hints, &res); - if(error) { - infof(conn->data, "getaddrinfo() failed for %s:%d; %s\n", - hostname, port, Curl_strerror(conn, SOCKERRNO)); - return NULL; - } - return res; -} - -#endif /* !HAVE_GETADDRINFO */ - -CURLcode Curl_set_dns_servers(struct SessionHandle *data, - char *servers) -{ - (void)data; - (void)servers; - return CURLE_NOT_BUILT_IN; - -} - -CURLcode Curl_set_dns_interface(struct SessionHandle *data, - const char *interf) -{ - (void)data; - (void)interf; - return CURLE_NOT_BUILT_IN; -} - -CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data, - const char *local_ip4) -{ - (void)data; - (void)local_ip4; - return CURLE_NOT_BUILT_IN; -} - -CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data, - const char *local_ip6) -{ - (void)data; - (void)local_ip6; - return CURLE_NOT_BUILT_IN; -} - -#endif /* CURLRES_THREADED */ diff --git a/Externals/curl/lib/asyn.h b/Externals/curl/lib/asyn.h deleted file mode 100644 index 416510f95f..0000000000 --- a/Externals/curl/lib/asyn.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef HEADER_CURL_ASYN_H -#define HEADER_CURL_ASYN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" -#include "curl_addrinfo.h" - -struct addrinfo; -struct hostent; -struct SessionHandle; -struct connectdata; -struct Curl_dns_entry; - -/* - * This header defines all functions in the internal asynch resolver interface. - * All asynch resolvers need to provide these functions. - * asyn-ares.c and asyn-thread.c are the current implementations of asynch - * resolver backends. - */ - -/* - * Curl_resolver_global_init() - * - * Called from curl_global_init() to initialize global resolver environment. - * Returning anything else than CURLE_OK fails curl_global_init(). - */ -int Curl_resolver_global_init(void); - -/* - * Curl_resolver_global_cleanup() - * Called from curl_global_cleanup() to destroy global resolver environment. - */ -void Curl_resolver_global_cleanup(void); - -/* - * Curl_resolver_init() - * Called from curl_easy_init() -> Curl_open() to initialize resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Should fill the passed pointer by the initialized handler. - * Returning anything else than CURLE_OK fails curl_easy_init() with the - * correspondent code. - */ -CURLcode Curl_resolver_init(void **resolver); - -/* - * Curl_resolver_cleanup() - * Called from curl_easy_cleanup() -> Curl_close() to cleanup resolver - * URL-state specific environment ('resolver' member of the UrlState - * structure). Should destroy the handler and free all resources connected to - * it. - */ -void Curl_resolver_cleanup(void *resolver); - -/* - * Curl_resolver_duphandle() - * Called from curl_easy_duphandle() to duplicate resolver URL-state specific - * environment ('resolver' member of the UrlState structure). Should - * duplicate the 'from' handle and pass the resulting handle to the 'to' - * pointer. Returning anything else than CURLE_OK causes failed - * curl_easy_duphandle() call. - */ -int Curl_resolver_duphandle(void **to, void *from); - -/* - * Curl_resolver_cancel(). - * - * It is called from inside other functions to cancel currently performing - * resolver request. Should also free any temporary resources allocated to - * perform a request. - */ -void Curl_resolver_cancel(struct connectdata *conn); - -/* Curl_resolver_getsock() - * - * This function is called from the multi_getsock() function. 'sock' is a - * pointer to an array to hold the file descriptors, with 'numsock' being the - * size of that array (in number of entries). This function is supposed to - * return bitmask indicating what file descriptors (referring to array indexes - * in the 'sock' array) to wait for, read/write. - */ -int Curl_resolver_getsock(struct connectdata *conn, curl_socket_t *sock, - int numsocks); - -/* - * Curl_resolver_is_resolved() - * - * Called repeatedly to check if a previous name resolve request has - * completed. It should also make sure to time-out if the operation seems to - * take too long. - * - * Returns normal CURLcode errors. - */ -CURLcode Curl_resolver_is_resolved(struct connectdata *conn, - struct Curl_dns_entry **dns); - -/* - * Curl_resolver_wait_resolv() - * - * waits for a resolve to finish. This function should be avoided since using - * this risk getting the multi interface to "hang". - * - * If 'entry' is non-NULL, make it point to the resolved dns entry - * - * Returns CURLE_COULDNT_RESOLVE_HOST if the host was not resolved, and - * CURLE_OPERATION_TIMEDOUT if a time-out occurred. - - */ -CURLcode Curl_resolver_wait_resolv(struct connectdata *conn, - struct Curl_dns_entry **dnsentry); - -/* - * Curl_resolver_getaddrinfo() - when using this resolver - * - * Returns name information about the given hostname and port number. If - * successful, the 'hostent' is returned and the forth argument will point to - * memory we need to free after use. That memory *MUST* be freed with - * Curl_freeaddrinfo(), nothing else. - * - * Each resolver backend must of course make sure to return data in the - * correct format to comply with this. - */ -Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp); - -#ifndef CURLRES_ASYNCH -/* convert these functions if an asynch resolver isn't used */ -#define Curl_resolver_cancel(x) Curl_nop_stmt -#define Curl_resolver_is_resolved(x,y) CURLE_COULDNT_RESOLVE_HOST -#define Curl_resolver_wait_resolv(x,y) CURLE_COULDNT_RESOLVE_HOST -#define Curl_resolver_getsock(x,y,z) 0 -#define Curl_resolver_duphandle(x,y) CURLE_OK -#define Curl_resolver_init(x) CURLE_OK -#define Curl_resolver_global_init() CURLE_OK -#define Curl_resolver_global_cleanup() Curl_nop_stmt -#define Curl_resolver_cleanup(x) Curl_nop_stmt -#endif - -#ifdef CURLRES_ASYNCH -#define Curl_resolver_asynch() 1 -#else -#define Curl_resolver_asynch() 0 -#endif - - -/********** end of generic resolver interface functions *****************/ -#endif /* HEADER_CURL_ASYN_H */ diff --git a/Externals/curl/lib/base64.c b/Externals/curl/lib/base64.c deleted file mode 100644 index 0ef24d51f8..0000000000 --- a/Externals/curl/lib/base64.c +++ /dev/null @@ -1,315 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* Base64 encoding/decoding */ - -#include "curl_setup.h" -#include "urldata.h" /* for the SessionHandle definition */ -#include "warnless.h" -#include "curl_base64.h" -#include "non-ascii.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* ---- Base64 Encoding/Decoding Table --- */ -static const char base64[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/* The Base 64 encoding with an URL and filename safe alphabet, RFC 4648 - section 5 */ -static const char base64url[]= - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - -static size_t decodeQuantum(unsigned char *dest, const char *src) -{ - size_t padding = 0; - const char *s, *p; - unsigned long i, x = 0; - - for(i = 0, s = src; i < 4; i++, s++) { - unsigned long v = 0; - - if(*s == '=') { - x = (x << 6); - padding++; - } - else { - p = base64; - - while(*p && (*p != *s)) { - v++; - p++; - } - - if(*p == *s) - x = (x << 6) + v; - else - return 0; - } - } - - if(padding < 1) - dest[2] = curlx_ultouc(x & 0xFFUL); - - x >>= 8; - if(padding < 2) - dest[1] = curlx_ultouc(x & 0xFFUL); - - x >>= 8; - dest[0] = curlx_ultouc(x & 0xFFUL); - - return 3 - padding; -} - -/* - * Curl_base64_decode() - * - * Given a base64 NUL-terminated string at src, decode it and return a - * pointer in *outptr to a newly allocated memory area holding decoded - * data. Size of decoded data is returned in variable pointed by outlen. - * - * Returns CURLE_OK on success, otherwise specific error code. Function - * output shall not be considered valid unless CURLE_OK is returned. - * - * When decoded data length is 0, returns NULL in *outptr. - * - * @unittest: 1302 - */ -CURLcode Curl_base64_decode(const char *src, - unsigned char **outptr, size_t *outlen) -{ - size_t srclen = 0; - size_t length = 0; - size_t padding = 0; - size_t i; - size_t numQuantums; - size_t rawlen = 0; - unsigned char *pos; - unsigned char *newstr; - - *outptr = NULL; - *outlen = 0; - srclen = strlen(src); - - /* Check the length of the input string is valid */ - if(!srclen || srclen % 4) - return CURLE_BAD_CONTENT_ENCODING; - - /* Find the position of any = padding characters */ - while((src[length] != '=') && src[length]) - length++; - - /* A maximum of two = padding characters is allowed */ - if(src[length] == '=') { - padding++; - if(src[length + 1] == '=') - padding++; - } - - /* Check the = padding characters weren't part way through the input */ - if(length + padding != srclen) - return CURLE_BAD_CONTENT_ENCODING; - - /* Calculate the number of quantums */ - numQuantums = srclen / 4; - - /* Calculate the size of the decoded string */ - rawlen = (numQuantums * 3) - padding; - - /* Allocate our buffer including room for a zero terminator */ - newstr = malloc(rawlen + 1); - if(!newstr) - return CURLE_OUT_OF_MEMORY; - - pos = newstr; - - /* Decode the quantums */ - for(i = 0; i < numQuantums; i++) { - size_t result = decodeQuantum(pos, src); - if(!result) { - free(newstr); - - return CURLE_BAD_CONTENT_ENCODING; - } - - pos += result; - src += 4; - } - - /* Zero terminate */ - *pos = '\0'; - - /* Return the decoded data */ - *outptr = newstr; - *outlen = rawlen; - - return CURLE_OK; -} - -static CURLcode base64_encode(const char *table64, - struct SessionHandle *data, - const char *inputbuff, size_t insize, - char **outptr, size_t *outlen) -{ - CURLcode result; - unsigned char ibuf[3]; - unsigned char obuf[4]; - int i; - int inputparts; - char *output; - char *base64data; - char *convbuf = NULL; - - const char *indata = inputbuff; - - *outptr = NULL; - *outlen = 0; - - if(!insize) - insize = strlen(indata); - - base64data = output = malloc(insize * 4 / 3 + 4); - if(!output) - return CURLE_OUT_OF_MEMORY; - - /* - * The base64 data needs to be created using the network encoding - * not the host encoding. And we can't change the actual input - * so we copy it to a buffer, translate it, and use that instead. - */ - result = Curl_convert_clone(data, indata, insize, &convbuf); - if(result) { - free(output); - return result; - } - - if(convbuf) - indata = (char *)convbuf; - - while(insize > 0) { - for(i = inputparts = 0; i < 3; i++) { - if(insize > 0) { - inputparts++; - ibuf[i] = (unsigned char) *indata; - indata++; - insize--; - } - else - ibuf[i] = 0; - } - - obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2); - obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \ - ((ibuf[1] & 0xF0) >> 4)); - obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \ - ((ibuf[2] & 0xC0) >> 6)); - obuf[3] = (unsigned char) (ibuf[2] & 0x3F); - - switch(inputparts) { - case 1: /* only one byte read */ - snprintf(output, 5, "%c%c==", - table64[obuf[0]], - table64[obuf[1]]); - break; - - case 2: /* two bytes read */ - snprintf(output, 5, "%c%c%c=", - table64[obuf[0]], - table64[obuf[1]], - table64[obuf[2]]); - break; - - default: - snprintf(output, 5, "%c%c%c%c", - table64[obuf[0]], - table64[obuf[1]], - table64[obuf[2]], - table64[obuf[3]]); - break; - } - output += 4; - } - - /* Zero terminate */ - *output = '\0'; - - /* Return the pointer to the new data (allocated memory) */ - *outptr = base64data; - - free(convbuf); - - /* Return the length of the new data */ - *outlen = strlen(base64data); - - return CURLE_OK; -} - -/* - * Curl_base64_encode() - * - * Given a pointer to an input buffer and an input size, encode it and - * return a pointer in *outptr to a newly allocated memory area holding - * encoded data. Size of encoded data is returned in variable pointed by - * outlen. - * - * Input length of 0 indicates input buffer holds a NUL-terminated string. - * - * Returns CURLE_OK on success, otherwise specific error code. Function - * output shall not be considered valid unless CURLE_OK is returned. - * - * When encoded data length is 0, returns NULL in *outptr. - * - * @unittest: 1302 - */ -CURLcode Curl_base64_encode(struct SessionHandle *data, - const char *inputbuff, size_t insize, - char **outptr, size_t *outlen) -{ - return base64_encode(base64, data, inputbuff, insize, outptr, outlen); -} - -/* - * Curl_base64url_encode() - * - * Given a pointer to an input buffer and an input size, encode it and - * return a pointer in *outptr to a newly allocated memory area holding - * encoded data. Size of encoded data is returned in variable pointed by - * outlen. - * - * Input length of 0 indicates input buffer holds a NUL-terminated string. - * - * Returns CURLE_OK on success, otherwise specific error code. Function - * output shall not be considered valid unless CURLE_OK is returned. - * - * When encoded data length is 0, returns NULL in *outptr. - * - * @unittest: 1302 - */ -CURLcode Curl_base64url_encode(struct SessionHandle *data, - const char *inputbuff, size_t insize, - char **outptr, size_t *outlen) -{ - return base64_encode(base64url, data, inputbuff, insize, outptr, outlen); -} diff --git a/Externals/curl/lib/checksrc.pl b/Externals/curl/lib/checksrc.pl deleted file mode 100755 index aacb242b5d..0000000000 --- a/Externals/curl/lib/checksrc.pl +++ /dev/null @@ -1,493 +0,0 @@ -#!/usr/bin/perl -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) 2011 - 2016, Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -########################################################################### - -my $max_column = 79; -my $indent = 2; - -my $warnings; -my $errors; -my $supressed; # whitelisted problems -my $file; -my $dir="."; -my $wlist; -my $windows_os = $^O eq 'MSWin32' || $^O eq 'msys' || $^O eq 'cygwin'; -my $verbose; -my %whitelist; - -my %warnings = ( - 'LONGLINE' => "Line longer than $max_column", - 'TABS' => 'TAB characters not allowed', - 'TRAILINGSPACE' => 'Trailing white space on the line', - 'CPPCOMMENTS' => '// comment detected', - 'SPACEBEFOREPAREN' => 'space before an open parenthesis', - 'SPACEAFTERPAREN' => 'space after open parenthesis', - 'SPACEBEFORECLOSE' => 'space before a close parenthesis', - 'SPACEBEFORECOMMA' => 'space before a comma', - 'RETURNNOSPACE' => 'return without space', - 'COMMANOSPACE' => 'comma without following space', - 'BRACEELSE' => '} else on the same line', - 'PARENBRACE' => '){ without sufficient space', - 'SPACESEMILCOLON' => 'space before semicolon', - 'BANNEDFUNC' => 'a banned function was used', - 'FOPENMODE' => 'fopen needs a macro for the mode string', - 'BRACEPOS' => 'wrong position for an open brace', - 'INDENTATION' => 'wrong start column for code', - 'COPYRIGHT' => 'file missing a copyright statement', - 'BADCOMMAND' => 'bad !checksrc! instruction', - 'UNUSEDIGNORE' => 'a warning ignore was not used', - 'OPENCOMMENT' => 'file ended with a /* comment still "open"' - ); - -sub readwhitelist { - open(W, "<$dir/checksrc.whitelist"); - my @all=; - for(@all) { - $windows_os ? $_ =~ s/\r?\n$// : chomp; - $whitelist{$_}=1; - } - close(W); -} - -sub checkwarn { - my ($name, $num, $col, $file, $line, $msg, $error) = @_; - - my $w=$error?"error":"warning"; - my $nowarn=0; - - #if(!$warnings{$name}) { - # print STDERR "Dev! there's no description for $name!\n"; - #} - - # checksrc.whitelist - if($whitelist{$line}) { - $nowarn = 1; - } - # !checksrc! controlled - elsif($ignore{$name}) { - $ignore{$name}--; - $ignore_used{$name}++; - $nowarn = 1; - if(!$ignore{$name}) { - # reached zero, enable again - enable_warn($name, $line, $file, $l); - } - } - - if($nowarn) { - $supressed++; - if($w) { - $swarnings++; - } - else { - $serrors++; - } - return; - } - - if($w) { - $warnings++; - } - else { - $errors++; - } - - $col++; - print "$file:$num:$col: $w: $msg ($name)\n"; - print " $line\n"; - - if($col < 80) { - my $pref = (' ' x $col); - print "${pref}^\n"; - } -} - -$file = shift @ARGV; - -while(1) { - - if($file =~ /-D(.*)/) { - $dir = $1; - $file = shift @ARGV; - next; - } - elsif($file =~ /-W(.*)/) { - $wlist .= " $1 "; - $file = shift @ARGV; - next; - } - elsif($file =~ /^(-h|--help)/) { - undef $file; - last; - } - - last; -} - -if(!$file) { - print "checksrc.pl [option] [file2] ...\n"; - print " Options:\n"; - print " -D[DIR] Directory to prepend file names\n"; - print " -h Show help output\n"; - print " -W[file] Whitelist the given file - ignore all its flaws\n"; - print "\nDetects and warns for these problems:\n"; - for(sort keys %warnings) { - printf (" %-18s: %s\n", $_, $warnings{$_}); - } - exit; -} - -readwhitelist(); - -do { - if("$wlist" !~ / $file /) { - my $fullname = $file; - $fullname = "$dir/$file" if ($fullname !~ '^\.?\.?/'); - scanfile($fullname); - } - $file = shift @ARGV; - -} while($file); - -sub checksrc_clear { - undef %ignore; - undef %ignore_set; - undef @ignore_line; -} - -sub checksrc_endoffile { - my ($file) = @_; - for(keys %ignore_set) { - if($ignore_set{$_} && !$ignore_used{$_}) { - checkwarn("UNUSEDIGNORE", $ignore_set{$_}, - length($_)+11, $file, - $ignore_line[$ignore_set{$_}], - "Unused ignore: $_"); - } - } -} - -sub enable_warn { - my ($what, $line, $file, $l) = @_; - - # switch it back on, but warn if not triggered! - if(!$ignore_used{$what}) { - checkwarn("UNUSEDIGNORE", - $line, length($what) + 11, $file, $l, - "No warning was inhibited!"); - } - $ignore_set{$what}=0; - $ignore_used{$what}=0; - $ignore{$what}=0; -} -sub checksrc { - my ($cmd, $line, $file, $l) = @_; - if($cmd =~ / *([^ ]*) *(.*)/) { - my ($enable, $what) = ($1, $2); - $what =~ s: *\*/$::; # cut off end of C comment - # print "ENABLE $enable WHAT $what\n"; - if($enable eq "disable") { - my ($warn, $scope)=($1, $2); - if($what =~ /([^ ]*) +(.*)/) { - ($warn, $scope)=($1, $2); - } - else { - $warn = $what; - $scope = 1; - } - # print "IGNORE $warn for SCOPE $scope\n"; - if($scope eq "all") { - $scope=999999; - } - - if($ignore_set{$warn}) { - checkwarn("BADCOMMAND", - $line, 0, $file, $l, - "$warn already disabled from line $ignore_set{$warn}"); - } - else { - $ignore{$warn}=$scope; - $ignore_set{$warn}=$line; - $ignore_line[$line]=$l; - } - } - elsif($enable eq "enable") { - enable_warn($what, $line, $file, $l); - } - else { - checkwarn("BADCOMMAND", - $line, 0, $file, $l, - "Illegal !checksrc! command"); - } - } -} - -sub scanfile { - my ($file) = @_; - - my $line = 1; - my $prevl; - my $l; - open(R, "<$file") || die "failed to open $file"; - - my $incomment=0; - my $copyright=0; - checksrc_clear(); # for file based ignores - - while() { - $windows_os ? $_ =~ s/\r?\n$// : chomp; - my $l = $_; - my $ol = $l; # keep the unmodified line for error reporting - my $column = 0; - - # check for !checksrc! commands - if($l =~ /\!checksrc\! (.*)/) { - my $cmd = $1; - checksrc($cmd, $line, $file, $l) - } - - # check for a copyright statement - if(!$copyright && ($l =~ /copyright .* \d\d\d\d/i)) { - $copyright=1; - } - - # detect long lines - if(length($l) > $max_column) { - checkwarn("LONGLINE", $line, length($l), $file, $l, - "Longer than $max_column columns"); - } - # detect TAB characters - if($l =~ /^(.*)\t/) { - checkwarn("TABS", - $line, length($1), $file, $l, "Contains TAB character", 1); - } - # detect trailing white space - if($l =~ /^(.*)[ \t]+\z/) { - checkwarn("TRAILINGSPACE", - $line, length($1), $file, $l, "Trailing whitespace"); - } - - # ------------------------------------------------------------ - # Above this marker, the checks were done on lines *including* - # comments - # ------------------------------------------------------------ - - # strip off C89 comments - - comment: - if(!$incomment) { - if($l =~ s/\/\*.*\*\// /g) { - # full /* comments */ were removed! - } - if($l =~ s/\/\*.*//) { - # start of /* comment was removed - $incomment = 1; - } - } - else { - if($l =~ s/.*\*\///) { - # end of comment */ was removed - $incomment = 0; - goto comment; - } - else { - # still within a comment - $l=""; - } - } - - # ------------------------------------------------------------ - # Below this marker, the checks were done on lines *without* - # comments - # ------------------------------------------------------------ - - # crude attempt to detect // comments without too many false - # positives - if($l =~ /^([^"\*]*)[^:"]\/\//) { - checkwarn("CPPCOMMENTS", - $line, length($1), $file, $l, "\/\/ comment"); - } - - # check spaces after for/if/while - if($l =~ /^(.*)(for|if|while) \(/) { - if($1 =~ / *\#/) { - # this is a #if, treat it differently - } - else { - checkwarn("SPACEBEFOREPAREN", $line, length($1)+length($2), $file, $l, - "$2 with space"); - } - } - - # check spaces after open parentheses - if($l =~ /^(.*[a-z])\( /i) { - checkwarn("SPACEAFTERPAREN", - $line, length($1)+1, $file, $l, - "space after open parenthesis"); - } - - # check spaces before close parentheses, unless it was a space or a - # close parenthesis! - if($l =~ /(.*[^\) ]) \)/) { - checkwarn("SPACEBEFORECLOSE", - $line, length($1)+1, $file, $l, - "space before close parenthesis"); - } - - # check spaces before comma! - if($l =~ /(.*[^ ]) ,/) { - checkwarn("SPACEBEFORECOMMA", - $line, length($1)+1, $file, $l, - "space before comma"); - } - - # check for "return(" without space - if($l =~ /^(.*)return\(/) { - if($1 =~ / *\#/) { - # this is a #if, treat it differently - } - else { - checkwarn("RETURNNOSPACE", $line, length($1)+6, $file, $l, - "return without space before paren"); - } - } - - # check for comma without space - if($l =~ /^(.*),[^ \n]/) { - my $pref=$1; - my $ign=0; - if($pref =~ / *\#/) { - # this is a #if, treat it differently - $ign=1; - } - elsif($pref =~ /\/\*/) { - # this is a comment - $ign=1; - } - elsif($pref =~ /[\"\']/) { - $ign = 1; - # There is a quote here, figure out whether the comma is - # within a string or '' or not. - if($pref =~ /\"/) { - # withing a string - } - elsif($pref =~ /\'$/) { - # a single letter - } - else { - $ign = 0; - } - } - if(!$ign) { - checkwarn("COMMANOSPACE", $line, length($pref)+1, $file, $l, - "comma without following space"); - } - } - - # check for "} else" - if($l =~ /^(.*)\} *else/) { - checkwarn("BRACEELSE", - $line, length($1), $file, $l, "else after closing brace on same line"); - } - # check for "){" - if($l =~ /^(.*)\)\{/) { - checkwarn("PARENBRACE", - $line, length($1)+1, $file, $l, "missing space after close paren"); - } - - # check for space before the semicolon last in a line - if($l =~ /^(.*[^ ].*) ;$/) { - checkwarn("SPACESEMILCOLON", - $line, length($1), $file, $ol, "space before last semicolon"); - } - - # scan for use of banned functions - if($l =~ /^(.*\W)(sprintf|vsprintf|strcat|strncat|_mbscat|_mbsncat|_tcscat|_tcsncat|wcscat|wcsncat|gets)\s*\(/) { - checkwarn("BANNEDFUNC", - $line, length($1), $file, $ol, - "use of $2 is banned"); - } - - # scan for use of non-binary fopen without the macro - if($l =~ /^(.*\W)fopen\s*\([^,]*, *\"([^"]*)/) { - my $mode = $2; - if($mode !~ /b/) { - checkwarn("FOPENMODE", - $line, length($1), $file, $ol, - "use of non-binary fopen without FOPEN_* macro: $mode"); - } - } - - # check for open brace first on line but not first column - # only alert if previous line ended with a close paren and wasn't a cpp - # line - if((($prevl =~ /\)\z/) && ($prevl !~ /^ *#/)) && ($l =~ /^( +)\{/)) { - checkwarn("BRACEPOS", - $line, length($1), $file, $ol, "badly placed open brace"); - } - - # if the previous line starts with if/while/for AND ends with an open - # brace, check that this line is indented $indent more steps, if not - # a cpp line - if($prevl =~ /^( *)(if|while|for)\(.*\{\z/) { - my $first = length($1); - - # this line has some character besides spaces - if(($l !~ /^ *#/) && ($l =~ /^( *)[^ ]/)) { - my $second = length($1); - my $expect = $first+$indent; - if($expect != $second) { - my $diff = $second - $first; - checkwarn("INDENTATION", $line, length($1), $file, $ol, - "not indented $indent steps, uses $diff)"); - - } - } - } - - $line++; - $prevl = $ol; - } - - if(!$copyright) { - checkwarn("COPYRIGHT", 1, 0, $file, "", "Missing copyright statement", 1); - } - if($incomment) { - checkwarn("OPENCOMMENT", 1, 0, $file, "", "Missing closing comment", 1); - } - - checksrc_endoffile($file); - - close(R); - -} - - -if($errors || $warnings || $verbose) { - printf "checksrc: %d errors and %d warnings\n", $errors, $warnings; - if($supressed) { - printf "checksrc: %d errors and %d warnings suppressed\n", - $serrors, - $swarnings; - } - exit 5; # return failure -} diff --git a/Externals/curl/lib/config-amigaos.h b/Externals/curl/lib/config-amigaos.h deleted file mode 100644 index 74f5f5278f..0000000000 --- a/Externals/curl/lib/config-amigaos.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_AMIGAOS_H -#define HEADER_CURL_CONFIG_AMIGAOS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for AmigaOS */ -/* ================================================================ */ - -#ifdef __AMIGA__ /* Any AmigaOS flavour */ - -#define HAVE_ARPA_INET_H 1 -#define HAVE_CLOSESOCKET_CAMEL 1 -#define HAVE_ERRNO_H 1 -#define HAVE_GETHOSTBYADDR 1 -#define HAVE_INET_ADDR 1 -#define HAVE_INTTYPES_H 1 -#define HAVE_IOCTLSOCKET_CAMEL 1 -#define HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 -#define HAVE_LIBCRYPTO 1 -#define HAVE_LIBSSL 1 -#define HAVE_LIBZ 1 -#define HAVE_LONGLONG 1 -#define HAVE_MALLOC_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_NETDB_H 1 -#define HAVE_NETINET_IN_H 1 -#define HAVE_NET_IF_H 1 -#define HAVE_OPENSSL_CRYPTO_H 1 -#define HAVE_OPENSSL_ERR_H 1 -#define HAVE_OPENSSL_PEM_H 1 -#define HAVE_OPENSSL_RSA_H 1 -#define HAVE_OPENSSL_SSL_H 1 -#define HAVE_OPENSSL_X509_H 1 -#define HAVE_PERROR 1 -#define HAVE_PWD_H 1 -#define HAVE_RAND_EGD 1 -#define HAVE_RAND_STATUS 1 -#define HAVE_SELECT 1 -#define HAVE_SETJMP_H 1 -#define HAVE_SGTTY_H 1 -#define HAVE_SIGNAL 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_SIG_ATOMIC_T 1 -#define HAVE_SOCKET 1 -#define HAVE_STRCASECMP 1 -#define HAVE_STRDUP 1 -#define HAVE_STRFTIME 1 -#define HAVE_STRICMP 1 -#define HAVE_STRINGS_H 1 -#define HAVE_STRING_H 1 -#define HAVE_STRSTR 1 -#define HAVE_STRUCT_TIMEVAL 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_SOCKET_H 1 -#define HAVE_SYS_SOCKIO_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_TIME_H 1 -#define HAVE_UNAME 1 -#define HAVE_UNISTD_H 1 -#define HAVE_UTIME 1 -#define HAVE_UTIME_H 1 -#define HAVE_WRITABLE_ARGV 1 -#define HAVE_ZLIB_H 1 -#define HAVE_SYS_IOCTL_H 1 - -#define NEED_MALLOC_H 1 - -#define SIZEOF_INT 4 -#define SIZEOF_SHORT 2 -#define SIZEOF_SIZE_T 4 - -#define USE_MANUAL 1 -#define USE_OPENSSL 1 -#define CURL_DISABLE_LDAP 1 - -#define OS "AmigaOS" - -#define PACKAGE "curl" -#define PACKAGE_BUGREPORT "curl-bug@haxx.se" -#define PACKAGE_NAME "curl" -#define PACKAGE_STRING "curl -" -#define PACKAGE_TARNAME "curl" -#define PACKAGE_VERSION "-" -#define CURL_CA_BUNDLE "s:curl-ca-bundle.crt" - -#define RETSIGTYPE void -#define SELECT_TYPE_ARG1 int -#define SELECT_TYPE_ARG234 (fd_set *) -#define SELECT_TYPE_ARG5 (struct timeval *) - -#define STDC_HEADERS 1 -#define TIME_WITH_SYS_TIME 1 - -#define in_addr_t int - -#ifndef F_OK -# define F_OK 0 -#endif - -#ifndef O_RDONLY -# define O_RDONLY 0x0000 -#endif - -#ifndef LONG_MAX -# define LONG_MAX 0x7fffffffL -#endif - -#ifndef LONG_MIN -# define LONG_MIN (-0x7fffffffL-1) -#endif - -#define HAVE_GETNAMEINFO 1 -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 int -#define GETNAMEINFO_TYPE_ARG46 size_t -#define GETNAMEINFO_TYPE_ARG7 int - -#define HAVE_RECV 1 -#define RECV_TYPE_ARG1 long -#define RECV_TYPE_ARG2 char * -#define RECV_TYPE_ARG3 long -#define RECV_TYPE_ARG4 long -#define RECV_TYPE_RETV long - -#define HAVE_RECVFROM 1 -#define RECVFROM_TYPE_ARG1 long -#define RECVFROM_TYPE_ARG2 char -#define RECVFROM_TYPE_ARG3 long -#define RECVFROM_TYPE_ARG4 long -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 long -#define RECVFROM_TYPE_RETV long - -#define HAVE_SEND 1 -#define SEND_TYPE_ARG1 int -#define SEND_QUAL_ARG2 const -#define SEND_TYPE_ARG2 char * -#define SEND_TYPE_ARG3 int -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV int - -#endif /* __AMIGA__ */ -#endif /* HEADER_CURL_CONFIG_AMIGAOS_H */ diff --git a/Externals/curl/lib/config-dos.h b/Externals/curl/lib/config-dos.h deleted file mode 100644 index f2c9ff4035..0000000000 --- a/Externals/curl/lib/config-dos.h +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_DOS_H -#define HEADER_CURL_CONFIG_DOS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - - -/* ================================================================ */ -/* lib/config-dos.h - Hand crafted config file for DOS */ -/* ================================================================ */ - -#if defined(DJGPP) - #define OS "MSDOS/djgpp" -#elif defined(__HIGHC__) - #define OS "MSDOS/HighC" -#elif defined(__WATCOMC__) - #define OS "MSDOS/Watcom" -#else - #define OS "MSDOS/?" -#endif - -#define PACKAGE "curl" - -#define HAVE_ARPA_INET_H 1 -#define HAVE_ERRNO_H 1 -#define HAVE_FCNTL_H 1 -#define HAVE_GETADDRINFO 1 -#define HAVE_GETNAMEINFO 1 -#define HAVE_GETPROTOBYNAME 1 -#define HAVE_GETTIMEOFDAY 1 -#define HAVE_IO_H 1 -#define HAVE_IOCTL 1 -#define HAVE_IOCTL_FIONBIO 1 -#define HAVE_IOCTLSOCKET 1 -#define HAVE_IOCTLSOCKET_FIONBIO 1 -#define HAVE_LIMITS_H 1 -#define HAVE_LOCALE_H 1 -#define HAVE_LONGLONG 1 -#define HAVE_MEMORY_H 1 -#define HAVE_NETDB_H 1 -#define HAVE_NETINET_IN_H 1 -#define HAVE_NETINET_TCP_H 1 -#define HAVE_NET_IF_H 1 -#define HAVE_PROCESS_H 1 -#define HAVE_RECV 1 -#define HAVE_RECVFROM 1 -#define HAVE_SELECT 1 -#define HAVE_SEND 1 -#define HAVE_SETJMP_H 1 -#define HAVE_SETLOCALE 1 -#define HAVE_SETMODE 1 -#define HAVE_SIGNAL 1 -#define HAVE_SOCKET 1 -#define HAVE_STRDUP 1 -#define HAVE_STRICMP 1 -#define HAVE_STRTOLL 1 -#define HAVE_STRUCT_TIMEVAL 1 -#define HAVE_STRUCT_IN6_ADDR 1 -#define HAVE_SYS_IOCTL_H 1 -#define HAVE_SYS_SOCKET_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_TIME_H 1 -#define HAVE_UNISTD_H 1 - -#define NEED_MALLOC_H 1 - -#define RETSIGTYPE void -#define SIZEOF_INT 4 -#define SIZEOF_LONG_DOUBLE 16 -#define SIZEOF_SHORT 2 -#define SIZEOF_SIZE_T 4 -#define STDC_HEADERS 1 -#define TIME_WITH_SYS_TIME 1 - -/* Qualifiers for send(), recv(), recvfrom() and getnameinfo(). */ - -#define SEND_TYPE_ARG1 int -#define SEND_QUAL_ARG2 const -#define SEND_TYPE_ARG2 void * -#define SEND_TYPE_ARG3 int -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV int - -#define RECV_TYPE_ARG1 int -#define RECV_TYPE_ARG2 void * -#define RECV_TYPE_ARG3 int -#define RECV_TYPE_ARG4 int -#define RECV_TYPE_RETV int - -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG3 int -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 int -#define RECVFROM_TYPE_RETV int -#define RECVFROM_TYPE_ARG2_IS_VOID 1 - -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 int -#define GETNAMEINFO_TYPE_ARG46 int -#define GETNAMEINFO_TYPE_ARG7 int - -#define BSD - -/* CURLDEBUG definition enables memory tracking */ -/* #define CURLDEBUG */ - -/* USE_ZLIB on cmd-line */ -#ifdef USE_ZLIB - #define HAVE_ZLIB_H 1 - #define HAVE_LIBZ 1 -#endif - -/* USE_OPENSSL on cmd-line */ -#ifdef USE_OPENSSL - #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - #define HAVE_OPENSSL_ENGINE_H 1 - #define OPENSSL_NO_KRB5 1 -#endif - -/* to disable LDAP */ -#define CURL_DISABLE_LDAP 1 - -#define in_addr_t u_long - -#if defined(__HIGHC__) || \ - (defined(__GNUC__) && (__GNUC__ < 4)) - #define ssize_t int -#endif - -#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE") - -/* Target HAVE_x section */ - -#if defined(DJGPP) - #define HAVE_BASENAME 1 - #define HAVE_STRCASECMP 1 - #define HAVE_SIGACTION 1 - #define HAVE_SIGSETJMP 1 - #define HAVE_SYS_TIME_H 1 - #define HAVE_TERMIOS_H 1 - #define HAVE_VARIADIC_MACROS_GCC 1 - -#elif defined(__WATCOMC__) - #define HAVE_STRCASECMP 1 - -#elif defined(__HIGHC__) - #define HAVE_SYS_TIME_H 1 - #define strerror(e) strerror_s_((e)) -#endif - -#ifdef MSDOS /* Watt-32 */ - #define HAVE_CLOSE_S 1 -#endif - -#undef word -#undef byte - -#endif /* HEADER_CURL_CONFIG_DOS_H */ - diff --git a/Externals/curl/lib/config-mac.h b/Externals/curl/lib/config-mac.h deleted file mode 100644 index 3c12bdfacc..0000000000 --- a/Externals/curl/lib/config-mac.h +++ /dev/null @@ -1,125 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_MAC_H -#define HEADER_CURL_CONFIG_MAC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* =================================================================== */ -/* Hand crafted config file for Mac OS 9 */ -/* =================================================================== */ -/* On Mac OS X you must run configure to generate curl_config.h file */ -/* =================================================================== */ - -#define OS "mac" - -/* Define if you want the built-in manual */ -#define USE_MANUAL 1 - -#define HAVE_ERRNO_H 1 -#define HAVE_NETINET_IN_H 1 -#define HAVE_SYS_SOCKET_H 1 -#define HAVE_SYS_SELECT_H 1 -#define HAVE_NETDB_H 1 -#define HAVE_ARPA_INET_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_NET_IF_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_GETTIMEOFDAY 1 -#define HAVE_FCNTL_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_ALLOCA_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_TIME_H 1 -#define HAVE_UTIME_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_UTIME_H 1 - -#define TIME_WITH_SYS_TIME 1 - -#define HAVE_ALARM 1 -#define HAVE_FTRUNCATE 1 -#define HAVE_UTIME 1 -#define HAVE_SETVBUF 1 -#define HAVE_STRFTIME 1 -#define HAVE_INET_ADDR 1 -#define HAVE_MEMCPY 1 -#define HAVE_SELECT 1 -#define HAVE_SOCKET 1 -#define HAVE_STRUCT_TIMEVAL 1 - -#define HAVE_SIGACTION 1 -#define HAVE_SIGNAL_H 1 -#define HAVE_SIG_ATOMIC_T 1 - -#ifdef MACOS_SSL_SUPPORT -# define USE_OPENSSL 1 -#endif - -#define CURL_DISABLE_LDAP 1 - -#define HAVE_RAND_STATUS 1 -#define HAVE_RAND_EGD 1 - -#define HAVE_IOCTL 1 -#define HAVE_IOCTL_FIONBIO 1 - -#define RETSIGTYPE void - -#define SIZEOF_INT 4 -#define SIZEOF_SHORT 2 -#define SIZEOF_SIZE_T 4 - -#define HAVE_GETNAMEINFO 1 -#define GETNAMEINFO_QUAL_ARG1 const -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * -#define GETNAMEINFO_TYPE_ARG2 socklen_t -#define GETNAMEINFO_TYPE_ARG46 size_t -#define GETNAMEINFO_TYPE_ARG7 int - -#define HAVE_RECV 1 -#define RECV_TYPE_ARG1 int -#define RECV_TYPE_ARG2 void * -#define RECV_TYPE_ARG3 size_t -#define RECV_TYPE_ARG4 int -#define RECV_TYPE_RETV ssize_t - -#define HAVE_RECVFROM 1 -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG3 size_t -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 int -#define RECVFROM_TYPE_RETV ssize_t -#define RECVFROM_TYPE_ARG2_IS_VOID 1 - -#define HAVE_SEND 1 -#define SEND_TYPE_ARG1 int -#define SEND_QUAL_ARG2 const -#define SEND_TYPE_ARG2 void * -#define SEND_TYPE_ARG3 size_T -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV ssize_t - -#define HAVE_EXTRA_STRICMP_H 1 -#define HAVE_EXTRA_STRDUP_H 1 - -#endif /* HEADER_CURL_CONFIG_MAC_H */ diff --git a/Externals/curl/lib/config-os400.h b/Externals/curl/lib/config-os400.h deleted file mode 100644 index fe5b864d64..0000000000 --- a/Externals/curl/lib/config-os400.h +++ /dev/null @@ -1,563 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_OS400_H -#define HEADER_CURL_CONFIG_OS400_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for OS/400 */ -/* ================================================================ */ - -#pragma enum(int) - -#undef PACKAGE - -/* Version number of this archive. */ -#undef VERSION - -/* Define if you have the getpass function. */ -#undef HAVE_GETPASS - -/* Define cpu-machine-OS */ -#define OS "OS/400" - -/* Define if you have the gethostbyaddr_r() function with 5 arguments */ -#define HAVE_GETHOSTBYADDR_R_5 - -/* Define if you have the gethostbyaddr_r() function with 7 arguments */ -#undef HAVE_GETHOSTBYADDR_R_7 - -/* Define if you have the gethostbyaddr_r() function with 8 arguments */ -#undef HAVE_GETHOSTBYADDR_R_8 - -/* OS400 supports a 3-argument ASCII version of gethostbyaddr_r(), but its - * prototype is incompatible with the "standard" one (1st argument is not - * const). However, getaddrinfo() is supported (ASCII version defined as - * a local wrapper in setup-os400.h) in a threadsafe way: we can then - * configure getaddrinfo() as such and get rid of gethostbyname_r() without - * loss of threadsafeness. */ -#undef HAVE_GETHOSTBYNAME_R -#undef HAVE_GETHOSTBYNAME_R_3 -#undef HAVE_GETHOSTBYNAME_R_5 -#undef HAVE_GETHOSTBYNAME_R_6 -#define HAVE_GETADDRINFO -#define HAVE_GETADDRINFO_THREADSAFE - -/* Define if you need the _REENTRANT define for some functions */ -#undef NEED_REENTRANT - -/* Define if you have the Kerberos4 libraries (including -ldes) */ -#undef HAVE_KRB4 - -/* Define if you want to enable IPv6 support */ -#define ENABLE_IPV6 - -/* Define if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define this to 'int' if ssize_t is not an available typedefed type */ -#undef ssize_t - -/* Define this as a suitable file to read random data from */ -#undef RANDOM_FILE - -/* Define this to your Entropy Gathering Daemon socket pathname */ -#undef EGD_SOCKET - -/* Define to 1 if you have the alarm function. */ -#define HAVE_ALARM 1 - -/* Define if you have the header file. */ -#undef HAVE_ALLOCA_H - -/* Define if you have the header file. */ -#define HAVE_ARPA_INET_H - -/* Define if you have the `closesocket' function. */ -#undef HAVE_CLOSESOCKET - -/* Define if you have the header file. */ -#undef HAVE_CRYPTO_H - -/* Define if you have the header file. */ -#undef HAVE_DES_H - -/* Define if you have the header file. */ -#define HAVE_ERRNO_H - -/* Define if you have the header file. */ -#undef HAVE_ERR_H - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H - -/* Define if you have the `geteuid' function. */ -#define HAVE_GETEUID - -/* Define if you have the `gethostbyaddr' function. */ -#define HAVE_GETHOSTBYADDR - -/* Define if you have the `gethostbyaddr_r' function. */ -#define HAVE_GETHOSTBYADDR_R - -/* Define if you have the `gethostname' function. */ -#define HAVE_GETHOSTNAME - -/* Define if you have the header file. */ -#undef HAVE_GETOPT_H - -/* Define if you have the `getpass_r' function. */ -#undef HAVE_GETPASS_R - -/* Define if you have the `getpwuid' function. */ -#define HAVE_GETPWUID - -/* Define if you have the `getservbyname' function. */ -#define HAVE_GETSERVBYNAME - -/* Define if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY - -/* Define if you have the `timeval' struct. */ -#define HAVE_STRUCT_TIMEVAL - -/* Define if you have the `inet_addr' function. */ -#define HAVE_INET_ADDR - -/* Define if you have the header file. */ -#define HAVE_INTTYPES_H - -/* Define if you have the header file. */ -#undef HAVE_IO_H - -/* Define if you have the `krb_get_our_ip_for_realm' function. */ -#undef HAVE_KRB_GET_OUR_IP_FOR_REALM - -/* Define if you have the header file. */ -#undef HAVE_KRB_H - -/* Define if you have the `crypto' library (-lcrypto). */ -#undef HAVE_LIBCRYPTO - -/* Define if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - -/* Define if you have the `resolv' library (-lresolv). */ -#undef HAVE_LIBRESOLV - -/* Define if you have the `resolve' library (-lresolve). */ -#undef HAVE_LIBRESOLVE - -/* Define if you have the `socket' library (-lsocket). */ -#undef HAVE_LIBSOCKET - -/* Define if you have the `ssl' library (-lssl). */ -#undef HAVE_LIBSSL - -/* Define if you have GSS API. */ -#define HAVE_GSSAPI - -/* Define if you have the GNU gssapi libraries */ -#undef HAVE_GSSGNU - -/* Define if you have the Heimdal gssapi libraries */ -#define HAVE_GSSHEIMDAL - -/* Define if you have the MIT gssapi libraries */ -#undef HAVE_GSSMIT - -/* Define if you have the `ucb' library (-lucb). */ -#undef HAVE_LIBUCB - -/* Define if you have the `localtime_r' function. */ -#define HAVE_LOCALTIME_R - -/* Define if you have the header file. */ -#define HAVE_MALLOC_H - -/* Define if you need the malloc.h header file even with stdlib.h */ -/* #define NEED_MALLOC_H 1 */ - -/* Define if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define if you have the header file. */ -#define HAVE_NETDB_H - -/* Define if you have the header file. */ -#undef HAVE_NETINET_IF_ETHER_H - -/* Define if you have the header file. */ -#define HAVE_NETINET_IN_H - -/* Define if you have the header file. */ -#define HAVE_NET_IF_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_CRYPTO_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_ERR_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_PEM_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_RSA_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_SSL_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_X509_H - -/* Define if you have the header file. */ -#undef HAVE_PEM_H - -/* Define if you have the `perror' function. */ -#define HAVE_PERROR - -/* Define if you have the header file. */ -#define HAVE_PWD_H - -/* Define if you have the `RAND_egd' function. */ -#undef HAVE_RAND_EGD - -/* Define if you have the `RAND_screen' function. */ -#undef HAVE_RAND_SCREEN - -/* Define if you have the `RAND_status' function. */ -#undef HAVE_RAND_STATUS - -/* Define if you have the header file. */ -#undef HAVE_RSA_H - -/* Define if you have the `select' function. */ -#define HAVE_SELECT - -/* Define if you have the `setvbuf' function. */ -#define HAVE_SETVBUF - -/* Define if you have the header file. */ -#undef HAVE_SGTTY_H - -/* Define if you have the `sigaction' function. */ -#define HAVE_SIGACTION - -/* Define if you have the `signal' function. */ -#undef HAVE_SIGNAL - -/* Define if you have the header file. */ -#define HAVE_SIGNAL_H - -/* Define if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T - -/* Define if sig_atomic_t is already defined as volatile. */ -#undef HAVE_SIG_ATOMIC_T_VOLATILE - -/* Define if you have the `socket' function. */ -#define HAVE_SOCKET - -/* Define if you have the header file. */ -#undef HAVE_SSL_H - -/* Define if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define if you have the header file. */ -#define HAVE_STDLIB_H - - -/* The following define is needed on OS400 to enable strcmpi(), stricmp() and - strdup(). */ -#define __cplusplus__strings__ - -/* Define if you have the `strcasecmp' function. */ -#undef HAVE_STRCASECMP - -/* Define if you have the `strcmpi' function. */ -#define HAVE_STRCMPI - -/* Define if you have the `stricmp' function. */ -#define HAVE_STRICMP - -/* Define if you have the `strdup' function. */ -#define HAVE_STRDUP - - -/* Define if you have the `strftime' function. */ -#define HAVE_STRFTIME - -/* Define if you have the header file. */ -#define HAVE_STRINGS_H - -/* Define if you have the header file. */ -#define HAVE_STRING_H - -/* Define if you have the `strlcpy' function. */ -#undef HAVE_STRLCPY - -/* Define if you have the header file. */ -#undef HAVE_STROPTS_H - -/* Define if you have the `strstr' function. */ -#define HAVE_STRSTR - -/* Define if you have the `strtok_r' function. */ -#define HAVE_STRTOK_R - -/* Define if you have the `strtoll' function. */ -#undef HAVE_STRTOLL /* Allows ASCII compile on V5R1. */ - -/* Define if you have the header file. */ -#define HAVE_SYS_PARAM_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define if you have the header file. */ -#define HAVE_SYS_SOCKET_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_SOCKIO_H - -/* Define if you have the header file. */ -#define HAVE_SYS_STAT_H - -/* Define if you have the header file. */ -#define HAVE_SYS_TIME_H - -/* Define if you have the header file. */ -#define HAVE_SYS_TYPES_H - -/* Define if you have the header file. */ -#define HAVE_SYS_UN_H - -/* Define if you have the header file. */ -#define HAVE_SYS_IOCTL_H - -/* Define if you have the `tcgetattr' function. */ -#undef HAVE_TCGETATTR - -/* Define if you have the `tcsetattr' function. */ -#undef HAVE_TCSETATTR - -/* Define if you have the header file. */ -#undef HAVE_TERMIOS_H - -/* Define if you have the header file. */ -#undef HAVE_TERMIO_H - -/* Define if you have the header file. */ -#define HAVE_TIME_H - -/* Define if you have the `uname' function. */ -#undef HAVE_UNAME - -/* Define if you have the header file. */ -#define HAVE_UNISTD_H - -/* Define if you have the header file. */ -#undef HAVE_WINSOCK_H - -/* Define if you have the header file. */ -#undef HAVE_X509_H - -/* Name of package */ -#undef PACKAGE - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of a `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 8 - -/* Define if the compiler supports the 'long long' data type. */ -#define HAVE_LONGLONG - -/* The size of a `long long', as computed by sizeof. */ -#define SIZEOF_LONG_LONG 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 8 - -/* Whether long long constants must be suffixed by LL. */ - -#define HAVE_LL - -/* Define this if you have struct sockaddr_storage */ -#define HAVE_STRUCT_SOCKADDR_STORAGE - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS - -/* Define if you can safely include both and . */ -#define TIME_WITH_SYS_TIME - -/* Version number of package */ -#undef VERSION - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - -/* Define for large files, on AIX-style hosts. */ -#define _LARGE_FILES - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* type to use in place of in_addr_t if not defined */ -#define in_addr_t unsigned long - -/* Define to `unsigned' if does not define. */ -#undef size_t - -/* Define if you have the ioctl function. */ -#define HAVE_IOCTL - -/* Define if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO - -/* Define if you have a working ioctl SIOCGIFADDR function. */ -#define HAVE_IOCTL_SIOCGIFADDR - -/* To disable LDAP */ -#undef CURL_DISABLE_LDAP - -/* Definition to make a library symbol externally visible. */ -#define CURL_EXTERN_SYMBOL - -/* Define if you have the ldap_url_parse procedure. */ -/* #define HAVE_LDAP_URL_PARSE */ /* Disabled because of an IBM bug. */ - -/* Define if you have the getnameinfo function. */ -/* OS400 has no ASCII version of this procedure: wrapped in setup-os400.h. */ -#define HAVE_GETNAMEINFO - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 socklen_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - -/* Define if you have the recv function. */ -#define HAVE_RECV - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 int - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 char * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int - -/* Define if you have the recvfrom function. */ -#define HAVE_RECVFROM - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 int - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - -/* Define if you have the send function. */ -#define HAVE_SEND - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 int - -/* Define to the type qualifier of arg 2 for send. */ -#define SEND_QUAL_ARG2 - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 char * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 int - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV int - -/* Define to use the GSKit package. */ -#define USE_GSKIT - -/* Define to use the OS/400 crypto library. */ -#define USE_OS400CRYPTO - -/* Define to use Unix sockets. */ -#define USE_UNIX_SOCKETS - -/* Use the system keyring as the default CA bundle. */ -#define CURL_CA_BUNDLE "/QIBM/UserData/ICSS/Cert/Server/DEFAULT.KDB" - -/* ---------------------------------------------------------------- */ -/* ADDITIONAL DEFINITIONS */ -/* ---------------------------------------------------------------- */ - -/* The following must be defined BEFORE system header files inclusion. */ - -#define __ptr128 /* No teraspace. */ -#define qadrt_use_fputc_inline /* Generate fputc() wrapper inline. */ -#define qadrt_use_fread_inline /* Generate fread() wrapper inline. */ -#define qadrt_use_fwrite_inline /* Generate fwrite() wrapper inline. */ - -#endif /* HEADER_CURL_CONFIG_OS400_H */ diff --git a/Externals/curl/lib/config-riscos.h b/Externals/curl/lib/config-riscos.h deleted file mode 100644 index 0379524fb3..0000000000 --- a/Externals/curl/lib/config-riscos.h +++ /dev/null @@ -1,513 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_RISCOS_H -#define HEADER_CURL_CONFIG_RISCOS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for RISC OS */ -/* ================================================================ */ - -/* Name of this package! */ -#undef PACKAGE - -/* Version number of this archive. */ -#undef VERSION - -/* Define if you have the getpass function. */ -#undef HAVE_GETPASS - -/* Define cpu-machine-OS */ -#define OS "ARM-RISC OS" - -/* Define if you want the built-in manual */ -#define USE_MANUAL - -/* Define if you have the gethostbyaddr_r() function with 5 arguments */ -#undef HAVE_GETHOSTBYADDR_R_5 - -/* Define if you have the gethostbyaddr_r() function with 7 arguments */ -#undef HAVE_GETHOSTBYADDR_R_7 - -/* Define if you have the gethostbyaddr_r() function with 8 arguments */ -#undef HAVE_GETHOSTBYADDR_R_8 - -/* Define if you have the gethostbyname_r() function with 3 arguments */ -#undef HAVE_GETHOSTBYNAME_R_3 - -/* Define if you have the gethostbyname_r() function with 5 arguments */ -#undef HAVE_GETHOSTBYNAME_R_5 - -/* Define if you have the gethostbyname_r() function with 6 arguments */ -#undef HAVE_GETHOSTBYNAME_R_6 - -/* Define if you need the _REENTRANT define for some functions */ -#undef NEED_REENTRANT - -/* Define if you have the Kerberos4 libraries (including -ldes) */ -#undef HAVE_KRB4 - -/* Define if you want to enable IPv6 support */ -#undef ENABLE_IPV6 - -/* Define if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define this to 'int' if ssize_t is not an available typedefed type */ -#undef ssize_t - -/* Define this as a suitable file to read random data from */ -#undef RANDOM_FILE - -/* Define this to your Entropy Gathering Daemon socket pathname */ -#undef EGD_SOCKET - -/* Define if you want to enable IPv6 support */ -#undef ENABLE_IPV6 - -/* Define if you have the alarm function. */ -#define HAVE_ALARM - -/* Define if you have the header file. */ -#define HAVE_ALLOCA_H - -/* Define if you have the header file. */ -#define HAVE_ARPA_INET_H - -/* Define if you have the `closesocket' function. */ -#undef HAVE_CLOSESOCKET - -/* Define if you have the header file. */ -#undef HAVE_CRYPTO_H - -/* Define if you have the header file. */ -#undef HAVE_DES_H - -/* Define if you have the header file. */ -#define HAVE_ERRNO_H - -/* Define if you have the header file. */ -#undef HAVE_ERR_H - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H - -/* Define if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE - -/* Define if getaddrinfo exists and works */ -#define HAVE_GETADDRINFO - -/* Define if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define if you have the `gethostbyaddr' function. */ -#define HAVE_GETHOSTBYADDR - -/* Define if you have the `gethostbyaddr_r' function. */ -#undef HAVE_GETHOSTBYADDR_R - -/* Define if you have the `gethostbyname_r' function. */ -#undef HAVE_GETHOSTBYNAME_R - -/* Define if you have the `gethostname' function. */ -#define HAVE_GETHOSTNAME - -/* Define if you have the header file. */ -#define HAVE_GETOPT_H - -/* Define if you have the `getpass_r' function. */ -#undef HAVE_GETPASS_R - -/* Define if you have the `getpwuid' function. */ -#undef HAVE_GETPWUID - -/* Define if you have the `getservbyname' function. */ -#undef HAVE_GETSERVBYNAME - -/* Define if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY - -/* Define if you have the `timeval' struct. */ -#define HAVE_STRUCT_TIMEVAL - -/* Define if you have the `inet_addr' function. */ -#undef HAVE_INET_ADDR - -/* Define if you have the header file. */ -#define HAVE_INTTYPES_H - -/* Define if you have the header file. */ -#undef HAVE_IO_H - -/* Define if you have the `krb_get_our_ip_for_realm' function. */ -#undef HAVE_KRB_GET_OUR_IP_FOR_REALM - -/* Define if you have the header file. */ -#undef HAVE_KRB_H - -/* Define if you have the `crypto' library (-lcrypto). */ -#undef HAVE_LIBCRYPTO - -/* Define if you have the `nsl' library (-lnsl). */ -#undef HAVE_LIBNSL - -/* Define if you have the `resolv' library (-lresolv). */ -#undef HAVE_LIBRESOLV - -/* Define if you have the `resolve' library (-lresolve). */ -#undef HAVE_LIBRESOLVE - -/* Define if you have the `socket' library (-lsocket). */ -#undef HAVE_LIBSOCKET - -/* Define if you have the `ssl' library (-lssl). */ -#undef HAVE_LIBSSL - -/* Define if you have the `ucb' library (-lucb). */ -#undef HAVE_LIBUCB - -/* Define if you have the `localtime_r' function. */ -#undef HAVE_LOCALTIME_R - -/* Define if you have the header file. */ -#define HAVE_MALLOC_H - -/* Define if you need the malloc.h header file even with stdlib.h */ -/* #define NEED_MALLOC_H 1 */ - -/* Define if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define if you have the header file. */ -#define HAVE_NETDB_H - -/* Define if you have the header file. */ -#undef HAVE_NETINET_IF_ETHER_H - -/* Define if you have the header file. */ -#define HAVE_NETINET_IN_H - -/* Define if you have the header file. */ -#define HAVE_NET_IF_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_CRYPTO_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_ERR_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_PEM_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_RSA_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_SSL_H - -/* Define if you have the header file. */ -#undef HAVE_OPENSSL_X509_H - -/* Define if you have the header file. */ -#undef HAVE_PEM_H - -/* Define if you have the `perror' function. */ -#undef HAVE_PERROR - -/* Define if you have the header file. */ -#undef HAVE_PWD_H - -/* Define if you have the `RAND_egd' function. */ -#undef HAVE_RAND_EGD - -/* Define if you have the `RAND_screen' function. */ -#undef HAVE_RAND_SCREEN - -/* Define if you have the `RAND_status' function. */ -#undef HAVE_RAND_STATUS - -/* Define if you have the header file. */ -#undef HAVE_RSA_H - -/* Define if you have the `select' function. */ -#define HAVE_SELECT - -/* Define if you have the `setvbuf' function. */ -#undef HAVE_SETVBUF - -/* Define if you have the header file. */ -#define HAVE_SGTTY_H - -/* Define if you have the `sigaction' function. */ -#undef HAVE_SIGACTION - -/* Define if you have the `signal' function. */ -#define HAVE_SIGNAL - -/* Define if you have the header file. */ -#define HAVE_SIGNAL_H - -/* Define if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T - -/* Define if sig_atomic_t is already defined as volatile. */ -#undef HAVE_SIG_ATOMIC_T_VOLATILE - -/* Define if you have the `socket' function. */ -#define HAVE_SOCKET - -/* Define if you have the header file. */ -#undef HAVE_SSL_H - -/* Define if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define if you have the header file. */ -#define HAVE_STDLIB_H - -/* Define if you have the `strcasecmp' function. */ -#undef HAVE_STRCASECMP - -/* Define if you have the `strcmpi' function. */ -#undef HAVE_STRCMPI - -/* Define if you have the `strdup' function. */ -#define HAVE_STRDUP - -/* Define if you have the `strftime' function. */ -#define HAVE_STRFTIME - -/* Define if you have the `stricmp' function. */ -#define HAVE_STRICMP - -/* Define if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define if you have the header file. */ -#define HAVE_STRING_H - -/* Define if you have the `strlcpy' function. */ -#undef HAVE_STRLCPY - -/* Define if you have the `strstr' function. */ -#define HAVE_STRSTR - -/* Define if you have the `strtok_r' function. */ -#undef HAVE_STRTOK_R - -/* Define if you have the `strtoll' function. */ -#undef HAVE_STRTOLL - -/* Define if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define if you have the header file. */ -#define HAVE_SYS_SOCKET_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_SOCKIO_H - -/* Define if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define if you have the header file. */ -#define HAVE_SYS_TIME_H - -/* Define if you have the header file. */ -#define HAVE_SYS_TYPES_H - -/* Define if you have the `tcgetattr' function. */ -#define HAVE_TCGETATTR - -/* Define if you have the `tcsetattr' function. */ -#define HAVE_TCSETATTR - -/* Define if you have the header file. */ -#define HAVE_TERMIOS_H - -/* Define if you have the header file. */ -#undef HAVE_TERMIO_H - -/* Define if you have the header file. */ -#undef HAVE_TIME_H - -/* Define if you have the `uname' function. */ -#define HAVE_UNAME - -/* Define if you have the header file. */ -#define HAVE_UNISTD_H - -/* Define if you have the header file. */ -#undef HAVE_WINSOCK_H - -/* Define if you have the header file. */ -#undef HAVE_X509_H - -/* Name of package */ -#undef PACKAGE - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `long double', as computed by sizeof. */ -#undef SIZEOF_LONG_DOUBLE - -/* The size of `long long', as computed by sizeof. */ -#undef SIZEOF_LONG_LONG - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 4 - -/* Define if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Version number of package */ -#undef VERSION - -/* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - -/* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `unsigned' if does not define. */ -#undef size_t - -/* Define to `int' if does not define. */ -#undef ssize_t - -/* Define if you have the ioctl function. */ -#define HAVE_IOCTL - -/* Define if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO - -/* to disable LDAP */ -#define CURL_DISABLE_LDAP - -/* Define if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 size_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - -/* Define if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 int - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 void * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV ssize_t - -/* Define 1 if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 int - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 void - -/* Define if the type pointed by arg 2 for recvfrom is void. */ -#define RECVFROM_TYPE_ARG2_IS_VOID - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV ssize_t - -/* Define if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 int - -/* Define to the type qualifier of arg 2 for send. */ -#define SEND_QUAL_ARG2 const - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 void * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV ssize_t - -#endif /* HEADER_CURL_CONFIG_RISCOS_H */ diff --git a/Externals/curl/lib/config-symbian.h b/Externals/curl/lib/config-symbian.h deleted file mode 100644 index 2603a46b46..0000000000 --- a/Externals/curl/lib/config-symbian.h +++ /dev/null @@ -1,811 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_SYMBIAN_H -#define HEADER_CURL_CONFIG_SYMBIAN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for Symbian */ -/* ================================================================ */ - -/* Location of default ca bundle */ -/* #define CURL_CA_BUNDLE "/etc/pki/tls/certs/ca-bundle.crt"*/ - -/* Location of default ca path */ -/* #undef CURL_CA_PATH */ - -/* to disable cookies support */ -/* #undef CURL_DISABLE_COOKIES */ - -/* to disable cryptographic authentication */ -/* #undef CURL_DISABLE_CRYPTO_AUTH */ - -/* to disable DICT */ -/* #undef CURL_DISABLE_DICT */ - -/* to disable FILE */ -/* #undef CURL_DISABLE_FILE */ - -/* to disable FTP */ -/* #undef CURL_DISABLE_FTP */ - -/* to disable HTTP */ -/* #undef CURL_DISABLE_HTTP */ - -/* to disable LDAP */ -#define CURL_DISABLE_LDAP 1 - -/* to disable LDAPS */ -#define CURL_DISABLE_LDAPS 1 - -/* to disable TELNET */ -/* #undef CURL_DISABLE_TELNET */ - -/* to disable TFTP */ -/* #undef CURL_DISABLE_TFTP */ - -/* to disable verbose strings */ -/* #define CURL_DISABLE_VERBOSE_STRINGS 1*/ - -/* Definition to make a library symbol externally visible. */ -/* #undef CURL_EXTERN_SYMBOL */ - -/* Use Windows LDAP implementation */ -/* #undef USE_WIN32_LDAP */ - -/* your Entropy Gathering Daemon socket pathname */ -/* #undef EGD_SOCKET */ - -/* Define if you want to enable IPv6 support */ -#define ENABLE_IPV6 1 - -/* Define if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 size_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - -/* Define to 1 if you have the header file. */ -/*#define HAVE_ALLOCA_H 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the header file. */ -/*#define HAVE_ARPA_TFTP_H 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_ASSERT_H 1 - -/* Define to 1 if you have the `basename' function. */ -/*#define HAVE_BASENAME 1*/ - -/* Define to 1 if bool is an available type. */ -/*#define HAVE_BOOL_T 1*/ - -/* Define to 1 if you have the `closesocket' function. */ -/* #undef HAVE_CLOSESOCKET */ - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -/*#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1*/ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_CRYPTO_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DES_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -/*#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ERR_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the fcntl function. */ -#define HAVE_FCNTL 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#define HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the `fork' function. */ -/*#define HAVE_FORK 1*/ - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define if getaddrinfo exists and works */ -#define HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `geteuid' function. */ -#define HAVE_GETEUID 1 - -/* Define to 1 if you have the `gethostbyaddr' function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* If you have gethostbyname */ -#define HAVE_GETHOSTBYNAME 1 - -/* Define to 1 if you have the `gethostbyname_r' function. */ -/* #undef HAVE_GETHOSTBYNAME_R */ - -/* gethostbyname_r() takes 3 args */ -/* #undef HAVE_GETHOSTBYNAME_R_3 */ - -/* gethostbyname_r() takes 5 args */ -/* #undef HAVE_GETHOSTBYNAME_R_5 */ - -/* gethostbyname_r() takes 6 args */ -/* #undef HAVE_GETHOSTBYNAME_R_6 */ - -/* Define to 1 if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to 1 if you have the `getpass_r' function. */ -/* #undef HAVE_GETPASS_R */ - -/* Define to 1 if you have the `getppid' function. */ -#define HAVE_GETPPID 1 - -/* Define to 1 if you have the `getprotobyname' function. */ -#define HAVE_GETPROTOBYNAME 1 - -/* Define to 1 if you have the `getpwuid' function. */ -#define HAVE_GETPWUID 1 - -/* Define to 1 if you have the `getrlimit' function. */ -/*#define HAVE_GETRLIMIT 1*/ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* we have a glibc-style strerror_r() */ -/* #undef HAVE_GLIBC_STRERROR_R */ - -/* Define to 1 if you have the `gmtime_r' function. */ -#define HAVE_GMTIME_R 1 - -/* if you have the gssapi libraries */ -/* #undef HAVE_GSSAPI */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */ - -/* if you have the GNU gssapi libraries */ -/* #undef HAVE_GSSGNU */ - -/* if you have the Heimdal gssapi libraries */ -/* #undef HAVE_GSSHEIMDAL */ - -/* if you have the MIT gssapi libraries */ -/* #undef HAVE_GSSMIT */ - -/* Define to 1 if you have the `idna_strerror' function. */ -/*#define HAVE_IDNA_STRERROR 1*/ - -/* Define to 1 if you have the `idn_free' function. */ -/*#define HAVE_IDN_FREE 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_IDN_FREE_H 1*/ - -/* Define to 1 if you have the `inet_addr' function. */ -/*#define HAVE_INET_ADDR 1*/ - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -/*#define HAVE_INET_NTOP 1*/ - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -/*#define HAVE_INET_PTON 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the ioctl function. */ -#define HAVE_IOCTL 1 - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have the ioctlsocket function. */ -/* #undef HAVE_IOCTLSOCKET */ - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -/* #undef HAVE_IOCTLSOCKET_FIONBIO */ - -/* Define to 1 if you have the IoctlSocket camel case function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL */ - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO - function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IO_H */ - -/* if you have the Kerberos4 libraries (including -ldes) */ -/* #undef HAVE_KRB4 */ - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_KRB_H */ - -/* Define to 1 if you have the lber.h header file. */ -/*#define HAVE_LBER_H 1*/ - -/* Define to 1 if you have the ldapssl.h header file. */ -/* #undef HAVE_LDAPSSL_H */ - -/* Define to 1 if you have the ldap.h header file. */ -/*#define HAVE_LDAP_H 1*/ - -/* Use LDAPS implementation */ -/*#define HAVE_LDAP_SSL 1*/ - -/* Define to 1 if you have the ldap_ssl.h header file. */ -/* #undef HAVE_LDAP_SSL_H */ - -/* Define to 1 if you have the `ldap_url_parse' function. */ -/*#define HAVE_LDAP_URL_PARSE 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_LIBGEN_H 1*/ - -/* Define to 1 if you have the `idn' library (-lidn). */ -/*#define HAVE_LIBIDN 1*/ - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -/* #undef HAVE_LIBRESOLV */ - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -/* #undef HAVE_LIBRESOLVE */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `ssh2' library (-lssh2). */ -/*#define HAVE_LIBSSH2 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_LIBSSH2_H 1*/ - -/* Define to 1 if you have the `ssl' library (-lssl). */ -/*#define HAVE_LIBSSL 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* if your compiler supports LL */ -#define HAVE_LL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the `localtime_r' function. */ -#define HAVE_LOCALTIME_R 1 - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#define HAVE_LONGLONG 1 - -/* Define to 1 if you have the malloc.h header file. */ -/*#define HAVE_MALLOC_H 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the MSG_NOSIGNAL flag. */ -/*#define HAVE_MSG_NOSIGNAL 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -/*#define HAVE_NETINET_TCP_H 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_NET_IF_H 1 - -/* Define to 1 if NI_WITHSCOPEID exists and works. */ -/*#define HAVE_NI_WITHSCOPEID 1*/ - -/* we have no strerror_r() proto */ -/* #undef HAVE_NO_STRERROR_R_DECL */ - -/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE - */ -/* #undef HAVE_OLD_GSSMIT */ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_CRYPTO_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_ENGINE_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_ERR_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_PEM_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_PKCS12_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_RSA_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_SSL_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_OPENSSL_X509_H 1*/ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PEM_H */ - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `pipe' function. */ -#define HAVE_PIPE 1 - -/* Define to 1 if you have the `poll' function. */ -/*#define HAVE_POLL 1*/ - -/* If you have a fine poll */ -/*#define HAVE_POLL_FINE 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_POLL_H 1*/ - -/* we have a POSIX-style strerror_r() */ -#define HAVE_POSIX_STRERROR_R 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_PWD_H 1 - -/* Define to 1 if you have the `RAND_egd' function. */ -#define HAVE_RAND_EGD 1 - -/* Define to 1 if you have the `RAND_screen' function. */ -/* #undef HAVE_RAND_SCREEN */ - -/* Define to 1 if you have the `RAND_status' function. */ -/*#define HAVE_RAND_STATUS 1*/ - -/* Define to 1 if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to 1 if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_RSA_H */ - -/* Define to 1 if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SETJMP_H 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `setmode' function. */ -/* #undef HAVE_SETMODE */ - -/* Define to 1 if you have the `setrlimit' function. */ -/*#define HAVE_SETRLIMIT 1*/ - -/* Define to 1 if you have the setsockopt function. */ -/* #undef HAVE_SETSOCKOPT */ - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_SGTTY_H 1*/ - -/* Define to 1 if you have the `sigaction' function. */ -/*#define HAVE_SIGACTION 1*/ - -/* Define to 1 if you have the `siginterrupt' function. */ -/*#define HAVE_SIGINTERRUPT 1*/ - -/* Define to 1 if you have the `signal' function. */ -/*#define HAVE_SIGNAL 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* If you have sigsetjmp */ -/*#define HAVE_SIGSETJMP 1*/ - -/* Define to 1 if sig_atomic_t is an available typedef. */ -/*#define HAVE_SIG_ATOMIC_T 1*/ - -/* Define to 1 if sig_atomic_t is already defined as volatile. */ -/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the `SSL_get_shutdown' function. */ -/*#define HAVE_SSL_GET_SHUTDOWN 1*/ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SSL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strcmpi' function. */ -/* #undef HAVE_STRCMPI */ - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the `stricmp' function. */ -/* #undef HAVE_STRICMP */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define HAVE_STRLCPY 1 - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the `strtok_r' function. */ -#define HAVE_STRTOK_R 1 - -/* Define to 1 if you have the `strtoll' function. */ -#define HAVE_STRTOLL 1 - -/* if struct sockaddr_storage is defined */ -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if you have the timeval struct. */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_FILIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -/*#define HAVE_SYS_POLL_H 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_UTIME_H */ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_TERMIOS_H 1*/ - -/* Define to 1 if you have the header file. */ -/*#define HAVE_TERMIO_H 1*/ - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the header file. */ -/*#define HAVE_TLD_H 1*/ - -/* Define to 1 if you have the `tld_strerror' function. */ -/*#define HAVE_TLD_STRERROR 1*/ - -/* Define to 1 if you have the `uname' function. */ -#define HAVE_UNAME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if compiler supports C99 variadic macro style. */ -#define HAVE_VARIADIC_MACROS_C99 1 - -/* Define to 1 if compiler supports old gcc variadic macro style. */ -/*#define HAVE_VARIADIC_MACROS_GCC 1*/ - -/* Define to 1 if you have the winber.h header file. */ -/* #undef HAVE_WINBER_H */ - -/* Define to 1 if you have the windows.h header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if you have the winldap.h header file. */ -/* #undef HAVE_WINLDAP_H */ - -/* Define to 1 if you have the winsock2.h header file. */ -/* #undef HAVE_WINSOCK2_H */ - -/* Define to 1 if you have the winsock.h header file. */ -/* #undef HAVE_WINSOCK_H */ - -/* Define this symbol if your OS supports changing the contents of argv */ -/*#define HAVE_WRITABLE_ARGV 1*/ - -/* Define to 1 if you have the ws2tcpip.h header file. */ -/* #undef HAVE_WS2TCPIP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_X509_H */ - -/* Define to 1 if you need the lber.h header file even with ldap.h */ -/* #undef NEED_LBER_H */ - -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -/* #undef NEED_MALLOC_H */ - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -/* #undef NEED_REENTRANT */ - -/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ -/* #undef NEED_THREAD_SAFE */ - -/* cpu-machine-OS */ -#ifdef __WINS__ -#define OS "i386-pc-epoc32" -#elif __MARM__ -#define OS "arm-unknown-epoc32" -#else -/* This won't happen on any current Symbian version */ -#define OS "unknown-unknown-epoc32" -#endif - -/* Name of package */ -/*#define PACKAGE "curl"*/ - -/* Define to the address where bug reports for this package should be sent. */ -/*#define PACKAGE_BUGREPORT \ - "a suitable curl mailing list => https://curl.haxx.se/mail/"*/ - -/* Define to the full name of this package. */ -/*#define PACKAGE_NAME "curl"*/ - -/* Define to the full name and version of this package. */ -/*#define PACKAGE_STRING "curl -"*/ - -/* Define to the one symbol short name of this package. */ -/*#define PACKAGE_TARNAME "curl"*/ - -/* Define to the version of this package. */ -/*#define PACKAGE_VERSION "-"*/ - -/* a suitable file to read random data from */ -/*#define RANDOM_FILE "/dev/urandom"*/ - -#define RECV_TYPE_ARG1 int -#define RECV_TYPE_ARG2 void* -#define RECV_TYPE_ARG3 size_t -#define RECV_TYPE_ARG4 int -#define RECV_TYPE_RETV ssize_t - -#define RECVFROM_TYPE_ARG1 int -#define RECVFROM_TYPE_ARG2 void -#define RECVFROM_TYPE_ARG3 size_t -#define RECVFROM_TYPE_ARG4 int -#define RECVFROM_TYPE_ARG5 struct sockaddr -#define RECVFROM_TYPE_ARG6 size_t -#define RECVFROM_TYPE_RETV ssize_t -#define RECVFROM_TYPE_ARG2_IS_VOID 1 - -#define SEND_TYPE_ARG1 int -#define SEND_QUAL_ARG2 const -#define SEND_TYPE_ARG2 void* -#define SEND_TYPE_ARG3 size_t -#define SEND_TYPE_ARG4 int -#define SEND_TYPE_RETV ssize_t - - -/* Define as the return type of signal handlers (`int' or `void'). */ -/*#define RETSIGTYPE void*/ - -/* Define to the type of arg 1 for `select'. */ -#define SELECT_TYPE_ARG1 int - -/* Define to the type of args 2, 3 and 4 for `select'. */ -#define SELECT_TYPE_ARG234 (fd_set *) - -/* Define to the type of arg 5 for `select'. */ -#define SELECT_TYPE_ARG5 (struct timeval *) - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `off_t', as computed by sizeof. */ -#define SIZEOF_OFF_T 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 4 - -/* The size of `time_t', as computed by sizeof. */ -#define SIZEOF_TIME_T 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Define if you want to enable c-ares support */ -/* #undef USE_ARES */ - -/* Define to disable non-blocking sockets */ -/* #undef USE_BLOCKING_SOCKETS */ - -/* if GnuTLS is enabled */ -/* #undef USE_GNUTLS */ - -/* if libSSH2 is in use */ -/*#define USE_LIBSSH2 1*/ - -/* If you want to build curl with the built-in manual */ -/*#define USE_MANUAL 1*/ - -/* if NSS is enabled */ -/* #undef USE_NSS */ - -/* to enable SSPI support */ -/* #undef USE_WINDOWS_SSPI */ - -/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ -/* #undef USE_YASSLEMUL */ - -/* Version number of package */ -/*#define VERSION "7.18.2-CVS"*/ - -/* Define to avoid automatic inclusion of winsock.h */ -/* #undef WIN32_LEAN_AND_MEAN */ - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#define _FILE_OFFSET_BITS 64 - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* type to use in place of in_addr_t if not defined */ -/* #undef in_addr_t */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* the signed version of size_t */ -/* #undef ssize_t */ - -/* Enabling curl debug mode when building in Symbian debug mode would work */ -/* except that debug mode introduces new exports that must be frozen. */ -#ifdef _DEBUG -/* #define CURLDEBUG */ -#endif - -/* sys/cdefs.h fails to define this for WINSCW prior to Symbian OS ver. 9.4 */ -#ifndef __LONG_LONG_SUPPORTED -#define __LONG_LONG_SUPPORTED -#endif - -/* Enable appropriate header only when zlib support is enabled */ -#ifdef HAVE_LIBZ -#define HAVE_ZLIB_H 1 -#endif - -#endif /* HEADER_CURL_CONFIG_SYMBIAN_H */ diff --git a/Externals/curl/lib/config-tpf.h b/Externals/curl/lib/config-tpf.h deleted file mode 100644 index d1714fdfc4..0000000000 --- a/Externals/curl/lib/config-tpf.h +++ /dev/null @@ -1,772 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_TPF_H -#define HEADER_CURL_CONFIG_TPF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for TPF */ -/* ================================================================ */ - -/* ---------------------------------------------------------------- */ -/* FEATURES, FUNCTIONS, and DEFINITIONS */ -/* ---------------------------------------------------------------- */ - -/* NOTE: Refer also to the .mak file for some of the flags below */ - -/* to disable cookies support */ -/* #undef CURL_DISABLE_COOKIES */ - -/* to disable cryptographic authentication */ -/* #undef CURL_DISABLE_CRYPTO_AUTH */ - -/* to disable DICT */ -/* #undef CURL_DISABLE_DICT */ - -/* to disable FILE */ -/* #undef CURL_DISABLE_FILE */ - -/* to disable FTP */ -/* #undef CURL_DISABLE_FTP */ - -/* to disable HTTP */ -/* #undef CURL_DISABLE_HTTP */ - -/* to disable LDAP */ -/* #undef CURL_DISABLE_LDAP */ - -/* to disable TELNET */ -/* #undef CURL_DISABLE_TELNET */ - -/* to disable TFTP */ -/* #undef CURL_DISABLE_TFTP */ - -/* to disable verbose strings */ -/* #undef CURL_DISABLE_VERBOSE_STRINGS */ - -/* lber dynamic library file */ -/* #undef DL_LBER_FILE */ - -/* ldap dynamic library file */ -/* #undef DL_LDAP_FILE */ - -/* your Entropy Gathering Daemon socket pathname */ -/* #undef EGD_SOCKET */ - -/* Define if you want to enable IPv6 support */ -/* #undef ENABLE_IPV6 */ - -/* Define if struct sockaddr_in6 has the sin6_scope_id member */ -/* #undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID */ - -/* Define to the type of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG1 */ - -/* Define to the type of arg 2 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG2 */ - -/* Define to the type of args 4 and 6 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG46 */ - -/* Define to the type of arg 7 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG7 */ - -/* Define to 1 if you have the alarm function. */ -#define HAVE_ALARM 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_TFTP_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_ASSERT_H 1 - -/* Define to 1 if you have the `basename' function. */ -#define HAVE_BASENAME 1 - -/* Define to 1 if you have the `closesocket' function. */ -/* #undef HAVE_CLOSESOCKET */ - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -/* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */ -#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_CRYPTO_H */ -#define HAVE_CRYPTO_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DES_H */ -#define HAVE_DES_H 1 - -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -/* #undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES */ -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ERR_H */ -#define HAVE_ERR_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the fcntl function. */ -#define HAVE_FCNTL 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#define HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the `fork' function. */ -/* #undef HAVE_FORK */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the `ftruncate' function. */ -#define HAVE_FTRUNCATE 1 - -/* Define if getaddrinfo exists and works */ -/* #undef HAVE_GETADDRINFO */ - -/* Define to 1 if you have the `geteuid' function. */ -#define HAVE_GETEUID 1 - -/* Define to 1 if you have the `gethostbyaddr' function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* If you have gethostbyname */ -#define HAVE_GETHOSTBYNAME 1 - -/* Define to 1 if you have the `gethostbyname_r' function. */ -/* #undef HAVE_GETHOSTBYNAME_R */ - -/* gethostbyname_r() takes 3 args */ -/* #undef HAVE_GETHOSTBYNAME_R_3 */ - -/* gethostbyname_r() takes 5 args */ -/* #undef HAVE_GETHOSTBYNAME_R_5 */ - -/* gethostbyname_r() takes 6 args */ -/* #undef HAVE_GETHOSTBYNAME_R_6 1 */ - -/* Define to 1 if you have the getnameinfo function. */ -/* #undef HAVE_GETNAMEINFO */ - -/* Define to 1 if you have the `getpass_r' function. */ -/* #undef HAVE_GETPASS_R */ - -/* Define to 1 if you have the `getprotobyname' function. */ -/* #undef HAVE_GETPROTOBYNAME */ - -/* Define to 1 if you have the `getpwuid' function. */ -#define HAVE_GETPWUID 1 - -/* Define to 1 if you have the `getrlimit' function. */ -/* #undef HAVE_GETRLIMIT */ - -/* Define to 1 if you have the `gettimeofday' function. */ -#define HAVE_GETTIMEOFDAY 1 - -/* we have a glibc-style strerror_r() */ -/* #undef HAVE_GLIBC_STRERROR_R */ -#define HAVE_GLIBC_STRERROR_R 1 - -/* Define to 1 if you have the `gmtime_r' function. */ -#define HAVE_GMTIME_R 1 - -/* if you have the gssapi libraries */ -/* #undef HAVE_GSSAPI */ - -/* if you have the GNU gssapi libraries */ -/* #undef HAVE_GSSGNU */ - -/* if you have the Heimdal gssapi libraries */ -/* #undef HAVE_GSSHEIMDAL */ - -/* if you have the MIT gssapi libraries */ -/* #undef HAVE_GSSMIT */ - -/* Define to 1 if you have the `iconv' functions. */ -#define HAVE_ICONV 1 - -/* Define to 1 if you have the `idna_strerror' function. */ -/* #undef HAVE_IDNA_STRERROR */ - -/* Define to 1 if you have the `idn_free' function. */ -/* #undef HAVE_IDN_FREE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IDN_FREE_H */ - -/* Define to 1 if you have the `inet_addr' function. */ -#define HAVE_INET_ADDR 1 - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -/* #undef HAVE_INET_NTOP */ - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -/* #undef HAVE_INET_PTON */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the ioctl function. */ -#define HAVE_IOCTL 1 - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have the ioctlsocket function. */ -/* #undef HAVE_IOCTLSOCKET */ - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -/* #undef HAVE_IOCTLSOCKET_FIONBIO */ - -/* Define to 1 if you have the IoctlSocket camel case function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL */ - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO - function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IO_H */ - -/* if you have the Kerberos4 libraries (including -ldes) */ -/* #undef HAVE_KRB4 */ - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_KRB_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIBGEN_H 1 */ - -/* Define to 1 if you have the `idn' library (-lidn). */ -/* #undef HAVE_LIBIDN */ - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -/* #undef HAVE_LIBRESOLV */ - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -/* #undef HAVE_LIBRESOLVE */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `ssl' library (-lssl). */ -/* #undef HAVE_LIBSSL */ -#define HAVE_LIBSSL 1 - -/* if zlib is available */ -/* #undef HAVE_LIBZ */ - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* if your compiler supports LL */ -#define HAVE_LL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have the `localtime_r' function. */ -#define HAVE_LOCALTIME_R 1 - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#define HAVE_LONGLONG 1 - -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -/* #undef NEED_MALLOC_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -/* undef HAVE_NETINET_TCP_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_NET_IF_H 1 - -/* Define if NI_WITHSCOPEID exists and works */ -/* #undef HAVE_NI_WITHSCOPEID */ - -/* we have no strerror_r() proto */ -/* #undef HAVE_NO_STRERROR_R_DECL */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_CRYPTO_H */ -#define HAVE_OPENSSL_CRYPTO_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_ENGINE_H */ -#define HAVE_OPENSSL_ENGINE_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_ERR_H */ -#define HAVE_OPENSSL_ERR_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_PEM_H */ -#define HAVE_OPENSSL_PEM_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_PKCS12_H */ -#define HAVE_OPENSSL_PKCS12_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_RSA_H */ -#define HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_SSL_H */ -#define HAVE_OPENSSL_SSL_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_OPENSSL_X509_H */ -#define HAVE_OPENSSL_X509_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PEM_H */ -#define HAVE_PEM_H 1 - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `pipe' function. */ -#define HAVE_PIPE 1 - -/* Define to 1 if you have the `poll' function. */ -/* #undef HAVE_POLL */ - -/* If you have a fine poll */ -/* #undef HAVE_POLL_FINE */ - -/* we have a POSIX-style strerror_r() */ -/* #undef HAVE_POSIX_STRERROR_R */ - -/* Define to 1 if you have the header file. */ -#define HAVE_PWD_H 1 - -/* Define to 1 if you have the `RAND_egd' function. */ -/* #undef HAVE_RAND_EGD */ -#define HAVE_RAND_EGD 1 - -/* Define to 1 if you have the `RAND_screen' function. */ -/* #undef HAVE_RAND_SCREEN */ - -/* Define to 1 if you have the `RAND_status' function. */ -/* #undef HAVE_RAND_STATUS */ -#define HAVE_RAND_STATUS 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_RSA_H */ -#define HAVE_RSA_H 1 - -/* Define to 1 if you have the `select' function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SETJMP_H 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `setrlimit' function. */ -#define HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the setsockopt function. */ -/* #undef HAVE_SETSOCKOPT */ - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SGTTY_H 1 */ - -/* Define to 1 if you have the `sigaction' function. */ -#define HAVE_SIGACTION 1 - -/* Define to 1 if you have the `siginterrupt' function. */ -/* #undef HAVE_SIGINTERRUPT */ - -/* Define to 1 if you have the `signal' function. */ -#define HAVE_SIGNAL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define to 1 if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T 1 - -/* Define to 1 if sig_atomic_t is already defined as volatile. */ -/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ - -/* If you have sigsetjmp */ -/* #undef HAVE_SIGSETJMP */ - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SSL_H */ -#define HAVE_SSL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcasecmp' function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the `strcmpi' function. */ -/* #undef HAVE_STRCMPI */ - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the `stricmp' function. */ -/* #undef HAVE_STRICMP */ -#define HAVE_STRICMP 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the `strtok_r' function. */ -#define HAVE_STRTOK_R 1 - -/* Define to 1 if you have the `strtoll' function. */ -#define HAVE_STRTOLL 1 - -/* if struct sockaddr_storage is defined */ -/* #undef HAVE_STRUCT_SOCKADDR_STORAGE */ - -/* Define this if you have struct timeval */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_FILIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_POLL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOCKIO_H */ -#define HAVE_SYS_SOCKIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_UTIME_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_TERMIOS_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_TERMIO_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_TLD_H */ - -/* Define to 1 if you have the `tld_strerror' function. */ -/* #undef HAVE_TLD_STRERROR */ - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINSOCK2_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_WINSOCK_H */ - -/* Define this symbol if your OS supports changing the contents of argv */ -/* #undef HAVE_WRITABLE_ARGV */ - -/* Define to 1 if you have the ws2tcpip.h header file. */ -/* #undef HAVE_WS2TCPIP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_X509_H */ - -/* if you have the zlib.h header file */ -/* #undef HAVE_ZLIB_H */ - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -/* #undef NEED_REENTRANT */ - -/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ -/* #undef NEED_THREAD_SAFE */ - -/* cpu-machine-OS */ -#define OS "s390x-ibm-tpf" - -/* Name of package */ -#define PACKAGE "curl" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT \ - "a suitable curl mailing list => https://curl.haxx.se/mail/" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "curl" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "curl -" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "curl" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "-" - -/* a suitable file to read random data from */ -/* #undef RANDOM_FILE */ - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to the type of arg 1 for `select'. */ -#define SELECT_TYPE_ARG1 int - -/* Define to the type of args 2, 3 and 4 for `select'. */ -#define SELECT_TYPE_ARG234 (fd_set *) - -/* Define to the type of arg 5 for `select'. */ -#define SELECT_TYPE_ARG5 (struct timeval *) - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `off_t', as computed by sizeof. */ -#define SIZEOF_OFF_T 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 8 - -/* The size of `time_t', as computed by sizeof. */ -#define SIZEOF_TIME_T 8 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Define if you want to enable ares support */ -/* #undef USE_ARES */ - -/* Define to disable non-blocking sockets */ -/* #undef USE_BLOCKING_SOCKETS */ - -/* if GnuTLS is enabled */ -/* #undef USE_GNUTLS */ - -/* If you want to build curl with the built-in manual */ -/* #undef USE_MANUAL */ - -/* if OpenSSL is in use */ -/* #undef USE_OPENSSL */ - -/* if SSL is enabled */ -/* #undef USE_OPENSSL */ - -/* to enable SSPI support */ -/* #undef USE_WINDOWS_SSPI */ - -/* Version number of package */ -#define VERSION "not-used" - -/* Define to avoid automatic inclusion of winsock.h */ -/* #undef WIN32_LEAN_AND_MEAN */ - -/* Define to 1 if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* type to use in place of in_addr_t if not defined */ -/* #undef in_addr_t */ - -/* Define to `unsigned' if does not define. */ -/* #undef size_t */ - -/* the signed version of size_t */ -/* #undef ssize_t */ - -/* Define to 1 if you have the getnameinfo function. */ -/* #undef HAVE_GETNAMEINFO 1 */ - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_QUAL_ARG1 const */ - -/* Define to the type of arg 1 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG1 struct sockaddr * */ - -/* Define to the type of arg 2 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG2 socklen_t */ - -/* Define to the type of args 4 and 6 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG46 size_t */ - -/* Define to the type of arg 7 for getnameinfo. */ -/* #undef GETNAMEINFO_TYPE_ARG7 int */ - -/* Define to 1 if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 int - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 char * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int - -/* Define to 1 if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 int - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - -/* Define to 1 if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 int - -/* Define to the type qualifier of arg 2 for send. */ -#define SEND_QUAL_ARG2 const - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 char * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 int - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV int - -#define CURL_DOES_CONVERSIONS -#ifndef CURL_ICONV_CODESET_OF_HOST -#define CURL_ICONV_CODESET_OF_HOST "IBM-1047" -#endif - - -#endif /* HEADER_CURL_CONFIG_TPF_H */ diff --git a/Externals/curl/lib/config-vxworks.h b/Externals/curl/lib/config-vxworks.h deleted file mode 100644 index 780a4a225f..0000000000 --- a/Externals/curl/lib/config-vxworks.h +++ /dev/null @@ -1,928 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_VXWORKS_H -#define HEADER_CURL_CONFIG_VXWORKS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* =============================================================== */ -/* Hand crafted config file for VxWorks */ -/* =============================================================== */ - -/* Location of default ca bundle */ -/* #undef CURL_CA_BUNDLE */ - -/* Location of default ca path */ -/* #undef CURL_CA_PATH */ - -/* to disable cookies support */ -/* #undef CURL_DISABLE_COOKIES */ - -/* to disable cryptographic authentication */ -/* #undef CURL_DISABLE_CRYPTO_AUTH */ - -/* to disable DICT */ -/* #undef CURL_DISABLE_DICT */ - -/* to disable FILE */ -/* #undef CURL_DISABLE_FILE */ - -/* to disable FTP */ -#define CURL_DISABLE_FTP 1 - -/* to disable HTTP */ -/* #undef CURL_DISABLE_HTTP */ - -/* to disable LDAP */ -#define CURL_DISABLE_LDAP 1 - -/* to disable LDAPS */ -#define CURL_DISABLE_LDAPS 1 - -/* to disable NTLM authentication */ -#define CURL_DISABLE_NTLM 1 - -/* to disable proxies */ -/* #undef CURL_DISABLE_PROXY */ - -/* to disable TELNET */ -#define CURL_DISABLE_TELNET 1 - -/* to disable TFTP */ -#define CURL_DISABLE_TFTP 1 - -/* to disable verbose strings */ -/* #undef CURL_DISABLE_VERBOSE_STRINGS */ - -/* Definition to make a library symbol externally visible. */ -/* #undef CURL_EXTERN_SYMBOL */ - -/* Use Windows LDAP implementation */ -/* #undef USE_WIN32_LDAP */ - -/* your Entropy Gathering Daemon socket pathname */ -/* #undef EGD_SOCKET */ - -/* Define if you want to enable IPv6 support */ -#define ENABLE_IPV6 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 size_t - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 unsigned int - -/* Specifies the number of arguments to getservbyport_r */ -#define GETSERVBYPORT_R_ARGS 6 - -/* Specifies the size of the buffer to pass to getservbyport_r */ -#define GETSERVBYPORT_R_BUFSIZE 4096 - -/* Define to 1 if you have the alarm function. */ -#define HAVE_ALARM 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ARPA_TFTP_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_ASSERT_H 1 - -/* Define to 1 if you have the `basename' function. */ -/* #undef HAVE_BASENAME */ - -/* Define to 1 if bool is an available type. */ -#define HAVE_BOOL_T 1 - -/* Define to 1 if you have the clock_gettime function and monotonic timer. */ -/* #undef HAVE_CLOCK_GETTIME_MONOTONIC */ - -/* Define to 1 if you have the `closesocket' function. */ -/* #undef HAVE_CLOSESOCKET */ - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_CRYPTO_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DES_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#define HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_ERR_H */ - -/* Define to 1 if you have the fcntl function. */ -#define HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#define HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the fdopen function. */ -#define HAVE_FDOPEN 1 - -/* Define to 1 if you have the `fork' function. */ -#define HAVE_FORK 1 - -/* Define to 1 if you have the freeaddrinfo function. */ -#define HAVE_FREEADDRINFO 1 - -/* Define to 1 if you have the freeifaddrs function. */ -#define HAVE_FREEIFADDRS 1 - -/* Define to 1 if you have the ftruncate function. */ -#define HAVE_FTRUNCATE 1 - -/* Define to 1 if you have a working getaddrinfo function. */ -#define HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `geteuid' function. */ -/* #undef HAVE_GETEUID */ - -/* Define to 1 if you have the gethostbyaddr function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* Define to 1 if you have the gethostbyaddr_r function. */ -#define HAVE_GETHOSTBYADDR_R 1 - -/* gethostbyaddr_r() takes 5 args */ -/* #undef HAVE_GETHOSTBYADDR_R_5 */ - -/* gethostbyaddr_r() takes 7 args */ -/* #undef HAVE_GETHOSTBYADDR_R_7 */ - -/* gethostbyaddr_r() takes 8 args */ -#define HAVE_GETHOSTBYADDR_R_8 1 - -/* Define to 1 if you have the gethostbyname function. */ -#define HAVE_GETHOSTBYNAME 1 - -/* Define to 1 if you have the gethostbyname_r function. */ -/* #undef HAVE_GETHOSTBYNAME_R */ - -/* gethostbyname_r() takes 3 args */ -/* #undef HAVE_GETHOSTBYNAME_R_3 */ - -/* gethostbyname_r() takes 5 args */ -/* #undef HAVE_GETHOSTBYNAME_R_5 */ - -/* gethostbyname_r() takes 6 args */ -/* #undef HAVE_GETHOSTBYNAME_R_6 */ - -/* Define to 1 if you have the gethostname function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define to 1 if you have a working getifaddrs function. */ -/* #undef HAVE_GETIFADDRS */ - -/* Define to 1 if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to 1 if you have the `getpass_r' function. */ -/* #undef HAVE_GETPASS_R */ - -/* Define to 1 if you have the `getppid' function. */ -#define HAVE_GETPPID 1 - -/* Define to 1 if you have the `getprotobyname' function. */ -#define HAVE_GETPROTOBYNAME 1 - -/* Define to 1 if you have the `getpwuid' function. */ -/* #undef HAVE_GETPWUID */ - -/* Define to 1 if you have the `getrlimit' function. */ -#define HAVE_GETRLIMIT 1 - -/* Define to 1 if you have the getservbyport_r function. */ -/* #undef HAVE_GETSERVBYPORT_R */ - -/* Define to 1 if you have the `gettimeofday' function. */ -/* #undef HAVE_GETTIMEOFDAY */ - -/* Define to 1 if you have a working glibc-style strerror_r function. */ -/* #undef HAVE_GLIBC_STRERROR_R */ - -/* Define to 1 if you have a working gmtime_r function. */ -#define HAVE_GMTIME_R 1 - -/* if you have the gssapi libraries */ -/* #undef HAVE_GSSAPI */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_GENERIC_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_KRB5_H */ - -/* if you have the GNU gssapi libraries */ -/* #undef HAVE_GSSGNU */ - -/* if you have the Heimdal gssapi libraries */ -/* #undef HAVE_GSSHEIMDAL */ - -/* if you have the MIT gssapi libraries */ -/* #undef HAVE_GSSMIT */ - -/* Define to 1 if you have the `idna_strerror' function. */ -/* #undef HAVE_IDNA_STRERROR */ - -/* Define to 1 if you have the `idn_free' function. */ -/* #undef HAVE_IDN_FREE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IDN_FREE_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_IFADDRS_H */ - -/* Define to 1 if you have the `inet_addr' function. */ -#define HAVE_INET_ADDR 1 - -/* Define to 1 if you have the inet_ntoa_r function. */ -/* #undef HAVE_INET_NTOA_R */ - -/* inet_ntoa_r() takes 2 args */ -/* #undef HAVE_INET_NTOA_R_2 */ - -/* inet_ntoa_r() takes 3 args */ -/* #undef HAVE_INET_NTOA_R_3 */ - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -/* #undef HAVE_INET_NTOP */ - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -/* #undef HAVE_INET_PTON */ - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the ioctl function. */ -#define HAVE_IOCTL 1 - -/* Define to 1 if you have the ioctlsocket function. */ -/* #undef HAVE_IOCTLSOCKET */ - -/* Define to 1 if you have the IoctlSocket camel case function. */ -/* #undef HAVE_IOCTLSOCKET_CAMEL */ - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. - */ -/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */ - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -/* #undef HAVE_IOCTLSOCKET_FIONBIO */ - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#define HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#define HAVE_IOCTL_SIOCGIFADDR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_IO_H 1 - -/* if you have the Kerberos4 libraries (including -ldes) */ -/* #undef HAVE_KRB4 */ - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -/* #undef HAVE_KRB_GET_OUR_IP_FOR_REALM */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_KRB_H */ - -/* Define to 1 if you have the lber.h header file. */ -/* #undef HAVE_LBER_H */ - -/* Define to 1 if you have the ldapssl.h header file. */ -/* #undef HAVE_LDAPSSL_H */ - -/* Define to 1 if you have the ldap.h header file. */ -/* #undef HAVE_LDAP_H */ - -/* Use LDAPS implementation */ -/* #undef HAVE_LDAP_SSL */ - -/* Define to 1 if you have the ldap_ssl.h header file. */ -/* #undef HAVE_LDAP_SSL_H */ - -/* Define to 1 if you have the `ldap_url_parse' function. */ -/* #undef HAVE_LDAP_URL_PARSE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIBGEN_H */ - -/* Define to 1 if you have the `idn' library (-lidn). */ -/* #undef HAVE_LIBIDN */ - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -/* #undef HAVE_LIBRESOLV */ - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -/* #undef HAVE_LIBRESOLVE */ - -/* Define to 1 if you have the `socket' library (-lsocket). */ -/* #undef HAVE_LIBSOCKET */ - -/* Define to 1 if you have the `ssh2' library (-lssh2). */ -/* #undef HAVE_LIBSSH2 */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_LIBSSH2_H */ - -/* Define to 1 if you have the `libssh2_version' function. */ -/* #undef HAVE_LIBSSH2_VERSION */ - -/* Define to 1 if you have the `ssl' library (-lssl). */ -#define HAVE_LIBSSL 1 - -/* if zlib is available */ -#define HAVE_LIBZ 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* if your compiler supports LL */ -#define HAVE_LL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define to 1 if you have a working localtime_r function. */ -#define HAVE_LOCALTIME_R 1 - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#define HAVE_LONGLONG 1 - -/* Define to 1 if you have the malloc.h header file. */ -#define HAVE_MALLOC_H 1 - -/* Define to 1 if you have the memory.h header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the MSG_NOSIGNAL flag. */ -/* #undef HAVE_MSG_NOSIGNAL */ - -/* Define to 1 if you have the header file. */ -#define HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_NET_IF_H 1 - -/* Define to 1 if NI_WITHSCOPEID exists and works. */ -/* #undef HAVE_NI_WITHSCOPEID */ - -/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE - */ -/* #undef HAVE_OLD_GSSMIT */ - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_CRYPTO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_ENGINE_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_ERR_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_PEM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_PKCS12_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_SSL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_OPENSSL_X509_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PEM_H */ - -/* Define to 1 if you have the `perror' function. */ -#define HAVE_PERROR 1 - -/* Define to 1 if you have the `pipe' function. */ -#define HAVE_PIPE 1 - -/* Define to 1 if you have a working poll function. */ -/* #undef HAVE_POLL */ - -/* If you have a fine poll */ -/* #undef HAVE_POLL_FINE */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_POLL_H */ - -/* Define to 1 if you have a working POSIX-style strerror_r function. */ -/* #undef HAVE_POSIX_STRERROR_R */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_PWD_H */ - -/* Define to 1 if you have the `RAND_egd' function. */ -#define HAVE_RAND_EGD 1 - -/* Define to 1 if you have the `RAND_screen' function. */ -/* #undef HAVE_RAND_SCREEN */ - -/* Define to 1 if you have the `RAND_status' function. */ -#define HAVE_RAND_STATUS 1 - -/* Define to 1 if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to 1 if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_RSA_H */ - -/* Define to 1 if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define to 1 if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SETJMP_H 1 - -/* Define to 1 if you have the `setlocale' function. */ -#define HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `setmode' function. */ -#define HAVE_SETMODE 1 - -/* Define to 1 if you have the `setrlimit' function. */ -#define HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the setsockopt function. */ -#define HAVE_SETSOCKOPT 1 - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SGTTY_H */ - -/* Define to 1 if you have the sigaction function. */ -#define HAVE_SIGACTION 1 - -/* Define to 1 if you have the siginterrupt function. */ -#define HAVE_SIGINTERRUPT 1 - -/* Define to 1 if you have the signal function. */ -#define HAVE_SIGNAL 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define to 1 if you have the sigsetjmp function or macro. */ -/* #undef HAVE_SIGSETJMP */ - -/* Define to 1 if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T 1 - -/* Define to 1 if sig_atomic_t is already defined as volatile. */ -/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */ - -/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define to 1 if you have the `socket' function. */ -#define HAVE_SOCKET 1 - -/* Define to 1 if you have the `SSL_get_shutdown' function. */ -#define HAVE_SSL_GET_SHUTDOWN 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SSL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STDINT_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the strcasecmp function. */ -#define HAVE_STRCASECMP 1 - -/* Define to 1 if you have the strcmpi function. */ -/* #undef HAVE_STRCMPI */ - -/* Define to 1 if you have the strdup function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the strerror_r function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the stricmp function. */ -/* #undef HAVE_STRICMP */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - -/* Define to 1 if you have the strncasecmp function. */ -#define HAVE_STRNCASECMP 1 - -/* Define to 1 if you have the strncmpi function. */ -/* #undef HAVE_STRNCMPI */ - -/* Define to 1 if you have the strnicmp function. */ -/* #undef HAVE_STRNICMP */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STROPTS_H */ - -/* Define to 1 if you have the strstr function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the strtok_r function. */ -#define HAVE_STRTOK_R 1 - -/* Define to 1 if you have the strtoll function. */ -/* #undef HAVE_STRTOLL */ - -/* if struct sockaddr_storage is defined */ -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if you have the timeval struct. */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_FILIO_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_PARAM_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_POLL_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SELECT_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_SOCKIO_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_TIME_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_UTIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TERMIOS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TERMIO_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_TLD_H */ - -/* Define to 1 if you have the `tld_strerror' function. */ -/* #undef HAVE_TLD_STRERROR */ - -/* Define to 1 if you have the `uname' function. */ -#define HAVE_UNAME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define to 1 if compiler supports C99 variadic macro style. */ -#define HAVE_VARIADIC_MACROS_C99 1 - -/* Define to 1 if compiler supports old gcc variadic macro style. */ -#define HAVE_VARIADIC_MACROS_GCC 1 - -/* Define to 1 if you have a working vxworks-style strerror_r function. */ -#define HAVE_VXWORKS_STRERROR_R 1 - -/* Define to 1 if you have the winber.h header file. */ -/* #undef HAVE_WINBER_H */ - -/* Define to 1 if you have the windows.h header file. */ -/* #undef HAVE_WINDOWS_H */ - -/* Define to 1 if you have the winldap.h header file. */ -/* #undef HAVE_WINLDAP_H */ - -/* Define to 1 if you have the winsock2.h header file. */ -/* #undef HAVE_WINSOCK2_H */ - -/* Define to 1 if you have the winsock.h header file. */ -/* #undef HAVE_WINSOCK_H */ - -/* Define this symbol if your OS supports changing the contents of argv */ -#define HAVE_WRITABLE_ARGV 1 - -/* Define to 1 if you have the writev function. */ -#define HAVE_WRITEV 1 - -/* Define to 1 if you have the ws2tcpip.h header file. */ -/* #undef HAVE_WS2TCPIP_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_X509_H */ - -/* if you have the zlib.h header file */ -#define HAVE_ZLIB_H 1 - -/* Define to 1 if you need the lber.h header file even with ldap.h */ -/* #undef NEED_LBER_H */ - -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -/* #undef NEED_MALLOC_H */ - -/* Define to 1 if you need the memory.h header file even with stdlib.h */ -/* #undef NEED_MEMORY_H */ - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -/* #undef NEED_REENTRANT */ - -/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ -/* #undef NEED_THREAD_SAFE */ - -/* Define to 1 if the open function requires three arguments. */ -#define OPEN_NEEDS_ARG3 1 - -/* cpu-machine-OS */ -#define OS "unknown-unknown-vxworks" - -/* Name of package */ -#define PACKAGE "curl" - -/* a suitable file to read random data from */ -#define RANDOM_FILE "/dev/urandom" - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 int - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 void - -/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ -#define RECVFROM_TYPE_ARG2_IS_VOID 1 - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ -/* #undef RECVFROM_TYPE_ARG5_IS_VOID */ - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 socklen_t - -/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ -/* #undef RECVFROM_TYPE_ARG6_IS_VOID */ - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 int - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 void * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int - -/* Define as the return type of signal handlers (`int' or `void'). */ -#define RETSIGTYPE void - -/* Define to the type qualifier of arg 5 for select. */ -#define SELECT_QUAL_ARG5 - -/* Define to the type of arg 1 for select. */ -#define SELECT_TYPE_ARG1 int - -/* Define to the type of args 2, 3 and 4 for select. */ -#define SELECT_TYPE_ARG234 fd_set * - -/* Define to the type of arg 5 for select. */ -#define SELECT_TYPE_ARG5 struct timeval * - -/* Define to the function return type for select. */ -#define SELECT_TYPE_RETV int - -/* Define to the type qualifier of arg 2 for send. */ -#define SEND_QUAL_ARG2 const - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 int - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 void * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 size_t - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV int - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - -/* The size of `off_t', as computed by sizeof. */ -#define SIZEOF_OFF_T 8 - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 4 - -/* The size of `time_t', as computed by sizeof. */ -#define SIZEOF_TIME_T 4 - -/* The size of `void*', as computed by sizeof. */ -#define SIZEOF_VOIDP 4 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to the type of arg 3 for strerror_r. */ -/* #undef STRERROR_R_TYPE_ARG3 */ - -/* Define to 1 if you can safely include both and . */ -/* #undef TIME_WITH_SYS_TIME */ - -/* Define if you want to enable c-ares support */ -/* #undef USE_ARES */ - -/* Define to disable non-blocking sockets. */ -/* #undef USE_BLOCKING_SOCKETS */ - -/* if GnuTLS is enabled */ -/* #undef USE_GNUTLS */ - -/* if libSSH2 is in use */ -/* #undef USE_LIBSSH2 */ - -/* If you want to build curl with the built-in manual */ -#define USE_MANUAL 1 - -/* if NSS is enabled */ -/* #undef USE_NSS */ - -/* if OpenSSL is in use */ -#define USE_OPENSSL 1 - -/* Define to 1 if you are building a Windows target without large file - support. */ -/* #undef USE_WIN32_LARGE_FILES */ - -/* to enable SSPI support */ -/* #undef USE_WINDOWS_SSPI */ - -/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ -/* #undef USE_YASSLEMUL */ - -/* Define to avoid automatic inclusion of winsock.h */ -/* #undef WIN32_LEAN_AND_MEAN */ - -/* Define to 1 if OS is AIX. */ -#ifndef _ALL_SOURCE -/* # undef _ALL_SOURCE */ -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Type to use in place of in_addr_t when system does not provide it. */ -/* #undef in_addr_t */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ - -/* the signed version of size_t */ -/* #undef ssize_t */ - -#endif /* HEADER_CURL_CONFIG_VXWORKS_H */ diff --git a/Externals/curl/lib/config-win32.h b/Externals/curl/lib/config-win32.h deleted file mode 100644 index a0df2314df..0000000000 --- a/Externals/curl/lib/config-win32.h +++ /dev/null @@ -1,725 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_WIN32_H -#define HEADER_CURL_CONFIG_WIN32_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* Hand crafted config file for Windows */ -/* ================================================================ */ - -/* ---------------------------------------------------------------- */ -/* HEADER FILES */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the header file. */ -/* #define HAVE_ARPA_INET_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_ASSERT_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_CRYPTO_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_ERRNO_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_ERR_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define if you have the header file. */ -#if defined(__MINGW32__) || defined(__POCC__) -#define HAVE_GETOPT_H 1 -#endif - -/* Define to 1 if you have the header file. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1800) -#define HAVE_INTTYPES_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_IO_H 1 - -/* Define if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the header file. */ -#define HAVE_LOCALE_H 1 - -/* Define if you need header even with header file. */ -#if !defined(__SALFORDC__) && !defined(__POCC__) -#define NEED_MALLOC_H 1 -#endif - -/* Define if you have the header file. */ -/* #define HAVE_NETDB_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_NETINET_IN_H 1 */ - -/* Define if you have the header file. */ -#ifndef __SALFORDC__ -#define HAVE_PROCESS_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SGTTY_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SSL_H 1 */ - -/* Define to 1 if you have the header file. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1800) -#define HAVE_STDBOOL_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SYS_PARAM_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SELECT_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SOCKET_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SOCKIO_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SYS_TIME_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define if you have the header file. */ -#ifndef __BORLANDC__ -#define HAVE_SYS_UTIME_H 1 -#endif - -/* Define if you have the header file. */ -/* #define HAVE_TERMIO_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_TERMIOS_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define if you have the header file. */ -#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) || \ - defined(__POCC__) -#define HAVE_UNISTD_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_WINDOWS_H 1 - -/* Define if you have the header file. */ -#define HAVE_WINSOCK_H 1 - -/* Define if you have the header file. */ -#ifndef __SALFORDC__ -#define HAVE_WINSOCK2_H 1 -#endif - -/* Define if you have the header file. */ -#ifndef __SALFORDC__ -#define HAVE_WS2TCPIP_H 1 -#endif - -/* ---------------------------------------------------------------- */ -/* OTHER HEADER INFO */ -/* ---------------------------------------------------------------- */ - -/* Define if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T 1 - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you can safely include both and . */ -/* #define TIME_WITH_SYS_TIME 1 */ - -/* Define to 1 if bool is an available type. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1800) -#define HAVE_BOOL_T 1 -#endif - -/* ---------------------------------------------------------------- */ -/* FUNCTIONS */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the closesocket function. */ -#define HAVE_CLOSESOCKET 1 - -/* Define if you don't have vprintf but do have _doprnt. */ -/* #define HAVE_DOPRNT 1 */ - -/* Define if you have the ftruncate function. */ -#define HAVE_FTRUNCATE 1 - -/* Define if you have the gethostbyaddr function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* Define if you have the gethostname function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define if you have the getpass function. */ -/* #define HAVE_GETPASS 1 */ - -/* Define if you have the getservbyname function. */ -#define HAVE_GETSERVBYNAME 1 - -/* Define if you have the getprotobyname function. */ -#define HAVE_GETPROTOBYNAME - -/* Define if you have the gettimeofday function. */ -/* #define HAVE_GETTIMEOFDAY 1 */ - -/* Define if you have the inet_addr function. */ -#define HAVE_INET_ADDR 1 - -/* Define if you have the ioctlsocket function. */ -#define HAVE_IOCTLSOCKET 1 - -/* Define if you have a working ioctlsocket FIONBIO function. */ -#define HAVE_IOCTLSOCKET_FIONBIO 1 - -/* Define if you have the perror function. */ -#define HAVE_PERROR 1 - -/* Define if you have the RAND_screen function when using SSL. */ -#define HAVE_RAND_SCREEN 1 - -/* Define if you have the `RAND_status' function when using SSL. */ -#define HAVE_RAND_STATUS 1 - -/* Define if you have the `CRYPTO_cleanup_all_ex_data' function. - This is present in OpenSSL versions after 0.9.6b */ -#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - -/* Define if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define if you have the setlocale function. */ -#define HAVE_SETLOCALE 1 - -/* Define if you have the setmode function. */ -#define HAVE_SETMODE 1 - -/* Define if you have the setvbuf function. */ -#define HAVE_SETVBUF 1 - -/* Define if you have the socket function. */ -#define HAVE_SOCKET 1 - -/* Define if you have the strcasecmp function. */ -/* #define HAVE_STRCASECMP 1 */ - -/* Define if you have the strdup function. */ -#define HAVE_STRDUP 1 - -/* Define if you have the strftime function. */ -#define HAVE_STRFTIME 1 - -/* Define if you have the stricmp function. */ -#define HAVE_STRICMP 1 - -/* Define if you have the strncasecmp function. */ -/* #define HAVE_STRNCASECMP 1 */ - -/* Define if you have the strnicmp function. */ -#define HAVE_STRNICMP 1 - -/* Define if you have the strstr function. */ -#define HAVE_STRSTR 1 - -/* Define if you have the strtoll function. */ -#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__POCC__) || \ - (defined(_MSC_VER) && (_MSC_VER >= 1800)) -#define HAVE_STRTOLL 1 -#endif - -/* Define if you have the tcgetattr function. */ -/* #define HAVE_TCGETATTR 1 */ - -/* Define if you have the tcsetattr function. */ -/* #define HAVE_TCSETATTR 1 */ - -/* Define if you have the utime function. */ -#ifndef __BORLANDC__ -#define HAVE_UTIME 1 -#endif - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 DWORD - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - -/* Define if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 SOCKET - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 char * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int - -/* Define if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 SOCKET - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - -/* Define if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 SOCKET - -/* Define to the type qualifier of arg 2 for send. */ -#define SEND_QUAL_ARG2 const - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 char * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 int - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV int - -/* ---------------------------------------------------------------- */ -/* TYPEDEF REPLACEMENTS */ -/* ---------------------------------------------------------------- */ - -/* Define if in_addr_t is not an available 'typedefed' type. */ -#define in_addr_t unsigned long - -/* Define to the return type of signal handlers (int or void). */ -#define RETSIGTYPE void - -/* Define if ssize_t is not an available 'typedefed' type. */ -#ifndef _SSIZE_T_DEFINED -# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \ - defined(__POCC__) || \ - defined(__MINGW32__) -# elif defined(_WIN64) -# define _SSIZE_T_DEFINED -# define ssize_t __int64 -# else -# define _SSIZE_T_DEFINED -# define ssize_t int -# endif -#endif - -/* ---------------------------------------------------------------- */ -/* TYPE SIZES */ -/* ---------------------------------------------------------------- */ - -/* Define to the size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* Define to the size of `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 16 - -/* Define to the size of `long long', as computed by sizeof. */ -/* #define SIZEOF_LONG_LONG 8 */ - -/* Define to the size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* Define to the size of `size_t', as computed by sizeof. */ -#if defined(_WIN64) -# define SIZEOF_SIZE_T 8 -#else -# define SIZEOF_SIZE_T 4 -#endif - -/* ---------------------------------------------------------------- */ -/* BSD-style lwIP TCP/IP stack SPECIFIC */ -/* ---------------------------------------------------------------- */ - -/* Define to use BSD-style lwIP TCP/IP stack. */ -/* #define USE_LWIPSOCK 1 */ - -#ifdef USE_LWIPSOCK -# undef USE_WINSOCK -# undef HAVE_WINSOCK_H -# undef HAVE_WINSOCK2_H -# undef HAVE_WS2TCPIP_H -# undef HAVE_ERRNO_H -# undef HAVE_GETHOSTNAME -# undef HAVE_GETNAMEINFO -# undef LWIP_POSIX_SOCKETS_IO_NAMES -# undef RECV_TYPE_ARG1 -# undef RECV_TYPE_ARG3 -# undef SEND_TYPE_ARG1 -# undef SEND_TYPE_ARG3 -# define HAVE_FREEADDRINFO -# define HAVE_GETADDRINFO -# define HAVE_GETHOSTBYNAME -# define HAVE_GETHOSTBYNAME_R -# define HAVE_GETHOSTBYNAME_R_6 -# define LWIP_POSIX_SOCKETS_IO_NAMES 0 -# define RECV_TYPE_ARG1 int -# define RECV_TYPE_ARG3 size_t -# define SEND_TYPE_ARG1 int -# define SEND_TYPE_ARG3 size_t -#endif - -/* ---------------------------------------------------------------- */ -/* Watt-32 tcp/ip SPECIFIC */ -/* ---------------------------------------------------------------- */ - -#ifdef USE_WATT32 - #include - #undef byte - #undef word - #undef USE_WINSOCK - #undef HAVE_WINSOCK_H - #undef HAVE_WINSOCK2_H - #undef HAVE_WS2TCPIP_H - #define HAVE_GETADDRINFO - #define HAVE_GETNAMEINFO - #define HAVE_SYS_IOCTL_H - #define HAVE_SYS_SOCKET_H - #define HAVE_NETINET_IN_H - #define HAVE_NETDB_H - #define HAVE_ARPA_INET_H - #define HAVE_FREEADDRINFO - #define SOCKET int -#endif - - -/* ---------------------------------------------------------------- */ -/* COMPILER SPECIFIC */ -/* ---------------------------------------------------------------- */ - -/* Define to nothing if compiler does not support 'const' qualifier. */ -/* #define const */ - -/* Define to nothing if compiler does not support 'volatile' qualifier. */ -/* #define volatile */ - -/* Windows should not have HAVE_GMTIME_R defined */ -/* #undef HAVE_GMTIME_R */ - -/* Define if the compiler supports C99 variadic macro style. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define HAVE_VARIADIC_MACROS_C99 1 -#endif - -/* Define if the compiler supports the 'long long' data type. */ -#if defined(__MINGW32__) || defined(__WATCOMC__) || \ - (defined(_MSC_VER) && (_MSC_VER >= 1310)) || \ - (defined(__BORLANDC__) && (__BORLANDC__ >= 0x561)) -#define HAVE_LONGLONG 1 -#endif - -/* Define to avoid VS2005 complaining about portable C functions. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define _CRT_SECURE_NO_DEPRECATE 1 -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif - -/* VS2005 and later dafault size for time_t is 64-bit, unless - _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -# ifndef _USE_32BIT_TIME_T -# define SIZEOF_TIME_T 8 -# else -# define SIZEOF_TIME_T 4 -# endif -#endif - -/* Define some minimum and default build targets for Visual Studio */ -#if defined(_MSC_VER) - /* Officially, Microsoft's Windows SDK versions 6.X does not support Windows - 2000 as a supported build target. VS2008 default installations provides - an embedded Windows SDK v6.0A along with the claim that Windows 2000 is a - valid build target for VS2008. Popular belief is that binaries built with - VS2008 using Windows SDK versions v6.X and Windows 2000 as a build target - are functional. */ -# define VS2008_MIN_TARGET 0x0500 - - /* The minimum build target for VS2012 is Vista unless Update 1 is installed - and the v110_xp toolset is choosen. */ -# if defined(_USING_V110_SDK71_) -# define VS2012_MIN_TARGET 0x0501 -# else -# define VS2012_MIN_TARGET 0x0600 -# endif - - /* VS2008 default build target is Windows Vista. We override default target - to be Windows XP. */ -# define VS2008_DEF_TARGET 0x0501 - - /* VS2012 default build target is Windows Vista unless Update 1 is installed - and the v110_xp toolset is choosen. */ -# if defined(_USING_V110_SDK71_) -# define VS2012_DEF_TARGET 0x0501 -# else -# define VS2012_DEF_TARGET 0x0600 -# endif -#endif - -/* VS2008 default target settings and minimum build target check. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (_MSC_VER <= 1600) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT VS2008_DEF_TARGET -# endif -# ifndef WINVER -# define WINVER VS2008_DEF_TARGET -# endif -#endif - -/* VS2012 default target settings and minimum build target check. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1700) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT VS2012_DEF_TARGET -# endif -# ifndef WINVER -# define WINVER VS2012_DEF_TARGET -# endif -#endif - -/* When no build target is specified Pelles C 5.00 and later default build - target is Windows Vista. We override default target to be Windows 2000. */ -#if defined(__POCC__) && (__POCC__ >= 500) -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0500 -# endif -# ifndef WINVER -# define WINVER 0x0500 -# endif -#endif - -/* Availability of freeaddrinfo, getaddrinfo and getnameinfo functions is - quite convoluted, compiler dependent and even build target dependent. */ -#if defined(HAVE_WS2TCPIP_H) -# if defined(__POCC__) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETADDRINFO_THREADSAFE 1 -# define HAVE_GETNAMEINFO 1 -# elif defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETADDRINFO_THREADSAFE 1 -# define HAVE_GETNAMEINFO 1 -# elif defined(_MSC_VER) && (_MSC_VER >= 1200) -# define HAVE_FREEADDRINFO 1 -# define HAVE_GETADDRINFO 1 -# define HAVE_GETADDRINFO_THREADSAFE 1 -# define HAVE_GETNAMEINFO 1 -# endif -#endif - -#if defined(__POCC__) -# ifndef _MSC_VER -# error Microsoft extensions /Ze compiler option is required -# endif -# ifndef __POCC__OLDNAMES -# error Compatibility names /Go compiler option is required -# endif -#endif - -/* ---------------------------------------------------------------- */ -/* STRUCT RELATED */ -/* ---------------------------------------------------------------- */ - -/* Define if you have struct sockaddr_storage. */ -#if !defined(__SALFORDC__) && !defined(__BORLANDC__) -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 -#endif - -/* Define if you have struct timeval. */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define if struct sockaddr_in6 has the sin6_scope_id member. */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -#if defined(HAVE_WINSOCK2_H) && defined(_WIN32_WINNT) && \ - (_WIN32_WINNT >= 0x0600) -#define HAVE_STRUCT_POLLFD 1 -#endif - -/* ---------------------------------------------------------------- */ -/* LARGE FILE SUPPORT */ -/* ---------------------------------------------------------------- */ - -#if defined(_MSC_VER) && !defined(_WIN32_WCE) -# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) -# define USE_WIN32_LARGE_FILES -# else -# define USE_WIN32_SMALL_FILES -# endif -#endif - -#if defined(__MINGW32__) && !defined(USE_WIN32_LARGE_FILES) -# define USE_WIN32_LARGE_FILES -#endif - -#if defined(__WATCOMC__) && !defined(USE_WIN32_LARGE_FILES) -# define USE_WIN32_LARGE_FILES -#endif - -#if defined(__POCC__) -# undef USE_WIN32_LARGE_FILES -#endif - -#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES) -# define USE_WIN32_SMALL_FILES -#endif - -/* ---------------------------------------------------------------- */ -/* DNS RESOLVER SPECIALTY */ -/* ---------------------------------------------------------------- */ - -/* - * Undefine both USE_ARES and USE_THREADS_WIN32 for synchronous DNS. - */ - -/* Define to enable c-ares asynchronous DNS lookups. */ -/* #define USE_ARES 1 */ - -/* Default define to enable threaded asynchronous DNS lookups. */ -#if !defined(USE_SYNC_DNS) && !defined(USE_ARES) && \ - !defined(USE_THREADS_WIN32) -# define USE_THREADS_WIN32 1 -#endif - -#if defined(USE_ARES) && defined(USE_THREADS_WIN32) -# error "Only one DNS lookup specialty may be defined at most" -#endif - -/* ---------------------------------------------------------------- */ -/* LDAP SUPPORT */ -/* ---------------------------------------------------------------- */ - -#if defined(CURL_HAS_NOVELL_LDAPSDK) || defined(CURL_HAS_MOZILLA_LDAPSDK) -#undef USE_WIN32_LDAP -#define HAVE_LDAP_SSL_H 1 -#define HAVE_LDAP_URL_PARSE 1 -#elif defined(CURL_HAS_OPENLDAP_LDAPSDK) -#undef USE_WIN32_LDAP -#define HAVE_LDAP_URL_PARSE 1 -#else -#undef HAVE_LDAP_URL_PARSE -#define USE_WIN32_LDAP 1 -#endif - -#if defined(__WATCOMC__) && defined(USE_WIN32_LDAP) -#if __WATCOMC__ < 1280 -#define WINBERAPI __declspec(cdecl) -#define WINLDAPAPI __declspec(cdecl) -#endif -#endif - -#if defined(__POCC__) && defined(USE_WIN32_LDAP) -# define CURL_DISABLE_LDAP 1 -#endif - -/* Define to use the Windows crypto library. */ -#if !defined(USE_OPENSSL) && !defined(USE_NSS) -#define USE_WIN32_CRYPTO -#endif - -/* ---------------------------------------------------------------- */ -/* ADDITIONAL DEFINITIONS */ -/* ---------------------------------------------------------------- */ - -/* Define cpu-machine-OS */ -#undef OS -#if defined(_M_IX86) || defined(__i386__) /* x86 (MSVC or gcc) */ -#define OS "i386-pc-win32" -#elif defined(_M_X64) || defined(__x86_64__) /* x86_64 (MSVC >=2005 or gcc) */ -#define OS "x86_64-pc-win32" -#elif defined(_M_IA64) /* Itanium */ -#define OS "ia64-pc-win32" -#else -#define OS "unknown-pc-win32" -#endif - -/* Name of package */ -#define PACKAGE "curl" - -/* If you want to build curl with the built-in manual */ -#define USE_MANUAL 1 - -#if defined(__POCC__) || defined(USE_IPV6) -# define ENABLE_IPV6 1 -#endif - -#endif /* HEADER_CURL_CONFIG_WIN32_H */ diff --git a/Externals/curl/lib/config-win32ce.h b/Externals/curl/lib/config-win32ce.h deleted file mode 100644 index 383948576d..0000000000 --- a/Externals/curl/lib/config-win32ce.h +++ /dev/null @@ -1,448 +0,0 @@ -#ifndef HEADER_CURL_CONFIG_WIN32CE_H -#define HEADER_CURL_CONFIG_WIN32CE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* lib/config-win32ce.h - Hand crafted config file for windows ce */ -/* ================================================================ */ - -/* ---------------------------------------------------------------- */ -/* HEADER FILES */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the header file. */ -/* #define HAVE_ARPA_INET_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_ASSERT_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_CRYPTO_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_ERRNO_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_ERR_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_GETOPT_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_IO_H 1 - -/* Define if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you need the malloc.h header header file even with stdlib.h */ -#define NEED_MALLOC_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_NETDB_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_NETINET_IN_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_SIGNAL_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_SGTTY_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SSL_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_PROCESS_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_PARAM_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SELECT_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SOCKET_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_SOCKIO_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define if you have the header file */ -/* #define HAVE_SYS_TIME_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_SYS_TYPES_H 1 */ - -/* Define if you have the header file */ -#define HAVE_SYS_UTIME_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_TERMIO_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_TERMIOS_H 1 */ - -/* Define if you have the header file. */ -#define HAVE_TIME_H 1 - -/* Define if you have the header file. */ -#if defined(__MINGW32__) || defined(__WATCOMC__) || defined(__LCC__) -#define HAVE_UNISTD_H 1 -#endif - -/* Define if you have the header file. */ -#define HAVE_WINDOWS_H 1 - -/* Define if you have the header file. */ -#define HAVE_WINSOCK_H 1 - -/* Define if you have the header file. */ -/* #define HAVE_WINSOCK2_H 1 */ - -/* Define if you have the header file. */ -/* #define HAVE_WS2TCPIP_H 1 */ - -/* ---------------------------------------------------------------- */ -/* OTHER HEADER INFO */ -/* ---------------------------------------------------------------- */ - -/* Define if sig_atomic_t is an available typedef. */ -#define HAVE_SIG_ATOMIC_T 1 - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you can safely include both and . */ -/* #define TIME_WITH_SYS_TIME 1 */ - -/* ---------------------------------------------------------------- */ -/* FUNCTIONS */ -/* ---------------------------------------------------------------- */ - -/* Define if you have the closesocket function. */ -#define HAVE_CLOSESOCKET 1 - -/* Define if you don't have vprintf but do have _doprnt. */ -/* #define HAVE_DOPRNT 1 */ - -/* Define if you have the gethostbyaddr function. */ -#define HAVE_GETHOSTBYADDR 1 - -/* Define if you have the gethostname function. */ -#define HAVE_GETHOSTNAME 1 - -/* Define if you have the getpass function. */ -/* #define HAVE_GETPASS 1 */ - -/* Define if you have the getservbyname function. */ -#define HAVE_GETSERVBYNAME 1 - -/* Define if you have the gettimeofday function. */ -/* #define HAVE_GETTIMEOFDAY 1 */ - -/* Define if you have the inet_addr function. */ -#define HAVE_INET_ADDR 1 - -/* Define if you have the ioctlsocket function. */ -#define HAVE_IOCTLSOCKET 1 - -/* Define if you have a working ioctlsocket FIONBIO function. */ -#define HAVE_IOCTLSOCKET_FIONBIO 1 - -/* Define if you have the perror function. */ -#define HAVE_PERROR 1 - -/* Define if you have the RAND_screen function when using SSL */ -#define HAVE_RAND_SCREEN 1 - -/* Define if you have the `RAND_status' function when using SSL. */ -#define HAVE_RAND_STATUS 1 - -/* Define if you have the select function. */ -#define HAVE_SELECT 1 - -/* Define if you have the setvbuf function. */ -#define HAVE_SETVBUF 1 - -/* Define if you have the socket function. */ -#define HAVE_SOCKET 1 - -/* Define if you have the strcasecmp function. */ -/* #define HAVE_STRCASECMP 1 */ - -/* Define if you have the strdup function. */ -/* #define HAVE_STRDUP 1 */ - -/* Define if you have the strftime function. */ -/* #define HAVE_STRFTIME 1 */ - -/* Define if you have the stricmp function. */ -/* #define HAVE_STRICMP 1 */ - -/* Define if you have the strncasecmp function. */ -/* #define HAVE_STRNCASECMP 1 */ - -/* Define if you have the strnicmp function. */ -/* #define HAVE_STRNICMP 1 */ - -/* Define if you have the strstr function. */ -#define HAVE_STRSTR 1 - -/* Define if you have the strtoll function. */ -#if defined(__MINGW32__) || defined(__WATCOMC__) -#define HAVE_STRTOLL 1 -#endif - -/* Define if you have the tcgetattr function. */ -/* #define HAVE_TCGETATTR 1 */ - -/* Define if you have the tcsetattr function. */ -/* #define HAVE_TCSETATTR 1 */ - -/* Define if you have the utime function */ -#define HAVE_UTIME 1 - -/* Define if you have the getnameinfo function. */ -#define HAVE_GETNAMEINFO 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#define GETNAMEINFO_QUAL_ARG1 const - -/* Define to the type of arg 1 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG1 struct sockaddr * - -/* Define to the type of arg 2 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG2 socklen_t - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG46 DWORD - -/* Define to the type of arg 7 for getnameinfo. */ -#define GETNAMEINFO_TYPE_ARG7 int - -/* Define if you have the recv function. */ -#define HAVE_RECV 1 - -/* Define to the type of arg 1 for recv. */ -#define RECV_TYPE_ARG1 SOCKET - -/* Define to the type of arg 2 for recv. */ -#define RECV_TYPE_ARG2 char * - -/* Define to the type of arg 3 for recv. */ -#define RECV_TYPE_ARG3 int - -/* Define to the type of arg 4 for recv. */ -#define RECV_TYPE_ARG4 int - -/* Define to the function return type for recv. */ -#define RECV_TYPE_RETV int - -/* Define if you have the recvfrom function. */ -#define HAVE_RECVFROM 1 - -/* Define to the type of arg 1 for recvfrom. */ -#define RECVFROM_TYPE_ARG1 SOCKET - -/* Define to the type pointed by arg 2 for recvfrom. */ -#define RECVFROM_TYPE_ARG2 char - -/* Define to the type of arg 3 for recvfrom. */ -#define RECVFROM_TYPE_ARG3 int - -/* Define to the type of arg 4 for recvfrom. */ -#define RECVFROM_TYPE_ARG4 int - -/* Define to the type pointed by arg 5 for recvfrom. */ -#define RECVFROM_TYPE_ARG5 struct sockaddr - -/* Define to the type pointed by arg 6 for recvfrom. */ -#define RECVFROM_TYPE_ARG6 int - -/* Define to the function return type for recvfrom. */ -#define RECVFROM_TYPE_RETV int - -/* Define if you have the send function. */ -#define HAVE_SEND 1 - -/* Define to the type of arg 1 for send. */ -#define SEND_TYPE_ARG1 SOCKET - -/* Define to the type qualifier of arg 2 for send. */ -#define SEND_QUAL_ARG2 const - -/* Define to the type of arg 2 for send. */ -#define SEND_TYPE_ARG2 char * - -/* Define to the type of arg 3 for send. */ -#define SEND_TYPE_ARG3 int - -/* Define to the type of arg 4 for send. */ -#define SEND_TYPE_ARG4 int - -/* Define to the function return type for send. */ -#define SEND_TYPE_RETV int - -/* ---------------------------------------------------------------- */ -/* TYPEDEF REPLACEMENTS */ -/* ---------------------------------------------------------------- */ - -/* Define this if in_addr_t is not an available 'typedefed' type */ -#define in_addr_t unsigned long - -/* Define as the return type of signal handlers (int or void). */ -#define RETSIGTYPE void - -/* Define ssize_t if it is not an available 'typedefed' type */ -#if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || defined(__POCC__) -#elif defined(_WIN64) -#define ssize_t __int64 -#else -#define ssize_t int -#endif - -/* ---------------------------------------------------------------- */ -/* TYPE SIZES */ -/* ---------------------------------------------------------------- */ - -/* The size of `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of `long double', as computed by sizeof. */ -#define SIZEOF_LONG_DOUBLE 16 - -/* The size of `long long', as computed by sizeof. */ -/* #define SIZEOF_LONG_LONG 8 */ - -/* The size of `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#if defined(_WIN64) -# define SIZEOF_SIZE_T 8 -#else -# define SIZEOF_SIZE_T 4 -#endif - -/* ---------------------------------------------------------------- */ -/* STRUCT RELATED */ -/* ---------------------------------------------------------------- */ - -/* Define this if you have struct sockaddr_storage */ -/* #define HAVE_STRUCT_SOCKADDR_STORAGE 1 */ - -/* Define this if you have struct timeval */ -#define HAVE_STRUCT_TIMEVAL 1 - -/* Define this if struct sockaddr_in6 has the sin6_scope_id member */ -#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* ---------------------------------------------------------------- */ -/* COMPILER SPECIFIC */ -/* ---------------------------------------------------------------- */ - -/* Undef keyword 'const' if it does not work. */ -/* #undef const */ - -/* Define to avoid VS2005 complaining about portable C functions */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define _CRT_SECURE_NO_DEPRECATE 1 -#define _CRT_NONSTDC_NO_DEPRECATE 1 -#endif - -/* VS2005 and later dafault size for time_t is 64-bit, unless */ -/* _USE_32BIT_TIME_T has been defined to get a 32-bit time_t. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -# ifndef _USE_32BIT_TIME_T -# define SIZEOF_TIME_T 8 -# else -# define SIZEOF_TIME_T 4 -# endif -#endif - -/* ---------------------------------------------------------------- */ -/* LARGE FILE SUPPORT */ -/* ---------------------------------------------------------------- */ - -#if defined(_MSC_VER) && !defined(_WIN32_WCE) -# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) -# define USE_WIN32_LARGE_FILES -# else -# define USE_WIN32_SMALL_FILES -# endif -#endif - -#if !defined(USE_WIN32_LARGE_FILES) && !defined(USE_WIN32_SMALL_FILES) -# define USE_WIN32_SMALL_FILES -#endif - -/* ---------------------------------------------------------------- */ -/* LDAP SUPPORT */ -/* ---------------------------------------------------------------- */ - -#define USE_WIN32_LDAP 1 -#undef HAVE_LDAP_URL_PARSE - -/* ---------------------------------------------------------------- */ -/* ADDITIONAL DEFINITIONS */ -/* ---------------------------------------------------------------- */ - -/* Define cpu-machine-OS */ -#undef OS -#define OS "i386-pc-win32ce" - -/* Name of package */ -#define PACKAGE "curl" - -/* ---------------------------------------------------------------- */ -/* WinCE */ -/* ---------------------------------------------------------------- */ - -#ifndef UNICODE -# define UNICODE -#endif - -#ifndef _UNICODE -# define _UNICODE -#endif - -#define CURL_DISABLE_FILE 1 -#define CURL_DISABLE_TELNET 1 -#define CURL_DISABLE_LDAP 1 - -#define ENOSPC 1 -#define ENOMEM 2 -#define EAGAIN 3 - -extern int stat(const char *path, struct stat *buffer); - -#endif /* HEADER_CURL_CONFIG_WIN32CE_H */ diff --git a/Externals/curl/lib/conncache.c b/Externals/curl/lib/conncache.c deleted file mode 100644 index d0c09c826d..0000000000 --- a/Externals/curl/lib/conncache.c +++ /dev/null @@ -1,370 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012, 2016, Linus Nielsen Feltzing, - * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "urldata.h" -#include "url.h" -#include "progress.h" -#include "multiif.h" -#include "sendf.h" -#include "rawstr.h" -#include "conncache.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -static void conn_llist_dtor(void *user, void *element) -{ - struct connectdata *data = element; - (void)user; - - data->bundle = NULL; -} - -static CURLcode bundle_create(struct SessionHandle *data, - struct connectbundle **cb_ptr) -{ - (void)data; - DEBUGASSERT(*cb_ptr == NULL); - *cb_ptr = malloc(sizeof(struct connectbundle)); - if(!*cb_ptr) - return CURLE_OUT_OF_MEMORY; - - (*cb_ptr)->num_connections = 0; - (*cb_ptr)->multiuse = BUNDLE_UNKNOWN; - - (*cb_ptr)->conn_list = Curl_llist_alloc((curl_llist_dtor) conn_llist_dtor); - if(!(*cb_ptr)->conn_list) { - Curl_safefree(*cb_ptr); - return CURLE_OUT_OF_MEMORY; - } - return CURLE_OK; -} - -static void bundle_destroy(struct connectbundle *cb_ptr) -{ - if(!cb_ptr) - return; - - if(cb_ptr->conn_list) { - Curl_llist_destroy(cb_ptr->conn_list, NULL); - cb_ptr->conn_list = NULL; - } - free(cb_ptr); -} - -/* Add a connection to a bundle */ -static CURLcode bundle_add_conn(struct connectbundle *cb_ptr, - struct connectdata *conn) -{ - if(!Curl_llist_insert_next(cb_ptr->conn_list, cb_ptr->conn_list->tail, conn)) - return CURLE_OUT_OF_MEMORY; - - conn->bundle = cb_ptr; - - cb_ptr->num_connections++; - return CURLE_OK; -} - -/* Remove a connection from a bundle */ -static int bundle_remove_conn(struct connectbundle *cb_ptr, - struct connectdata *conn) -{ - struct curl_llist_element *curr; - - curr = cb_ptr->conn_list->head; - while(curr) { - if(curr->ptr == conn) { - Curl_llist_remove(cb_ptr->conn_list, curr, NULL); - cb_ptr->num_connections--; - conn->bundle = NULL; - return 1; /* we removed a handle */ - } - curr = curr->next; - } - return 0; -} - -static void free_bundle_hash_entry(void *freethis) -{ - struct connectbundle *b = (struct connectbundle *) freethis; - - bundle_destroy(b); -} - -int Curl_conncache_init(struct conncache *connc, int size) -{ - return Curl_hash_init(&connc->hash, size, Curl_hash_str, - Curl_str_key_compare, free_bundle_hash_entry); -} - -void Curl_conncache_destroy(struct conncache *connc) -{ - if(connc) - Curl_hash_destroy(&connc->hash); -} - -/* returns an allocated key to find a bundle for this connection */ -static char *hashkey(struct connectdata *conn) -{ - const char *hostname; - - if(conn->bits.proxy) - hostname = conn->proxy.name; - else if(conn->bits.conn_to_host) - hostname = conn->conn_to_host.name; - else - hostname = conn->host.name; - - return aprintf("%s:%d", hostname, conn->port); -} - -/* Look up the bundle with all the connections to the same host this - connectdata struct is setup to use. */ -struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, - struct conncache *connc) -{ - struct connectbundle *bundle = NULL; - if(connc) { - char *key = hashkey(conn); - if(key) { - bundle = Curl_hash_pick(&connc->hash, key, strlen(key)); - free(key); - } - } - - return bundle; -} - -static bool conncache_add_bundle(struct conncache *connc, - char *key, - struct connectbundle *bundle) -{ - void *p = Curl_hash_add(&connc->hash, key, strlen(key), bundle); - - return p?TRUE:FALSE; -} - -static void conncache_remove_bundle(struct conncache *connc, - struct connectbundle *bundle) -{ - struct curl_hash_iterator iter; - struct curl_hash_element *he; - - if(!connc) - return; - - Curl_hash_start_iterate(&connc->hash, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - if(he->ptr == bundle) { - /* The bundle is destroyed by the hash destructor function, - free_bundle_hash_entry() */ - Curl_hash_delete(&connc->hash, he->key, he->key_len); - return; - } - - he = Curl_hash_next_element(&iter); - } -} - -CURLcode Curl_conncache_add_conn(struct conncache *connc, - struct connectdata *conn) -{ - CURLcode result; - struct connectbundle *bundle; - struct connectbundle *new_bundle = NULL; - struct SessionHandle *data = conn->data; - - bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache); - if(!bundle) { - char *key; - int rc; - - result = bundle_create(data, &new_bundle); - if(result) - return result; - - key = hashkey(conn); - if(!key) { - bundle_destroy(new_bundle); - return CURLE_OUT_OF_MEMORY; - } - - rc = conncache_add_bundle(data->state.conn_cache, key, new_bundle); - free(key); - if(!rc) { - bundle_destroy(new_bundle); - return CURLE_OUT_OF_MEMORY; - } - bundle = new_bundle; - } - - result = bundle_add_conn(bundle, conn); - if(result) { - if(new_bundle) - conncache_remove_bundle(data->state.conn_cache, new_bundle); - return result; - } - - conn->connection_id = connc->next_connection_id++; - connc->num_connections++; - - DEBUGF(infof(conn->data, "Added connection %ld. " - "The cache now contains %" CURL_FORMAT_CURL_OFF_TU " members\n", - conn->connection_id, (curl_off_t) connc->num_connections)); - - return CURLE_OK; -} - -void Curl_conncache_remove_conn(struct conncache *connc, - struct connectdata *conn) -{ - struct connectbundle *bundle = conn->bundle; - - /* The bundle pointer can be NULL, since this function can be called - due to a failed connection attempt, before being added to a bundle */ - if(bundle) { - bundle_remove_conn(bundle, conn); - if(bundle->num_connections == 0) { - conncache_remove_bundle(connc, bundle); - } - - if(connc) { - connc->num_connections--; - - DEBUGF(infof(conn->data, "The cache now contains %" - CURL_FORMAT_CURL_OFF_TU " members\n", - (curl_off_t) connc->num_connections)); - } - } -} - -/* This function iterates the entire connection cache and calls the - function func() with the connection pointer as the first argument - and the supplied 'param' argument as the other, - - Return 0 from func() to continue the loop, return 1 to abort it. - */ -void Curl_conncache_foreach(struct conncache *connc, - void *param, - int (*func)(struct connectdata *conn, void *param)) -{ - struct curl_hash_iterator iter; - struct curl_llist_element *curr; - struct curl_hash_element *he; - - if(!connc) - return; - - Curl_hash_start_iterate(&connc->hash, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - struct connectbundle *bundle; - - bundle = he->ptr; - he = Curl_hash_next_element(&iter); - - curr = bundle->conn_list->head; - while(curr) { - /* Yes, we need to update curr before calling func(), because func() - might decide to remove the connection */ - struct connectdata *conn = curr->ptr; - curr = curr->next; - - if(1 == func(conn, param)) - return; - } - } -} - -/* Return the first connection found in the cache. Used when closing all - connections */ -struct connectdata * -Curl_conncache_find_first_connection(struct conncache *connc) -{ - struct curl_hash_iterator iter; - struct curl_hash_element *he; - struct connectbundle *bundle; - - Curl_hash_start_iterate(&connc->hash, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - struct curl_llist_element *curr; - bundle = he->ptr; - - curr = bundle->conn_list->head; - if(curr) { - return curr->ptr; - } - - he = Curl_hash_next_element(&iter); - } - - return NULL; -} - - -#if 0 -/* Useful for debugging the connection cache */ -void Curl_conncache_print(struct conncache *connc) -{ - struct curl_hash_iterator iter; - struct curl_llist_element *curr; - struct curl_hash_element *he; - - if(!connc) - return; - - fprintf(stderr, "=Bundle cache=\n"); - - Curl_hash_start_iterate(connc->hash, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - struct connectbundle *bundle; - struct connectdata *conn; - - bundle = he->ptr; - - fprintf(stderr, "%s -", he->key); - curr = bundle->conn_list->head; - while(curr) { - conn = curr->ptr; - - fprintf(stderr, " [%p %d]", (void *)conn, conn->inuse); - curr = curr->next; - } - fprintf(stderr, "\n"); - - he = Curl_hash_next_element(&iter); - } -} -#endif diff --git a/Externals/curl/lib/conncache.h b/Externals/curl/lib/conncache.h deleted file mode 100644 index b1dadf9906..0000000000 --- a/Externals/curl/lib/conncache.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef HEADER_CURL_CONNCACHE_H -#define HEADER_CURL_CONNCACHE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2015, Daniel Stenberg, , et al. - * Copyright (C) 2012 - 2014, Linus Nielsen Feltzing, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -struct conncache { - struct curl_hash hash; - size_t num_connections; - long next_connection_id; - struct timeval last_cleanup; -}; - -#define BUNDLE_NO_MULTIUSE -1 -#define BUNDLE_UNKNOWN 0 /* initial value */ -#define BUNDLE_PIPELINING 1 -#define BUNDLE_MULTIPLEX 2 - -struct connectbundle { - int multiuse; /* supports multi-use */ - size_t num_connections; /* Number of connections in the bundle */ - struct curl_llist *conn_list; /* The connectdata members of the bundle */ -}; - -int Curl_conncache_init(struct conncache *, int size); - -void Curl_conncache_destroy(struct conncache *connc); - -/* return the correct bundle, to a host or a proxy */ -struct connectbundle *Curl_conncache_find_bundle(struct connectdata *conn, - struct conncache *connc); - -CURLcode Curl_conncache_add_conn(struct conncache *connc, - struct connectdata *conn); - -void Curl_conncache_remove_conn(struct conncache *connc, - struct connectdata *conn); - -void Curl_conncache_foreach(struct conncache *connc, - void *param, - int (*func)(struct connectdata *conn, - void *param)); - -struct connectdata * -Curl_conncache_find_first_connection(struct conncache *connc); - -void Curl_conncache_print(struct conncache *connc); - -#endif /* HEADER_CURL_CONNCACHE_H */ diff --git a/Externals/curl/lib/connect.c b/Externals/curl/lib/connect.c deleted file mode 100644 index ac2f26833f..0000000000 --- a/Externals/curl/lib/connect.c +++ /dev/null @@ -1,1416 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include /* may need it */ -#endif -#ifdef HAVE_SYS_UN_H -#include /* for sockaddr_un */ -#endif -#ifdef HAVE_NETINET_TCP_H -#include /* for TCP_NODELAY */ -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE)) -#include -#endif -#ifdef NETWARE -#undef in_addr_t -#define in_addr_t unsigned long -#endif -#ifdef __VMS -#include -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "if2ip.h" -#include "strerror.h" -#include "connect.h" -#include "select.h" -#include "url.h" /* for Curl_safefree() */ -#include "multiif.h" -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "inet_ntop.h" -#include "inet_pton.h" -#include "vtls/vtls.h" /* for Curl_ssl_check_cxn() */ -#include "progress.h" -#include "warnless.h" -#include "conncache.h" -#include "multihandle.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifdef __SYMBIAN32__ -/* This isn't actually supported under Symbian OS */ -#undef SO_NOSIGPIPE -#endif - -static bool verifyconnect(curl_socket_t sockfd, int *error); - -#if defined(__DragonFly__) || defined(HAVE_WINSOCK_H) -/* DragonFlyBSD and Windows use millisecond units */ -#define KEEPALIVE_FACTOR(x) (x *= 1000) -#else -#define KEEPALIVE_FACTOR(x) -#endif - -#if defined(HAVE_WINSOCK2_H) && !defined(SIO_KEEPALIVE_VALS) -#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) - -struct tcp_keepalive { - u_long onoff; - u_long keepalivetime; - u_long keepaliveinterval; -}; -#endif - -static void -tcpkeepalive(struct SessionHandle *data, - curl_socket_t sockfd) -{ - int optval = data->set.tcp_keepalive?1:0; - - /* only set IDLE and INTVL if setting KEEPALIVE is successful */ - if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, - (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set SO_KEEPALIVE on fd %d\n", sockfd); - } - else { -#if defined(SIO_KEEPALIVE_VALS) - struct tcp_keepalive vals; - DWORD dummy; - vals.onoff = 1; - optval = curlx_sltosi(data->set.tcp_keepidle); - KEEPALIVE_FACTOR(optval); - vals.keepalivetime = optval; - optval = curlx_sltosi(data->set.tcp_keepintvl); - KEEPALIVE_FACTOR(optval); - vals.keepaliveinterval = optval; - if(WSAIoctl(sockfd, SIO_KEEPALIVE_VALS, (LPVOID) &vals, sizeof(vals), - NULL, 0, &dummy, NULL, NULL) != 0) { - infof(data, "Failed to set SIO_KEEPALIVE_VALS on fd %d: %d\n", - (int)sockfd, WSAGetLastError()); - } -#else -#ifdef TCP_KEEPIDLE - optval = curlx_sltosi(data->set.tcp_keepidle); - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, - (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set TCP_KEEPIDLE on fd %d\n", sockfd); - } -#endif -#ifdef TCP_KEEPINTVL - optval = curlx_sltosi(data->set.tcp_keepintvl); - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, - (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set TCP_KEEPINTVL on fd %d\n", sockfd); - } -#endif -#ifdef TCP_KEEPALIVE - /* Mac OS X style */ - optval = curlx_sltosi(data->set.tcp_keepidle); - KEEPALIVE_FACTOR(optval); - if(setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPALIVE, - (void *)&optval, sizeof(optval)) < 0) { - infof(data, "Failed to set TCP_KEEPALIVE on fd %d\n", sockfd); - } -#endif -#endif - } -} - -static CURLcode -singleipconnect(struct connectdata *conn, - const Curl_addrinfo *ai, /* start connecting to this */ - curl_socket_t *sock); - -/* - * Curl_timeleft() returns the amount of milliseconds left allowed for the - * transfer/connection. If the value is negative, the timeout time has already - * elapsed. - * - * The start time is stored in progress.t_startsingle - as set with - * Curl_pgrsTime(..., TIMER_STARTSINGLE); - * - * If 'nowp' is non-NULL, it points to the current time. - * 'duringconnect' is FALSE if not during a connect, as then of course the - * connect timeout is not taken into account! - * - * @unittest: 1303 - */ -long Curl_timeleft(struct SessionHandle *data, - struct timeval *nowp, - bool duringconnect) -{ - int timeout_set = 0; - long timeout_ms = duringconnect?DEFAULT_CONNECT_TIMEOUT:0; - struct timeval now; - - /* if a timeout is set, use the most restrictive one */ - - if(data->set.timeout > 0) - timeout_set |= 1; - if(duringconnect && (data->set.connecttimeout > 0)) - timeout_set |= 2; - - switch (timeout_set) { - case 1: - timeout_ms = data->set.timeout; - break; - case 2: - timeout_ms = data->set.connecttimeout; - break; - case 3: - if(data->set.timeout < data->set.connecttimeout) - timeout_ms = data->set.timeout; - else - timeout_ms = data->set.connecttimeout; - break; - default: - /* use the default */ - if(!duringconnect) - /* if we're not during connect, there's no default timeout so if we're - at zero we better just return zero and not make it a negative number - by the math below */ - return 0; - break; - } - - if(!nowp) { - now = Curl_tvnow(); - nowp = &now; - } - - /* subtract elapsed time */ - if(duringconnect) - /* since this most recent connect started */ - timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startsingle); - else - /* since the entire operation started */ - timeout_ms -= Curl_tvdiff(*nowp, data->progress.t_startop); - if(!timeout_ms) - /* avoid returning 0 as that means no timeout! */ - return -1; - - return timeout_ms; -} - -static CURLcode bindlocal(struct connectdata *conn, - curl_socket_t sockfd, int af, unsigned int scope) -{ - struct SessionHandle *data = conn->data; - - struct Curl_sockaddr_storage sa; - struct sockaddr *sock = (struct sockaddr *)&sa; /* bind to this address */ - curl_socklen_t sizeof_sa = 0; /* size of the data sock points to */ - struct sockaddr_in *si4 = (struct sockaddr_in *)&sa; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 *si6 = (struct sockaddr_in6 *)&sa; -#endif - - struct Curl_dns_entry *h=NULL; - unsigned short port = data->set.localport; /* use this port number, 0 for - "random" */ - /* how many port numbers to try to bind to, increasing one at a time */ - int portnum = data->set.localportrange; - const char *dev = data->set.str[STRING_DEVICE]; - int error; - - /************************************************************* - * Select device to bind socket to - *************************************************************/ - if(!dev && !port) - /* no local kind of binding was requested */ - return CURLE_OK; - - memset(&sa, 0, sizeof(struct Curl_sockaddr_storage)); - - if(dev && (strlen(dev)<255) ) { - char myhost[256] = ""; - int done = 0; /* -1 for error, 1 for address found */ - bool is_interface = FALSE; - bool is_host = FALSE; - static const char *if_prefix = "if!"; - static const char *host_prefix = "host!"; - - if(strncmp(if_prefix, dev, strlen(if_prefix)) == 0) { - dev += strlen(if_prefix); - is_interface = TRUE; - } - else if(strncmp(host_prefix, dev, strlen(host_prefix)) == 0) { - dev += strlen(host_prefix); - is_host = TRUE; - } - - /* interface */ - if(!is_host) { - switch(Curl_if2ip(af, scope, conn->scope_id, dev, - myhost, sizeof(myhost))) { - case IF2IP_NOT_FOUND: - if(is_interface) { - /* Do not fall back to treating it as a host name */ - failf(data, "Couldn't bind to interface '%s'", dev); - return CURLE_INTERFACE_FAILED; - } - break; - case IF2IP_AF_NOT_SUPPORTED: - /* Signal the caller to try another address family if available */ - return CURLE_UNSUPPORTED_PROTOCOL; - case IF2IP_FOUND: - is_interface = TRUE; - /* - * We now have the numerical IP address in the 'myhost' buffer - */ - infof(data, "Local Interface %s is ip %s using address family %i\n", - dev, myhost, af); - done = 1; - -#ifdef SO_BINDTODEVICE - /* I am not sure any other OSs than Linux that provide this feature, - * and at the least I cannot test. --Ben - * - * This feature allows one to tightly bind the local socket to a - * particular interface. This will force even requests to other - * local interfaces to go out the external interface. - * - * - * Only bind to the interface when specified as interface, not just - * as a hostname or ip address. - */ - if(setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, - dev, (curl_socklen_t)strlen(dev)+1) != 0) { - error = SOCKERRNO; - infof(data, "SO_BINDTODEVICE %s failed with errno %d: %s;" - " will do regular bind\n", - dev, error, Curl_strerror(conn, error)); - /* This is typically "errno 1, error: Operation not permitted" if - you're not running as root or another suitable privileged - user */ - } -#endif - break; - } - } - if(!is_interface) { - /* - * This was not an interface, resolve the name as a host name - * or IP number - * - * Temporarily force name resolution to use only the address type - * of the connection. The resolve functions should really be changed - * to take a type parameter instead. - */ - long ipver = conn->ip_version; - int rc; - - if(af == AF_INET) - conn->ip_version = CURL_IPRESOLVE_V4; -#ifdef ENABLE_IPV6 - else if(af == AF_INET6) - conn->ip_version = CURL_IPRESOLVE_V6; -#endif - - rc = Curl_resolv(conn, dev, 0, &h); - if(rc == CURLRESOLV_PENDING) - (void)Curl_resolver_wait_resolv(conn, &h); - conn->ip_version = ipver; - - if(h) { - /* convert the resolved address, sizeof myhost >= INET_ADDRSTRLEN */ - Curl_printable_address(h->addr, myhost, sizeof(myhost)); - infof(data, "Name '%s' family %i resolved to '%s' family %i\n", - dev, af, myhost, h->addr->ai_family); - Curl_resolv_unlock(data, h); - done = 1; - } - else { - /* - * provided dev was no interface (or interfaces are not supported - * e.g. solaris) no ip address and no domain we fail here - */ - done = -1; - } - } - - if(done > 0) { -#ifdef ENABLE_IPV6 - /* IPv6 address */ - if(af == AF_INET6) { -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - char *scope_ptr = strchr(myhost, '%'); - if(scope_ptr) - *(scope_ptr++) = 0; -#endif - if(Curl_inet_pton(AF_INET6, myhost, &si6->sin6_addr) > 0) { - si6->sin6_family = AF_INET6; - si6->sin6_port = htons(port); -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - if(scope_ptr) - /* The "myhost" string either comes from Curl_if2ip or from - Curl_printable_address. The latter returns only numeric scope - IDs and the former returns none at all. So the scope ID, if - present, is known to be numeric */ - si6->sin6_scope_id = atoi(scope_ptr); -#endif - } - sizeof_sa = sizeof(struct sockaddr_in6); - } - else -#endif - /* IPv4 address */ - if((af == AF_INET) && - (Curl_inet_pton(AF_INET, myhost, &si4->sin_addr) > 0)) { - si4->sin_family = AF_INET; - si4->sin_port = htons(port); - sizeof_sa = sizeof(struct sockaddr_in); - } - } - - if(done < 1) { - failf(data, "Couldn't bind to '%s'", dev); - return CURLE_INTERFACE_FAILED; - } - } - else { - /* no device was given, prepare sa to match af's needs */ -#ifdef ENABLE_IPV6 - if(af == AF_INET6) { - si6->sin6_family = AF_INET6; - si6->sin6_port = htons(port); - sizeof_sa = sizeof(struct sockaddr_in6); - } - else -#endif - if(af == AF_INET) { - si4->sin_family = AF_INET; - si4->sin_port = htons(port); - sizeof_sa = sizeof(struct sockaddr_in); - } - } - - for(;;) { - if(bind(sockfd, sock, sizeof_sa) >= 0) { - /* we succeeded to bind */ - struct Curl_sockaddr_storage add; - curl_socklen_t size = sizeof(add); - memset(&add, 0, sizeof(struct Curl_sockaddr_storage)); - if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) { - data->state.os_errno = error = SOCKERRNO; - failf(data, "getsockname() failed with errno %d: %s", - error, Curl_strerror(conn, error)); - return CURLE_INTERFACE_FAILED; - } - infof(data, "Local port: %hu\n", port); - conn->bits.bound = TRUE; - return CURLE_OK; - } - - if(--portnum > 0) { - infof(data, "Bind to local port %hu failed, trying next\n", port); - port++; /* try next port */ - /* We re-use/clobber the port variable here below */ - if(sock->sa_family == AF_INET) - si4->sin_port = ntohs(port); -#ifdef ENABLE_IPV6 - else - si6->sin6_port = ntohs(port); -#endif - } - else - break; - } - - data->state.os_errno = error = SOCKERRNO; - failf(data, "bind failed with errno %d: %s", - error, Curl_strerror(conn, error)); - - return CURLE_INTERFACE_FAILED; -} - -/* - * verifyconnect() returns TRUE if the connect really has happened. - */ -static bool verifyconnect(curl_socket_t sockfd, int *error) -{ - bool rc = TRUE; -#ifdef SO_ERROR - int err = 0; - curl_socklen_t errSize = sizeof(err); - -#ifdef WIN32 - /* - * In October 2003 we effectively nullified this function on Windows due to - * problems with it using all CPU in multi-threaded cases. - * - * In May 2004, we bring it back to offer more info back on connect failures. - * Gisle Vanem could reproduce the former problems with this function, but - * could avoid them by adding this SleepEx() call below: - * - * "I don't have Rational Quantify, but the hint from his post was - * ntdll::NtRemoveIoCompletion(). So I'd assume the SleepEx (or maybe - * just Sleep(0) would be enough?) would release whatever - * mutex/critical-section the ntdll call is waiting on. - * - * Someone got to verify this on Win-NT 4.0, 2000." - */ - -#ifdef _WIN32_WCE - Sleep(0); -#else - SleepEx(0, FALSE); -#endif - -#endif - - if(0 != getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&err, &errSize)) - err = SOCKERRNO; -#ifdef _WIN32_WCE - /* Old WinCE versions don't support SO_ERROR */ - if(WSAENOPROTOOPT == err) { - SET_SOCKERRNO(0); - err = 0; - } -#endif -#ifdef __minix - /* Minix 3.1.x doesn't support getsockopt on UDP sockets */ - if(EBADIOCTL == err) { - SET_SOCKERRNO(0); - err = 0; - } -#endif - if((0 == err) || (EISCONN == err)) - /* we are connected, awesome! */ - rc = TRUE; - else - /* This wasn't a successful connect */ - rc = FALSE; - if(error) - *error = err; -#else - (void)sockfd; - if(error) - *error = SOCKERRNO; -#endif - return rc; -} - -/* Used within the multi interface. Try next IP address, return TRUE if no - more address exists or error */ -static CURLcode trynextip(struct connectdata *conn, - int sockindex, - int tempindex) -{ - const int other = tempindex ^ 1; - CURLcode result = CURLE_COULDNT_CONNECT; - - /* First clean up after the failed socket. - Don't close it yet to ensure that the next IP's socket gets a different - file descriptor, which can prevent bugs when the curl_multi_socket_action - interface is used with certain select() replacements such as kqueue. */ - curl_socket_t fd_to_close = conn->tempsock[tempindex]; - conn->tempsock[tempindex] = CURL_SOCKET_BAD; - - if(sockindex == FIRSTSOCKET) { - Curl_addrinfo *ai = NULL; - int family = AF_UNSPEC; - - if(conn->tempaddr[tempindex]) { - /* find next address in the same protocol family */ - family = conn->tempaddr[tempindex]->ai_family; - ai = conn->tempaddr[tempindex]->ai_next; - } -#ifdef ENABLE_IPV6 - else if(conn->tempaddr[0]) { - /* happy eyeballs - try the other protocol family */ - int firstfamily = conn->tempaddr[0]->ai_family; - family = (firstfamily == AF_INET) ? AF_INET6 : AF_INET; - ai = conn->tempaddr[0]->ai_next; - } -#endif - - while(ai) { - if(conn->tempaddr[other]) { - /* we can safely skip addresses of the other protocol family */ - while(ai && ai->ai_family != family) - ai = ai->ai_next; - } - - if(ai) { - result = singleipconnect(conn, ai, &conn->tempsock[tempindex]); - if(result == CURLE_COULDNT_CONNECT) { - ai = ai->ai_next; - continue; - } - - conn->tempaddr[tempindex] = ai; - } - break; - } - } - - if(fd_to_close != CURL_SOCKET_BAD) - Curl_closesocket(conn, fd_to_close); - - return result; -} - -/* Copies connection info into the session handle to make it available - when the session handle is no longer associated with a connection. */ -void Curl_persistconninfo(struct connectdata *conn) -{ - memcpy(conn->data->info.conn_primary_ip, conn->primary_ip, MAX_IPADR_LEN); - memcpy(conn->data->info.conn_local_ip, conn->local_ip, MAX_IPADR_LEN); - conn->data->info.conn_primary_port = conn->primary_port; - conn->data->info.conn_local_port = conn->local_port; -} - -/* retrieves ip address and port from a sockaddr structure */ -static bool getaddressinfo(struct sockaddr* sa, char* addr, - long* port) -{ - unsigned short us_port; - struct sockaddr_in* si = NULL; -#ifdef ENABLE_IPV6 - struct sockaddr_in6* si6 = NULL; -#endif -#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) - struct sockaddr_un* su = NULL; -#endif - - switch (sa->sa_family) { - case AF_INET: - si = (struct sockaddr_in*)(void*) sa; - if(Curl_inet_ntop(sa->sa_family, &si->sin_addr, - addr, MAX_IPADR_LEN)) { - us_port = ntohs(si->sin_port); - *port = us_port; - return TRUE; - } - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - si6 = (struct sockaddr_in6*)(void*) sa; - if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr, - addr, MAX_IPADR_LEN)) { - us_port = ntohs(si6->sin6_port); - *port = us_port; - return TRUE; - } - break; -#endif -#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX) - case AF_UNIX: - su = (struct sockaddr_un*)sa; - snprintf(addr, MAX_IPADR_LEN, "%s", su->sun_path); - *port = 0; - return TRUE; -#endif - default: - break; - } - - addr[0] = '\0'; - *port = 0; - - return FALSE; -} - -/* retrieves the start/end point information of a socket of an established - connection */ -void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd) -{ - curl_socklen_t len; - struct Curl_sockaddr_storage ssrem; - struct Curl_sockaddr_storage ssloc; - struct SessionHandle *data = conn->data; - - if(conn->socktype == SOCK_DGRAM) - /* there's no connection! */ - return; - - if(!conn->bits.reuse && !conn->bits.tcp_fastopen) { - int error; - - len = sizeof(struct Curl_sockaddr_storage); - if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) { - error = SOCKERRNO; - failf(data, "getpeername() failed with errno %d: %s", - error, Curl_strerror(conn, error)); - return; - } - - len = sizeof(struct Curl_sockaddr_storage); - memset(&ssloc, 0, sizeof(ssloc)); - if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) { - error = SOCKERRNO; - failf(data, "getsockname() failed with errno %d: %s", - error, Curl_strerror(conn, error)); - return; - } - - if(!getaddressinfo((struct sockaddr*)&ssrem, - conn->primary_ip, &conn->primary_port)) { - error = ERRNO; - failf(data, "ssrem inet_ntop() failed with errno %d: %s", - error, Curl_strerror(conn, error)); - return; - } - memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN); - - if(!getaddressinfo((struct sockaddr*)&ssloc, - conn->local_ip, &conn->local_port)) { - error = ERRNO; - failf(data, "ssloc inet_ntop() failed with errno %d: %s", - error, Curl_strerror(conn, error)); - return; - } - - } - - /* persist connection info in session handle */ - Curl_persistconninfo(conn); -} - -/* - * Curl_is_connected() checks if the socket has connected. - */ - -CURLcode Curl_is_connected(struct connectdata *conn, - int sockindex, - bool *connected) -{ - struct SessionHandle *data = conn->data; - CURLcode result = CURLE_OK; - long allow; - int error = 0; - struct timeval now; - int rc; - int i; - - DEBUGASSERT(sockindex >= FIRSTSOCKET && sockindex <= SECONDARYSOCKET); - - *connected = FALSE; /* a very negative world view is best */ - - if(conn->bits.tcpconnect[sockindex]) { - /* we are connected already! */ - *connected = TRUE; - return CURLE_OK; - } - - now = Curl_tvnow(); - - /* figure out how long time we have left to connect */ - allow = Curl_timeleft(data, &now, TRUE); - - if(allow < 0) { - /* time-out, bail out, go home */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - for(i=0; i<2; i++) { - const int other = i ^ 1; - if(conn->tempsock[i] == CURL_SOCKET_BAD) - continue; - -#ifdef mpeix - /* Call this function once now, and ignore the results. We do this to - "clear" the error state on the socket so that we can later read it - reliably. This is reported necessary on the MPE/iX operating system. */ - (void)verifyconnect(conn->tempsock[i], NULL); -#endif - - /* check socket for connect */ - rc = Curl_socket_ready(CURL_SOCKET_BAD, conn->tempsock[i], 0); - - if(rc == 0) { /* no connection yet */ - error = 0; - if(curlx_tvdiff(now, conn->connecttime) >= conn->timeoutms_per_addr) { - infof(data, "After %ldms connect time, move on!\n", - conn->timeoutms_per_addr); - error = ETIMEDOUT; - } - - /* should we try another protocol family? */ - if(i == 0 && conn->tempaddr[1] == NULL && - curlx_tvdiff(now, conn->connecttime) >= HAPPY_EYEBALLS_TIMEOUT) { - trynextip(conn, sockindex, 1); - } - } - else if(rc == CURL_CSELECT_OUT || conn->bits.tcp_fastopen) { - if(verifyconnect(conn->tempsock[i], &error)) { - /* we are connected with TCP, awesome! */ - - /* use this socket from now on */ - conn->sock[sockindex] = conn->tempsock[i]; - conn->ip_addr = conn->tempaddr[i]; - conn->tempsock[i] = CURL_SOCKET_BAD; - - /* close the other socket, if open */ - if(conn->tempsock[other] != CURL_SOCKET_BAD) { - Curl_closesocket(conn, conn->tempsock[other]); - conn->tempsock[other] = CURL_SOCKET_BAD; - } - - /* see if we need to do any proxy magic first once we connected */ - result = Curl_connected_proxy(conn, sockindex); - if(result) - return result; - - conn->bits.tcpconnect[sockindex] = TRUE; - - *connected = TRUE; - if(sockindex == FIRSTSOCKET) - Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */ - Curl_updateconninfo(conn, conn->sock[sockindex]); - Curl_verboseconnect(conn); - - return CURLE_OK; - } - else - infof(data, "Connection failed\n"); - } - else if(rc & CURL_CSELECT_ERR) - (void)verifyconnect(conn->tempsock[i], &error); - - /* - * The connection failed here, we should attempt to connect to the "next - * address" for the given host. But first remember the latest error. - */ - if(error) { - data->state.os_errno = error; - SET_SOCKERRNO(error); - if(conn->tempaddr[i]) { - CURLcode status; - char ipaddress[MAX_IPADR_LEN]; - Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN); - infof(data, "connect to %s port %ld failed: %s\n", - ipaddress, conn->port, Curl_strerror(conn, error)); - - conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ? - allow : allow / 2; - - status = trynextip(conn, sockindex, i); - if(status != CURLE_COULDNT_CONNECT - || conn->tempsock[other] == CURL_SOCKET_BAD) - /* the last attempt failed and no other sockets remain open */ - result = status; - } - } - } - - if(result) { - /* no more addresses to try */ - - const char* hostname; - - /* if the first address family runs out of addresses to try before - the happy eyeball timeout, go ahead and try the next family now */ - if(conn->tempaddr[1] == NULL) { - result = trynextip(conn, sockindex, 1); - if(!result) - return result; - } - - if(conn->bits.proxy) - hostname = conn->proxy.name; - else if(conn->bits.conn_to_host) - hostname = conn->conn_to_host.name; - else - hostname = conn->host.name; - - failf(data, "Failed to connect to %s port %ld: %s", - hostname, conn->port, Curl_strerror(conn, error)); - } - - return result; -} - -void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd) -{ -#if defined(TCP_NODELAY) -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) - struct SessionHandle *data = conn->data; -#endif - curl_socklen_t onoff = (curl_socklen_t) 1; - int level = IPPROTO_TCP; - -#if 0 - /* The use of getprotobyname() is disabled since it isn't thread-safe on - numerous systems. On these getprotobyname_r() should be used instead, but - that exists in at least one 4 arg version and one 5 arg version, and - since the proto number rarely changes anyway we now just use the hard - coded number. The "proper" fix would need a configure check for the - correct function much in the same style the gethostbyname_r versions are - detected. */ - struct protoent *pe = getprotobyname("tcp"); - if(pe) - level = pe->p_proto; -#endif - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) conn; -#endif - - if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff, - sizeof(onoff)) < 0) - infof(data, "Could not set TCP_NODELAY: %s\n", - Curl_strerror(conn, SOCKERRNO)); - else - infof(data, "TCP_NODELAY set\n"); -#else - (void)conn; - (void)sockfd; -#endif -} - -#ifdef SO_NOSIGPIPE -/* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when - sending data to a dead peer (instead of relying on the 4th argument to send - being MSG_NOSIGNAL). Possibly also existing and in use on other BSD - systems? */ -static void nosigpipe(struct connectdata *conn, - curl_socket_t sockfd) -{ - struct SessionHandle *data= conn->data; - int onoff = 1; - if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff, - sizeof(onoff)) < 0) - infof(data, "Could not set SO_NOSIGPIPE: %s\n", - Curl_strerror(conn, SOCKERRNO)); -} -#else -#define nosigpipe(x,y) Curl_nop_stmt -#endif - -#ifdef USE_WINSOCK -/* When you run a program that uses the Windows Sockets API, you may - experience slow performance when you copy data to a TCP server. - - https://support.microsoft.com/kb/823764 - - Work-around: Make the Socket Send Buffer Size Larger Than the Program Send - Buffer Size - - The problem described in this knowledge-base is applied only to pre-Vista - Windows. Following function trying to detect OS version and skips - SO_SNDBUF adjustment for Windows Vista and above. -*/ -#define DETECT_OS_NONE 0 -#define DETECT_OS_PREVISTA 1 -#define DETECT_OS_VISTA_OR_LATER 2 - -void Curl_sndbufset(curl_socket_t sockfd) -{ - int val = CURL_MAX_WRITE_SIZE + 32; - int curval = 0; - int curlen = sizeof(curval); - DWORD majorVersion = 6; - - static int detectOsState = DETECT_OS_NONE; - - if(detectOsState == DETECT_OS_NONE) { -#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \ - (_WIN32_WINNT < _WIN32_WINNT_WIN2K) - OSVERSIONINFO osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - - detectOsState = DETECT_OS_PREVISTA; - if(GetVersionEx(&osver)) { - if(osver.dwMajorVersion >= majorVersion) - detectOsState = DETECT_OS_VISTA_OR_LATER; - } -#else - ULONGLONG cm; - OSVERSIONINFOEX osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwMajorVersion = majorVersion; - - cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - - if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR), - cm)) - detectOsState = DETECT_OS_VISTA_OR_LATER; - else - detectOsState = DETECT_OS_PREVISTA; -#endif - } - - if(detectOsState == DETECT_OS_VISTA_OR_LATER) - return; - - if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0) - if(curval > val) - return; - - setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (const char *)&val, sizeof(val)); -} -#endif - -/* - * singleipconnect() - * - * Note that even on connect fail it returns CURLE_OK, but with 'sock' set to - * CURL_SOCKET_BAD. Other errors will however return proper errors. - * - * singleipconnect() connects to the given IP only, and it may return without - * having connected. - */ -static CURLcode singleipconnect(struct connectdata *conn, - const Curl_addrinfo *ai, - curl_socket_t *sockp) -{ - struct Curl_sockaddr_ex addr; - int rc = -1; - int error = 0; - bool isconnected = FALSE; - struct SessionHandle *data = conn->data; - curl_socket_t sockfd; - CURLcode result; - char ipaddress[MAX_IPADR_LEN]; - long port; - bool is_tcp; - - *sockp = CURL_SOCKET_BAD; - - result = Curl_socket(conn, ai, &addr, &sockfd); - if(result) - /* Failed to create the socket, but still return OK since we signal the - lack of socket as well. This allows the parent function to keep looping - over alternative addresses/socket families etc. */ - return CURLE_OK; - - /* store remote address and port used in this connection attempt */ - if(!getaddressinfo((struct sockaddr*)&addr.sa_addr, - ipaddress, &port)) { - /* malformed address or bug in inet_ntop, try next address */ - error = ERRNO; - failf(data, "sa_addr inet_ntop() failed with errno %d: %s", - error, Curl_strerror(conn, error)); - Curl_closesocket(conn, sockfd); - return CURLE_OK; - } - infof(data, " Trying %s...\n", ipaddress); - -#ifdef ENABLE_IPV6 - is_tcp = (addr.family == AF_INET || addr.family == AF_INET6) && - addr.socktype == SOCK_STREAM; -#else - is_tcp = (addr.family == AF_INET) && addr.socktype == SOCK_STREAM; -#endif - if(is_tcp && data->set.tcp_nodelay) - Curl_tcpnodelay(conn, sockfd); - - nosigpipe(conn, sockfd); - - Curl_sndbufset(sockfd); - - if(is_tcp && data->set.tcp_keepalive) - tcpkeepalive(data, sockfd); - - if(data->set.fsockopt) { - /* activate callback for setting socket options */ - error = data->set.fsockopt(data->set.sockopt_client, - sockfd, - CURLSOCKTYPE_IPCXN); - - if(error == CURL_SOCKOPT_ALREADY_CONNECTED) - isconnected = TRUE; - else if(error) { - Curl_closesocket(conn, sockfd); /* close the socket and bail out */ - return CURLE_ABORTED_BY_CALLBACK; - } - } - - /* possibly bind the local end to an IP, interface or port */ - if(addr.family == AF_INET -#ifdef ENABLE_IPV6 - || addr.family == AF_INET6 -#endif - ) { - result = bindlocal(conn, sockfd, addr.family, - Curl_ipv6_scope((struct sockaddr*)&addr.sa_addr)); - if(result) { - Curl_closesocket(conn, sockfd); /* close socket and bail out */ - if(result == CURLE_UNSUPPORTED_PROTOCOL) { - /* The address family is not supported on this interface. - We can continue trying addresses */ - return CURLE_COULDNT_CONNECT; - } - return result; - } - } - - /* set socket non-blocking */ - (void)curlx_nonblock(sockfd, TRUE); - - conn->connecttime = Curl_tvnow(); - if(conn->num_addr > 1) - Curl_expire_latest(data, conn->timeoutms_per_addr); - - /* Connect TCP sockets, bind UDP */ - if(!isconnected && (conn->socktype == SOCK_STREAM)) { - if(conn->bits.tcp_fastopen) { -#if defined(CONNECT_DATA_IDEMPOTENT) /* OS X */ - sa_endpoints_t endpoints; - endpoints.sae_srcif = 0; - endpoints.sae_srcaddr = NULL; - endpoints.sae_srcaddrlen = 0; - endpoints.sae_dstaddr = &addr.sa_addr; - endpoints.sae_dstaddrlen = addr.addrlen; - - rc = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY, - CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT, - NULL, 0, NULL, NULL); -#elif defined(MSG_FASTOPEN) /* Linux */ - rc = 0; /* Do nothing */ -#endif - } - else { - rc = connect(sockfd, &addr.sa_addr, addr.addrlen); - } - - if(-1 == rc) - error = SOCKERRNO; - } - else { - *sockp = sockfd; - return CURLE_OK; - } - -#ifdef ENABLE_IPV6 - conn->bits.ipv6 = (addr.family == AF_INET6)?TRUE:FALSE; -#endif - - if(-1 == rc) { - switch(error) { - case EINPROGRESS: - case EWOULDBLOCK: -#if defined(EAGAIN) -#if (EAGAIN) != (EWOULDBLOCK) - /* On some platforms EAGAIN and EWOULDBLOCK are the - * same value, and on others they are different, hence - * the odd #if - */ - case EAGAIN: -#endif -#endif - result = CURLE_OK; - break; - - default: - /* unknown error, fallthrough and try another address! */ - infof(data, "Immediate connect fail for %s: %s\n", - ipaddress, Curl_strerror(conn, error)); - data->state.os_errno = error; - - /* connect failed */ - Curl_closesocket(conn, sockfd); - result = CURLE_COULDNT_CONNECT; - } - } - - if(!result) - *sockp = sockfd; - - return result; -} - -/* - * TCP connect to the given host with timeout, proxy or remote doesn't matter. - * There might be more than one IP address to try out. Fill in the passed - * pointer with the connected socket. - */ - -CURLcode Curl_connecthost(struct connectdata *conn, /* context */ - const struct Curl_dns_entry *remotehost) -{ - struct SessionHandle *data = conn->data; - struct timeval before = Curl_tvnow(); - CURLcode result = CURLE_COULDNT_CONNECT; - - long timeout_ms = Curl_timeleft(data, &before, TRUE); - - if(timeout_ms < 0) { - /* a precaution, no need to continue if time already is up */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - conn->num_addr = Curl_num_addresses(remotehost->addr); - conn->tempaddr[0] = remotehost->addr; - conn->tempaddr[1] = NULL; - conn->tempsock[0] = CURL_SOCKET_BAD; - conn->tempsock[1] = CURL_SOCKET_BAD; - Curl_expire(conn->data, HAPPY_EYEBALLS_TIMEOUT); - - /* Max time for the next connection attempt */ - conn->timeoutms_per_addr = - conn->tempaddr[0]->ai_next == NULL ? timeout_ms : timeout_ms / 2; - - /* start connecting to first IP */ - while(conn->tempaddr[0]) { - result = singleipconnect(conn, conn->tempaddr[0], &(conn->tempsock[0])); - if(!result) - break; - conn->tempaddr[0] = conn->tempaddr[0]->ai_next; - } - - if(conn->tempsock[0] == CURL_SOCKET_BAD) { - if(!result) - result = CURLE_COULDNT_CONNECT; - return result; - } - - data->info.numconnects++; /* to track the number of connections made */ - - return CURLE_OK; -} - -struct connfind { - struct connectdata *tofind; - bool found; -}; - -static int conn_is_conn(struct connectdata *conn, void *param) -{ - struct connfind *f = (struct connfind *)param; - if(conn == f->tofind) { - f->found = TRUE; - return 1; - } - return 0; -} - -/* - * Used to extract socket and connectdata struct for the most recent - * transfer on the given SessionHandle. - * - * The returned socket will be CURL_SOCKET_BAD in case of failure! - */ -curl_socket_t Curl_getconnectinfo(struct SessionHandle *data, - struct connectdata **connp) -{ - curl_socket_t sockfd; - - DEBUGASSERT(data); - - /* this works for an easy handle: - * - that has been used for curl_easy_perform() - * - that is associated with a multi handle, and whose connection - * was detached with CURLOPT_CONNECT_ONLY - */ - if(data->state.lastconnect && (data->multi_easy || data->multi)) { - struct connectdata *c = data->state.lastconnect; - struct connfind find; - find.tofind = data->state.lastconnect; - find.found = FALSE; - - Curl_conncache_foreach(data->multi_easy? - &data->multi_easy->conn_cache: - &data->multi->conn_cache, &find, conn_is_conn); - - if(!find.found) { - data->state.lastconnect = NULL; - return CURL_SOCKET_BAD; - } - - if(connp) - /* only store this if the caller cares for it */ - *connp = c; - sockfd = c->sock[FIRSTSOCKET]; - /* we have a socket connected, let's determine if the server shut down */ - /* determine if ssl */ - if(c->ssl[FIRSTSOCKET].use) { - /* use the SSL context */ - if(!Curl_ssl_check_cxn(c)) - return CURL_SOCKET_BAD; /* FIN received */ - } -/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */ -#ifdef MSG_PEEK - else if(sockfd != CURL_SOCKET_BAD) { - /* use the socket */ - char buf; - if(recv((RECV_TYPE_ARG1)sockfd, (RECV_TYPE_ARG2)&buf, - (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) { - return CURL_SOCKET_BAD; /* FIN received */ - } - } -#endif - } - else - return CURL_SOCKET_BAD; - - return sockfd; -} - -/* - * Close a socket. - * - * 'conn' can be NULL, beware! - */ -int Curl_closesocket(struct connectdata *conn, - curl_socket_t sock) -{ - if(conn && conn->fclosesocket) { - if((sock == conn->sock[SECONDARYSOCKET]) && - conn->sock_accepted[SECONDARYSOCKET]) - /* if this socket matches the second socket, and that was created with - accept, then we MUST NOT call the callback but clear the accepted - status */ - conn->sock_accepted[SECONDARYSOCKET] = FALSE; - else { - Curl_multi_closed(conn, sock); - return conn->fclosesocket(conn->closesocket_client, sock); - } - } - - if(conn) - /* tell the multi-socket code about this */ - Curl_multi_closed(conn, sock); - - sclose(sock); - - return 0; -} - -/* - * Create a socket based on info from 'conn' and 'ai'. - * - * 'addr' should be a pointer to the correct struct to get data back, or NULL. - * 'sockfd' must be a pointer to a socket descriptor. - * - * If the open socket callback is set, used that! - * - */ -CURLcode Curl_socket(struct connectdata *conn, - const Curl_addrinfo *ai, - struct Curl_sockaddr_ex *addr, - curl_socket_t *sockfd) -{ - struct SessionHandle *data = conn->data; - struct Curl_sockaddr_ex dummy; - - if(!addr) - /* if the caller doesn't want info back, use a local temp copy */ - addr = &dummy; - - /* - * The Curl_sockaddr_ex structure is basically libcurl's external API - * curl_sockaddr structure with enough space available to directly hold - * any protocol-specific address structures. The variable declared here - * will be used to pass / receive data to/from the fopensocket callback - * if this has been set, before that, it is initialized from parameters. - */ - - addr->family = ai->ai_family; - addr->socktype = conn->socktype; - addr->protocol = conn->socktype==SOCK_DGRAM?IPPROTO_UDP:ai->ai_protocol; - addr->addrlen = ai->ai_addrlen; - - if(addr->addrlen > sizeof(struct Curl_sockaddr_storage)) - addr->addrlen = sizeof(struct Curl_sockaddr_storage); - memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen); - - if(data->set.fopensocket) - /* - * If the opensocket callback is set, all the destination address - * information is passed to the callback. Depending on this information the - * callback may opt to abort the connection, this is indicated returning - * CURL_SOCKET_BAD; otherwise it will return a not-connected socket. When - * the callback returns a valid socket the destination address information - * might have been changed and this 'new' address will actually be used - * here to connect. - */ - *sockfd = data->set.fopensocket(data->set.opensocket_client, - CURLSOCKTYPE_IPCXN, - (struct curl_sockaddr *)addr); - else - /* opensocket callback not set, so simply create the socket now */ - *sockfd = socket(addr->family, addr->socktype, addr->protocol); - - if(*sockfd == CURL_SOCKET_BAD) - /* no socket, no connection */ - return CURLE_COULDNT_CONNECT; - -#if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID) - if(conn->scope_id && (addr->family == AF_INET6)) { - struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr; - sa6->sin6_scope_id = conn->scope_id; - } -#endif - - return CURLE_OK; - -} - -#ifdef CURLDEBUG -/* - * Curl_conncontrol() is used to set the conn->bits.close bit on or off. It - * MUST be called with the connclose() or connkeep() macros with a stated - * reason. The reason is only shown in debug builds but helps to figure out - * decision paths when connections are or aren't re-used as expected. - */ -void Curl_conncontrol(struct connectdata *conn, bool closeit, - const char *reason) -{ -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) reason; -#endif - if(closeit != conn->bits.close) { - infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive", - reason); - - conn->bits.close = closeit; /* the only place in the source code that - should assign this bit */ - } -} -#endif diff --git a/Externals/curl/lib/connect.h b/Externals/curl/lib/connect.h deleted file mode 100644 index f3d4ac747c..0000000000 --- a/Externals/curl/lib/connect.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef HEADER_CURL_CONNECT_H -#define HEADER_CURL_CONNECT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "nonblock.h" /* for curlx_nonblock(), formerly Curl_nonblock() */ -#include "sockaddr.h" - -CURLcode Curl_is_connected(struct connectdata *conn, - int sockindex, - bool *connected); - -CURLcode Curl_connecthost(struct connectdata *conn, - const struct Curl_dns_entry *host); - -/* generic function that returns how much time there's left to run, according - to the timeouts set */ -long Curl_timeleft(struct SessionHandle *data, - struct timeval *nowp, - bool duringconnect); - -#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */ -#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between - IPv4/IPv6 connection attempts */ - -/* - * Used to extract socket and connectdata struct for the most recent - * transfer on the given SessionHandle. - * - * The returned socket will be CURL_SOCKET_BAD in case of failure! - */ -curl_socket_t Curl_getconnectinfo(struct SessionHandle *data, - struct connectdata **connp); - -#ifdef USE_WINSOCK -/* When you run a program that uses the Windows Sockets API, you may - experience slow performance when you copy data to a TCP server. - - https://support.microsoft.com/kb/823764 - - Work-around: Make the Socket Send Buffer Size Larger Than the Program Send - Buffer Size - -*/ -void Curl_sndbufset(curl_socket_t sockfd); -#else -#define Curl_sndbufset(y) Curl_nop_stmt -#endif - -void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd); -void Curl_persistconninfo(struct connectdata *conn); -int Curl_closesocket(struct connectdata *conn, curl_socket_t sock); - -/* - * The Curl_sockaddr_ex structure is basically libcurl's external API - * curl_sockaddr structure with enough space available to directly hold any - * protocol-specific address structures. The variable declared here will be - * used to pass / receive data to/from the fopensocket callback if this has - * been set, before that, it is initialized from parameters. - */ -struct Curl_sockaddr_ex { - int family; - int socktype; - int protocol; - unsigned int addrlen; - union { - struct sockaddr addr; - struct Curl_sockaddr_storage buff; - } _sa_ex_u; -}; -#define sa_addr _sa_ex_u.addr - -/* - * Create a socket based on info from 'conn' and 'ai'. - * - * Fill in 'addr' and 'sockfd' accordingly if OK is returned. If the open - * socket callback is set, used that! - * - */ -CURLcode Curl_socket(struct connectdata *conn, - const Curl_addrinfo *ai, - struct Curl_sockaddr_ex *addr, - curl_socket_t *sockfd); - -void Curl_tcpnodelay(struct connectdata *conn, curl_socket_t sockfd); - -#ifdef CURLDEBUG -/* - * Curl_connclose() sets the bit.close bit to TRUE with an explanation. - * Nothing else. - */ -void Curl_conncontrol(struct connectdata *conn, - bool closeit, - const char *reason); -#define connclose(x,y) Curl_conncontrol(x,TRUE, y) -#define connkeep(x,y) Curl_conncontrol(x, FALSE, y) -#else /* if !CURLDEBUG */ - -#define connclose(x,y) (x)->bits.close = TRUE -#define connkeep(x,y) (x)->bits.close = FALSE - -#endif - -#endif /* HEADER_CURL_CONNECT_H */ diff --git a/Externals/curl/lib/content_encoding.c b/Externals/curl/lib/content_encoding.c deleted file mode 100644 index 2d30816c15..0000000000 --- a/Externals/curl/lib/content_encoding.c +++ /dev/null @@ -1,435 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_LIBZ - -#include "urldata.h" -#include -#include "sendf.h" -#include "content_encoding.h" -#include "curl_memory.h" - -#include "memdebug.h" - -/* Comment this out if zlib is always going to be at least ver. 1.2.0.4 - (doing so will reduce code size slightly). */ -#define OLD_ZLIB_SUPPORT 1 - -#define DSIZ CURL_MAX_WRITE_SIZE /* buffer size for decompressed data */ - -#define GZIP_MAGIC_0 0x1f -#define GZIP_MAGIC_1 0x8b - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -static voidpf -zalloc_cb(voidpf opaque, unsigned int items, unsigned int size) -{ - (void) opaque; - /* not a typo, keep it calloc() */ - return (voidpf) calloc(items, size); -} - -static void -zfree_cb(voidpf opaque, voidpf ptr) -{ - (void) opaque; - free(ptr); -} - -static CURLcode -process_zlib_error(struct connectdata *conn, z_stream *z) -{ - struct SessionHandle *data = conn->data; - if(z->msg) - failf (data, "Error while processing content unencoding: %s", - z->msg); - else - failf (data, "Error while processing content unencoding: " - "Unknown failure within decompression software."); - - return CURLE_BAD_CONTENT_ENCODING; -} - -static CURLcode -exit_zlib(z_stream *z, zlibInitState *zlib_init, CURLcode result) -{ - inflateEnd(z); - *zlib_init = ZLIB_UNINIT; - return result; -} - -static CURLcode -inflate_stream(struct connectdata *conn, - struct SingleRequest *k) -{ - int allow_restart = 1; - z_stream *z = &k->z; /* zlib state structure */ - uInt nread = z->avail_in; - Bytef *orig_in = z->next_in; - int status; /* zlib status */ - CURLcode result = CURLE_OK; /* Curl_client_write status */ - char *decomp; /* Put the decompressed data here. */ - - /* Dynamically allocate a buffer for decompression because it's uncommonly - large to hold on the stack */ - decomp = malloc(DSIZ); - if(decomp == NULL) { - return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); - } - - /* because the buffer size is fixed, iteratively decompress and transfer to - the client via client_write. */ - for(;;) { - /* (re)set buffer for decompressed output for every iteration */ - z->next_out = (Bytef *)decomp; - z->avail_out = DSIZ; - - status = inflate(z, Z_SYNC_FLUSH); - if(status == Z_OK || status == Z_STREAM_END) { - allow_restart = 0; - if((DSIZ - z->avail_out) && (!k->ignorebody)) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, decomp, - DSIZ - z->avail_out); - /* if !CURLE_OK, clean up, return */ - if(result) { - free(decomp); - return exit_zlib(z, &k->zlib_init, result); - } - } - - /* Done? clean up, return */ - if(status == Z_STREAM_END) { - free(decomp); - if(inflateEnd(z) == Z_OK) - return exit_zlib(z, &k->zlib_init, result); - else - return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); - } - - /* Done with these bytes, exit */ - - /* status is always Z_OK at this point! */ - if(z->avail_in == 0) { - free(decomp); - return result; - } - } - else if(allow_restart && status == Z_DATA_ERROR) { - /* some servers seem to not generate zlib headers, so this is an attempt - to fix and continue anyway */ - - (void) inflateEnd(z); /* don't care about the return code */ - if(inflateInit2(z, -MAX_WBITS) != Z_OK) { - free(decomp); - return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); - } - z->next_in = orig_in; - z->avail_in = nread; - allow_restart = 0; - continue; - } - else { /* Error; exit loop, handle below */ - free(decomp); - return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); - } - } - /* Will never get here */ -} - -CURLcode -Curl_unencode_deflate_write(struct connectdata *conn, - struct SingleRequest *k, - ssize_t nread) -{ - z_stream *z = &k->z; /* zlib state structure */ - - /* Initialize zlib? */ - if(k->zlib_init == ZLIB_UNINIT) { - memset(z, 0, sizeof(z_stream)); - z->zalloc = (alloc_func)zalloc_cb; - z->zfree = (free_func)zfree_cb; - - if(inflateInit(z) != Z_OK) - return process_zlib_error(conn, z); - k->zlib_init = ZLIB_INIT; - } - - /* Set the compressed input when this function is called */ - z->next_in = (Bytef *)k->str; - z->avail_in = (uInt)nread; - - /* Now uncompress the data */ - return inflate_stream(conn, k); -} - -#ifdef OLD_ZLIB_SUPPORT -/* Skip over the gzip header */ -static enum { - GZIP_OK, - GZIP_BAD, - GZIP_UNDERFLOW -} check_gzip_header(unsigned char const *data, ssize_t len, ssize_t *headerlen) -{ - int method, flags; - const ssize_t totallen = len; - - /* The shortest header is 10 bytes */ - if(len < 10) - return GZIP_UNDERFLOW; - - if((data[0] != GZIP_MAGIC_0) || (data[1] != GZIP_MAGIC_1)) - return GZIP_BAD; - - method = data[2]; - flags = data[3]; - - if(method != Z_DEFLATED || (flags & RESERVED) != 0) { - /* Can't handle this compression method or unknown flag */ - return GZIP_BAD; - } - - /* Skip over time, xflags, OS code and all previous bytes */ - len -= 10; - data += 10; - - if(flags & EXTRA_FIELD) { - ssize_t extra_len; - - if(len < 2) - return GZIP_UNDERFLOW; - - extra_len = (data[1] << 8) | data[0]; - - if(len < (extra_len+2)) - return GZIP_UNDERFLOW; - - len -= (extra_len + 2); - data += (extra_len + 2); - } - - if(flags & ORIG_NAME) { - /* Skip over NUL-terminated file name */ - while(len && *data) { - --len; - ++data; - } - if(!len || *data) - return GZIP_UNDERFLOW; - - /* Skip over the NUL */ - --len; - ++data; - } - - if(flags & COMMENT) { - /* Skip over NUL-terminated comment */ - while(len && *data) { - --len; - ++data; - } - if(!len || *data) - return GZIP_UNDERFLOW; - - /* Skip over the NUL */ - --len; - } - - if(flags & HEAD_CRC) { - if(len < 2) - return GZIP_UNDERFLOW; - - len -= 2; - } - - *headerlen = totallen - len; - return GZIP_OK; -} -#endif - -CURLcode -Curl_unencode_gzip_write(struct connectdata *conn, - struct SingleRequest *k, - ssize_t nread) -{ - z_stream *z = &k->z; /* zlib state structure */ - - /* Initialize zlib? */ - if(k->zlib_init == ZLIB_UNINIT) { - memset(z, 0, sizeof(z_stream)); - z->zalloc = (alloc_func)zalloc_cb; - z->zfree = (free_func)zfree_cb; - - if(strcmp(zlibVersion(), "1.2.0.4") >= 0) { - /* zlib ver. >= 1.2.0.4 supports transparent gzip decompressing */ - if(inflateInit2(z, MAX_WBITS+32) != Z_OK) { - return process_zlib_error(conn, z); - } - k->zlib_init = ZLIB_INIT_GZIP; /* Transparent gzip decompress state */ - } - else { - /* we must parse the gzip header ourselves */ - if(inflateInit2(z, -MAX_WBITS) != Z_OK) { - return process_zlib_error(conn, z); - } - k->zlib_init = ZLIB_INIT; /* Initial call state */ - } - } - - if(k->zlib_init == ZLIB_INIT_GZIP) { - /* Let zlib handle the gzip decompression entirely */ - z->next_in = (Bytef *)k->str; - z->avail_in = (uInt)nread; - /* Now uncompress the data */ - return inflate_stream(conn, k); - } - -#ifndef OLD_ZLIB_SUPPORT - /* Support for old zlib versions is compiled away and we are running with - an old version, so return an error. */ - return exit_zlib(z, &k->zlib_init, CURLE_FUNCTION_NOT_FOUND); - -#else - /* This next mess is to get around the potential case where there isn't - * enough data passed in to skip over the gzip header. If that happens, we - * malloc a block and copy what we have then wait for the next call. If - * there still isn't enough (this is definitely a worst-case scenario), we - * make the block bigger, copy the next part in and keep waiting. - * - * This is only required with zlib versions < 1.2.0.4 as newer versions - * can handle the gzip header themselves. - */ - - switch (k->zlib_init) { - /* Skip over gzip header? */ - case ZLIB_INIT: - { - /* Initial call state */ - ssize_t hlen; - - switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) { - case GZIP_OK: - z->next_in = (Bytef *)k->str + hlen; - z->avail_in = (uInt)(nread - hlen); - k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */ - break; - - case GZIP_UNDERFLOW: - /* We need more data so we can find the end of the gzip header. It's - * possible that the memory block we malloc here will never be freed if - * the transfer abruptly aborts after this point. Since it's unlikely - * that circumstances will be right for this code path to be followed in - * the first place, and it's even more unlikely for a transfer to fail - * immediately afterwards, it should seldom be a problem. - */ - z->avail_in = (uInt)nread; - z->next_in = malloc(z->avail_in); - if(z->next_in == NULL) { - return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); - } - memcpy(z->next_in, k->str, z->avail_in); - k->zlib_init = ZLIB_GZIP_HEADER; /* Need more gzip header data state */ - /* We don't have any data to inflate yet */ - return CURLE_OK; - - case GZIP_BAD: - default: - return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); - } - - } - break; - - case ZLIB_GZIP_HEADER: - { - /* Need more gzip header data state */ - ssize_t hlen; - unsigned char *oldblock = z->next_in; - - z->avail_in += (uInt)nread; - z->next_in = realloc(z->next_in, z->avail_in); - if(z->next_in == NULL) { - free(oldblock); - return exit_zlib(z, &k->zlib_init, CURLE_OUT_OF_MEMORY); - } - /* Append the new block of data to the previous one */ - memcpy(z->next_in + z->avail_in - nread, k->str, nread); - - switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) { - case GZIP_OK: - /* This is the zlib stream data */ - free(z->next_in); - /* Don't point into the malloced block since we just freed it */ - z->next_in = (Bytef *)k->str + hlen + nread - z->avail_in; - z->avail_in = (uInt)(z->avail_in - hlen); - k->zlib_init = ZLIB_GZIP_INFLATING; /* Inflating stream state */ - break; - - case GZIP_UNDERFLOW: - /* We still don't have any data to inflate! */ - return CURLE_OK; - - case GZIP_BAD: - default: - free(z->next_in); - return exit_zlib(z, &k->zlib_init, process_zlib_error(conn, z)); - } - - } - break; - - case ZLIB_GZIP_INFLATING: - default: - /* Inflating stream state */ - z->next_in = (Bytef *)k->str; - z->avail_in = (uInt)nread; - break; - } - - if(z->avail_in == 0) { - /* We don't have any data to inflate; wait until next time */ - return CURLE_OK; - } - - /* We've parsed the header, now uncompress the data */ - return inflate_stream(conn, k); -#endif -} - -void Curl_unencode_cleanup(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - struct SingleRequest *k = &data->req; - z_stream *z = &k->z; - if(k->zlib_init != ZLIB_UNINIT) - (void) exit_zlib(z, &k->zlib_init, CURLE_OK); -} - -#endif /* HAVE_LIBZ */ diff --git a/Externals/curl/lib/content_encoding.h b/Externals/curl/lib/content_encoding.h deleted file mode 100644 index 3fadd28997..0000000000 --- a/Externals/curl/lib/content_encoding.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef HEADER_CURL_CONTENT_ENCODING_H -#define HEADER_CURL_CONTENT_ENCODING_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -/* - * Comma-separated list all supported Content-Encodings ('identity' is implied) - */ -#ifdef HAVE_LIBZ -#define ALL_CONTENT_ENCODINGS "deflate, gzip" -/* force a cleanup */ -void Curl_unencode_cleanup(struct connectdata *conn); -#else -#define ALL_CONTENT_ENCODINGS "identity" -#define Curl_unencode_cleanup(x) Curl_nop_stmt -#endif - -CURLcode Curl_unencode_deflate_write(struct connectdata *conn, - struct SingleRequest *req, - ssize_t nread); - -CURLcode -Curl_unencode_gzip_write(struct connectdata *conn, - struct SingleRequest *k, - ssize_t nread); - - -#endif /* HEADER_CURL_CONTENT_ENCODING_H */ diff --git a/Externals/curl/lib/cookie.c b/Externals/curl/lib/cookie.c deleted file mode 100644 index 01ce270bb6..0000000000 --- a/Externals/curl/lib/cookie.c +++ /dev/null @@ -1,1393 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/*** - - -RECEIVING COOKIE INFORMATION -============================ - -struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, - const char *file, struct CookieInfo *inc, bool newsession); - - Inits a cookie struct to store data in a local file. This is always - called before any cookies are set. - -struct Cookie *Curl_cookie_add(struct SessionHandle *data, - struct CookieInfo *c, bool httpheader, char *lineptr, - const char *domain, const char *path); - - The 'lineptr' parameter is a full "Set-cookie:" line as - received from a server. - - The function need to replace previously stored lines that this new - line superceeds. - - It may remove lines that are expired. - - It should return an indication of success/error. - - -SENDING COOKIE INFORMATION -========================== - -struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie, - char *host, char *path, bool secure); - - For a given host and path, return a linked list of cookies that - the client should send to the server if used now. The secure - boolean informs the cookie if a secure connection is achieved or - not. - - It shall only return cookies that haven't expired. - - -Example set of cookies: - - Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure - Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/ftgw; secure - Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT; - domain=.fidelity.com; path=/; secure - Set-cookie: - Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday, - 13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure -****/ - - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - -#ifdef USE_LIBPSL -# include -#endif - -#include "urldata.h" -#include "cookie.h" -#include "strequal.h" -#include "strtok.h" -#include "sendf.h" -#include "slist.h" -#include "share.h" -#include "strtoofft.h" -#include "rawstr.h" -#include "curl_memrchr.h" -#include "inet_pton.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -static void freecookie(struct Cookie *co) -{ - free(co->expirestr); - free(co->domain); - free(co->path); - free(co->spath); - free(co->name); - free(co->value); - free(co->maxage); - free(co->version); - free(co); -} - -static bool tailmatch(const char *cooke_domain, const char *hostname) -{ - size_t cookie_domain_len = strlen(cooke_domain); - size_t hostname_len = strlen(hostname); - - if(hostname_len < cookie_domain_len) - return FALSE; - - if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len)) - return FALSE; - - /* A lead char of cookie_domain is not '.'. - RFC6265 4.1.2.3. The Domain Attribute says: - For example, if the value of the Domain attribute is - "example.com", the user agent will include the cookie in the Cookie - header when making HTTP requests to example.com, www.example.com, and - www.corp.example.com. - */ - if(hostname_len == cookie_domain_len) - return TRUE; - if('.' == *(hostname + hostname_len - cookie_domain_len - 1)) - return TRUE; - return FALSE; -} - -/* - * matching cookie path and url path - * RFC6265 5.1.4 Paths and Path-Match - */ -static bool pathmatch(const char* cookie_path, const char* request_uri) -{ - size_t cookie_path_len; - size_t uri_path_len; - char* uri_path = NULL; - char* pos; - bool ret = FALSE; - - /* cookie_path must not have last '/' separator. ex: /sample */ - cookie_path_len = strlen(cookie_path); - if(1 == cookie_path_len) { - /* cookie_path must be '/' */ - return TRUE; - } - - uri_path = strdup(request_uri); - if(!uri_path) - return FALSE; - pos = strchr(uri_path, '?'); - if(pos) - *pos = 0x0; - - /* #-fragments are already cut off! */ - if(0 == strlen(uri_path) || uri_path[0] != '/') { - free(uri_path); - uri_path = strdup("/"); - if(!uri_path) - return FALSE; - } - - /* here, RFC6265 5.1.4 says - 4. Output the characters of the uri-path from the first character up - to, but not including, the right-most %x2F ("/"). - but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site - without redirect. - Ignore this algorithm because /hoge is uri path for this case - (uri path is not /). - */ - - uri_path_len = strlen(uri_path); - - if(uri_path_len < cookie_path_len) { - ret = FALSE; - goto pathmatched; - } - - /* not using checkprefix() because matching should be case-sensitive */ - if(strncmp(cookie_path, uri_path, cookie_path_len)) { - ret = FALSE; - goto pathmatched; - } - - /* The cookie-path and the uri-path are identical. */ - if(cookie_path_len == uri_path_len) { - ret = TRUE; - goto pathmatched; - } - - /* here, cookie_path_len < url_path_len */ - if(uri_path[cookie_path_len] == '/') { - ret = TRUE; - goto pathmatched; - } - - ret = FALSE; - -pathmatched: - free(uri_path); - return ret; -} - -/* - * cookie path sanitize - */ -static char *sanitize_cookie_path(const char *cookie_path) -{ - size_t len; - char *new_path = strdup(cookie_path); - if(!new_path) - return NULL; - - /* some stupid site sends path attribute with '"'. */ - len = strlen(new_path); - if(new_path[0] == '\"') { - memmove((void *)new_path, (const void *)(new_path + 1), len); - len--; - } - if(len && (new_path[len - 1] == '\"')) { - new_path[len - 1] = 0x0; - len--; - } - - /* RFC6265 5.2.4 The Path Attribute */ - if(new_path[0] != '/') { - /* Let cookie-path be the default-path. */ - free(new_path); - new_path = strdup("/"); - return new_path; - } - - /* convert /hoge/ to /hoge */ - if(len && new_path[len - 1] == '/') { - new_path[len - 1] = 0x0; - } - - return new_path; -} - -/* - * Load cookies from all given cookie files (CURLOPT_COOKIEFILE). - * - * NOTE: OOM or cookie parsing failures are ignored. - */ -void Curl_cookie_loadfiles(struct SessionHandle *data) -{ - struct curl_slist *list = data->change.cookielist; - if(list) { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - while(list) { - struct CookieInfo *newcookies = Curl_cookie_init(data, - list->data, - data->cookies, - data->set.cookiesession); - if(!newcookies) - /* Failure may be due to OOM or a bad cookie; both are ignored - * but only the first should be - */ - infof(data, "ignoring failed cookie_init for %s\n", list->data); - else - data->cookies = newcookies; - list = list->next; - } - curl_slist_free_all(data->change.cookielist); /* clean up list */ - data->change.cookielist = NULL; /* don't do this again! */ - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } -} - -/* - * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL - * that will be freed before the allocated string is stored there. - * - * It is meant to easily replace strdup() - */ -static void strstore(char **str, const char *newstr) -{ - free(*str); - *str = strdup(newstr); -} - -/* - * remove_expired() removes expired cookies. - */ -static void remove_expired(struct CookieInfo *cookies) -{ - struct Cookie *co, *nx, *pv; - curl_off_t now = (curl_off_t)time(NULL); - - co = cookies->cookies; - pv = NULL; - while(co) { - nx = co->next; - if(co->expires && co->expires < now) { - if(co == cookies->cookies) { - cookies->cookies = co->next; - } - else { - pv->next = co->next; - } - cookies->numcookies--; - freecookie(co); - } - else { - pv = co; - } - co = nx; - } -} - -/* - * Return true if the given string is an IP(v4|v6) address. - */ -static bool isip(const char *domain) -{ - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif - - if(Curl_inet_pton(AF_INET, domain, &addr) -#ifdef ENABLE_IPV6 - || Curl_inet_pton(AF_INET6, domain, &addr6) -#endif - ) { - /* domain name given as IP address */ - return TRUE; - } - - return FALSE; -} - -/**************************************************************************** - * - * Curl_cookie_add() - * - * Add a single cookie line to the cookie keeping object. - * - * Be aware that sometimes we get an IP-only host name, and that might also be - * a numerical IPv6 address. - * - * Returns NULL on out of memory or invalid cookie. This is suboptimal, - * as they should be treated separately. - ***************************************************************************/ - -struct Cookie * -Curl_cookie_add(struct SessionHandle *data, - /* The 'data' pointer here may be NULL at times, and thus - must only be used very carefully for things that can deal - with data being NULL. Such as infof() and similar */ - - struct CookieInfo *c, - bool httpheader, /* TRUE if HTTP header-style line */ - char *lineptr, /* first character of the line */ - const char *domain, /* default domain */ - const char *path) /* full path used when this cookie is set, - used to get default path for the cookie - unless set */ -{ - struct Cookie *clist; - char name[MAX_NAME]; - struct Cookie *co; - struct Cookie *lastc=NULL; - time_t now = time(NULL); - bool replace_old = FALSE; - bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */ - -#ifdef USE_LIBPSL - const psl_ctx_t *psl; -#endif - -#ifdef CURL_DISABLE_VERBOSE_STRINGS - (void)data; -#endif - - /* First, alloc and init a new struct for it */ - co = calloc(1, sizeof(struct Cookie)); - if(!co) - return NULL; /* bail out if we're this low on memory */ - - if(httpheader) { - /* This line was read off a HTTP-header */ - const char *ptr; - const char *semiptr; - char *what; - - what = malloc(MAX_COOKIE_LINE); - if(!what) { - free(co); - return NULL; - } - - semiptr=strchr(lineptr, ';'); /* first, find a semicolon */ - - while(*lineptr && ISBLANK(*lineptr)) - lineptr++; - - ptr = lineptr; - do { - /* we have a = pair or a stand-alone word here */ - name[0]=what[0]=0; /* init the buffers */ - if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;\r\n=] =%" - MAX_COOKIE_LINE_TXT "[^;\r\n]", - name, what)) { - /* Use strstore() below to properly deal with received cookie - headers that have the same string property set more than once, - and then we use the last one. */ - const char *whatptr; - bool done = FALSE; - bool sep; - size_t len=strlen(what); - size_t nlen = strlen(name); - const char *endofn = &ptr[ nlen ]; - - /* name ends with a '=' ? */ - sep = (*endofn == '=')?TRUE:FALSE; - - if(nlen) { - endofn--; /* move to the last character */ - if(ISBLANK(*endofn)) { - /* skip trailing spaces in name */ - while(*endofn && ISBLANK(*endofn) && nlen) { - endofn--; - nlen--; - } - name[nlen]=0; /* new end of name */ - } - } - - /* Strip off trailing whitespace from the 'what' */ - while(len && ISBLANK(what[len-1])) { - what[len-1]=0; - len--; - } - - /* Skip leading whitespace from the 'what' */ - whatptr=what; - while(*whatptr && ISBLANK(*whatptr)) - whatptr++; - - if(!co->name && sep) { - /* The very first name/value pair is the actual cookie name */ - co->name = strdup(name); - co->value = strdup(whatptr); - if(!co->name || !co->value) { - badcookie = TRUE; - break; - } - } - else if(!len) { - /* this was a "=" with no content, and we must allow - 'secure' and 'httponly' specified this weirdly */ - done = TRUE; - if(Curl_raw_equal("secure", name)) - co->secure = TRUE; - else if(Curl_raw_equal("httponly", name)) - co->httponly = TRUE; - else if(sep) - /* there was a '=' so we're not done parsing this field */ - done = FALSE; - } - if(done) - ; - else if(Curl_raw_equal("path", name)) { - strstore(&co->path, whatptr); - if(!co->path) { - badcookie = TRUE; /* out of memory bad */ - break; - } - co->spath = sanitize_cookie_path(co->path); - if(!co->spath) { - badcookie = TRUE; /* out of memory bad */ - break; - } - } - else if(Curl_raw_equal("domain", name)) { - bool is_ip; - const char *dotp; - - /* Now, we make sure that our host is within the given domain, - or the given domain is not valid and thus cannot be set. */ - - if('.' == whatptr[0]) - whatptr++; /* ignore preceding dot */ - - is_ip = isip(domain ? domain : whatptr); - - /* check for more dots */ - dotp = strchr(whatptr, '.'); - if(!dotp) - domain=":"; - - if(!domain - || (is_ip && !strcmp(whatptr, domain)) - || (!is_ip && tailmatch(whatptr, domain))) { - strstore(&co->domain, whatptr); - if(!co->domain) { - badcookie = TRUE; - break; - } - if(!is_ip) - co->tailmatch=TRUE; /* we always do that if the domain name was - given */ - } - else { - /* we did not get a tailmatch and then the attempted set domain - is not a domain to which the current host belongs. Mark as - bad. */ - badcookie=TRUE; - infof(data, "skipped cookie with bad tailmatch domain: %s\n", - whatptr); - } - } - else if(Curl_raw_equal("version", name)) { - strstore(&co->version, whatptr); - if(!co->version) { - badcookie = TRUE; - break; - } - } - else if(Curl_raw_equal("max-age", name)) { - /* Defined in RFC2109: - - Optional. The Max-Age attribute defines the lifetime of the - cookie, in seconds. The delta-seconds value is a decimal non- - negative integer. After delta-seconds seconds elapse, the - client should discard the cookie. A value of zero means the - cookie should be discarded immediately. - - */ - strstore(&co->maxage, whatptr); - if(!co->maxage) { - badcookie = TRUE; - break; - } - } - else if(Curl_raw_equal("expires", name)) { - strstore(&co->expirestr, whatptr); - if(!co->expirestr) { - badcookie = TRUE; - break; - } - } - /* - else this is the second (or more) name we don't know - about! */ - } - else { - /* this is an "illegal" = pair */ - } - - if(!semiptr || !*semiptr) { - /* we already know there are no more cookies */ - semiptr = NULL; - continue; - } - - ptr=semiptr+1; - while(*ptr && ISBLANK(*ptr)) - ptr++; - semiptr=strchr(ptr, ';'); /* now, find the next semicolon */ - - if(!semiptr && *ptr) - /* There are no more semicolons, but there's a final name=value pair - coming up */ - semiptr=strchr(ptr, '\0'); - } while(semiptr); - - if(co->maxage) { - co->expires = - curlx_strtoofft((*co->maxage=='\"')? - &co->maxage[1]:&co->maxage[0], NULL, 10); - if(CURL_OFF_T_MAX - now < co->expires) - /* avoid overflow */ - co->expires = CURL_OFF_T_MAX; - else - co->expires += now; - } - else if(co->expirestr) { - /* Note that if the date couldn't get parsed for whatever reason, - the cookie will be treated as a session cookie */ - co->expires = curl_getdate(co->expirestr, NULL); - - /* Session cookies have expires set to 0 so if we get that back - from the date parser let's add a second to make it a - non-session cookie */ - if(co->expires == 0) - co->expires = 1; - else if(co->expires < 0) - co->expires = 0; - } - - if(!badcookie && !co->domain) { - if(domain) { - /* no domain was given in the header line, set the default */ - co->domain=strdup(domain); - if(!co->domain) - badcookie = TRUE; - } - } - - if(!badcookie && !co->path && path) { - /* No path was given in the header line, set the default. - Note that the passed-in path to this function MAY have a '?' and - following part that MUST not be stored as part of the path. */ - char *queryp = strchr(path, '?'); - - /* queryp is where the interesting part of the path ends, so now we - want to the find the last */ - char *endslash; - if(!queryp) - endslash = strrchr(path, '/'); - else - endslash = memrchr(path, '/', (size_t)(queryp - path)); - if(endslash) { - size_t pathlen = (size_t)(endslash-path+1); /* include ending slash */ - co->path=malloc(pathlen+1); /* one extra for the zero byte */ - if(co->path) { - memcpy(co->path, path, pathlen); - co->path[pathlen]=0; /* zero terminate */ - co->spath = sanitize_cookie_path(co->path); - if(!co->spath) - badcookie = TRUE; /* out of memory bad */ - } - else - badcookie = TRUE; - } - } - - free(what); - - if(badcookie || !co->name) { - /* we didn't get a cookie name or a bad one, - this is an illegal line, bail out */ - freecookie(co); - return NULL; - } - - } - else { - /* This line is NOT a HTTP header style line, we do offer support for - reading the odd netscape cookies-file format here */ - char *ptr; - char *firstptr; - char *tok_buf=NULL; - int fields; - - /* IE introduced HTTP-only cookies to prevent XSS attacks. Cookies - marked with httpOnly after the domain name are not accessible - from javascripts, but since curl does not operate at javascript - level, we include them anyway. In Firefox's cookie files, these - lines are preceded with #HttpOnly_ and then everything is - as usual, so we skip 10 characters of the line.. - */ - if(strncmp(lineptr, "#HttpOnly_", 10) == 0) { - lineptr += 10; - co->httponly = TRUE; - } - - if(lineptr[0]=='#') { - /* don't even try the comments */ - free(co); - return NULL; - } - /* strip off the possible end-of-line characters */ - ptr=strchr(lineptr, '\r'); - if(ptr) - *ptr=0; /* clear it */ - ptr=strchr(lineptr, '\n'); - if(ptr) - *ptr=0; /* clear it */ - - firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */ - - /* Now loop through the fields and init the struct we already have - allocated */ - for(ptr=firstptr, fields=0; ptr && !badcookie; - ptr=strtok_r(NULL, "\t", &tok_buf), fields++) { - switch(fields) { - case 0: - if(ptr[0]=='.') /* skip preceding dots */ - ptr++; - co->domain = strdup(ptr); - if(!co->domain) - badcookie = TRUE; - break; - case 1: - /* This field got its explanation on the 23rd of May 2001 by - Andrs Garca: - - flag: A TRUE/FALSE value indicating if all machines within a given - domain can access the variable. This value is set automatically by - the browser, depending on the value you set for the domain. - - As far as I can see, it is set to true when the cookie says - .domain.com and to false when the domain is complete www.domain.com - */ - co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE; - break; - case 2: - /* It turns out, that sometimes the file format allows the path - field to remain not filled in, we try to detect this and work - around it! Andrs Garca made us aware of this... */ - if(strcmp("TRUE", ptr) && strcmp("FALSE", ptr)) { - /* only if the path doesn't look like a boolean option! */ - co->path = strdup(ptr); - if(!co->path) - badcookie = TRUE; - else { - co->spath = sanitize_cookie_path(co->path); - if(!co->spath) { - badcookie = TRUE; /* out of memory bad */ - } - } - break; - } - /* this doesn't look like a path, make one up! */ - co->path = strdup("/"); - if(!co->path) - badcookie = TRUE; - co->spath = strdup("/"); - if(!co->spath) - badcookie = TRUE; - fields++; /* add a field and fall down to secure */ - /* FALLTHROUGH */ - case 3: - co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE; - break; - case 4: - co->expires = curlx_strtoofft(ptr, NULL, 10); - break; - case 5: - co->name = strdup(ptr); - if(!co->name) - badcookie = TRUE; - break; - case 6: - co->value = strdup(ptr); - if(!co->value) - badcookie = TRUE; - break; - } - } - if(6 == fields) { - /* we got a cookie with blank contents, fix it */ - co->value = strdup(""); - if(!co->value) - badcookie = TRUE; - else - fields++; - } - - if(!badcookie && (7 != fields)) - /* we did not find the sufficient number of fields */ - badcookie = TRUE; - - if(badcookie) { - freecookie(co); - return NULL; - } - - } - - if(!c->running && /* read from a file */ - c->newsession && /* clean session cookies */ - !co->expires) { /* this is a session cookie since it doesn't expire! */ - freecookie(co); - return NULL; - } - - co->livecookie = c->running; - - /* now, we have parsed the incoming line, we must now check if this - superceeds an already existing cookie, which it may if the previous have - the same domain and path as this */ - - /* at first, remove expired cookies */ - remove_expired(c); - -#ifdef USE_LIBPSL - /* Check if the domain is a Public Suffix and if yes, ignore the cookie. - This needs a libpsl compiled with builtin data. */ - if(domain && co->domain && !isip(co->domain)) { - if(((psl = psl_builtin()) != NULL) - && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) { - infof(data, - "cookie '%s' dropped, domain '%s' must not set cookies for '%s'\n", - co->name, domain, co->domain); - freecookie(co); - return NULL; - } - } -#endif - - clist = c->cookies; - replace_old = FALSE; - while(clist) { - if(Curl_raw_equal(clist->name, co->name)) { - /* the names are identical */ - - if(clist->domain && co->domain) { - if(Curl_raw_equal(clist->domain, co->domain)) - /* The domains are identical */ - replace_old=TRUE; - } - else if(!clist->domain && !co->domain) - replace_old = TRUE; - - if(replace_old) { - /* the domains were identical */ - - if(clist->spath && co->spath) { - if(Curl_raw_equal(clist->spath, co->spath)) { - replace_old = TRUE; - } - else - replace_old = FALSE; - } - else if(!clist->spath && !co->spath) - replace_old = TRUE; - else - replace_old = FALSE; - - } - - if(replace_old && !co->livecookie && clist->livecookie) { - /* Both cookies matched fine, except that the already present - cookie is "live", which means it was set from a header, while - the new one isn't "live" and thus only read from a file. We let - live cookies stay alive */ - - /* Free the newcomer and get out of here! */ - freecookie(co); - return NULL; - } - - if(replace_old) { - co->next = clist->next; /* get the next-pointer first */ - - /* then free all the old pointers */ - free(clist->name); - free(clist->value); - free(clist->domain); - free(clist->path); - free(clist->spath); - free(clist->expirestr); - free(clist->version); - free(clist->maxage); - - *clist = *co; /* then store all the new data */ - - free(co); /* free the newly alloced memory */ - co = clist; /* point to the previous struct instead */ - - /* We have replaced a cookie, now skip the rest of the list but - make sure the 'lastc' pointer is properly set */ - do { - lastc = clist; - clist = clist->next; - } while(clist); - break; - } - } - lastc = clist; - clist = clist->next; - } - - if(c->running) - /* Only show this when NOT reading the cookies from a file */ - infof(data, "%s cookie %s=\"%s\" for domain %s, path %s, " - "expire %" CURL_FORMAT_CURL_OFF_T "\n", - replace_old?"Replaced":"Added", co->name, co->value, - co->domain, co->path, co->expires); - - if(!replace_old) { - /* then make the last item point on this new one */ - if(lastc) - lastc->next = co; - else - c->cookies = co; - c->numcookies++; /* one more cookie in the jar */ - } - - return co; -} - -/***************************************************************************** - * - * Curl_cookie_init() - * - * Inits a cookie struct to read data from a local file. This is always - * called before any cookies are set. File may be NULL. - * - * If 'newsession' is TRUE, discard all "session cookies" on read from file. - * - * Returns NULL on out of memory. Invalid cookies are ignored. - ****************************************************************************/ -struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, - const char *file, - struct CookieInfo *inc, - bool newsession) -{ - struct CookieInfo *c; - FILE *fp = NULL; - bool fromfile=TRUE; - char *line = NULL; - - if(NULL == inc) { - /* we didn't get a struct, create one */ - c = calloc(1, sizeof(struct CookieInfo)); - if(!c) - return NULL; /* failed to get memory */ - c->filename = strdup(file?file:"none"); /* copy the name just in case */ - if(!c->filename) - goto fail; /* failed to get memory */ - } - else { - /* we got an already existing one, use that */ - c = inc; - } - c->running = FALSE; /* this is not running, this is init */ - - if(file && strequal(file, "-")) { - fp = stdin; - fromfile=FALSE; - } - else if(file && !*file) { - /* points to a "" string */ - fp = NULL; - } - else - fp = file?fopen(file, FOPEN_READTEXT):NULL; - - c->newsession = newsession; /* new session? */ - - if(fp) { - char *lineptr; - bool headerline; - - line = malloc(MAX_COOKIE_LINE); - if(!line) - goto fail; - while(fgets(line, MAX_COOKIE_LINE, fp)) { - if(checkprefix("Set-Cookie:", line)) { - /* This is a cookie line, get it! */ - lineptr=&line[11]; - headerline=TRUE; - } - else { - lineptr=line; - headerline=FALSE; - } - while(*lineptr && ISBLANK(*lineptr)) - lineptr++; - - Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL); - } - free(line); /* free the line buffer */ - - if(fromfile) - fclose(fp); - } - - c->running = TRUE; /* now, we're running */ - - return c; - -fail: - free(line); - if(!inc) - /* Only clean up if we allocated it here, as the original could still be in - * use by a share handle */ - Curl_cookie_cleanup(c); - if(fromfile && fp) - fclose(fp); - return NULL; /* out of memory */ -} - -/* sort this so that the longest path gets before the shorter path */ -static int cookie_sort(const void *p1, const void *p2) -{ - struct Cookie *c1 = *(struct Cookie **)p1; - struct Cookie *c2 = *(struct Cookie **)p2; - size_t l1, l2; - - /* 1 - compare cookie path lengths */ - l1 = c1->path ? strlen(c1->path) : 0; - l2 = c2->path ? strlen(c2->path) : 0; - - if(l1 != l2) - return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */ - - /* 2 - compare cookie domain lengths */ - l1 = c1->domain ? strlen(c1->domain) : 0; - l2 = c2->domain ? strlen(c2->domain) : 0; - - if(l1 != l2) - return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */ - - /* 3 - compare cookie names */ - if(c1->name && c2->name) - return strcmp(c1->name, c2->name); - - /* sorry, can't be more deterministic */ - return 0; -} - -/***************************************************************************** - * - * Curl_cookie_getlist() - * - * For a given host and path, return a linked list of cookies that the - * client should send to the server if used now. The secure boolean informs - * the cookie if a secure connection is achieved or not. - * - * It shall only return cookies that haven't expired. - * - ****************************************************************************/ - -struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, - const char *host, const char *path, - bool secure) -{ - struct Cookie *newco; - struct Cookie *co; - time_t now = time(NULL); - struct Cookie *mainco=NULL; - size_t matches = 0; - bool is_ip; - - if(!c || !c->cookies) - return NULL; /* no cookie struct or no cookies in the struct */ - - /* at first, remove expired cookies */ - remove_expired(c); - - /* check if host is an IP(v4|v6) address */ - is_ip = isip(host); - - co = c->cookies; - - while(co) { - /* only process this cookie if it is not expired or had no expire - date AND that if the cookie requires we're secure we must only - continue if we are! */ - if((!co->expires || (co->expires > now)) && - (co->secure?secure:TRUE)) { - - /* now check if the domain is correct */ - if(!co->domain || - (co->tailmatch && !is_ip && tailmatch(co->domain, host)) || - ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) { - /* the right part of the host matches the domain stuff in the - cookie data */ - - /* now check the left part of the path with the cookies path - requirement */ - if(!co->spath || pathmatch(co->spath, path) ) { - - /* and now, we know this is a match and we should create an - entry for the return-linked-list */ - - newco = malloc(sizeof(struct Cookie)); - if(newco) { - /* first, copy the whole source cookie: */ - memcpy(newco, co, sizeof(struct Cookie)); - - /* then modify our next */ - newco->next = mainco; - - /* point the main to us */ - mainco = newco; - - matches++; - } - else { - fail: - /* failure, clear up the allocated chain and return NULL */ - while(mainco) { - co = mainco->next; - free(mainco); - mainco = co; - } - - return NULL; - } - } - } - } - co = co->next; - } - - if(matches) { - /* Now we need to make sure that if there is a name appearing more than - once, the longest specified path version comes first. To make this - the swiftest way, we just sort them all based on path length. */ - struct Cookie **array; - size_t i; - - /* alloc an array and store all cookie pointers */ - array = malloc(sizeof(struct Cookie *) * matches); - if(!array) - goto fail; - - co = mainco; - - for(i=0; co; co = co->next) - array[i++] = co; - - /* now sort the cookie pointers in path length order */ - qsort(array, matches, sizeof(struct Cookie *), cookie_sort); - - /* remake the linked list order according to the new order */ - - mainco = array[0]; /* start here */ - for(i=0; inext = array[i+1]; - array[matches-1]->next = NULL; /* terminate the list */ - - free(array); /* remove the temporary data again */ - } - - return mainco; /* return the new list */ -} - -/***************************************************************************** - * - * Curl_cookie_clearall() - * - * Clear all existing cookies and reset the counter. - * - ****************************************************************************/ -void Curl_cookie_clearall(struct CookieInfo *cookies) -{ - if(cookies) { - Curl_cookie_freelist(cookies->cookies, TRUE); - cookies->cookies = NULL; - cookies->numcookies = 0; - } -} - -/***************************************************************************** - * - * Curl_cookie_freelist() - * - * Free a list of cookies previously returned by Curl_cookie_getlist(); - * - * The 'cookiestoo' argument tells this function whether to just free the - * list or actually also free all cookies within the list as well. - * - ****************************************************************************/ - -void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo) -{ - struct Cookie *next; - while(co) { - next = co->next; - if(cookiestoo) - freecookie(co); - else - free(co); /* we only free the struct since the "members" are all just - pointed out in the main cookie list! */ - co = next; - } -} - - -/***************************************************************************** - * - * Curl_cookie_clearsess() - * - * Free all session cookies in the cookies list. - * - ****************************************************************************/ -void Curl_cookie_clearsess(struct CookieInfo *cookies) -{ - struct Cookie *first, *curr, *next, *prev = NULL; - - if(!cookies || !cookies->cookies) - return; - - first = curr = prev = cookies->cookies; - - for(; curr; curr = next) { - next = curr->next; - if(!curr->expires) { - if(first == curr) - first = next; - - if(prev == curr) - prev = next; - else - prev->next = next; - - freecookie(curr); - cookies->numcookies--; - } - else - prev = curr; - } - - cookies->cookies = first; -} - - -/***************************************************************************** - * - * Curl_cookie_cleanup() - * - * Free a "cookie object" previous created with Curl_cookie_init(). - * - ****************************************************************************/ -void Curl_cookie_cleanup(struct CookieInfo *c) -{ - if(c) { - free(c->filename); - Curl_cookie_freelist(c->cookies, TRUE); - free(c); /* free the base struct as well */ - } -} - -/* get_netscape_format() - * - * Formats a string for Netscape output file, w/o a newline at the end. - * - * Function returns a char * to a formatted line. Has to be free()d -*/ -static char *get_netscape_format(const struct Cookie *co) -{ - return aprintf( - "%s" /* httponly preamble */ - "%s%s\t" /* domain */ - "%s\t" /* tailmatch */ - "%s\t" /* path */ - "%s\t" /* secure */ - "%" CURL_FORMAT_CURL_OFF_T "\t" /* expires */ - "%s\t" /* name */ - "%s", /* value */ - co->httponly?"#HttpOnly_":"", - /* Make sure all domains are prefixed with a dot if they allow - tailmatching. This is Mozilla-style. */ - (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"", - co->domain?co->domain:"unknown", - co->tailmatch?"TRUE":"FALSE", - co->path?co->path:"/", - co->secure?"TRUE":"FALSE", - co->expires, - co->name, - co->value?co->value:""); -} - -/* - * cookie_output() - * - * Writes all internally known cookies to the specified file. Specify - * "-" as file name to write to stdout. - * - * The function returns non-zero on write failure. - */ -static int cookie_output(struct CookieInfo *c, const char *dumphere) -{ - struct Cookie *co; - FILE *out; - bool use_stdout=FALSE; - char *format_ptr; - - if((NULL == c) || (0 == c->numcookies)) - /* If there are no known cookies, we don't write or even create any - destination file */ - return 0; - - /* at first, remove expired cookies */ - remove_expired(c); - - if(strequal("-", dumphere)) { - /* use stdout */ - out = stdout; - use_stdout=TRUE; - } - else { - out = fopen(dumphere, FOPEN_WRITETEXT); - if(!out) - return 1; /* failure */ - } - - fputs("# Netscape HTTP Cookie File\n" - "# https://curl.haxx.se/docs/http-cookies.html\n" - "# This file was generated by libcurl! Edit at your own risk.\n\n", - out); - - for(co = c->cookies; co; co = co->next) { - if(!co->domain) - continue; - format_ptr = get_netscape_format(co); - if(format_ptr == NULL) { - fprintf(out, "#\n# Fatal libcurl error\n"); - if(!use_stdout) - fclose(out); - return 1; - } - fprintf(out, "%s\n", format_ptr); - free(format_ptr); - } - - if(!use_stdout) - fclose(out); - - return 0; -} - -struct curl_slist *Curl_cookie_list(struct SessionHandle *data) -{ - struct curl_slist *list = NULL; - struct curl_slist *beg; - struct Cookie *c; - char *line; - - if((data->cookies == NULL) || - (data->cookies->numcookies == 0)) - return NULL; - - for(c = data->cookies->cookies; c; c = c->next) { - if(!c->domain) - continue; - line = get_netscape_format(c); - if(!line) { - curl_slist_free_all(list); - return NULL; - } - beg = Curl_slist_append_nodup(list, line); - if(!beg) { - free(line); - curl_slist_free_all(list); - return NULL; - } - list = beg; - } - - return list; -} - -void Curl_flush_cookies(struct SessionHandle *data, int cleanup) -{ - if(data->set.str[STRING_COOKIEJAR]) { - if(data->change.cookielist) { - /* If there is a list of cookie files to read, do it first so that - we have all the told files read before we write the new jar. - Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */ - Curl_cookie_loadfiles(data); - } - - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - - /* if we have a destination file for all the cookies to get dumped to */ - if(cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) - infof(data, "WARNING: failed to save cookies in %s\n", - data->set.str[STRING_COOKIEJAR]); - } - else { - if(cleanup && data->change.cookielist) { - /* since nothing is written, we can just free the list of cookie file - names */ - curl_slist_free_all(data->change.cookielist); /* clean up list */ - data->change.cookielist = NULL; - } - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - } - - if(cleanup && (!data->share || (data->cookies != data->share->cookies))) { - Curl_cookie_cleanup(data->cookies); - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); -} - -#endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */ diff --git a/Externals/curl/lib/cookie.h b/Externals/curl/lib/cookie.h deleted file mode 100644 index 74a9224ec8..0000000000 --- a/Externals/curl/lib/cookie.h +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef HEADER_CURL_COOKIE_H -#define HEADER_CURL_COOKIE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#include - -struct Cookie { - struct Cookie *next; /* next in the chain */ - char *name; /* = value */ - char *value; /* name = */ - char *path; /* path = which is in Set-Cookie: */ - char *spath; /* sanitized cookie path */ - char *domain; /* domain = */ - curl_off_t expires; /* expires = */ - char *expirestr; /* the plain text version */ - bool tailmatch; /* weather we do tail-matchning of the domain name */ - - /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */ - char *version; /* Version = */ - char *maxage; /* Max-Age = */ - - bool secure; /* whether the 'secure' keyword was used */ - bool livecookie; /* updated from a server, not a stored file */ - bool httponly; /* true if the httponly directive is present */ -}; - -struct CookieInfo { - /* linked list of cookies we know of */ - struct Cookie *cookies; - - char *filename; /* file we read from/write to */ - bool running; /* state info, for cookie adding information */ - long numcookies; /* number of cookies in the "jar" */ - bool newsession; /* new session, discard session cookies on load */ -}; - -/* This is the maximum line length we accept for a cookie line. RFC 2109 - section 6.3 says: - - "at least 4096 bytes per cookie (as measured by the size of the characters - that comprise the cookie non-terminal in the syntax description of the - Set-Cookie header)" - -*/ -#define MAX_COOKIE_LINE 5000 -#define MAX_COOKIE_LINE_TXT "4999" - -/* This is the maximum length of a cookie name we deal with: */ -#define MAX_NAME 1024 -#define MAX_NAME_TXT "1023" - -struct SessionHandle; -/* - * Add a cookie to the internal list of cookies. The domain and path arguments - * are only used if the header boolean is TRUE. - */ - -struct Cookie *Curl_cookie_add(struct SessionHandle *data, - struct CookieInfo *, bool header, char *lineptr, - const char *domain, const char *path); - -struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *, - const char *, bool); -void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo); -void Curl_cookie_clearall(struct CookieInfo *cookies); -void Curl_cookie_clearsess(struct CookieInfo *cookies); - -#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES) -#define Curl_cookie_list(x) NULL -#define Curl_cookie_loadfiles(x) Curl_nop_stmt -#define Curl_cookie_init(x,y,z,w) NULL -#define Curl_cookie_cleanup(x) Curl_nop_stmt -#define Curl_flush_cookies(x,y) Curl_nop_stmt -#else -void Curl_flush_cookies(struct SessionHandle *data, int cleanup); -void Curl_cookie_cleanup(struct CookieInfo *); -struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, - const char *, struct CookieInfo *, bool); -struct curl_slist *Curl_cookie_list(struct SessionHandle *data); -void Curl_cookie_loadfiles(struct SessionHandle *data); -#endif - -#endif /* HEADER_CURL_COOKIE_H */ diff --git a/Externals/curl/lib/curl_addrinfo.c b/Externals/curl/lib/curl_addrinfo.c deleted file mode 100644 index 8fa0c84ccc..0000000000 --- a/Externals/curl/lib/curl_addrinfo.c +++ /dev/null @@ -1,565 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_SYS_UN_H -# include -#endif - -#ifdef __VMS -# include -# include -#endif - -#if defined(NETWARE) && defined(__NOVELL_LIBC__) -# undef in_addr_t -# define in_addr_t unsigned long -#endif - -#include "curl_addrinfo.h" -#include "inet_pton.h" -#include "warnless.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_freeaddrinfo() - * - * This is used to free a linked list of Curl_addrinfo structs along - * with all its associated allocated storage. This function should be - * called once for each successful call to Curl_getaddrinfo_ex() or to - * any function call which actually allocates a Curl_addrinfo struct. - */ - -#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \ - defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__) - /* workaround icc 9.1 optimizer issue */ -# define vqualifier volatile -#else -# define vqualifier -#endif - -void -Curl_freeaddrinfo(Curl_addrinfo *cahead) -{ - Curl_addrinfo *vqualifier canext; - Curl_addrinfo *ca; - - for(ca = cahead; ca != NULL; ca = canext) { - free(ca->ai_addr); - free(ca->ai_canonname); - canext = ca->ai_next; - - free(ca); - } -} - - -#ifdef HAVE_GETADDRINFO -/* - * Curl_getaddrinfo_ex() - * - * This is a wrapper function around system's getaddrinfo(), with - * the only difference that instead of returning a linked list of - * addrinfo structs this one returns a linked list of Curl_addrinfo - * ones. The memory allocated by this function *MUST* be free'd with - * Curl_freeaddrinfo(). For each successful call to this function - * there must be an associated call later to Curl_freeaddrinfo(). - * - * There should be no single call to system's getaddrinfo() in the - * whole library, any such call should be 'routed' through this one. - */ - -int -Curl_getaddrinfo_ex(const char *nodename, - const char *servname, - const struct addrinfo *hints, - Curl_addrinfo **result) -{ - const struct addrinfo *ai; - struct addrinfo *aihead; - Curl_addrinfo *cafirst = NULL; - Curl_addrinfo *calast = NULL; - Curl_addrinfo *ca; - size_t ss_size; - int error; - - *result = NULL; /* assume failure */ - - error = getaddrinfo(nodename, servname, hints, &aihead); - if(error) - return error; - - /* traverse the addrinfo list */ - - for(ai = aihead; ai != NULL; ai = ai->ai_next) { - - /* ignore elements with unsupported address family, */ - /* settle family-specific sockaddr structure size. */ - if(ai->ai_family == AF_INET) - ss_size = sizeof(struct sockaddr_in); -#ifdef ENABLE_IPV6 - else if(ai->ai_family == AF_INET6) - ss_size = sizeof(struct sockaddr_in6); -#endif - else - continue; - - /* ignore elements without required address info */ - if((ai->ai_addr == NULL) || !(ai->ai_addrlen > 0)) - continue; - - /* ignore elements with bogus address size */ - if((size_t)ai->ai_addrlen < ss_size) - continue; - - if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) { - error = EAI_MEMORY; - break; - } - - /* copy each structure member individually, member ordering, */ - /* size, or padding might be different for each platform. */ - - ca->ai_flags = ai->ai_flags; - ca->ai_family = ai->ai_family; - ca->ai_socktype = ai->ai_socktype; - ca->ai_protocol = ai->ai_protocol; - ca->ai_addrlen = (curl_socklen_t)ss_size; - ca->ai_addr = NULL; - ca->ai_canonname = NULL; - ca->ai_next = NULL; - - if((ca->ai_addr = malloc(ss_size)) == NULL) { - error = EAI_MEMORY; - free(ca); - break; - } - memcpy(ca->ai_addr, ai->ai_addr, ss_size); - - if(ai->ai_canonname != NULL) { - if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) { - error = EAI_MEMORY; - free(ca->ai_addr); - free(ca); - break; - } - } - - /* if the return list is empty, this becomes the first element */ - if(!cafirst) - cafirst = ca; - - /* add this element last in the return list */ - if(calast) - calast->ai_next = ca; - calast = ca; - - } - - /* destroy the addrinfo list */ - if(aihead) - freeaddrinfo(aihead); - - /* if we failed, also destroy the Curl_addrinfo list */ - if(error) { - Curl_freeaddrinfo(cafirst); - cafirst = NULL; - } - else if(!cafirst) { -#ifdef EAI_NONAME - /* rfc3493 conformant */ - error = EAI_NONAME; -#else - /* rfc3493 obsoleted */ - error = EAI_NODATA; -#endif -#ifdef USE_WINSOCK - SET_SOCKERRNO(error); -#endif - } - - *result = cafirst; - - /* This is not a CURLcode */ - return error; -} -#endif /* HAVE_GETADDRINFO */ - - -/* - * Curl_he2ai() - * - * This function returns a pointer to the first element of a newly allocated - * Curl_addrinfo struct linked list filled with the data of a given hostent. - * Curl_addrinfo is meant to work like the addrinfo struct does for a IPv6 - * stack, but usable also for IPv4, all hosts and environments. - * - * The memory allocated by this function *MUST* be free'd later on calling - * Curl_freeaddrinfo(). For each successful call to this function there - * must be an associated call later to Curl_freeaddrinfo(). - * - * Curl_addrinfo defined in "lib/curl_addrinfo.h" - * - * struct Curl_addrinfo { - * int ai_flags; - * int ai_family; - * int ai_socktype; - * int ai_protocol; - * curl_socklen_t ai_addrlen; * Follow rfc3493 struct addrinfo * - * char *ai_canonname; - * struct sockaddr *ai_addr; - * struct Curl_addrinfo *ai_next; - * }; - * typedef struct Curl_addrinfo Curl_addrinfo; - * - * hostent defined in - * - * struct hostent { - * char *h_name; - * char **h_aliases; - * int h_addrtype; - * int h_length; - * char **h_addr_list; - * }; - * - * for backward compatibility: - * - * #define h_addr h_addr_list[0] - */ - -Curl_addrinfo * -Curl_he2ai(const struct hostent *he, int port) -{ - Curl_addrinfo *ai; - Curl_addrinfo *prevai = NULL; - Curl_addrinfo *firstai = NULL; - struct sockaddr_in *addr; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 *addr6; -#endif - CURLcode result = CURLE_OK; - int i; - char *curr; - - if(!he) - /* no input == no output! */ - return NULL; - - DEBUGASSERT((he->h_name != NULL) && (he->h_addr_list != NULL)); - - for(i=0; (curr = he->h_addr_list[i]) != NULL; i++) { - - size_t ss_size; -#ifdef ENABLE_IPV6 - if(he->h_addrtype == AF_INET6) - ss_size = sizeof (struct sockaddr_in6); - else -#endif - ss_size = sizeof (struct sockaddr_in); - - if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL) { - result = CURLE_OUT_OF_MEMORY; - break; - } - if((ai->ai_canonname = strdup(he->h_name)) == NULL) { - result = CURLE_OUT_OF_MEMORY; - free(ai); - break; - } - if((ai->ai_addr = calloc(1, ss_size)) == NULL) { - result = CURLE_OUT_OF_MEMORY; - free(ai->ai_canonname); - free(ai); - break; - } - - if(!firstai) - /* store the pointer we want to return from this function */ - firstai = ai; - - if(prevai) - /* make the previous entry point to this */ - prevai->ai_next = ai; - - ai->ai_family = he->h_addrtype; - - /* we return all names as STREAM, so when using this address for TFTP - the type must be ignored and conn->socktype be used instead! */ - ai->ai_socktype = SOCK_STREAM; - - ai->ai_addrlen = (curl_socklen_t)ss_size; - - /* leave the rest of the struct filled with zero */ - - switch (ai->ai_family) { - case AF_INET: - addr = (void *)ai->ai_addr; /* storage area for this info */ - - memcpy(&addr->sin_addr, curr, sizeof(struct in_addr)); - addr->sin_family = (unsigned short)(he->h_addrtype); - addr->sin_port = htons((unsigned short)port); - break; - -#ifdef ENABLE_IPV6 - case AF_INET6: - addr6 = (void *)ai->ai_addr; /* storage area for this info */ - - memcpy(&addr6->sin6_addr, curr, sizeof(struct in6_addr)); - addr6->sin6_family = (unsigned short)(he->h_addrtype); - addr6->sin6_port = htons((unsigned short)port); - break; -#endif - } - - prevai = ai; - } - - if(result) { - Curl_freeaddrinfo(firstai); - firstai = NULL; - } - - return firstai; -} - - -struct namebuff { - struct hostent hostentry; - union { - struct in_addr ina4; -#ifdef ENABLE_IPV6 - struct in6_addr ina6; -#endif - } addrentry; - char *h_addr_list[2]; -}; - - -/* - * Curl_ip2addr() - * - * This function takes an internet address, in binary form, as input parameter - * along with its address family and the string version of the address, and it - * returns a Curl_addrinfo chain filled in correctly with information for the - * given address/host - */ - -Curl_addrinfo * -Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port) -{ - Curl_addrinfo *ai; - -#if defined(__VMS) && \ - defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) -#pragma pointer_size save -#pragma pointer_size short -#pragma message disable PTRMISMATCH -#endif - - struct hostent *h; - struct namebuff *buf; - char *addrentry; - char *hoststr; - size_t addrsize; - - DEBUGASSERT(inaddr && hostname); - - buf = malloc(sizeof(struct namebuff)); - if(!buf) - return NULL; - - hoststr = strdup(hostname); - if(!hoststr) { - free(buf); - return NULL; - } - - switch(af) { - case AF_INET: - addrsize = sizeof(struct in_addr); - addrentry = (void *)&buf->addrentry.ina4; - memcpy(addrentry, inaddr, sizeof(struct in_addr)); - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - addrsize = sizeof(struct in6_addr); - addrentry = (void *)&buf->addrentry.ina6; - memcpy(addrentry, inaddr, sizeof(struct in6_addr)); - break; -#endif - default: - free(hoststr); - free(buf); - return NULL; - } - - h = &buf->hostentry; - h->h_name = hoststr; - h->h_aliases = NULL; - h->h_addrtype = (short)af; - h->h_length = (short)addrsize; - h->h_addr_list = &buf->h_addr_list[0]; - h->h_addr_list[0] = addrentry; - h->h_addr_list[1] = NULL; /* terminate list of entries */ - -#if defined(__VMS) && \ - defined(__INITIAL_POINTER_SIZE) && (__INITIAL_POINTER_SIZE == 64) -#pragma pointer_size restore -#pragma message enable PTRMISMATCH -#endif - - ai = Curl_he2ai(h, port); - - free(hoststr); - free(buf); - - return ai; -} - -/* - * Given an IPv4 or IPv6 dotted string address, this converts it to a proper - * allocated Curl_addrinfo struct and returns it. - */ -Curl_addrinfo *Curl_str2addr(char *address, int port) -{ - struct in_addr in; - if(Curl_inet_pton(AF_INET, address, &in) > 0) - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(AF_INET, &in, address, port); -#ifdef ENABLE_IPV6 - else { - struct in6_addr in6; - if(Curl_inet_pton(AF_INET6, address, &in6) > 0) - /* This is a dotted IPv6 address ::1-style */ - return Curl_ip2addr(AF_INET6, &in6, address, port); - } -#endif - return NULL; /* bad input format */ -} - -#ifdef USE_UNIX_SOCKETS -/** - * Given a path to a Unix domain socket, return a newly allocated Curl_addrinfo - * struct initialized with this path. - */ -Curl_addrinfo *Curl_unix2addr(const char *path) -{ - Curl_addrinfo *ai; - struct sockaddr_un *sa_un; - size_t path_len; - - ai = calloc(1, sizeof(Curl_addrinfo)); - if(!ai) - return NULL; - if((ai->ai_addr = calloc(1, sizeof(struct sockaddr_un))) == NULL) { - free(ai); - return NULL; - } - /* sun_path must be able to store the NUL-terminated path */ - path_len = strlen(path); - if(path_len >= sizeof(sa_un->sun_path)) { - free(ai->ai_addr); - free(ai); - return NULL; - } - - ai->ai_family = AF_UNIX; - ai->ai_socktype = SOCK_STREAM; /* assume reliable transport for HTTP */ - ai->ai_addrlen = (curl_socklen_t) sizeof(struct sockaddr_un); - sa_un = (void *) ai->ai_addr; - sa_un->sun_family = AF_UNIX; - memcpy(sa_un->sun_path, path, path_len + 1); /* copy NUL byte */ - return ai; -} -#endif - -#if defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) -/* - * curl_dofreeaddrinfo() - * - * This is strictly for memory tracing and are using the same style as the - * family otherwise present in memdebug.c. I put these ones here since they - * require a bunch of structs I didn't want to include in memdebug.c - */ - -void -curl_dofreeaddrinfo(struct addrinfo *freethis, - int line, const char *source) -{ -#ifdef USE_LWIPSOCK - lwip_freeaddrinfo(freethis); -#else - (freeaddrinfo)(freethis); -#endif - curl_memlog("ADDR %s:%d freeaddrinfo(%p)\n", - source, line, (void *)freethis); -} -#endif /* defined(CURLDEBUG) && defined(HAVE_FREEADDRINFO) */ - - -#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) -/* - * curl_dogetaddrinfo() - * - * This is strictly for memory tracing and are using the same style as the - * family otherwise present in memdebug.c. I put these ones here since they - * require a bunch of structs I didn't want to include in memdebug.c - */ - -int -curl_dogetaddrinfo(const char *hostname, - const char *service, - const struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source) -{ -#ifdef USE_LWIPSOCK - int res=lwip_getaddrinfo(hostname, service, hints, result); -#else - int res=(getaddrinfo)(hostname, service, hints, result); -#endif - if(0 == res) - /* success */ - curl_memlog("ADDR %s:%d getaddrinfo() = %p\n", - source, line, (void *)*result); - else - curl_memlog("ADDR %s:%d getaddrinfo() failed\n", - source, line); - return res; -} -#endif /* defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) */ - diff --git a/Externals/curl/lib/curl_addrinfo.h b/Externals/curl/lib/curl_addrinfo.h deleted file mode 100644 index 01f2864785..0000000000 --- a/Externals/curl/lib/curl_addrinfo.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef HEADER_CURL_ADDRINFO_H -#define HEADER_CURL_ADDRINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef __VMS -# include -# include -# include -#endif - - -/* - * Curl_addrinfo is our internal struct definition that we use to allow - * consistent internal handling of this data. We use this even when the - * system provides an addrinfo structure definition. And we use this for - * all sorts of IPv4 and IPV6 builds. - */ - -struct Curl_addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - curl_socklen_t ai_addrlen; /* Follow rfc3493 struct addrinfo */ - char *ai_canonname; - struct sockaddr *ai_addr; - struct Curl_addrinfo *ai_next; -}; -typedef struct Curl_addrinfo Curl_addrinfo; - -void -Curl_freeaddrinfo(Curl_addrinfo *cahead); - -#ifdef HAVE_GETADDRINFO -int -Curl_getaddrinfo_ex(const char *nodename, - const char *servname, - const struct addrinfo *hints, - Curl_addrinfo **result); -#endif - -Curl_addrinfo * -Curl_he2ai(const struct hostent *he, int port); - -Curl_addrinfo * -Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port); - -Curl_addrinfo *Curl_str2addr(char *dotted, int port); - -#ifdef USE_UNIX_SOCKETS -Curl_addrinfo *Curl_unix2addr(const char *path); -#endif - -#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \ - defined(HAVE_FREEADDRINFO) -void -curl_dofreeaddrinfo(struct addrinfo *freethis, - int line, const char *source); -#endif - -#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) -int -curl_dogetaddrinfo(const char *hostname, - const char *service, - const struct addrinfo *hints, - struct addrinfo **result, - int line, const char *source); -#endif - -#endif /* HEADER_CURL_ADDRINFO_H */ diff --git a/Externals/curl/lib/curl_base64.h b/Externals/curl/lib/curl_base64.h deleted file mode 100644 index c262417673..0000000000 --- a/Externals/curl/lib/curl_base64.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HEADER_CURL_BASE64_H -#define HEADER_CURL_BASE64_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -CURLcode Curl_base64_encode(struct SessionHandle *data, - const char *inputbuff, size_t insize, - char **outptr, size_t *outlen); -CURLcode Curl_base64url_encode(struct SessionHandle *data, - const char *inputbuff, size_t insize, - char **outptr, size_t *outlen); - -CURLcode Curl_base64_decode(const char *src, - unsigned char **outptr, size_t *outlen); - -#endif /* HEADER_CURL_BASE64_H */ diff --git a/Externals/curl/lib/curl_config.h.cmake b/Externals/curl/lib/curl_config.h.cmake deleted file mode 100644 index 6b5070a8bc..0000000000 --- a/Externals/curl/lib/curl_config.h.cmake +++ /dev/null @@ -1,985 +0,0 @@ -/* lib/curl_config.h.in. Generated somehow by cmake. */ - -/* when building libcurl itself */ -#cmakedefine BUILDING_LIBCURL 1 - -/* Location of default ca bundle */ -#cmakedefine CURL_CA_BUNDLE ${CURL_CA_BUNDLE} - -/* Location of default ca path */ -#cmakedefine CURL_CA_PATH ${CURL_CA_PATH} - -/* to disable cookies support */ -#cmakedefine CURL_DISABLE_COOKIES 1 - -/* to disable cryptographic authentication */ -#cmakedefine CURL_DISABLE_CRYPTO_AUTH 1 - -/* to disable DICT */ -#cmakedefine CURL_DISABLE_DICT 1 - -/* to disable FILE */ -#cmakedefine CURL_DISABLE_FILE 1 - -/* to disable FTP */ -#cmakedefine CURL_DISABLE_FTP 1 - -/* to disable GOPHER */ -#cmakedefine CURL_DISABLE_GOPHER 1 - -/* to disable IMAP */ -#cmakedefine CURL_DISABLE_IMAP 1 - -/* to disable HTTP */ -#cmakedefine CURL_DISABLE_HTTP 1 - -/* to disable LDAP */ -#cmakedefine CURL_DISABLE_LDAP 1 - -/* to disable LDAPS */ -#cmakedefine CURL_DISABLE_LDAPS 1 - -/* to disable POP3 */ -#cmakedefine CURL_DISABLE_POP3 1 - -/* to disable proxies */ -#cmakedefine CURL_DISABLE_PROXY 1 - -/* to disable RTSP */ -#cmakedefine CURL_DISABLE_RTSP 1 - -/* to disable RTMP */ -#cmakedefine CURL_DISABLE_RTMP 1 - -/* to disable SMB */ -#cmakedefine CURL_DISABLE_SMB 1 - -/* to disable SMTP */ -#cmakedefine CURL_DISABLE_SMTP 1 - -/* to disable TELNET */ -#cmakedefine CURL_DISABLE_TELNET 1 - -/* to disable TFTP */ -#cmakedefine CURL_DISABLE_TFTP 1 - -/* to disable verbose strings */ -#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1 - -/* to make a symbol visible */ -#cmakedefine CURL_EXTERN_SYMBOL 1 -/* Ensure using CURL_EXTERN_SYMBOL is possible */ -#ifndef CURL_EXTERN_SYMBOL -#define CURL_EXTERN_SYMBOL -#endif - -/* Use Windows LDAP implementation */ -#cmakedefine USE_WIN32_LDAP 1 - -/* when not building a shared library */ -#cmakedefine CURL_STATICLIB 1 - -/* Set to explicitly specify we don't want to use thread-safe functions */ -#cmakedefine DISABLED_THREADSAFE 1 - -/* your Entropy Gathering Daemon socket pathname */ -#cmakedefine EGD_SOCKET ${EGD_SOCKET} - -/* Define if you want to enable IPv6 support */ -#cmakedefine ENABLE_IPV6 1 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#cmakedefine GETNAMEINFO_QUAL_ARG1 ${GETNAMEINFO_QUAL_ARG1} - -/* Define to the type of arg 1 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG1 ${GETNAMEINFO_TYPE_ARG1} - -/* Define to the type of arg 2 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG2 ${GETNAMEINFO_TYPE_ARG2} - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG46 ${GETNAMEINFO_TYPE_ARG46} - -/* Define to the type of arg 7 for getnameinfo. */ -#cmakedefine GETNAMEINFO_TYPE_ARG7 ${GETNAMEINFO_TYPE_ARG7} - -/* Specifies the number of arguments to getservbyport_r */ -#cmakedefine GETSERVBYPORT_R_ARGS ${GETSERVBYPORT_R_ARGS} - -/* Specifies the size of the buffer to pass to getservbyport_r */ -#cmakedefine GETSERVBYPORT_R_BUFSIZE ${GETSERVBYPORT_R_BUFSIZE} - -/* Define to 1 if you have the alarm function. */ -#cmakedefine HAVE_ALARM 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ALLOCA_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ARPA_TFTP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ASSERT_H 1 - -/* Define to 1 if you have the `basename' function. */ -#cmakedefine HAVE_BASENAME 1 - -/* Define to 1 if bool is an available type. */ -#cmakedefine HAVE_BOOL_T 1 - -/* Define to 1 if you have the clock_gettime function and monotonic timer. */ -#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC 1 - -/* Define to 1 if you have the `closesocket' function. */ -#cmakedefine HAVE_CLOSESOCKET 1 - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -#cmakedefine HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_CRYPTO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#cmakedefine HAVE_ENGINE_LOAD_BUILTIN_ENGINES 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ERRNO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ERR_H 1 - -/* Define to 1 if you have the fcntl function. */ -#cmakedefine HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_FCNTL_H 1 - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#cmakedefine HAVE_FCNTL_O_NONBLOCK 1 - -/* Define to 1 if you have the fdopen function. */ -#cmakedefine HAVE_FDOPEN 1 - -/* Define to 1 if you have the `fork' function. */ -#cmakedefine HAVE_FORK 1 - -/* Define to 1 if you have the freeaddrinfo function. */ -#cmakedefine HAVE_FREEADDRINFO 1 - -/* Define to 1 if you have the freeifaddrs function. */ -#cmakedefine HAVE_FREEIFADDRS 1 - -/* Define to 1 if you have the ftruncate function. */ -#cmakedefine HAVE_FTRUNCATE 1 - -/* Define to 1 if you have a working getaddrinfo function. */ -#cmakedefine HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `geteuid' function. */ -#cmakedefine HAVE_GETEUID 1 - -/* Define to 1 if you have the gethostbyaddr function. */ -#cmakedefine HAVE_GETHOSTBYADDR 1 - -/* Define to 1 if you have the gethostbyaddr_r function. */ -#cmakedefine HAVE_GETHOSTBYADDR_R 1 - -/* gethostbyaddr_r() takes 5 args */ -#cmakedefine HAVE_GETHOSTBYADDR_R_5 1 - -/* gethostbyaddr_r() takes 7 args */ -#cmakedefine HAVE_GETHOSTBYADDR_R_7 1 - -/* gethostbyaddr_r() takes 8 args */ -#cmakedefine HAVE_GETHOSTBYADDR_R_8 1 - -/* Define to 1 if you have the gethostbyname function. */ -#cmakedefine HAVE_GETHOSTBYNAME 1 - -/* Define to 1 if you have the gethostbyname_r function. */ -#cmakedefine HAVE_GETHOSTBYNAME_R 1 - -/* gethostbyname_r() takes 3 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_3 1 - -/* gethostbyname_r() takes 5 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_5 1 - -/* gethostbyname_r() takes 6 args */ -#cmakedefine HAVE_GETHOSTBYNAME_R_6 1 - -/* Define to 1 if you have the gethostname function. */ -#cmakedefine HAVE_GETHOSTNAME 1 - -/* Define to 1 if you have a working getifaddrs function. */ -#cmakedefine HAVE_GETIFADDRS 1 - -/* Define to 1 if you have the getnameinfo function. */ -#cmakedefine HAVE_GETNAMEINFO 1 - -/* Define to 1 if you have the `getpass_r' function. */ -#cmakedefine HAVE_GETPASS_R 1 - -/* Define to 1 if you have the `getppid' function. */ -#cmakedefine HAVE_GETPPID 1 - -/* Define to 1 if you have the `getprotobyname' function. */ -#cmakedefine HAVE_GETPROTOBYNAME 1 - -/* Define to 1 if you have the `getpwuid' function. */ -#cmakedefine HAVE_GETPWUID 1 - -/* Define to 1 if you have the `getrlimit' function. */ -#cmakedefine HAVE_GETRLIMIT 1 - -/* Define to 1 if you have the getservbyport_r function. */ -#cmakedefine HAVE_GETSERVBYPORT_R 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#cmakedefine HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have a working glibc-style strerror_r function. */ -#cmakedefine HAVE_GLIBC_STRERROR_R 1 - -/* Define to 1 if you have a working gmtime_r function. */ -#cmakedefine HAVE_GMTIME_R 1 - -/* if you have the gssapi libraries */ -#cmakedefine HAVE_GSSAPI 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GSSAPI_GSSAPI_GENERIC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GSSAPI_GSSAPI_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_GSSAPI_GSSAPI_KRB5_H 1 - -/* if you have the GNU gssapi libraries */ -#cmakedefine HAVE_GSSGNU 1 - -/* if you have the Heimdal gssapi libraries */ -#cmakedefine HAVE_GSSHEIMDAL 1 - -/* if you have the MIT gssapi libraries */ -#cmakedefine HAVE_GSSMIT 1 - -/* Define to 1 if you have the `idna_strerror' function. */ -#cmakedefine HAVE_IDNA_STRERROR 1 - -/* Define to 1 if you have the `idn_free' function. */ -#cmakedefine HAVE_IDN_FREE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_IDN_FREE_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_IFADDRS_H 1 - -/* Define to 1 if you have the `inet_addr' function. */ -#cmakedefine HAVE_INET_ADDR 1 - -/* Define to 1 if you have the inet_ntoa_r function. */ -#cmakedefine HAVE_INET_NTOA_R 1 - -/* inet_ntoa_r() takes 2 args */ -#cmakedefine HAVE_INET_NTOA_R_2 1 - -/* inet_ntoa_r() takes 3 args */ -#cmakedefine HAVE_INET_NTOA_R_3 1 - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -#cmakedefine HAVE_INET_NTOP 1 - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -#cmakedefine HAVE_INET_PTON 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the ioctl function. */ -#cmakedefine HAVE_IOCTL 1 - -/* Define to 1 if you have the ioctlsocket function. */ -#cmakedefine HAVE_IOCTLSOCKET 1 - -/* Define to 1 if you have the IoctlSocket camel case function. */ -#cmakedefine HAVE_IOCTLSOCKET_CAMEL 1 - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. - */ -#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1 - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -#cmakedefine HAVE_IOCTLSOCKET_FIONBIO 1 - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#cmakedefine HAVE_IOCTL_FIONBIO 1 - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#cmakedefine HAVE_IOCTL_SIOCGIFADDR 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_IO_H 1 - -/* if you have the Kerberos4 libraries (including -ldes) */ -#cmakedefine HAVE_KRB4 1 - -/* Define to 1 if you have the `krb_get_our_ip_for_realm' function. */ -#cmakedefine HAVE_KRB_GET_OUR_IP_FOR_REALM 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_KRB_H 1 - -/* Define to 1 if you have the lber.h header file. */ -#cmakedefine HAVE_LBER_H 1 - -/* Define to 1 if you have the ldapssl.h header file. */ -#cmakedefine HAVE_LDAPSSL_H 1 - -/* Define to 1 if you have the ldap.h header file. */ -#cmakedefine HAVE_LDAP_H 1 - -/* Use LDAPS implementation */ -#cmakedefine HAVE_LDAP_SSL 1 - -/* Define to 1 if you have the ldap_ssl.h header file. */ -#cmakedefine HAVE_LDAP_SSL_H 1 - -/* Define to 1 if you have the `ldap_url_parse' function. */ -#cmakedefine HAVE_LDAP_URL_PARSE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBGEN_H 1 - -/* Define to 1 if you have the `idn' library (-lidn). */ -#cmakedefine HAVE_LIBIDN 1 - -/* Define to 1 if you have the `resolv' library (-lresolv). */ -#cmakedefine HAVE_LIBRESOLV 1 - -/* Define to 1 if you have the `resolve' library (-lresolve). */ -#cmakedefine HAVE_LIBRESOLVE 1 - -/* Define to 1 if you have the `socket' library (-lsocket). */ -#cmakedefine HAVE_LIBSOCKET 1 - -/* Define to 1 if you have the `ssh2' library (-lssh2). */ -#cmakedefine HAVE_LIBSSH2 1 - -/* Define to 1 if libssh2 provides `libssh2_version'. */ -#cmakedefine HAVE_LIBSSH2_VERSION 1 - -/* Define to 1 if libssh2 provides `libssh2_init'. */ -#cmakedefine HAVE_LIBSSH2_INIT 1 - -/* Define to 1 if libssh2 provides `libssh2_exit'. */ -#cmakedefine HAVE_LIBSSH2_EXIT 1 - -/* Define to 1 if libssh2 provides `libssh2_scp_send64'. */ -#cmakedefine HAVE_LIBSSH2_SCP_SEND64 1 - -/* Define to 1 if libssh2 provides `libssh2_session_handshake'. */ -#cmakedefine HAVE_LIBSSH2_SESSION_HANDSHAKE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIBSSH2_H 1 - -/* Define to 1 if you have the `ssl' library (-lssl). */ -#cmakedefine HAVE_LIBSSL 1 - -/* if zlib is available */ -#cmakedefine HAVE_LIBZ 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LIMITS_H 1 - -/* if your compiler supports LL */ -#cmakedefine HAVE_LL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_LOCALE_H 1 - -/* Define to 1 if you have a working localtime_r function. */ -#cmakedefine HAVE_LOCALTIME_R 1 - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#cmakedefine HAVE_LONGLONG 1 - -/* Define to 1 if you have the malloc.h header file. */ -#cmakedefine HAVE_MALLOC_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMORY_H 1 - -/* Define to 1 if you have the MSG_NOSIGNAL flag. */ -#cmakedefine HAVE_MSG_NOSIGNAL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETDB_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_NET_IF_H 1 - -/* Define to 1 if NI_WITHSCOPEID exists and works. */ -#cmakedefine HAVE_NI_WITHSCOPEID 1 - -/* if you have an old MIT gssapi library, lacking GSS_C_NT_HOSTBASED_SERVICE */ -#cmakedefine HAVE_OLD_GSSMIT 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_CRYPTO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_ENGINE_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_ERR_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_PEM_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_PKCS12_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_RSA_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_SSL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_OPENSSL_X509_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PEM_H 1 - -/* Define to 1 if you have the `perror' function. */ -#cmakedefine HAVE_PERROR 1 - -/* Define to 1 if you have the `pipe' function. */ -#cmakedefine HAVE_PIPE 1 - -/* Define to 1 if you have a working poll function. */ -#cmakedefine HAVE_POLL 1 - -/* If you have a fine poll */ -#cmakedefine HAVE_POLL_FINE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_POLL_H 1 - -/* Define to 1 if you have a working POSIX-style strerror_r function. */ -#cmakedefine HAVE_POSIX_STRERROR_R 1 - -/* Define to 1 if you have the header file */ -#cmakedefine HAVE_PTHREAD_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_PWD_H 1 - -/* Define to 1 if you have the `RAND_egd' function. */ -#cmakedefine HAVE_RAND_EGD 1 - -/* Define to 1 if you have the `RAND_screen' function. */ -#cmakedefine HAVE_RAND_SCREEN 1 - -/* Define to 1 if you have the `RAND_status' function. */ -#cmakedefine HAVE_RAND_STATUS 1 - -/* Define to 1 if you have the recv function. */ -#cmakedefine HAVE_RECV 1 - -/* Define to 1 if you have the recvfrom function. */ -#cmakedefine HAVE_RECVFROM 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_RSA_H 1 - -/* Define to 1 if you have the select function. */ -#cmakedefine HAVE_SELECT 1 - -/* Define to 1 if you have the send function. */ -#cmakedefine HAVE_SEND 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SETJMP_H 1 - -/* Define to 1 if you have the `setlocale' function. */ -#cmakedefine HAVE_SETLOCALE 1 - -/* Define to 1 if you have the `setmode' function. */ -#cmakedefine HAVE_SETMODE 1 - -/* Define to 1 if you have the `setrlimit' function. */ -#cmakedefine HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the setsockopt function. */ -#cmakedefine HAVE_SETSOCKOPT 1 - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SGTTY_H 1 - -/* Define to 1 if you have the sigaction function. */ -#cmakedefine HAVE_SIGACTION 1 - -/* Define to 1 if you have the siginterrupt function. */ -#cmakedefine HAVE_SIGINTERRUPT 1 - -/* Define to 1 if you have the signal function. */ -#cmakedefine HAVE_SIGNAL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SIGNAL_H 1 - -/* Define to 1 if you have the sigsetjmp function or macro. */ -#cmakedefine HAVE_SIGSETJMP 1 - -/* Define to 1 if sig_atomic_t is an available typedef. */ -#cmakedefine HAVE_SIG_ATOMIC_T 1 - -/* Define to 1 if sig_atomic_t is already defined as volatile. */ -#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE 1 - -/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ -#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1 - -/* Define to 1 if you have the `socket' function. */ -#cmakedefine HAVE_SOCKET 1 - -/* Define to 1 if you have the `SSL_get_shutdown' function. */ -#cmakedefine HAVE_SSL_GET_SHUTDOWN 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SSL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDLIB_H 1 - -/* Define to 1 if you have the strcasecmp function. */ -#cmakedefine HAVE_STRCASECMP 1 - -/* Define to 1 if you have the strcasestr function. */ -#cmakedefine HAVE_STRCASESTR 1 - -/* Define to 1 if you have the strcmpi function. */ -#cmakedefine HAVE_STRCMPI 1 - -/* Define to 1 if you have the strdup function. */ -#cmakedefine HAVE_STRDUP 1 - -/* Define to 1 if you have the strerror_r function. */ -#cmakedefine HAVE_STRERROR_R 1 - -/* Define to 1 if you have the stricmp function. */ -#cmakedefine HAVE_STRICMP 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRING_H 1 - -/* Define to 1 if you have the strlcat function. */ -#cmakedefine HAVE_STRLCAT 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#cmakedefine HAVE_STRLCPY 1 - -/* Define to 1 if you have the strncasecmp function. */ -#cmakedefine HAVE_STRNCASECMP 1 - -/* Define to 1 if you have the strncmpi function. */ -#cmakedefine HAVE_STRNCMPI 1 - -/* Define to 1 if you have the strnicmp function. */ -#cmakedefine HAVE_STRNICMP 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STROPTS_H 1 - -/* Define to 1 if you have the strstr function. */ -#cmakedefine HAVE_STRSTR 1 - -/* Define to 1 if you have the strtok_r function. */ -#cmakedefine HAVE_STRTOK_R 1 - -/* Define to 1 if you have the strtoll function. */ -#cmakedefine HAVE_STRTOLL 1 - -/* if struct sockaddr_storage is defined */ -#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if you have the timeval struct. */ -#cmakedefine HAVE_STRUCT_TIMEVAL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_FILIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_POLL_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_SOCKIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_UTIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TERMIOS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TERMIO_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_TLD_H 1 - -/* Define to 1 if you have the `tld_strerror' function. */ -#cmakedefine HAVE_TLD_STRERROR 1 - -/* Define to 1 if you have the `uname' function. */ -#cmakedefine HAVE_UNAME 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#cmakedefine HAVE_UTIME 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UTIME_H 1 - -/* Define to 1 if compiler supports C99 variadic macro style. */ -#cmakedefine HAVE_VARIADIC_MACROS_C99 1 - -/* Define to 1 if compiler supports old gcc variadic macro style. */ -#cmakedefine HAVE_VARIADIC_MACROS_GCC 1 - -/* Define to 1 if you have the winber.h header file. */ -#cmakedefine HAVE_WINBER_H 1 - -/* Define to 1 if you have the windows.h header file. */ -#cmakedefine HAVE_WINDOWS_H 1 - -/* Define to 1 if you have the winldap.h header file. */ -#cmakedefine HAVE_WINLDAP_H 1 - -/* Define to 1 if you have the winsock2.h header file. */ -#cmakedefine HAVE_WINSOCK2_H 1 - -/* Define to 1 if you have the winsock.h header file. */ -#cmakedefine HAVE_WINSOCK_H 1 - -/* Define this symbol if your OS supports changing the contents of argv */ -#cmakedefine HAVE_WRITABLE_ARGV 1 - -/* Define to 1 if you have the writev function. */ -#cmakedefine HAVE_WRITEV 1 - -/* Define to 1 if you have the ws2tcpip.h header file. */ -#cmakedefine HAVE_WS2TCPIP_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_X509_H 1 - -/* Define if you have the header file. */ -#cmakedefine HAVE_PROCESS_H 1 - -/* if you have the zlib.h header file */ -#cmakedefine HAVE_ZLIB_H 1 - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#cmakedefine LT_OBJDIR ${LT_OBJDIR} - -/* If you lack a fine basename() prototype */ -#cmakedefine NEED_BASENAME_PROTO 1 - -/* Define to 1 if you need the lber.h header file even with ldap.h */ -#cmakedefine NEED_LBER_H 1 - -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -#cmakedefine NEED_MALLOC_H 1 - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -#cmakedefine NEED_REENTRANT 1 - -/* cpu-machine-OS */ -#cmakedefine OS ${OS} - -/* Name of package */ -#cmakedefine PACKAGE ${PACKAGE} - -/* Define to the address where bug reports for this package should be sent. */ -#cmakedefine PACKAGE_BUGREPORT ${PACKAGE_BUGREPORT} - -/* Define to the full name of this package. */ -#cmakedefine PACKAGE_NAME ${PACKAGE_NAME} - -/* Define to the full name and version of this package. */ -#cmakedefine PACKAGE_STRING ${PACKAGE_STRING} - -/* Define to the one symbol short name of this package. */ -#cmakedefine PACKAGE_TARNAME ${PACKAGE_TARNAME} - -/* Define to the version of this package. */ -#cmakedefine PACKAGE_VERSION ${PACKAGE_VERSION} - -/* a suitable file to read random data from */ -#cmakedefine RANDOM_FILE "${RANDOM_FILE}" - -/* Define to the type of arg 1 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG1 ${RECVFROM_TYPE_ARG1} - -/* Define to the type pointed by arg 2 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG2 ${RECVFROM_TYPE_ARG2} - -/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ -#cmakedefine RECVFROM_TYPE_ARG2_IS_VOID 1 - -/* Define to the type of arg 3 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG3 ${RECVFROM_TYPE_ARG3} - -/* Define to the type of arg 4 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG4 ${RECVFROM_TYPE_ARG4} - -/* Define to the type pointed by arg 5 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG5 ${RECVFROM_TYPE_ARG5} - -/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ -#cmakedefine RECVFROM_TYPE_ARG5_IS_VOID 1 - -/* Define to the type pointed by arg 6 for recvfrom. */ -#cmakedefine RECVFROM_TYPE_ARG6 ${RECVFROM_TYPE_ARG6} - -/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ -#cmakedefine RECVFROM_TYPE_ARG6_IS_VOID 1 - -/* Define to the function return type for recvfrom. */ -#cmakedefine RECVFROM_TYPE_RETV ${RECVFROM_TYPE_RETV} - -/* Define to the type of arg 1 for recv. */ -#cmakedefine RECV_TYPE_ARG1 ${RECV_TYPE_ARG1} - -/* Define to the type of arg 2 for recv. */ -#cmakedefine RECV_TYPE_ARG2 ${RECV_TYPE_ARG2} - -/* Define to the type of arg 3 for recv. */ -#cmakedefine RECV_TYPE_ARG3 ${RECV_TYPE_ARG3} - -/* Define to the type of arg 4 for recv. */ -#cmakedefine RECV_TYPE_ARG4 ${RECV_TYPE_ARG4} - -/* Define to the function return type for recv. */ -#cmakedefine RECV_TYPE_RETV ${RECV_TYPE_RETV} - -/* Define as the return type of signal handlers (`int' or `void'). */ -#cmakedefine RETSIGTYPE ${RETSIGTYPE} - -/* Define to the type qualifier of arg 5 for select. */ -#cmakedefine SELECT_QUAL_ARG5 ${SELECT_QUAL_ARG5} - -/* Define to the type of arg 1 for select. */ -#cmakedefine SELECT_TYPE_ARG1 ${SELECT_TYPE_ARG1} - -/* Define to the type of args 2, 3 and 4 for select. */ -#cmakedefine SELECT_TYPE_ARG234 ${SELECT_TYPE_ARG234} - -/* Define to the type of arg 5 for select. */ -#cmakedefine SELECT_TYPE_ARG5 ${SELECT_TYPE_ARG5} - -/* Define to the function return type for select. */ -#cmakedefine SELECT_TYPE_RETV ${SELECT_TYPE_RETV} - -/* Define to the type qualifier of arg 2 for send. */ -#cmakedefine SEND_QUAL_ARG2 ${SEND_QUAL_ARG2} - -/* Define to the type of arg 1 for send. */ -#cmakedefine SEND_TYPE_ARG1 ${SEND_TYPE_ARG1} - -/* Define to the type of arg 2 for send. */ -#cmakedefine SEND_TYPE_ARG2 ${SEND_TYPE_ARG2} - -/* Define to the type of arg 3 for send. */ -#cmakedefine SEND_TYPE_ARG3 ${SEND_TYPE_ARG3} - -/* Define to the type of arg 4 for send. */ -#cmakedefine SEND_TYPE_ARG4 ${SEND_TYPE_ARG4} - -/* Define to the function return type for send. */ -#cmakedefine SEND_TYPE_RETV ${SEND_TYPE_RETV} - -/* The size of `int', as computed by sizeof. */ -#cmakedefine SIZEOF_INT ${SIZEOF_INT} - -/* The size of `short', as computed by sizeof. */ -#cmakedefine SIZEOF_SHORT ${SIZEOF_SHORT} - -/* The size of `long', as computed by sizeof. */ -#cmakedefine SIZEOF_LONG ${SIZEOF_LONG} - -/* The size of `off_t', as computed by sizeof. */ -#cmakedefine SIZEOF_OFF_T ${SIZEOF_OFF_T} - -/* The size of `size_t', as computed by sizeof. */ -#cmakedefine SIZEOF_SIZE_T ${SIZEOF_SIZE_T} - -/* The size of `time_t', as computed by sizeof. */ -#cmakedefine SIZEOF_TIME_T ${SIZEOF_TIME_T} - -/* The size of `void*', as computed by sizeof. */ -#cmakedefine SIZEOF_VOIDP ${SIZEOF_VOIDP} - -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine STDC_HEADERS 1 - -/* Define to the type of arg 3 for strerror_r. */ -#cmakedefine STRERROR_R_TYPE_ARG3 ${STRERROR_R_TYPE_ARG3} - -/* Define to 1 if you can safely include both and . */ -#cmakedefine TIME_WITH_SYS_TIME 1 - -/* Define if you want to enable c-ares support */ -#cmakedefine USE_ARES 1 - -/* Define if you want to enable POSIX threaded DNS lookup */ -#cmakedefine USE_THREADS_POSIX 1 - -/* Define to disable non-blocking sockets. */ -#cmakedefine USE_BLOCKING_SOCKETS 1 - -/* if GnuTLS is enabled */ -#cmakedefine USE_GNUTLS 1 - -/* if PolarSSL is enabled */ -#cmakedefine USE_POLARSSL 1 - -/* if libSSH2 is in use */ -#cmakedefine USE_LIBSSH2 1 - -/* If you want to build curl with the built-in manual */ -#cmakedefine USE_MANUAL 1 - -/* if NSS is enabled */ -#cmakedefine USE_NSS 1 - -/* if you want to use OpenLDAP code instead of legacy ldap implementation */ -#cmakedefine USE_OPENLDAP 1 - -/* if OpenSSL is in use */ -#cmakedefine USE_OPENSSL 1 - -/* if Unix domain sockets are enabled */ -#cmakedefine USE_UNIX_SOCKETS - -/* Define to 1 if you are building a Windows target without large file - support. */ -#cmakedefine USE_WIN32_LARGE_FILES 1 - -/* to enable SSPI support */ -#cmakedefine USE_WINDOWS_SSPI 1 - -/* to enable Windows SSL */ -#cmakedefine USE_SCHANNEL 1 - -/* Define to 1 if using yaSSL in OpenSSL compatibility mode. */ -#cmakedefine USE_YASSLEMUL 1 - -/* Version number of package */ -#cmakedefine VERSION ${VERSION} - -/* Define to avoid automatic inclusion of winsock.h */ -#cmakedefine WIN32_LEAN_AND_MEAN 1 - -/* Define to 1 if OS is AIX. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS} - -/* Define for large files, on AIX-style hosts. */ -#cmakedefine _LARGE_FILES ${_LARGE_FILES} - -/* define this if you need it to compile thread-safe code */ -#cmakedefine _THREAD_SAFE ${_THREAD_SAFE} - -/* Define to empty if `const' does not conform to ANSI C. */ -#cmakedefine const ${const} - -/* Type to use in place of in_addr_t when system does not provide it. */ -#cmakedefine in_addr_t ${in_addr_t} - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `unsigned int' if does not define. */ -#cmakedefine size_t ${size_t} - -/* the signed version of size_t */ -#cmakedefine ssize_t ${ssize_t} diff --git a/Externals/curl/lib/curl_config.h.in b/Externals/curl/lib/curl_config.h.in deleted file mode 100644 index ebdf680b28..0000000000 --- a/Externals/curl/lib/curl_config.h.in +++ /dev/null @@ -1,1048 +0,0 @@ -/* lib/curl_config.h.in. Generated from configure.ac by autoheader. */ - -/* Location of default ca bundle */ -#undef CURL_CA_BUNDLE - -/* define "1" to use built in CA store of SSL library */ -#undef CURL_CA_FALLBACK - -/* Location of default ca path */ -#undef CURL_CA_PATH - -/* to disable cookies support */ -#undef CURL_DISABLE_COOKIES - -/* to disable cryptographic authentication */ -#undef CURL_DISABLE_CRYPTO_AUTH - -/* to disable DICT */ -#undef CURL_DISABLE_DICT - -/* to disable FILE */ -#undef CURL_DISABLE_FILE - -/* to disable FTP */ -#undef CURL_DISABLE_FTP - -/* to disable Gopher */ -#undef CURL_DISABLE_GOPHER - -/* to disable HTTP */ -#undef CURL_DISABLE_HTTP - -/* to disable IMAP */ -#undef CURL_DISABLE_IMAP - -/* to disable LDAP */ -#undef CURL_DISABLE_LDAP - -/* to disable LDAPS */ -#undef CURL_DISABLE_LDAPS - -/* to disable --libcurl C code generation option */ -#undef CURL_DISABLE_LIBCURL_OPTION - -/* to disable POP3 */ -#undef CURL_DISABLE_POP3 - -/* to disable proxies */ -#undef CURL_DISABLE_PROXY - -/* to disable RTSP */ -#undef CURL_DISABLE_RTSP - -/* to disable SMB/CIFS */ -#undef CURL_DISABLE_SMB - -/* to disable SMTP */ -#undef CURL_DISABLE_SMTP - -/* to disable TELNET */ -#undef CURL_DISABLE_TELNET - -/* to disable TFTP */ -#undef CURL_DISABLE_TFTP - -/* to disable TLS-SRP authentication */ -#undef CURL_DISABLE_TLS_SRP - -/* to disable verbose strings */ -#undef CURL_DISABLE_VERBOSE_STRINGS - -/* Definition to make a library symbol externally visible. */ -#undef CURL_EXTERN_SYMBOL - -/* your Entropy Gathering Daemon socket pathname */ -#undef EGD_SOCKET - -/* Define if you want to enable IPv6 support */ -#undef ENABLE_IPV6 - -/* Define to the type of arg 2 for gethostname. */ -#undef GETHOSTNAME_TYPE_ARG2 - -/* Define to the type qualifier of arg 1 for getnameinfo. */ -#undef GETNAMEINFO_QUAL_ARG1 - -/* Define to the type of arg 1 for getnameinfo. */ -#undef GETNAMEINFO_TYPE_ARG1 - -/* Define to the type of arg 2 for getnameinfo. */ -#undef GETNAMEINFO_TYPE_ARG2 - -/* Define to the type of args 4 and 6 for getnameinfo. */ -#undef GETNAMEINFO_TYPE_ARG46 - -/* Define to the type of arg 7 for getnameinfo. */ -#undef GETNAMEINFO_TYPE_ARG7 - -/* Specifies the number of arguments to getservbyport_r */ -#undef GETSERVBYPORT_R_ARGS - -/* Specifies the size of the buffer to pass to getservbyport_r */ -#undef GETSERVBYPORT_R_BUFSIZE - -/* Define to 1 if you have the alarm function. */ -#undef HAVE_ALARM - -/* Define to 1 if you have the header file. */ -#undef HAVE_ALLOCA_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ARPA_INET_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ARPA_TFTP_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ASSERT_H - -/* Define to 1 if you have the basename function. */ -#undef HAVE_BASENAME - -/* Define to 1 if bool is an available type. */ -#undef HAVE_BOOL_T - -/* Define to 1 if using BoringSSL. */ -#undef HAVE_BORINGSSL - -/* Define to 1 if you have the clock_gettime function and monotonic timer. */ -#undef HAVE_CLOCK_GETTIME_MONOTONIC - -/* Define to 1 if you have the closesocket function. */ -#undef HAVE_CLOSESOCKET - -/* Define to 1 if you have the CloseSocket camel case function. */ -#undef HAVE_CLOSESOCKET_CAMEL - -/* Define to 1 if you have the connect function. */ -#undef HAVE_CONNECT - -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ -#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA - -/* Define to 1 if you have the header file. */ -#undef HAVE_CRYPTO_H - -/* Define to 1 if you have the `CyaSSL_CTX_UseSupportedCurve' function. */ -#undef HAVE_CYASSL_CTX_USESUPPORTEDCURVE - -/* Define to 1 if you have the header file. */ -#undef HAVE_CYASSL_ERROR_SSL_H - -/* Define to 1 if you have the `CyaSSL_get_peer_certificate' function. */ -#undef HAVE_CYASSL_GET_PEER_CERTIFICATE - -/* Define to 1 if you have the header file. */ -#undef HAVE_CYASSL_OPTIONS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the `ENGINE_cleanup' function. */ -#undef HAVE_ENGINE_CLEANUP - -/* Define to 1 if you have the `ENGINE_load_builtin_engines' function. */ -#undef HAVE_ENGINE_LOAD_BUILTIN_ENGINES - -/* Define to 1 if you have the header file. */ -#undef HAVE_ERRNO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_ERR_H - -/* Define to 1 if you have the fcntl function. */ -#undef HAVE_FCNTL - -/* Define to 1 if you have the header file. */ -#undef HAVE_FCNTL_H - -/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ -#undef HAVE_FCNTL_O_NONBLOCK - -/* Define to 1 if you have the fdopen function. */ -#undef HAVE_FDOPEN - -/* Define to 1 if you have the `fork' function. */ -#undef HAVE_FORK - -/* Define to 1 if you have the freeaddrinfo function. */ -#undef HAVE_FREEADDRINFO - -/* Define to 1 if you have the freeifaddrs function. */ -#undef HAVE_FREEIFADDRS - -/* Define to 1 if you have the fsetxattr function. */ -#undef HAVE_FSETXATTR - -/* fsetxattr() takes 5 args */ -#undef HAVE_FSETXATTR_5 - -/* fsetxattr() takes 6 args */ -#undef HAVE_FSETXATTR_6 - -/* Define to 1 if you have the ftruncate function. */ -#undef HAVE_FTRUNCATE - -/* Define to 1 if you have the gai_strerror function. */ -#undef HAVE_GAI_STRERROR - -/* Define to 1 if you have a working getaddrinfo function. */ -#undef HAVE_GETADDRINFO - -/* Define to 1 if the getaddrinfo function is threadsafe. */ -#undef HAVE_GETADDRINFO_THREADSAFE - -/* Define to 1 if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the gethostbyaddr function. */ -#undef HAVE_GETHOSTBYADDR - -/* Define to 1 if you have the gethostbyaddr_r function. */ -#undef HAVE_GETHOSTBYADDR_R - -/* gethostbyaddr_r() takes 5 args */ -#undef HAVE_GETHOSTBYADDR_R_5 - -/* gethostbyaddr_r() takes 7 args */ -#undef HAVE_GETHOSTBYADDR_R_7 - -/* gethostbyaddr_r() takes 8 args */ -#undef HAVE_GETHOSTBYADDR_R_8 - -/* Define to 1 if you have the gethostbyname function. */ -#undef HAVE_GETHOSTBYNAME - -/* Define to 1 if you have the gethostbyname_r function. */ -#undef HAVE_GETHOSTBYNAME_R - -/* gethostbyname_r() takes 3 args */ -#undef HAVE_GETHOSTBYNAME_R_3 - -/* gethostbyname_r() takes 5 args */ -#undef HAVE_GETHOSTBYNAME_R_5 - -/* gethostbyname_r() takes 6 args */ -#undef HAVE_GETHOSTBYNAME_R_6 - -/* Define to 1 if you have the gethostname function. */ -#undef HAVE_GETHOSTNAME - -/* Define to 1 if you have a working getifaddrs function. */ -#undef HAVE_GETIFADDRS - -/* Define to 1 if you have the getnameinfo function. */ -#undef HAVE_GETNAMEINFO - -/* Define to 1 if you have the `getpass_r' function. */ -#undef HAVE_GETPASS_R - -/* Define to 1 if you have the `getppid' function. */ -#undef HAVE_GETPPID - -/* Define to 1 if you have the `getprotobyname' function. */ -#undef HAVE_GETPROTOBYNAME - -/* Define to 1 if you have the `getpwuid' function. */ -#undef HAVE_GETPWUID - -/* Define to 1 if you have the `getpwuid_r' function. */ -#undef HAVE_GETPWUID_R - -/* Define to 1 if you have the `getrlimit' function. */ -#undef HAVE_GETRLIMIT - -/* Define to 1 if you have the getservbyport_r function. */ -#undef HAVE_GETSERVBYPORT_R - -/* Define to 1 if you have the `gettimeofday' function. */ -#undef HAVE_GETTIMEOFDAY - -/* Define to 1 if you have a working glibc-style strerror_r function. */ -#undef HAVE_GLIBC_STRERROR_R - -/* Define to 1 if you have a working gmtime_r function. */ -#undef HAVE_GMTIME_R - -/* Define to 1 if you have the `gnutls_certificate_set_x509_key_file2' - function. */ -#undef HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 - -/* if you have the function gnutls_srp_verifier */ -#undef HAVE_GNUTLS_SRP - -/* if you have GSS-API libraries */ -#undef HAVE_GSSAPI - -/* Define to 1 if you have the header file. */ -#undef HAVE_GSSAPI_GSSAPI_GENERIC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_GSSAPI_GSSAPI_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_GSSAPI_GSSAPI_KRB5_H - -/* if you have GNU GSS */ -#undef HAVE_GSSGNU - -/* if you have Heimdal */ -#undef HAVE_GSSHEIMDAL - -/* if you have MIT Kerberos */ -#undef HAVE_GSSMIT - -/* Define to 1 if you have the `idna_strerror' function. */ -#undef HAVE_IDNA_STRERROR - -/* Define to 1 if you have the `idn_free' function. */ -#undef HAVE_IDN_FREE - -/* Define to 1 if you have the header file. */ -#undef HAVE_IDN_FREE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_IFADDRS_H - -/* Define to 1 if you have the `if_nametoindex' function. */ -#undef HAVE_IF_NAMETOINDEX - -/* Define to 1 if you have the `inet_addr' function. */ -#undef HAVE_INET_ADDR - -/* Define to 1 if you have the inet_ntoa_r function. */ -#undef HAVE_INET_NTOA_R - -/* inet_ntoa_r() takes 2 args */ -#undef HAVE_INET_NTOA_R_2 - -/* inet_ntoa_r() takes 3 args */ -#undef HAVE_INET_NTOA_R_3 - -/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ -#undef HAVE_INET_NTOP - -/* Define to 1 if you have a IPv6 capable working inet_pton function. */ -#undef HAVE_INET_PTON - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the ioctl function. */ -#undef HAVE_IOCTL - -/* Define to 1 if you have the ioctlsocket function. */ -#undef HAVE_IOCTLSOCKET - -/* Define to 1 if you have the IoctlSocket camel case function. */ -#undef HAVE_IOCTLSOCKET_CAMEL - -/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. - */ -#undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO - -/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ -#undef HAVE_IOCTLSOCKET_FIONBIO - -/* Define to 1 if you have a working ioctl FIONBIO function. */ -#undef HAVE_IOCTL_FIONBIO - -/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ -#undef HAVE_IOCTL_SIOCGIFADDR - -/* Define to 1 if you have the header file. */ -#undef HAVE_IO_H - -/* Define to 1 if you have the lber.h header file. */ -#undef HAVE_LBER_H - -/* Define to 1 if you have the ldapssl.h header file. */ -#undef HAVE_LDAPSSL_H - -/* Define to 1 if you have the ldap.h header file. */ -#undef HAVE_LDAP_H - -/* Define to 1 if you have the `ldap_init_fd' function. */ -#undef HAVE_LDAP_INIT_FD - -/* Use LDAPS implementation */ -#undef HAVE_LDAP_SSL - -/* Define to 1 if you have the ldap_ssl.h header file. */ -#undef HAVE_LDAP_SSL_H - -/* Define to 1 if you have the `ldap_url_parse' function. */ -#undef HAVE_LDAP_URL_PARSE - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBGEN_H - -/* Define to 1 if you have the `idn' library (-lidn). */ -#undef HAVE_LIBIDN - -/* Define to 1 if using libressl. */ -#undef HAVE_LIBRESSL - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBRTMP_RTMP_H - -/* Define to 1 if you have the `ssh2' library (-lssh2). */ -#undef HAVE_LIBSSH2 - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBSSH2_H - -/* Define to 1 if you have the `ssl' library (-lssl). */ -#undef HAVE_LIBSSL - -/* if zlib is available */ -#undef HAVE_LIBZ - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* if your compiler supports LL */ -#undef HAVE_LL - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALE_H - -/* Define to 1 if you have a working localtime_r function. */ -#undef HAVE_LOCALTIME_R - -/* Define to 1 if the compiler supports the 'long long' data type. */ -#undef HAVE_LONGLONG - -/* Define to 1 if you have the malloc.h header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the memory.h header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the memrchr function or macro. */ -#undef HAVE_MEMRCHR - -/* Define to 1 if you have the MSG_NOSIGNAL flag. */ -#undef HAVE_MSG_NOSIGNAL - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETDB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_IN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_TCP_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NET_IF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NGHTTP2_NGHTTP2_H - -/* Define to 1 if NI_WITHSCOPEID exists and works. */ -#undef HAVE_NI_WITHSCOPEID - -/* if you have an old MIT Kerberos version, lacking GSS_C_NT_HOSTBASED_SERVICE - */ -#undef HAVE_OLD_GSSMIT - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_CRYPTO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_ENGINE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_ERR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_PEM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_PKCS12_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_RSA_H - -/* if you have the function SRP_Calc_client_key */ -#undef HAVE_OPENSSL_SRP - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_SSL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_OPENSSL_X509_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_PEM_H - -/* Define to 1 if you have the `perror' function. */ -#undef HAVE_PERROR - -/* Define to 1 if you have the `pipe' function. */ -#undef HAVE_PIPE - -/* Define to 1 if you have a working poll function. */ -#undef HAVE_POLL - -/* If you have a fine poll */ -#undef HAVE_POLL_FINE - -/* Define to 1 if you have the header file. */ -#undef HAVE_POLL_H - -/* Define to 1 if you have a working POSIX-style strerror_r function. */ -#undef HAVE_POSIX_STRERROR_R - -/* if you have */ -#undef HAVE_PTHREAD_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_PWD_H - -/* Define to 1 if you have the `RAND_egd' function. */ -#undef HAVE_RAND_EGD - -/* Define to 1 if you have the `RAND_screen' function. */ -#undef HAVE_RAND_SCREEN - -/* Define to 1 if you have the `RAND_status' function. */ -#undef HAVE_RAND_STATUS - -/* Define to 1 if you have the recv function. */ -#undef HAVE_RECV - -/* Define to 1 if you have the header file. */ -#undef HAVE_RSA_H - -/* Define to 1 if you have the select function. */ -#undef HAVE_SELECT - -/* Define to 1 if you have the send function. */ -#undef HAVE_SEND - -/* Define to 1 if you have the header file. */ -#undef HAVE_SETJMP_H - -/* Define to 1 if you have the `setlocale' function. */ -#undef HAVE_SETLOCALE - -/* Define to 1 if you have the `setmode' function. */ -#undef HAVE_SETMODE - -/* Define to 1 if you have the `setrlimit' function. */ -#undef HAVE_SETRLIMIT - -/* Define to 1 if you have the setsockopt function. */ -#undef HAVE_SETSOCKOPT - -/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ -#undef HAVE_SETSOCKOPT_SO_NONBLOCK - -/* Define to 1 if you have the header file. */ -#undef HAVE_SGTTY_H - -/* Define to 1 if you have the sigaction function. */ -#undef HAVE_SIGACTION - -/* Define to 1 if you have the siginterrupt function. */ -#undef HAVE_SIGINTERRUPT - -/* Define to 1 if you have the signal function. */ -#undef HAVE_SIGNAL - -/* Define to 1 if you have the header file. */ -#undef HAVE_SIGNAL_H - -/* Define to 1 if you have the sigsetjmp function or macro. */ -#undef HAVE_SIGSETJMP - -/* Define to 1 if sig_atomic_t is an available typedef. */ -#undef HAVE_SIG_ATOMIC_T - -/* Define to 1 if sig_atomic_t is already defined as volatile. */ -#undef HAVE_SIG_ATOMIC_T_VOLATILE - -/* Define to 1 if struct sockaddr_in6 has the sin6_scope_id member */ -#undef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - -/* Define to 1 if you have the socket function. */ -#undef HAVE_SOCKET - -/* Define to 1 if you have the socketpair function. */ -#undef HAVE_SOCKETPAIR - -/* Define to 1 if you have the header file. */ -#undef HAVE_SOCKET_H - -/* Define to 1 if you have the `SSLv2_client_method' function. */ -#undef HAVE_SSLV2_CLIENT_METHOD - -/* Define to 1 if you have the `SSL_get_shutdown' function. */ -#undef HAVE_SSL_GET_SHUTDOWN - -/* Define to 1 if you have the header file. */ -#undef HAVE_SSL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDBOOL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the strcasecmp function. */ -#undef HAVE_STRCASECMP - -/* Define to 1 if you have the strcmpi function. */ -#undef HAVE_STRCMPI - -/* Define to 1 if you have the strdup function. */ -#undef HAVE_STRDUP - -/* Define to 1 if you have the strerror_r function. */ -#undef HAVE_STRERROR_R - -/* Define to 1 if you have the stricmp function. */ -#undef HAVE_STRICMP - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the strncasecmp function. */ -#undef HAVE_STRNCASECMP - -/* Define to 1 if you have the strncmpi function. */ -#undef HAVE_STRNCMPI - -/* Define to 1 if you have the strnicmp function. */ -#undef HAVE_STRNICMP - -/* Define to 1 if you have the header file. */ -#undef HAVE_STROPTS_H - -/* Define to 1 if you have the strstr function. */ -#undef HAVE_STRSTR - -/* Define to 1 if you have the strtok_r function. */ -#undef HAVE_STRTOK_R - -/* Define to 1 if you have the strtoll function. */ -#undef HAVE_STRTOLL - -/* if struct sockaddr_storage is defined */ -#undef HAVE_STRUCT_SOCKADDR_STORAGE - -/* Define to 1 if you have the timeval struct. */ -#undef HAVE_STRUCT_TIMEVAL - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_FILIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_IOCTL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_POLL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_RESOURCE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOCKIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_UTIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_WAIT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_XATTR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_TERMIOS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_TERMIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_TIME_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_TLD_H - -/* Define to 1 if you have the `tld_strerror' function. */ -#undef HAVE_TLD_STRERROR - -/* Define to 1 if you have the `uname' function. */ -#undef HAVE_UNAME - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define to 1 if you have the `utime' function. */ -#undef HAVE_UTIME - -/* Define to 1 if you have the header file. */ -#undef HAVE_UTIME_H - -/* Define to 1 if compiler supports C99 variadic macro style. */ -#undef HAVE_VARIADIC_MACROS_C99 - -/* Define to 1 if compiler supports old gcc variadic macro style. */ -#undef HAVE_VARIADIC_MACROS_GCC - -/* Define to 1 if you have the winber.h header file. */ -#undef HAVE_WINBER_H - -/* Define to 1 if you have the windows.h header file. */ -#undef HAVE_WINDOWS_H - -/* Define to 1 if you have the winldap.h header file. */ -#undef HAVE_WINLDAP_H - -/* Define to 1 if you have the winsock2.h header file. */ -#undef HAVE_WINSOCK2_H - -/* Define to 1 if you have the winsock.h header file. */ -#undef HAVE_WINSOCK_H - -/* Define to 1 if you have the `wolfSSLv3_client_method' function. */ -#undef HAVE_WOLFSSLV3_CLIENT_METHOD - -/* Define to 1 if you have the `wolfSSL_CTX_UseSupportedCurve' function. */ -#undef HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE - -/* Define to 1 if you have the `wolfSSL_get_peer_certificate' function. */ -#undef HAVE_WOLFSSL_GET_PEER_CERTIFICATE - -/* Define to 1 if you have the `wolfSSL_UseALPN' function. */ -#undef HAVE_WOLFSSL_USEALPN - -/* Define this symbol if your OS supports changing the contents of argv */ -#undef HAVE_WRITABLE_ARGV - -/* Define to 1 if you have the writev function. */ -#undef HAVE_WRITEV - -/* Define to 1 if you have the ws2tcpip.h header file. */ -#undef HAVE_WS2TCPIP_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_X509_H - -/* if you have the zlib.h header file */ -#undef HAVE_ZLIB_H - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#undef LT_OBJDIR - -/* Define to 1 if you need the lber.h header file even with ldap.h */ -#undef NEED_LBER_H - -/* Define to 1 if you need the malloc.h header file even with stdlib.h */ -#undef NEED_MALLOC_H - -/* Define to 1 if you need the memory.h header file even with stdlib.h */ -#undef NEED_MEMORY_H - -/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ -#undef NEED_REENTRANT - -/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */ -#undef NEED_THREAD_SAFE - -/* Define to enable NTLM delegation to winbind's ntlm_auth helper. */ -#undef NTLM_WB_ENABLED - -/* Define absolute filename for winbind's ntlm_auth helper. */ -#undef NTLM_WB_FILE - -/* cpu-machine-OS */ -#undef OS - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the home page for this package. */ -#undef PACKAGE_URL - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* a suitable file to read random data from */ -#undef RANDOM_FILE - -/* Define to the type of arg 1 for recv. */ -#undef RECV_TYPE_ARG1 - -/* Define to the type of arg 2 for recv. */ -#undef RECV_TYPE_ARG2 - -/* Define to the type of arg 3 for recv. */ -#undef RECV_TYPE_ARG3 - -/* Define to the type of arg 4 for recv. */ -#undef RECV_TYPE_ARG4 - -/* Define to the function return type for recv. */ -#undef RECV_TYPE_RETV - -/* Define as the return type of signal handlers (`int' or `void'). */ -#undef RETSIGTYPE - -/* Define to the type qualifier of arg 5 for select. */ -#undef SELECT_QUAL_ARG5 - -/* Define to the type of arg 1 for select. */ -#undef SELECT_TYPE_ARG1 - -/* Define to the type of args 2, 3 and 4 for select. */ -#undef SELECT_TYPE_ARG234 - -/* Define to the type of arg 5 for select. */ -#undef SELECT_TYPE_ARG5 - -/* Define to the function return type for select. */ -#undef SELECT_TYPE_RETV - -/* Define to the type qualifier of arg 2 for send. */ -#undef SEND_QUAL_ARG2 - -/* Define to the type of arg 1 for send. */ -#undef SEND_TYPE_ARG1 - -/* Define to the type of arg 2 for send. */ -#undef SEND_TYPE_ARG2 - -/* Define to the type of arg 3 for send. */ -#undef SEND_TYPE_ARG3 - -/* Define to the type of arg 4 for send. */ -#undef SEND_TYPE_ARG4 - -/* Define to the function return type for send. */ -#undef SEND_TYPE_RETV - -/* The size of `int', as computed by sizeof. */ -#undef SIZEOF_INT - -/* The size of `long', as computed by sizeof. */ -#undef SIZEOF_LONG - -/* The size of `long long', as computed by sizeof. */ -#undef SIZEOF_LONG_LONG - -/* The size of `off_t', as computed by sizeof. */ -#undef SIZEOF_OFF_T - -/* The size of `short', as computed by sizeof. */ -#undef SIZEOF_SHORT - -/* The size of `size_t', as computed by sizeof. */ -#undef SIZEOF_SIZE_T - -/* The size of `time_t', as computed by sizeof. */ -#undef SIZEOF_TIME_T - -/* The size of `void*', as computed by sizeof. */ -#undef SIZEOF_VOIDP - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Define to the type of arg 3 for strerror_r. */ -#undef STRERROR_R_TYPE_ARG3 - -/* Define to 1 if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - -/* Define to enable c-ares support */ -#undef USE_ARES - -/* if axTLS is enabled */ -#undef USE_AXTLS - -/* if CyaSSL/WolfSSL is enabled */ -#undef USE_CYASSL - -/* to enable iOS/Mac OS X native SSL/TLS support */ -#undef USE_DARWINSSL - -/* if GnuTLS is enabled */ -#undef USE_GNUTLS - -/* if GnuTLS uses nettle as crypto backend */ -#undef USE_GNUTLS_NETTLE - -/* PSL support enabled */ -#undef USE_LIBPSL - -/* if librtmp is in use */ -#undef USE_LIBRTMP - -/* if libSSH2 is in use */ -#undef USE_LIBSSH2 - -/* If you want to build curl with the built-in manual */ -#undef USE_MANUAL - -/* if mbedTLS is enabled */ -#undef USE_MBEDTLS - -/* Define to enable metalink support */ -#undef USE_METALINK - -/* if nghttp2 is in use */ -#undef USE_NGHTTP2 - -/* if NSS is enabled */ -#undef USE_NSS - -/* Use OpenLDAP-specific code */ -#undef USE_OPENLDAP - -/* if OpenSSL is in use */ -#undef USE_OPENSSL - -/* if PolarSSL is enabled */ -#undef USE_POLARSSL - -/* to enable Windows native SSL/TLS support */ -#undef USE_SCHANNEL - -/* if you want POSIX threaded DNS lookup */ -#undef USE_THREADS_POSIX - -/* Use TLS-SRP authentication */ -#undef USE_TLS_SRP - -/* Use Unix domain sockets */ -#undef USE_UNIX_SOCKETS - -/* Define to 1 if you have the `normaliz' (WinIDN) library (-lnormaliz). */ -#undef USE_WIN32_IDN - -/* Define to 1 if you are building a Windows target with large file support. - */ -#undef USE_WIN32_LARGE_FILES - -/* Use Windows LDAP implementation */ -#undef USE_WIN32_LDAP - -/* Define to 1 if you are building a Windows target without large file - support. */ -#undef USE_WIN32_SMALL_FILES - -/* to enable SSPI support */ -#undef USE_WINDOWS_SSPI - -/* Version number of package */ -#undef VERSION - -/* Define to 1 to provide own prototypes. */ -#undef WANT_IDN_PROTOTYPES - -/* Define to avoid automatic inclusion of winsock.h */ -#undef WIN32_LEAN_AND_MEAN - -/* Define to 1 if OS is AIX. */ -#ifndef _ALL_SOURCE -# undef _ALL_SOURCE -#endif - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#undef _FILE_OFFSET_BITS - -/* Define for large files, on AIX-style hosts. */ -#undef _LARGE_FILES - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Type to use in place of in_addr_t when system does not provide it. */ -#undef in_addr_t - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `unsigned int' if does not define. */ -#undef size_t - -/* the signed version of size_t */ -#undef ssize_t diff --git a/Externals/curl/lib/curl_des.c b/Externals/curl/lib/curl_des.c deleted file mode 100644 index 421c9f768d..0000000000 --- a/Externals/curl/lib/curl_des.c +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2015, Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_NTLM) && !defined(USE_OPENSSL) - -#include "curl_des.h" - -/* - * Curl_des_set_odd_parity() - * - * This is used to apply odd parity to the given byte array. It is typically - * used by when a cryptography engines doesn't have it's own version. - * - * The function is a port of the Java based oddParity() function over at: - * - * http://davenport.sourceforge.net/ntlm.html - * - * Parameters: - * - * bytes [in/out] - The data whose parity bits are to be adjusted for - * odd parity. - * len [out] - The length of the data. - */ -void Curl_des_set_odd_parity(unsigned char *bytes, size_t len) -{ - size_t i; - - for(i = 0; i < len; i++) { - unsigned char b = bytes[i]; - - bool needs_parity = (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ - (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ - (b >> 1)) & 0x01) == 0; - - if(needs_parity) - bytes[i] |= 0x01; - else - bytes[i] &= 0xfe; - } -} - -#endif /* USE_NTLM && !USE_OPENSSL */ diff --git a/Externals/curl/lib/curl_des.h b/Externals/curl/lib/curl_des.h deleted file mode 100644 index 129060ff7d..0000000000 --- a/Externals/curl/lib/curl_des.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef HEADER_CURL_DES_H -#define HEADER_CURL_DES_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2015, Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_NTLM) && !defined(USE_OPENSSL) - -/* Applies odd parity to the given byte array */ -void Curl_des_set_odd_parity(unsigned char *bytes, size_t length); - -#endif /* USE_NTLM && !USE_OPENSSL */ - -#endif /* HEADER_CURL_DES_H */ diff --git a/Externals/curl/lib/curl_endian.c b/Externals/curl/lib/curl_endian.c deleted file mode 100644 index 76deca6aa5..0000000000 --- a/Externals/curl/lib/curl_endian.c +++ /dev/null @@ -1,236 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "curl_endian.h" - -/* - * Curl_read16_le() - * - * This function converts a 16-bit integer from the little endian format, as - * used in the incoming package to whatever endian format we're using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 2 byte buffer. - * - * Returns the integer. - */ -unsigned short Curl_read16_le(unsigned char *buf) -{ - return (unsigned short)(((unsigned short)buf[0]) | - ((unsigned short)buf[1] << 8)); -} - -/* - * Curl_read32_le() - * - * This function converts a 32-bit integer from the little endian format, as - * used in the incoming package to whatever endian format we're using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 4 byte buffer. - * - * Returns the integer. - */ -unsigned int Curl_read32_le(unsigned char *buf) -{ - return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) | - ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24); -} - -#if (CURL_SIZEOF_CURL_OFF_T > 4) -/* - * Curl_read64_le() - * - * This function converts a 64-bit integer from the little endian format, as - * used in the incoming package to whatever endian format we're using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 8 byte buffer. - * - * Returns the integer. - */ -#if defined(HAVE_LONGLONG) -unsigned long long Curl_read64_le(unsigned char *buf) -{ - return ((unsigned long long)buf[0]) | - ((unsigned long long)buf[1] << 8) | - ((unsigned long long)buf[2] << 16) | - ((unsigned long long)buf[3] << 24) | - ((unsigned long long)buf[4] << 32) | - ((unsigned long long)buf[5] << 40) | - ((unsigned long long)buf[6] << 48) | - ((unsigned long long)buf[7] << 56); -} -#else -unsigned __int64 Curl_read64_le(unsigned char *buf) -{ - return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) | - ((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) | - ((unsigned __int64)buf[4] << 32) | ((unsigned __int64)buf[5] << 40) | - ((unsigned __int64)buf[6] << 48) | ((unsigned __int64)buf[7] << 56); -} -#endif - -#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */ - -/* - * Curl_read16_be() - * - * This function converts a 16-bit integer from the big endian format, as - * used in the incoming package to whatever endian format we're using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 2 byte buffer. - * - * Returns the integer. - */ -unsigned short Curl_read16_be(unsigned char *buf) -{ - return (unsigned short)(((unsigned short)buf[0] << 8) | - ((unsigned short)buf[1])); -} - -/* - * Curl_read32_be() - * - * This function converts a 32-bit integer from the big endian format, as - * used in the incoming package to whatever endian format we're using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 4 byte buffer. - * - * Returns the integer. - */ -unsigned int Curl_read32_be(unsigned char *buf) -{ - return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) | - ((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]); -} - -#if (CURL_SIZEOF_CURL_OFF_T > 4) -/* - * Curl_read64_be() - * - * This function converts a 64-bit integer from the big endian format, as - * used in the incoming package to whatever endian format we're using - * natively. - * - * Parameters: - * - * buf [in] - A pointer to a 8 byte buffer. - * - * Returns the integer. - */ -#if defined(HAVE_LONGLONG) -unsigned long long Curl_read64_be(unsigned char *buf) -{ - return ((unsigned long long)buf[0] << 56) | - ((unsigned long long)buf[1] << 48) | - ((unsigned long long)buf[2] << 40) | - ((unsigned long long)buf[3] << 32) | - ((unsigned long long)buf[4] << 24) | - ((unsigned long long)buf[5] << 16) | - ((unsigned long long)buf[6] << 8) | - ((unsigned long long)buf[7]); -} -#else -unsigned __int64 Curl_read64_be(unsigned char *buf) -{ - return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) | - ((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) | - ((unsigned __int64)buf[4] << 24) | ((unsigned __int64)buf[5] << 16) | - ((unsigned __int64)buf[6] << 8) | ((unsigned __int64)buf[7]); -} -#endif - -#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */ - -/* - * Curl_write16_le() - * - * This function converts a 16-bit integer from the native endian format, - * to little endian format ready for sending down the wire. - * - * Parameters: - * - * value [in] - The 16-bit integer value. - * buffer [in] - A pointer to the output buffer. - */ -void Curl_write16_le(const short value, unsigned char *buffer) -{ - buffer[0] = (char)(value & 0x00FF); - buffer[1] = (char)((value & 0xFF00) >> 8); -} - -/* - * Curl_write32_le() - * - * This function converts a 32-bit integer from the native endian format, - * to little endian format ready for sending down the wire. - * - * Parameters: - * - * value [in] - The 32-bit integer value. - * buffer [in] - A pointer to the output buffer. - */ -void Curl_write32_le(const int value, unsigned char *buffer) -{ - buffer[0] = (char)(value & 0x000000FF); - buffer[1] = (char)((value & 0x0000FF00) >> 8); - buffer[2] = (char)((value & 0x00FF0000) >> 16); - buffer[3] = (char)((value & 0xFF000000) >> 24); -} - -#if (CURL_SIZEOF_CURL_OFF_T > 4) -/* - * Curl_write64_le() - * - * This function converts a 64-bit integer from the native endian format, - * to little endian format ready for sending down the wire. - * - * Parameters: - * - * value [in] - The 64-bit integer value. - * buffer [in] - A pointer to the output buffer. - */ -#if defined(HAVE_LONGLONG) -void Curl_write64_le(const long long value, unsigned char *buffer) -#else -void Curl_write64_le(const __int64 value, unsigned char *buffer) -#endif -{ - Curl_write32_le((int)value, buffer); - Curl_write32_le((int)(value >> 32), buffer + 4); -} -#endif /* CURL_SIZEOF_CURL_OFF_T > 4 */ diff --git a/Externals/curl/lib/curl_endian.h b/Externals/curl/lib/curl_endian.h deleted file mode 100644 index df8398c8c8..0000000000 --- a/Externals/curl/lib/curl_endian.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef HEADER_CURL_ENDIAN_H -#define HEADER_CURL_ENDIAN_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* Converts a 16-bit integer from little endian */ -unsigned short Curl_read16_le(unsigned char *buf); - -/* Converts a 32-bit integer from little endian */ -unsigned int Curl_read32_le(unsigned char *buf); - -#if (CURL_SIZEOF_CURL_OFF_T > 4) -/* Converts a 64-bit integer from little endian */ -#if defined(HAVE_LONGLONG) -unsigned long long Curl_read64_le(unsigned char *buf); -#else -unsigned __int64 Curl_read64_le(unsigned char *buf); -#endif -#endif - -/* Converts a 16-bit integer from big endian */ -unsigned short Curl_read16_be(unsigned char *buf); - -/* Converts a 32-bit integer from big endian */ -unsigned int Curl_read32_be(unsigned char *buf); - -#if (CURL_SIZEOF_CURL_OFF_T > 4) -/* Converts a 64-bit integer from big endian */ -#if defined(HAVE_LONGLONG) -unsigned long long Curl_read64_be(unsigned char *buf); -#else -unsigned __int64 Curl_read64_be(unsigned char *buf); -#endif -#endif - -/* Converts a 16-bit integer to little endian */ -void Curl_write16_le(const short value, unsigned char *buffer); - -/* Converts a 32-bit integer to little endian */ -void Curl_write32_le(const int value, unsigned char *buffer); - -#if (CURL_SIZEOF_CURL_OFF_T > 4) -/* Converts a 64-bit integer to little endian */ -#if defined(HAVE_LONGLONG) -void Curl_write64_le(const long long value, unsigned char *buffer); -#else -void Curl_write64_le(const __int64 value, unsigned char *buffer); -#endif -#endif - -#endif /* HEADER_CURL_ENDIAN_H */ diff --git a/Externals/curl/lib/curl_fnmatch.c b/Externals/curl/lib/curl_fnmatch.c deleted file mode 100644 index e8108bb10e..0000000000 --- a/Externals/curl/lib/curl_fnmatch.c +++ /dev/null @@ -1,426 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "curl_fnmatch.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -#define CURLFNM_CHARSET_LEN (sizeof(char) * 256) -#define CURLFNM_CHSET_SIZE (CURLFNM_CHARSET_LEN + 15) - -#define CURLFNM_NEGATE CURLFNM_CHARSET_LEN - -#define CURLFNM_ALNUM (CURLFNM_CHARSET_LEN + 1) -#define CURLFNM_DIGIT (CURLFNM_CHARSET_LEN + 2) -#define CURLFNM_XDIGIT (CURLFNM_CHARSET_LEN + 3) -#define CURLFNM_ALPHA (CURLFNM_CHARSET_LEN + 4) -#define CURLFNM_PRINT (CURLFNM_CHARSET_LEN + 5) -#define CURLFNM_BLANK (CURLFNM_CHARSET_LEN + 6) -#define CURLFNM_LOWER (CURLFNM_CHARSET_LEN + 7) -#define CURLFNM_GRAPH (CURLFNM_CHARSET_LEN + 8) -#define CURLFNM_SPACE (CURLFNM_CHARSET_LEN + 9) -#define CURLFNM_UPPER (CURLFNM_CHARSET_LEN + 10) - -typedef enum { - CURLFNM_LOOP_DEFAULT = 0, - CURLFNM_LOOP_BACKSLASH -} loop_state; - -typedef enum { - CURLFNM_SCHS_DEFAULT = 0, - CURLFNM_SCHS_MAYRANGE, - CURLFNM_SCHS_MAYRANGE2, - CURLFNM_SCHS_RIGHTBR, - CURLFNM_SCHS_RIGHTBRLEFTBR -} setcharset_state; - -typedef enum { - CURLFNM_PKW_INIT = 0, - CURLFNM_PKW_DDOT -} parsekey_state; - -#define SETCHARSET_OK 1 -#define SETCHARSET_FAIL 0 - -static int parsekeyword(unsigned char **pattern, unsigned char *charset) -{ - parsekey_state state = CURLFNM_PKW_INIT; -#define KEYLEN 10 - char keyword[KEYLEN] = { 0 }; - int found = FALSE; - int i; - unsigned char *p = *pattern; - for(i = 0; !found; i++) { - char c = *p++; - if(i >= KEYLEN) - return SETCHARSET_FAIL; - switch(state) { - case CURLFNM_PKW_INIT: - if(ISALPHA(c) && ISLOWER(c)) - keyword[i] = c; - else if(c == ':') - state = CURLFNM_PKW_DDOT; - else - return 0; - break; - case CURLFNM_PKW_DDOT: - if(c == ']') - found = TRUE; - else - return SETCHARSET_FAIL; - } - } -#undef KEYLEN - - *pattern = p; /* move caller's pattern pointer */ - if(strcmp(keyword, "digit") == 0) - charset[CURLFNM_DIGIT] = 1; - else if(strcmp(keyword, "alnum") == 0) - charset[CURLFNM_ALNUM] = 1; - else if(strcmp(keyword, "alpha") == 0) - charset[CURLFNM_ALPHA] = 1; - else if(strcmp(keyword, "xdigit") == 0) - charset[CURLFNM_XDIGIT] = 1; - else if(strcmp(keyword, "print") == 0) - charset[CURLFNM_PRINT] = 1; - else if(strcmp(keyword, "graph") == 0) - charset[CURLFNM_GRAPH] = 1; - else if(strcmp(keyword, "space") == 0) - charset[CURLFNM_SPACE] = 1; - else if(strcmp(keyword, "blank") == 0) - charset[CURLFNM_BLANK] = 1; - else if(strcmp(keyword, "upper") == 0) - charset[CURLFNM_UPPER] = 1; - else if(strcmp(keyword, "lower") == 0) - charset[CURLFNM_LOWER] = 1; - else - return SETCHARSET_FAIL; - return SETCHARSET_OK; -} - -/* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */ -static int setcharset(unsigned char **p, unsigned char *charset) -{ - setcharset_state state = CURLFNM_SCHS_DEFAULT; - unsigned char rangestart = 0; - unsigned char lastchar = 0; - bool something_found = FALSE; - unsigned char c; - for(;;) { - c = **p; - switch(state) { - case CURLFNM_SCHS_DEFAULT: - if(ISALNUM(c)) { /* ASCII value */ - rangestart = c; - charset[c] = 1; - (*p)++; - state = CURLFNM_SCHS_MAYRANGE; - something_found = TRUE; - } - else if(c == ']') { - if(something_found) - return SETCHARSET_OK; - else - something_found = TRUE; - state = CURLFNM_SCHS_RIGHTBR; - charset[c] = 1; - (*p)++; - } - else if(c == '[') { - char c2 = *((*p)+1); - if(c2 == ':') { /* there has to be a keyword */ - (*p) += 2; - if(parsekeyword(p, charset)) { - state = CURLFNM_SCHS_DEFAULT; - } - else - return SETCHARSET_FAIL; - } - else { - charset[c] = 1; - (*p)++; - } - something_found = TRUE; - } - else if(c == '?' || c == '*') { - something_found = TRUE; - charset[c] = 1; - (*p)++; - } - else if(c == '^' || c == '!') { - if(!something_found) { - if(charset[CURLFNM_NEGATE]) { - charset[c] = 1; - something_found = TRUE; - } - else - charset[CURLFNM_NEGATE] = 1; /* negate charset */ - } - else - charset[c] = 1; - (*p)++; - } - else if(c == '\\') { - c = *(++(*p)); - if(ISPRINT((c))) { - something_found = TRUE; - state = CURLFNM_SCHS_MAYRANGE; - charset[c] = 1; - rangestart = c; - (*p)++; - } - else - return SETCHARSET_FAIL; - } - else if(c == '\0') { - return SETCHARSET_FAIL; - } - else { - charset[c] = 1; - (*p)++; - something_found = TRUE; - } - break; - case CURLFNM_SCHS_MAYRANGE: - if(c == '-') { - charset[c] = 1; - (*p)++; - lastchar = '-'; - state = CURLFNM_SCHS_MAYRANGE2; - } - else if(c == '[') { - state = CURLFNM_SCHS_DEFAULT; - } - else if(ISALNUM(c)) { - charset[c] = 1; - (*p)++; - } - else if(c == '\\') { - c = *(++(*p)); - if(ISPRINT(c)) { - charset[c] = 1; - (*p)++; - } - else - return SETCHARSET_FAIL; - } - else if(c == ']') { - return SETCHARSET_OK; - } - else - return SETCHARSET_FAIL; - break; - case CURLFNM_SCHS_MAYRANGE2: - if(c == '\\') { - c = *(++(*p)); - if(!ISPRINT(c)) - return SETCHARSET_FAIL; - } - if(c == ']') { - return SETCHARSET_OK; - } - else if(c == '\\') { - c = *(++(*p)); - if(ISPRINT(c)) { - charset[c] = 1; - state = CURLFNM_SCHS_DEFAULT; - (*p)++; - } - else - return SETCHARSET_FAIL; - } - if(c >= rangestart) { - if((ISLOWER(c) && ISLOWER(rangestart)) || - (ISDIGIT(c) && ISDIGIT(rangestart)) || - (ISUPPER(c) && ISUPPER(rangestart))) { - charset[lastchar] = 0; - rangestart++; - while(rangestart++ <= c) - charset[rangestart-1] = 1; - (*p)++; - state = CURLFNM_SCHS_DEFAULT; - } - else - return SETCHARSET_FAIL; - } - break; - case CURLFNM_SCHS_RIGHTBR: - if(c == '[') { - state = CURLFNM_SCHS_RIGHTBRLEFTBR; - charset[c] = 1; - (*p)++; - } - else if(c == ']') { - return SETCHARSET_OK; - } - else if(c == '\0') { - return SETCHARSET_FAIL; - } - else if(ISPRINT(c)) { - charset[c] = 1; - (*p)++; - state = CURLFNM_SCHS_DEFAULT; - } - else - /* used 'goto fail' instead of 'return SETCHARSET_FAIL' to avoid a - * nonsense warning 'statement not reached' at end of the fnc when - * compiling on Solaris */ - goto fail; - break; - case CURLFNM_SCHS_RIGHTBRLEFTBR: - if(c == ']') { - return SETCHARSET_OK; - } - else { - state = CURLFNM_SCHS_DEFAULT; - charset[c] = 1; - (*p)++; - } - break; - } - } -fail: - return SETCHARSET_FAIL; -} - -static int loop(const unsigned char *pattern, const unsigned char *string) -{ - loop_state state = CURLFNM_LOOP_DEFAULT; - unsigned char *p = (unsigned char *)pattern; - unsigned char *s = (unsigned char *)string; - unsigned char charset[CURLFNM_CHSET_SIZE] = { 0 }; - int rc = 0; - - for(;;) { - switch(state) { - case CURLFNM_LOOP_DEFAULT: - if(*p == '*') { - while(*(p+1) == '*') /* eliminate multiple stars */ - p++; - if(*s == '\0' && *(p+1) == '\0') - return CURL_FNMATCH_MATCH; - rc = loop(p + 1, s); /* *.txt matches .txt <=> .txt matches .txt */ - if(rc == CURL_FNMATCH_MATCH) - return CURL_FNMATCH_MATCH; - if(*s) /* let the star eat up one character */ - s++; - else - return CURL_FNMATCH_NOMATCH; - } - else if(*p == '?') { - if(ISPRINT(*s)) { - s++; - p++; - } - else if(*s == '\0') - return CURL_FNMATCH_NOMATCH; - else - return CURL_FNMATCH_FAIL; /* cannot deal with other character */ - } - else if(*p == '\0') { - if(*s == '\0') - return CURL_FNMATCH_MATCH; - else - return CURL_FNMATCH_NOMATCH; - } - else if(*p == '\\') { - state = CURLFNM_LOOP_BACKSLASH; - p++; - } - else if(*p == '[') { - unsigned char *pp = p+1; /* cannot handle with pointer to register */ - if(setcharset(&pp, charset)) { - int found = FALSE; - if(charset[(unsigned int)*s]) - found = TRUE; - else if(charset[CURLFNM_ALNUM]) - found = ISALNUM(*s); - else if(charset[CURLFNM_ALPHA]) - found = ISALPHA(*s); - else if(charset[CURLFNM_DIGIT]) - found = ISDIGIT(*s); - else if(charset[CURLFNM_XDIGIT]) - found = ISXDIGIT(*s); - else if(charset[CURLFNM_PRINT]) - found = ISPRINT(*s); - else if(charset[CURLFNM_SPACE]) - found = ISSPACE(*s); - else if(charset[CURLFNM_UPPER]) - found = ISUPPER(*s); - else if(charset[CURLFNM_LOWER]) - found = ISLOWER(*s); - else if(charset[CURLFNM_BLANK]) - found = ISBLANK(*s); - else if(charset[CURLFNM_GRAPH]) - found = ISGRAPH(*s); - - if(charset[CURLFNM_NEGATE]) - found = !found; - - if(found) { - p = pp+1; - s++; - memset(charset, 0, CURLFNM_CHSET_SIZE); - } - else - return CURL_FNMATCH_NOMATCH; - } - else - return CURL_FNMATCH_FAIL; - } - else { - if(*p++ != *s++) - return CURL_FNMATCH_NOMATCH; - } - break; - case CURLFNM_LOOP_BACKSLASH: - if(ISPRINT(*p)) { - if(*p++ == *s++) - state = CURLFNM_LOOP_DEFAULT; - else - return CURL_FNMATCH_NOMATCH; - } - else - return CURL_FNMATCH_FAIL; - break; - } - } -} - -/* - * @unittest: 1307 - */ -int Curl_fnmatch(void *ptr, const char *pattern, const char *string) -{ - (void)ptr; /* the argument is specified by the curl_fnmatch_callback - prototype, but not used by Curl_fnmatch() */ - if(!pattern || !string) { - return CURL_FNMATCH_FAIL; - } - return loop((unsigned char *)pattern, (unsigned char *)string); -} diff --git a/Externals/curl/lib/curl_fnmatch.h b/Externals/curl/lib/curl_fnmatch.h deleted file mode 100644 index 69ffe392fd..0000000000 --- a/Externals/curl/lib/curl_fnmatch.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef HEADER_CURL_FNMATCH_H -#define HEADER_CURL_FNMATCH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#define CURL_FNMATCH_MATCH 0 -#define CURL_FNMATCH_NOMATCH 1 -#define CURL_FNMATCH_FAIL 2 - -/* default pattern matching function - * ================================= - * Implemented with recursive backtracking, if you want to use Curl_fnmatch, - * please note that there is not implemented UTF/UNICODE support. - * - * Implemented features: - * '?' notation, does not match UTF characters - * '*' can also work with UTF string - * [a-zA-Z0-9] enumeration support - * - * keywords: alnum, digit, xdigit, alpha, print, blank, lower, graph, space - * and upper (use as "[[:alnum:]]") - */ -int Curl_fnmatch(void *ptr, const char *pattern, const char *string); - -#endif /* HEADER_CURL_FNMATCH_H */ diff --git a/Externals/curl/lib/curl_gethostname.c b/Externals/curl/lib/curl_gethostname.c deleted file mode 100644 index 2591fd8863..0000000000 --- a/Externals/curl/lib/curl_gethostname.c +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "curl_gethostname.h" - -/* - * Curl_gethostname() is a wrapper around gethostname() which allows - * overriding the host name that the function would normally return. - * This capability is used by the test suite to verify exact matching - * of NTLM authentication, which exercises libcurl's MD4 and DES code - * as well as by the SMTP module when a hostname is not provided. - * - * For libcurl debug enabled builds host name overriding takes place - * when environment variable CURL_GETHOSTNAME is set, using the value - * held by the variable to override returned host name. - * - * Note: The function always returns the un-qualified hostname rather - * than being provider dependent. - * - * For libcurl shared library release builds the test suite preloads - * another shared library named libhostname using the LD_PRELOAD - * mechanism which intercepts, and might override, the gethostname() - * function call. In this case a given platform must support the - * LD_PRELOAD mechanism and additionally have environment variable - * CURL_GETHOSTNAME set in order to override the returned host name. - * - * For libcurl static library release builds no overriding takes place. - */ - -int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) { - -#ifndef HAVE_GETHOSTNAME - - /* Allow compilation and return failure when unavailable */ - (void) name; - (void) namelen; - return -1; - -#else - int err; - char* dot; - -#ifdef DEBUGBUILD - - /* Override host name when environment variable CURL_GETHOSTNAME is set */ - const char *force_hostname = getenv("CURL_GETHOSTNAME"); - if(force_hostname) { - strncpy(name, force_hostname, namelen); - err = 0; - } - else { - name[0] = '\0'; - err = gethostname(name, namelen); - } - -#else /* DEBUGBUILD */ - - /* The call to system's gethostname() might get intercepted by the - libhostname library when libcurl is built as a non-debug shared - library when running the test suite. */ - name[0] = '\0'; - err = gethostname(name, namelen); - -#endif - - name[namelen - 1] = '\0'; - - if(err) - return err; - - /* Truncate domain, leave only machine name */ - dot = strchr(name, '.'); - if(dot) - *dot = '\0'; - - return 0; -#endif - -} diff --git a/Externals/curl/lib/curl_gethostname.h b/Externals/curl/lib/curl_gethostname.h deleted file mode 100644 index 07517c5359..0000000000 --- a/Externals/curl/lib/curl_gethostname.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_GETHOSTNAME_H -#define HEADER_CURL_GETHOSTNAME_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* Hostname buffer size */ -#define HOSTNAME_MAX 1024 - -/* This returns the local machine's un-qualified hostname */ -int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen); - -#endif /* HEADER_CURL_GETHOSTNAME_H */ diff --git a/Externals/curl/lib/curl_gssapi.c b/Externals/curl/lib/curl_gssapi.c deleted file mode 100644 index 6f9121e4ee..0000000000 --- a/Externals/curl/lib/curl_gssapi.c +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2011 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_GSSAPI - -#include "curl_gssapi.h" -#include "sendf.h" - -static char spnego_oid_bytes[] = "\x2b\x06\x01\x05\x05\x02"; -gss_OID_desc Curl_spnego_mech_oid = { 6, &spnego_oid_bytes }; -static char krb5_oid_bytes[] = "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"; -gss_OID_desc Curl_krb5_mech_oid = { 9, &krb5_oid_bytes }; - -OM_uint32 Curl_gss_init_sec_context( - struct SessionHandle *data, - OM_uint32 *minor_status, - gss_ctx_id_t *context, - gss_name_t target_name, - gss_OID mech_type, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_buffer_t output_token, - const bool mutual_auth, - OM_uint32 *ret_flags) -{ - OM_uint32 req_flags = GSS_C_REPLAY_FLAG; - - if(mutual_auth) - req_flags |= GSS_C_MUTUAL_FLAG; - - if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) { -#ifdef GSS_C_DELEG_POLICY_FLAG - req_flags |= GSS_C_DELEG_POLICY_FLAG; -#else - infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not " - "compiled in\n"); -#endif - } - - if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG) - req_flags |= GSS_C_DELEG_FLAG; - - return gss_init_sec_context(minor_status, - GSS_C_NO_CREDENTIAL, /* cred_handle */ - context, - target_name, - mech_type, - req_flags, - 0, /* time_req */ - input_chan_bindings, - input_token, - NULL, /* actual_mech_type */ - output_token, - ret_flags, - NULL /* time_rec */); -} - -#define GSS_LOG_BUFFER_LEN 1024 -static size_t display_gss_error(OM_uint32 status, int type, - char *buf, size_t len) { - OM_uint32 maj_stat; - OM_uint32 min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status_string; - - do { - maj_stat = gss_display_status(&min_stat, - status, - type, - GSS_C_NO_OID, - &msg_ctx, - &status_string); - if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) { - len += snprintf(buf + len, GSS_LOG_BUFFER_LEN - len, - "%.*s. ", (int)status_string.length, - (char*)status_string.value); - } - gss_release_buffer(&min_stat, &status_string); - } while(!GSS_ERROR(maj_stat) && msg_ctx != 0); - - return len; -} - -/* - * Curl_gss_log_error() - * - * This is used to log a GSS-API error status. - * - * Parameters: - * - * data [in] - The session handle. - * prefix [in] - The prefix of the log message. - * major [in] - The major status code. - * minor [in] - The minor status code. - */ -void Curl_gss_log_error(struct SessionHandle *data, const char *prefix, - OM_uint32 major, OM_uint32 minor) -{ - char buf[GSS_LOG_BUFFER_LEN]; - size_t len = 0; - - if(major != GSS_S_FAILURE) - len = display_gss_error(major, GSS_C_GSS_CODE, buf, len); - - display_gss_error(minor, GSS_C_MECH_CODE, buf, len); - - infof(data, "%s%s\n", prefix, buf); -} - -#endif /* HAVE_GSSAPI */ diff --git a/Externals/curl/lib/curl_gssapi.h b/Externals/curl/lib/curl_gssapi.h deleted file mode 100644 index 42fd1e41dc..0000000000 --- a/Externals/curl/lib/curl_gssapi.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef HEADER_CURL_GSSAPI_H -#define HEADER_CURL_GSSAPI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2011 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" -#include "urldata.h" - -#ifdef HAVE_GSSAPI - -#ifdef HAVE_GSSGNU -# include -#elif defined HAVE_GSSMIT - /* MIT style */ -# include -# include -# include -#else - /* Heimdal-style */ -# include -#endif - -extern gss_OID_desc Curl_spnego_mech_oid; -extern gss_OID_desc Curl_krb5_mech_oid; - -/* Common method for using GSS-API */ -OM_uint32 Curl_gss_init_sec_context( - struct SessionHandle *data, - OM_uint32 *minor_status, - gss_ctx_id_t *context, - gss_name_t target_name, - gss_OID mech_type, - gss_channel_bindings_t input_chan_bindings, - gss_buffer_t input_token, - gss_buffer_t output_token, - const bool mutual_auth, - OM_uint32 *ret_flags); - -/* Helper to log a GSS-API error status */ -void Curl_gss_log_error(struct SessionHandle *data, const char *prefix, - OM_uint32 major, OM_uint32 minor); - -/* Provide some definitions missing in old headers */ -#ifdef HAVE_OLD_GSSMIT -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name -#define NCOMPAT 1 -#endif - -/* Define our privacy and integrity protection values */ -#define GSSAUTH_P_NONE 1 -#define GSSAUTH_P_INTEGRITY 2 -#define GSSAUTH_P_PRIVACY 4 - -#endif /* HAVE_GSSAPI */ - -#endif /* HEADER_CURL_GSSAPI_H */ diff --git a/Externals/curl/lib/curl_hmac.h b/Externals/curl/lib/curl_hmac.h deleted file mode 100644 index 41703b42fc..0000000000 --- a/Externals/curl/lib/curl_hmac.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef HEADER_CURL_HMAC_H -#define HEADER_CURL_HMAC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifndef CURL_DISABLE_CRYPTO_AUTH - -typedef void (* HMAC_hinit_func)(void * context); -typedef void (* HMAC_hupdate_func)(void * context, - const unsigned char * data, - unsigned int len); -typedef void (* HMAC_hfinal_func)(unsigned char * result, void * context); - - -/* Per-hash function HMAC parameters. */ - -typedef struct { - HMAC_hinit_func hmac_hinit; /* Initialize context procedure. */ - HMAC_hupdate_func hmac_hupdate; /* Update context with data. */ - HMAC_hfinal_func hmac_hfinal; /* Get final result procedure. */ - unsigned int hmac_ctxtsize; /* Context structure size. */ - unsigned int hmac_maxkeylen; /* Maximum key length (bytes). */ - unsigned int hmac_resultlen; /* Result length (bytes). */ -} HMAC_params; - - -/* HMAC computation context. */ - -typedef struct { - const HMAC_params * hmac_hash; /* Hash function definition. */ - void * hmac_hashctxt1; /* Hash function context 1. */ - void * hmac_hashctxt2; /* Hash function context 2. */ -} HMAC_context; - - -/* Prototypes. */ - -HMAC_context * Curl_HMAC_init(const HMAC_params * hashparams, - const unsigned char * key, - unsigned int keylen); -int Curl_HMAC_update(HMAC_context * context, - const unsigned char * data, - unsigned int len); -int Curl_HMAC_final(HMAC_context * context, unsigned char * result); - -#endif - -#endif /* HEADER_CURL_HMAC_H */ diff --git a/Externals/curl/lib/curl_ldap.h b/Externals/curl/lib/curl_ldap.h deleted file mode 100644 index 27d03810fb..0000000000 --- a/Externals/curl/lib/curl_ldap.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HEADER_CURL_LDAP_H -#define HEADER_CURL_LDAP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifndef CURL_DISABLE_LDAP -extern const struct Curl_handler Curl_handler_ldap; - -#if !defined(CURL_DISABLE_LDAPS) && \ - ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ - (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) -extern const struct Curl_handler Curl_handler_ldaps; -#endif - -#endif -#endif /* HEADER_CURL_LDAP_H */ - diff --git a/Externals/curl/lib/curl_md4.h b/Externals/curl/lib/curl_md4.h deleted file mode 100644 index 8c26d1222a..0000000000 --- a/Externals/curl/lib/curl_md4.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef HEADER_CURL_MD4_H -#define HEADER_CURL_MD4_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so - * that we have a local implementation of it */ -#if defined(USE_NSS) || defined(USE_OS400CRYPTO) - -void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len); - -#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */ - -#endif /* HEADER_CURL_MD4_H */ diff --git a/Externals/curl/lib/curl_md5.h b/Externals/curl/lib/curl_md5.h deleted file mode 100644 index 5f70c96346..0000000000 --- a/Externals/curl/lib/curl_md5.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef HEADER_CURL_MD5_H -#define HEADER_CURL_MD5_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifndef CURL_DISABLE_CRYPTO_AUTH -#include "curl_hmac.h" - -#define MD5_DIGEST_LEN 16 - -typedef void (* Curl_MD5_init_func)(void *context); -typedef void (* Curl_MD5_update_func)(void *context, - const unsigned char *data, - unsigned int len); -typedef void (* Curl_MD5_final_func)(unsigned char *result, void *context); - -typedef struct { - Curl_MD5_init_func md5_init_func; /* Initialize context procedure */ - Curl_MD5_update_func md5_update_func; /* Update context with data */ - Curl_MD5_final_func md5_final_func; /* Get final result procedure */ - unsigned int md5_ctxtsize; /* Context structure size */ - unsigned int md5_resultlen; /* Result length (bytes) */ -} MD5_params; - -typedef struct { - const MD5_params *md5_hash; /* Hash function definition */ - void *md5_hashctx; /* Hash function context */ -} MD5_context; - -extern const MD5_params Curl_DIGEST_MD5[1]; -extern const HMAC_params Curl_HMAC_MD5[1]; - -void Curl_md5it(unsigned char *output, - const unsigned char *input); - -MD5_context * Curl_MD5_init(const MD5_params *md5params); -int Curl_MD5_update(MD5_context *context, - const unsigned char *data, - unsigned int len); -int Curl_MD5_final(MD5_context *context, unsigned char *result); - -#endif - -#endif /* HEADER_CURL_MD5_H */ diff --git a/Externals/curl/lib/curl_memory.h b/Externals/curl/lib/curl_memory.h deleted file mode 100644 index 6f792fffda..0000000000 --- a/Externals/curl/lib/curl_memory.h +++ /dev/null @@ -1,156 +0,0 @@ -#ifndef HEADER_CURL_MEMORY_H -#define HEADER_CURL_MEMORY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Nasty internal details ahead... - * - * File curl_memory.h must be included by _all_ *.c source files - * that use memory related functions strdup, malloc, calloc, realloc - * or free, and given source file is used to build libcurl library. - * It should be included immediately before memdebug.h as the last files - * included to avoid undesired interaction with other memory function - * headers in dependent libraries. - * - * There is nearly no exception to above rule. All libcurl source - * files in 'lib' subdirectory as well as those living deep inside - * 'packages' subdirectories and linked together in order to build - * libcurl library shall follow it. - * - * File lib/strdup.c is an exception, given that it provides a strdup - * clone implementation while using malloc. Extra care needed inside - * this one. TODO: revisit this paragraph and related code. - * - * The need for curl_memory.h inclusion is due to libcurl's feature - * of allowing library user to provide memory replacement functions, - * memory callbacks, at runtime with curl_global_init_mem() - * - * Any *.c source file used to build libcurl library that does not - * include curl_memory.h and uses any memory function of the five - * mentioned above will compile without any indication, but it will - * trigger weird memory related issues at runtime. - * - * OTOH some source files from 'lib' subdirectory may additionally be - * used directly as source code when using some curlx_ functions by - * third party programs that don't even use libcurl at all. When using - * these source files in this way it is necessary these are compiled - * with CURLX_NO_MEMORY_CALLBACKS defined, in order to ensure that no - * attempt of calling libcurl's memory callbacks is done from code - * which can not use this machinery. - * - * Notice that libcurl's 'memory tracking' system works chaining into - * the memory callback machinery. This implies that when compiling - * 'lib' source files with CURLX_NO_MEMORY_CALLBACKS defined this file - * disengages usage of libcurl's 'memory tracking' system, defining - * MEMDEBUG_NODEFINES and overriding CURLDEBUG purpose. - * - * CURLX_NO_MEMORY_CALLBACKS takes precedence over CURLDEBUG. This is - * done in order to allow building a 'memory tracking' enabled libcurl - * and at the same time allow building programs which do not use it. - * - * Programs and libraries in 'tests' subdirectories have specific - * purposes and needs, and as such each one will use whatever fits - * best, depending additionally wether it links with libcurl or not. - * - * Caveat emptor. Proper curlx_* separation is a work in progress - * the same as CURLX_NO_MEMORY_CALLBACKS usage, some adjustments may - * still be required. IOW don't use them yet, there are sharp edges. - */ - -#ifdef HEADER_CURL_MEMDEBUG_H -#error "Header memdebug.h shall not be included before curl_memory.h" -#endif - -#ifndef CURLX_NO_MEMORY_CALLBACKS - -#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS /* only if not already done */ -/* - * The following memory function replacement typedef's are COPIED from - * curl/curl.h and MUST match the originals. We copy them to avoid having to - * include curl/curl.h here. We avoid that include since it includes stdio.h - * and other headers that may get messed up with defines done here. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); -#define CURL_DID_MEMORY_FUNC_TYPEDEFS -#endif - -extern curl_malloc_callback Curl_cmalloc; -extern curl_free_callback Curl_cfree; -extern curl_realloc_callback Curl_crealloc; -extern curl_strdup_callback Curl_cstrdup; -extern curl_calloc_callback Curl_ccalloc; -#if defined(WIN32) && defined(UNICODE) -extern curl_wcsdup_callback Curl_cwcsdup; -#endif - -#ifndef CURLDEBUG - -/* - * libcurl's 'memory tracking' system defines strdup, malloc, calloc, - * realloc and free, along with others, in memdebug.h in a different - * way although still using memory callbacks forward declared above. - * When using the 'memory tracking' system (CURLDEBUG defined) we do - * not define here the five memory functions given that definitions - * from memdebug.h are the ones that shall be used. - */ - -#undef strdup -#define strdup(ptr) Curl_cstrdup(ptr) -#undef malloc -#define malloc(size) Curl_cmalloc(size) -#undef calloc -#define calloc(nbelem,size) Curl_ccalloc(nbelem, size) -#undef realloc -#define realloc(ptr,size) Curl_crealloc(ptr, size) -#undef free -#define free(ptr) Curl_cfree(ptr) - -#ifdef WIN32 -# ifdef UNICODE -# undef wcsdup -# define wcsdup(ptr) Curl_cwcsdup(ptr) -# undef _wcsdup -# define _wcsdup(ptr) Curl_cwcsdup(ptr) -# undef _tcsdup -# define _tcsdup(ptr) Curl_cwcsdup(ptr) -# else -# undef _tcsdup -# define _tcsdup(ptr) Curl_cstrdup(ptr) -# endif -#endif - -#endif /* CURLDEBUG */ - -#else /* CURLX_NO_MEMORY_CALLBACKS */ - -#ifndef MEMDEBUG_NODEFINES -#define MEMDEBUG_NODEFINES -#endif - -#endif /* CURLX_NO_MEMORY_CALLBACKS */ - -#endif /* HEADER_CURL_MEMORY_H */ diff --git a/Externals/curl/lib/curl_memrchr.c b/Externals/curl/lib/curl_memrchr.c deleted file mode 100644 index c521497b21..0000000000 --- a/Externals/curl/lib/curl_memrchr.c +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "curl_memrchr.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -#ifndef HAVE_MEMRCHR - -/* - * Curl_memrchr() - * - * Our memrchr() function clone for systems which lack this function. The - * memrchr() function is like the memchr() function, except that it searches - * backwards from the end of the n bytes pointed to by s instead of forward - * from the beginning. - */ - -void * -Curl_memrchr(const void *s, int c, size_t n) -{ - const unsigned char *p = s; - const unsigned char *q = s; - - p += n - 1; - - while(p >= q) { - if(*p == (unsigned char)c) - return (void *)p; - p--; - } - - return NULL; -} - -#endif /* HAVE_MEMRCHR */ diff --git a/Externals/curl/lib/curl_memrchr.h b/Externals/curl/lib/curl_memrchr.h deleted file mode 100644 index 747509c45a..0000000000 --- a/Externals/curl/lib/curl_memrchr.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef HEADER_CURL_MEMRCHR_H -#define HEADER_CURL_MEMRCHR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_MEMRCHR - -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif - -#else /* HAVE_MEMRCHR */ - -void *Curl_memrchr(const void *s, int c, size_t n); - -#define memrchr(x,y,z) Curl_memrchr((x),(y),(z)) - -#endif /* HAVE_MEMRCHR */ - -#endif /* HEADER_CURL_MEMRCHR_H */ diff --git a/Externals/curl/lib/curl_multibyte.c b/Externals/curl/lib/curl_multibyte.c deleted file mode 100644 index e78bb5002e..0000000000 --- a/Externals/curl/lib/curl_multibyte.c +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \ - defined(USE_WIN32_LDAP)) && defined(UNICODE)) - - /* - * MultiByte conversions using Windows kernel32 library. - */ - -#include "curl_multibyte.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8) -{ - wchar_t *str_w = NULL; - - if(str_utf8) { - int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - str_utf8, -1, NULL, 0); - if(str_w_len > 0) { - str_w = malloc(str_w_len * sizeof(wchar_t)); - if(str_w) { - if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w, - str_w_len) == 0) { - free(str_w); - return NULL; - } - } - } - } - - return str_w; -} - -char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w) -{ - char *str_utf8 = NULL; - - if(str_w) { - int str_utf8_len = WideCharToMultiByte(CP_UTF8, 0, str_w, -1, NULL, - 0, NULL, NULL); - if(str_utf8_len > 0) { - str_utf8 = malloc(str_utf8_len * sizeof(wchar_t)); - if(str_utf8) { - if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, str_utf8_len, - NULL, FALSE) == 0) { - free(str_utf8); - return NULL; - } - } - } - } - - return str_utf8; -} - -#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */ diff --git a/Externals/curl/lib/curl_multibyte.h b/Externals/curl/lib/curl_multibyte.h deleted file mode 100644 index 615f5c086c..0000000000 --- a/Externals/curl/lib/curl_multibyte.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef HEADER_CURL_MULTIBYTE_H -#define HEADER_CURL_MULTIBYTE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_WIN32_IDN) || ((defined(USE_WINDOWS_SSPI) || \ - defined(USE_WIN32_LDAP)) && defined(UNICODE)) - - /* - * MultiByte conversions using Windows kernel32 library. - */ - -wchar_t *Curl_convert_UTF8_to_wchar(const char *str_utf8); -char *Curl_convert_wchar_to_UTF8(const wchar_t *str_w); - -#endif /* USE_WIN32_IDN || ((USE_WINDOWS_SSPI || USE_WIN32_LDAP) && UNICODE) */ - - -#if defined(USE_WIN32_IDN) || defined(USE_WINDOWS_SSPI) || \ - defined(USE_WIN32_LDAP) - -/* - * Macros Curl_convert_UTF8_to_tchar(), Curl_convert_tchar_to_UTF8() - * and Curl_unicodefree() main purpose is to minimize the number of - * preprocessor conditional directives needed by code using these - * to differentiate UNICODE from non-UNICODE builds. - * - * When building with UNICODE defined, this two macros - * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8() - * return a pointer to a newly allocated memory area holding result. - * When the result is no longer needed, allocated memory is intended - * to be free'ed with Curl_unicodefree(). - * - * When building without UNICODE defined, this macros - * Curl_convert_UTF8_to_tchar() and Curl_convert_tchar_to_UTF8() - * return the pointer received as argument. Curl_unicodefree() does - * no actual free'ing of this pointer it is simply set to NULL. - */ - -#ifdef UNICODE - -#define Curl_convert_UTF8_to_tchar(ptr) Curl_convert_UTF8_to_wchar((ptr)) -#define Curl_convert_tchar_to_UTF8(ptr) Curl_convert_wchar_to_UTF8((ptr)) -#define Curl_unicodefree(ptr) \ - do {if((ptr)) {free((ptr)); (ptr) = NULL;}} WHILE_FALSE - -typedef union { - unsigned short *tchar_ptr; - const unsigned short *const_tchar_ptr; - unsigned short *tbyte_ptr; - const unsigned short *const_tbyte_ptr; -} xcharp_u; - -#else - -#define Curl_convert_UTF8_to_tchar(ptr) (ptr) -#define Curl_convert_tchar_to_UTF8(ptr) (ptr) -#define Curl_unicodefree(ptr) \ - do {(ptr) = NULL;} WHILE_FALSE - -typedef union { - char *tchar_ptr; - const char *const_tchar_ptr; - unsigned char *tbyte_ptr; - const unsigned char *const_tbyte_ptr; -} xcharp_u; - -#endif /* UNICODE */ - -#endif /* USE_WIN32_IDN || USE_WINDOWS_SSPI || USE_WIN32_LDAP */ - -#endif /* HEADER_CURL_MULTIBYTE_H */ diff --git a/Externals/curl/lib/curl_ntlm_core.c b/Externals/curl/lib/curl_ntlm_core.c deleted file mode 100644 index ea7548dd18..0000000000 --- a/Externals/curl/lib/curl_ntlm_core.c +++ /dev/null @@ -1,761 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_NTLM) - -/* - * NTLM details: - * - * http://davenport.sourceforge.net/ntlm.html - * https://www.innovation.ch/java/ntlm.html - */ - -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - -#ifdef USE_OPENSSL - -# ifdef USE_OPENSSL -# include -# ifndef OPENSSL_NO_MD4 -# include -# endif -# include -# include -# include -# else -# include -# ifndef OPENSSL_NO_MD4 -# include -# endif -# include -# include -# include -# endif -# if (OPENSSL_VERSION_NUMBER < 0x00907001L) -# define DES_key_schedule des_key_schedule -# define DES_cblock des_cblock -# define DES_set_odd_parity des_set_odd_parity -# define DES_set_key des_set_key -# define DES_ecb_encrypt des_ecb_encrypt -# define DESKEY(x) x -# define DESKEYARG(x) x -# else -# define DESKEYARG(x) *x -# define DESKEY(x) &x -# endif - -#elif defined(USE_GNUTLS_NETTLE) - -# include -# include - -#elif defined(USE_GNUTLS) - -# include -# define MD5_DIGEST_LENGTH 16 -# define MD4_DIGEST_LENGTH 16 - -#elif defined(USE_NSS) - -# include -# include -# include -# include "curl_md4.h" -# define MD5_DIGEST_LENGTH MD5_LENGTH - -#elif defined(USE_DARWINSSL) - -# include -# include - -#elif defined(USE_OS400CRYPTO) -# include "cipher.mih" /* mih/cipher */ -# include "curl_md4.h" -#elif defined(USE_WIN32_CRYPTO) -# include -#else -# error "Can't compile NTLM support without a crypto library." -#endif - -#include "urldata.h" -#include "non-ascii.h" -#include "rawstr.h" -#include "curl_ntlm_core.h" -#include "curl_md5.h" -#include "curl_hmac.h" -#include "warnless.h" -#include "curl_endian.h" -#include "curl_des.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#define NTLM_HMAC_MD5_LEN (16) -#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00" -#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4) - -/* -* Turns a 56-bit key into being 64-bit wide. -*/ -static void extend_key_56_to_64(const unsigned char *key_56, char *key) -{ - key[0] = key_56[0]; - key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1)); - key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2)); - key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3)); - key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4)); - key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5)); - key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6)); - key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF); -} - -#ifdef USE_OPENSSL -/* - * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The - * key schedule ks is also set. - */ -static void setup_des_key(const unsigned char *key_56, - DES_key_schedule DESKEYARG(ks)) -{ - DES_cblock key; - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, (char *) &key); - - /* Set the key parity to odd */ - DES_set_odd_parity(&key); - - /* Set the key */ - DES_set_key(&key, ks); -} - -#elif defined(USE_GNUTLS_NETTLE) - -static void setup_des_key(const unsigned char *key_56, - struct des_ctx *des) -{ - char key[8]; - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); - - /* Set the key */ - des_set_key(des, (const uint8_t *) key); -} - -#elif defined(USE_GNUTLS) - -/* - * Turns a 56 bit key into the 64 bit, odd parity key and sets the key. - */ -static void setup_des_key(const unsigned char *key_56, - gcry_cipher_hd_t *des) -{ - char key[8]; - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); - - /* Set the key */ - gcry_cipher_setkey(*des, key, sizeof(key)); -} - -#elif defined(USE_NSS) - -/* - * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using - * the expanded key. The caller is responsible for giving 64 bit of valid - * data is IN and (at least) 64 bit large buffer as OUT. - */ -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */ - PK11SlotInfo *slot = NULL; - char key[8]; /* expanded 64 bit key */ - SECItem key_item; - PK11SymKey *symkey = NULL; - SECItem *param = NULL; - PK11Context *ctx = NULL; - int out_len; /* not used, required by NSS */ - bool rv = FALSE; - - /* use internal slot for DES encryption (requires NSS to be initialized) */ - slot = PK11_GetInternalKeySlot(); - if(!slot) - return FALSE; - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); - - /* Import the key */ - key_item.data = (unsigned char *)key; - key_item.len = sizeof(key); - symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT, - &key_item, NULL); - if(!symkey) - goto fail; - - /* Create the DES encryption context */ - param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL); - if(!param) - goto fail; - ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param); - if(!ctx) - goto fail; - - /* Perform the encryption */ - if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8, - (unsigned char *)in, /* inbuflen */ 8) - && SECSuccess == PK11_Finalize(ctx)) - rv = /* all OK */ TRUE; - -fail: - /* cleanup */ - if(ctx) - PK11_DestroyContext(ctx, PR_TRUE); - if(symkey) - PK11_FreeSymKey(symkey); - if(param) - SECITEM_FreeItem(param, PR_TRUE); - PK11_FreeSlot(slot); - return rv; -} - -#elif defined(USE_DARWINSSL) - -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - char key[8]; - size_t out_len; - CCCryptorStatus err; - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) key, sizeof(key)); - - /* Perform the encryption */ - err = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionECBMode, key, - kCCKeySizeDES, NULL, in, 8 /* inbuflen */, out, - 8 /* outbuflen */, &out_len); - - return err == kCCSuccess; -} - -#elif defined(USE_OS400CRYPTO) - -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - char key[8]; - _CIPHER_Control_T ctl; - - /* Setup the cipher control structure */ - ctl.Func_ID = ENCRYPT_ONLY; - ctl.Data_Len = sizeof(key); - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, ctl.Crypto_Key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) ctl.Crypto_Key, ctl.Data_Len); - - /* Perform the encryption */ - _CIPHER((_SPCPTR *) &out, &ctl, (_SPCPTR *) &in); - - return TRUE; -} - -#elif defined(USE_WIN32_CRYPTO) - -static bool encrypt_des(const unsigned char *in, unsigned char *out, - const unsigned char *key_56) -{ - HCRYPTPROV hprov; - HCRYPTKEY hkey; - struct { - BLOBHEADER hdr; - unsigned int len; - char key[8]; - } blob; - DWORD len = 8; - - /* Acquire the crypto provider */ - if(!CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) - return FALSE; - - /* Setup the key blob structure */ - memset(&blob, 0, sizeof(blob)); - blob.hdr.bType = PLAINTEXTKEYBLOB; - blob.hdr.bVersion = 2; - blob.hdr.aiKeyAlg = CALG_DES; - blob.len = sizeof(blob.key); - - /* Expand the 56-bit key to 64-bits */ - extend_key_56_to_64(key_56, blob.key); - - /* Set the key parity to odd */ - Curl_des_set_odd_parity((unsigned char *) blob.key, sizeof(blob.key)); - - /* Import the key */ - if(!CryptImportKey(hprov, (BYTE *) &blob, sizeof(blob), 0, 0, &hkey)) { - CryptReleaseContext(hprov, 0); - - return FALSE; - } - - memcpy(out, in, 8); - - /* Perform the encryption */ - CryptEncrypt(hkey, 0, FALSE, 0, out, &len, len); - - CryptDestroyKey(hkey); - CryptReleaseContext(hprov, 0); - - return TRUE; -} - -#endif /* defined(USE_WIN32_CRYPTO) */ - - /* - * takes a 21 byte array and treats it as 3 56-bit DES keys. The - * 8 byte plaintext is encrypted with each key and the resulting 24 - * bytes are stored in the results array. - */ -void Curl_ntlm_core_lm_resp(const unsigned char *keys, - const unsigned char *plaintext, - unsigned char *results) -{ -#ifdef USE_OPENSSL - DES_key_schedule ks; - - setup_des_key(keys, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results, - DESKEY(ks), DES_ENCRYPT); - - setup_des_key(keys + 7, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 8), - DESKEY(ks), DES_ENCRYPT); - - setup_des_key(keys + 14, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results + 16), - DESKEY(ks), DES_ENCRYPT); -#elif defined(USE_GNUTLS_NETTLE) - struct des_ctx des; - setup_des_key(keys, &des); - des_encrypt(&des, 8, results, plaintext); - setup_des_key(keys + 7, &des); - des_encrypt(&des, 8, results + 8, plaintext); - setup_des_key(keys + 14, &des); - des_encrypt(&des, 8, results + 16, plaintext); -#elif defined(USE_GNUTLS) - gcry_cipher_hd_t des; - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(keys, &des); - gcry_cipher_encrypt(des, results, 8, plaintext, 8); - gcry_cipher_close(des); - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(keys + 7, &des); - gcry_cipher_encrypt(des, results + 8, 8, plaintext, 8); - gcry_cipher_close(des); - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(keys + 14, &des); - gcry_cipher_encrypt(des, results + 16, 8, plaintext, 8); - gcry_cipher_close(des); -#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \ - || defined(USE_WIN32_CRYPTO) - encrypt_des(plaintext, results, keys); - encrypt_des(plaintext, results + 8, keys + 7); - encrypt_des(plaintext, results + 16, keys + 14); -#endif -} - -/* - * Set up lanmanager hashed password - */ -CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data, - const char *password, - unsigned char *lmbuffer /* 21 bytes */) -{ - CURLcode result; - unsigned char pw[14]; - static const unsigned char magic[] = { - 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */ - }; - size_t len = CURLMIN(strlen(password), 14); - - Curl_strntoupper((char *)pw, password, len); - memset(&pw[len], 0, 14 - len); - - /* - * The LanManager hashed password needs to be created using the - * password in the network encoding not the host encoding. - */ - result = Curl_convert_to_network(data, (char *)pw, 14); - if(result) - return result; - - { - /* Create LanManager hashed password. */ - -#ifdef USE_OPENSSL - DES_key_schedule ks; - - setup_des_key(pw, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer, - DESKEY(ks), DES_ENCRYPT); - - setup_des_key(pw + 7, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8), - DESKEY(ks), DES_ENCRYPT); -#elif defined(USE_GNUTLS_NETTLE) - struct des_ctx des; - setup_des_key(pw, &des); - des_encrypt(&des, 8, lmbuffer, magic); - setup_des_key(pw + 7, &des); - des_encrypt(&des, 8, lmbuffer + 8, magic); -#elif defined(USE_GNUTLS) - gcry_cipher_hd_t des; - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(pw, &des); - gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8); - gcry_cipher_close(des); - - gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(pw + 7, &des); - gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8); - gcry_cipher_close(des); -#elif defined(USE_NSS) || defined(USE_DARWINSSL) || defined(USE_OS400CRYPTO) \ - || defined(USE_WIN32_CRYPTO) - encrypt_des(magic, lmbuffer, pw); - encrypt_des(magic, lmbuffer + 8, pw + 7); -#endif - - memset(lmbuffer + 16, 0, 21 - 16); - } - - return CURLE_OK; -} - -#if USE_NTRESPONSES -static void ascii_to_unicode_le(unsigned char *dest, const char *src, - size_t srclen) -{ - size_t i; - for(i = 0; i < srclen; i++) { - dest[2 * i] = (unsigned char)src[i]; - dest[2 * i + 1] = '\0'; - } -} - -#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI) - -static void ascii_uppercase_to_unicode_le(unsigned char *dest, - const char *src, size_t srclen) -{ - size_t i; - for(i = 0; i < srclen; i++) { - dest[2 * i] = (unsigned char)(toupper(src[i])); - dest[2 * i + 1] = '\0'; - } -} - -#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */ - -/* - * Set up nt hashed passwords - * @unittest: 1600 - */ -CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data, - const char *password, - unsigned char *ntbuffer /* 21 bytes */) -{ - size_t len = strlen(password); - unsigned char *pw = malloc(len * 2); - CURLcode result; - if(!pw) - return CURLE_OUT_OF_MEMORY; - - ascii_to_unicode_le(pw, password, len); - - /* - * The NT hashed password needs to be created using the password in the - * network encoding not the host encoding. - */ - result = Curl_convert_to_network(data, (char *)pw, len * 2); - if(result) - return result; - - { - /* Create NT hashed password. */ -#ifdef USE_OPENSSL - MD4_CTX MD4pw; - MD4_Init(&MD4pw); - MD4_Update(&MD4pw, pw, 2 * len); - MD4_Final(ntbuffer, &MD4pw); -#elif defined(USE_GNUTLS_NETTLE) - struct md4_ctx MD4pw; - md4_init(&MD4pw); - md4_update(&MD4pw, (unsigned int)(2 * len), pw); - md4_digest(&MD4pw, MD4_DIGEST_SIZE, ntbuffer); -#elif defined(USE_GNUTLS) - gcry_md_hd_t MD4pw; - gcry_md_open(&MD4pw, GCRY_MD_MD4, 0); - gcry_md_write(MD4pw, pw, 2 * len); - memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH); - gcry_md_close(MD4pw); -#elif defined(USE_NSS) || defined(USE_OS400CRYPTO) - Curl_md4it(ntbuffer, pw, 2 * len); -#elif defined(USE_DARWINSSL) - (void)CC_MD4(pw, (CC_LONG)(2 * len), ntbuffer); -#elif defined(USE_WIN32_CRYPTO) - HCRYPTPROV hprov; - if(CryptAcquireContext(&hprov, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - HCRYPTHASH hhash; - if(CryptCreateHash(hprov, CALG_MD4, 0, 0, &hhash)) { - DWORD length = 16; - CryptHashData(hhash, pw, (unsigned int)len * 2, 0); - CryptGetHashParam(hhash, HP_HASHVAL, ntbuffer, &length, 0); - CryptDestroyHash(hhash); - } - CryptReleaseContext(hprov, 0); - } -#endif - - memset(ntbuffer + 16, 0, 21 - 16); - } - - free(pw); - - return CURLE_OK; -} - -#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI) - -/* This returns the HMAC MD5 digest */ -CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen, - const unsigned char *data, unsigned int datalen, - unsigned char *output) -{ - HMAC_context *ctxt = Curl_HMAC_init(Curl_HMAC_MD5, key, keylen); - - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - /* Update the digest with the given challenge */ - Curl_HMAC_update(ctxt, data, datalen); - - /* Finalise the digest */ - Curl_HMAC_final(ctxt, output); - - return CURLE_OK; -} - -/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode - * (uppercase UserName + Domain) as the data - */ -CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, - const char *domain, size_t domlen, - unsigned char *ntlmhash, - unsigned char *ntlmv2hash) -{ - /* Unicode representation */ - size_t identity_len = (userlen + domlen) * 2; - unsigned char *identity = malloc(identity_len); - CURLcode result = CURLE_OK; - - if(!identity) - return CURLE_OUT_OF_MEMORY; - - ascii_uppercase_to_unicode_le(identity, user, userlen); - ascii_to_unicode_le(identity + (userlen << 1), domain, domlen); - - result = Curl_hmac_md5(ntlmhash, 16, identity, curlx_uztoui(identity_len), - ntlmv2hash); - - free(identity); - - return result; -} - -/* - * Curl_ntlm_core_mk_ntlmv2_resp() - * - * This creates the NTLMv2 response as set in the ntlm type-3 message. - * - * Parameters: - * - * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) - * challenge_client [in] - The client nonce (8 bytes) - * ntlm [in] - The ntlm data struct being used to read TargetInfo - and Server challenge received in the type-2 message - * ntresp [out] - The address where a pointer to newly allocated - * memory holding the NTLMv2 response. - * ntresp_len [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, - unsigned char *challenge_client, - struct ntlmdata *ntlm, - unsigned char **ntresp, - unsigned int *ntresp_len) -{ -/* NTLMv2 response structure : ------------------------------------------------------------------------------- -0 HMAC MD5 16 bytes -------BLOB-------------------------------------------------------------------- -16 Signature 0x01010000 -20 Reserved long (0x00000000) -24 Timestamp LE, 64-bit signed value representing the number of - tenths of a microsecond since January 1, 1601. -32 Client Nonce 8 bytes -40 Unknown 4 bytes -44 Target Info N bytes (from the type-2 message) -44+N Unknown 4 bytes ------------------------------------------------------------------------------- -*/ - - unsigned int len = 0; - unsigned char *ptr = NULL; - unsigned char hmac_output[NTLM_HMAC_MD5_LEN]; - curl_off_t tw; - - CURLcode result = CURLE_OK; - -#if CURL_SIZEOF_CURL_OFF_T < 8 -#error "this section needs 64bit support to work" -#endif - - /* Calculate the timestamp */ -#ifdef DEBUGBUILD - char *force_timestamp = getenv("CURL_FORCETIME"); - if(force_timestamp) - tw = CURL_OFF_T_C(11644473600) * 10000000; - else -#endif - tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000; - - /* Calculate the response len */ - len = NTLM_HMAC_MD5_LEN + NTLMv2_BLOB_LEN; - - /* Allocate the response */ - ptr = malloc(len); - if(!ptr) - return CURLE_OUT_OF_MEMORY; - - memset(ptr, 0, len); - - /* Create the BLOB structure */ - snprintf((char *)ptr + NTLM_HMAC_MD5_LEN, NTLMv2_BLOB_LEN, - NTLMv2_BLOB_SIGNATURE - "%c%c%c%c", /* Reserved = 0 */ - 0, 0, 0, 0); - - Curl_write64_le(tw, ptr + 24); - memcpy(ptr + 32, challenge_client, 8); - memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len); - - /* Concatenate the Type 2 challenge with the BLOB and do HMAC MD5 */ - memcpy(ptr + 8, &ntlm->nonce[0], 8); - result = Curl_hmac_md5(ntlmv2hash, NTLM_HMAC_MD5_LEN, ptr + 8, - NTLMv2_BLOB_LEN + 8, hmac_output); - if(result) { - free(ptr); - return result; - } - - /* Concatenate the HMAC MD5 output with the BLOB */ - memcpy(ptr, hmac_output, NTLM_HMAC_MD5_LEN); - - /* Return the response */ - *ntresp = ptr; - *ntresp_len = len; - - return result; -} - -/* - * Curl_ntlm_core_mk_lmv2_resp() - * - * This creates the LMv2 response as used in the ntlm type-3 message. - * - * Parameters: - * - * ntlmv2hash [in] - The ntlmv2 hash (16 bytes) - * challenge_client [in] - The client nonce (8 bytes) - * challenge_client [in] - The server challenge (8 bytes) - * lmresp [out] - The LMv2 response (24 bytes) - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, - unsigned char *challenge_client, - unsigned char *challenge_server, - unsigned char *lmresp) -{ - unsigned char data[16]; - unsigned char hmac_output[16]; - CURLcode result = CURLE_OK; - - memcpy(&data[0], challenge_server, 8); - memcpy(&data[8], challenge_client, 8); - - result = Curl_hmac_md5(ntlmv2hash, 16, &data[0], 16, hmac_output); - if(result) - return result; - - /* Concatenate the HMAC MD5 output with the client nonce */ - memcpy(lmresp, hmac_output, 16); - memcpy(lmresp+16, challenge_client, 8); - - return result; -} - -#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */ - -#endif /* USE_NTRESPONSES */ - -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* USE_NTLM */ diff --git a/Externals/curl/lib/curl_ntlm_core.h b/Externals/curl/lib/curl_ntlm_core.h deleted file mode 100644 index cf37dc811a..0000000000 --- a/Externals/curl/lib/curl_ntlm_core.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef HEADER_CURL_NTLM_CORE_H -#define HEADER_CURL_NTLM_CORE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_NTLM) - -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - -#ifdef USE_OPENSSL -# if !defined(OPENSSL_VERSION_NUMBER) && \ - !defined(HEADER_SSL_H) && !defined(HEADER_MD5_H) -# error "curl_ntlm_core.h shall not be included before OpenSSL headers." -# endif -# ifdef OPENSSL_NO_MD4 -# define USE_NTRESPONSES 0 -# define USE_NTLM2SESSION 0 -# define USE_NTLM_V2 0 -# endif -#endif - -/* Define USE_NTRESPONSES to 1 in order to make the type-3 message include - * the NT response message. */ -#ifndef USE_NTRESPONSES -#define USE_NTRESPONSES 1 -#endif - -/* Define USE_NTLM2SESSION to 1 in order to make the type-3 message include the - NTLM2Session response message, requires USE_NTRESPONSES defined to 1 and a - Crypto engine that we have curl_ssl_md5sum() for. */ -#if !defined(USE_NTLM2SESSION) && USE_NTRESPONSES && !defined(USE_WIN32_CRYPTO) -#define USE_NTLM2SESSION 1 -#endif - -/* Define USE_NTLM_V2 to 1 in order to allow the type-3 message to include the - LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1 - and support for 64-bit integers. */ -#if !defined(USE_NTLM_V2) && USE_NTRESPONSES && (CURL_SIZEOF_CURL_OFF_T > 4) -#define USE_NTLM_V2 1 -#endif - -void Curl_ntlm_core_lm_resp(const unsigned char *keys, - const unsigned char *plaintext, - unsigned char *results); - -CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data, - const char *password, - unsigned char *lmbuffer /* 21 bytes */); - -#if USE_NTRESPONSES -CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data, - const char *password, - unsigned char *ntbuffer /* 21 bytes */); - -#if USE_NTLM_V2 && !defined(USE_WINDOWS_SSPI) - -CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen, - const unsigned char *data, unsigned int datalen, - unsigned char *output); - -CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen, - const char *domain, size_t domlen, - unsigned char *ntlmhash, - unsigned char *ntlmv2hash); - -CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash, - unsigned char *challenge_client, - struct ntlmdata *ntlm, - unsigned char **ntresp, - unsigned int *ntresp_len); - -CURLcode Curl_ntlm_core_mk_lmv2_resp(unsigned char *ntlmv2hash, - unsigned char *challenge_client, - unsigned char *challenge_server, - unsigned char *lmresp); - -#endif /* USE_NTLM_V2 && !USE_WINDOWS_SSPI */ - -#endif /* USE_NTRESPONSES */ - -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* USE_NTLM */ - -#endif /* HEADER_CURL_NTLM_CORE_H */ diff --git a/Externals/curl/lib/curl_ntlm_wb.c b/Externals/curl/lib/curl_ntlm_wb.c deleted file mode 100644 index afdea16c05..0000000000 --- a/Externals/curl/lib/curl_ntlm_wb.c +++ /dev/null @@ -1,430 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ - defined(NTLM_WB_ENABLED) - -/* - * NTLM details: - * - * http://davenport.sourceforge.net/ntlm.html - * https://www.innovation.ch/java/ntlm.html - */ - -#define DEBUG_ME 0 - -#ifdef HAVE_SYS_WAIT_H -#include -#endif -#ifdef HAVE_SIGNAL_H -#include -#endif -#ifdef HAVE_PWD_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "select.h" -#include "vauth/ntlm.h" -#include "curl_ntlm_wb.h" -#include "url.h" -#include "strerror.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#if DEBUG_ME -# define DEBUG_OUT(x) x -#else -# define DEBUG_OUT(x) Curl_nop_stmt -#endif - -/* Portable 'sclose_nolog' used only in child process instead of 'sclose' - to avoid fooling the socket leak detector */ -#if defined(HAVE_CLOSESOCKET) -# define sclose_nolog(x) closesocket((x)) -#elif defined(HAVE_CLOSESOCKET_CAMEL) -# define sclose_nolog(x) CloseSocket((x)) -#else -# define sclose_nolog(x) close((x)) -#endif - -void Curl_ntlm_wb_cleanup(struct connectdata *conn) -{ - if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD) { - sclose(conn->ntlm_auth_hlpr_socket); - conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; - } - - if(conn->ntlm_auth_hlpr_pid) { - int i; - for(i = 0; i < 4; i++) { - pid_t ret = waitpid(conn->ntlm_auth_hlpr_pid, NULL, WNOHANG); - if(ret == conn->ntlm_auth_hlpr_pid || errno == ECHILD) - break; - switch(i) { - case 0: - kill(conn->ntlm_auth_hlpr_pid, SIGTERM); - break; - case 1: - /* Give the process another moment to shut down cleanly before - bringing down the axe */ - Curl_wait_ms(1); - break; - case 2: - kill(conn->ntlm_auth_hlpr_pid, SIGKILL); - break; - case 3: - break; - } - } - conn->ntlm_auth_hlpr_pid = 0; - } - - free(conn->challenge_header); - conn->challenge_header = NULL; - free(conn->response_header); - conn->response_header = NULL; -} - -static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp) -{ - curl_socket_t sockfds[2]; - pid_t child_pid; - const char *username; - char *slash, *domain = NULL; - const char *ntlm_auth = NULL; - char *ntlm_auth_alloc = NULL; -#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - struct passwd pw, *pw_res; - char pwbuf[1024]; -#endif - int error; - - /* Return if communication with ntlm_auth already set up */ - if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD || - conn->ntlm_auth_hlpr_pid) - return CURLE_OK; - - username = userp; - /* The real ntlm_auth really doesn't like being invoked with an - empty username. It won't make inferences for itself, and expects - the client to do so (mostly because it's really designed for - servers like squid to use for auth, and client support is an - afterthought for it). So try hard to provide a suitable username - if we don't already have one. But if we can't, provide the - empty one anyway. Perhaps they have an implementation of the - ntlm_auth helper which *doesn't* need it so we might as well try */ - if(!username || !username[0]) { - username = getenv("NTLMUSER"); - if(!username || !username[0]) - username = getenv("LOGNAME"); - if(!username || !username[0]) - username = getenv("USER"); -#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - if((!username || !username[0]) && - !getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) && - pw_res) { - username = pw.pw_name; - } -#endif - if(!username || !username[0]) - username = userp; - } - slash = strpbrk(username, "\\/"); - if(slash) { - if((domain = strdup(username)) == NULL) - return CURLE_OUT_OF_MEMORY; - slash = domain + (slash - username); - *slash = '\0'; - username = username + (slash - domain) + 1; - } - - /* For testing purposes, when DEBUGBUILD is defined and environment - variable CURL_NTLM_WB_FILE is set a fake_ntlm is used to perform - NTLM challenge/response which only accepts commands and output - strings pre-written in test case definitions */ -#ifdef DEBUGBUILD - ntlm_auth_alloc = curl_getenv("CURL_NTLM_WB_FILE"); - if(ntlm_auth_alloc) - ntlm_auth = ntlm_auth_alloc; - else -#endif - ntlm_auth = NTLM_WB_FILE; - - if(access(ntlm_auth, X_OK) != 0) { - error = ERRNO; - failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s", - ntlm_auth, error, Curl_strerror(conn, error)); - goto done; - } - - if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) { - error = ERRNO; - failf(conn->data, "Could not open socket pair. errno %d: %s", - error, Curl_strerror(conn, error)); - goto done; - } - - child_pid = fork(); - if(child_pid == -1) { - error = ERRNO; - sclose(sockfds[0]); - sclose(sockfds[1]); - failf(conn->data, "Could not fork. errno %d: %s", - error, Curl_strerror(conn, error)); - goto done; - } - else if(!child_pid) { - /* - * child process - */ - - /* Don't use sclose in the child since it fools the socket leak detector */ - sclose_nolog(sockfds[0]); - if(dup2(sockfds[1], STDIN_FILENO) == -1) { - error = ERRNO; - failf(conn->data, "Could not redirect child stdin. errno %d: %s", - error, Curl_strerror(conn, error)); - exit(1); - } - - if(dup2(sockfds[1], STDOUT_FILENO) == -1) { - error = ERRNO; - failf(conn->data, "Could not redirect child stdout. errno %d: %s", - error, Curl_strerror(conn, error)); - exit(1); - } - - if(domain) - execl(ntlm_auth, ntlm_auth, - "--helper-protocol", "ntlmssp-client-1", - "--use-cached-creds", - "--username", username, - "--domain", domain, - NULL); - else - execl(ntlm_auth, ntlm_auth, - "--helper-protocol", "ntlmssp-client-1", - "--use-cached-creds", - "--username", username, - NULL); - - error = ERRNO; - sclose_nolog(sockfds[1]); - failf(conn->data, "Could not execl(). errno %d: %s", - error, Curl_strerror(conn, error)); - exit(1); - } - - sclose(sockfds[1]); - conn->ntlm_auth_hlpr_socket = sockfds[0]; - conn->ntlm_auth_hlpr_pid = child_pid; - free(domain); - free(ntlm_auth_alloc); - return CURLE_OK; - -done: - free(domain); - free(ntlm_auth_alloc); - return CURLE_REMOTE_ACCESS_DENIED; -} - -static CURLcode ntlm_wb_response(struct connectdata *conn, - const char *input, curlntlm state) -{ - char *buf = malloc(NTLM_BUFSIZE); - size_t len_in = strlen(input), len_out = 0; - - if(!buf) - return CURLE_OUT_OF_MEMORY; - - while(len_in > 0) { - ssize_t written = swrite(conn->ntlm_auth_hlpr_socket, input, len_in); - if(written == -1) { - /* Interrupted by a signal, retry it */ - if(errno == EINTR) - continue; - /* write failed if other errors happen */ - goto done; - } - input += written; - len_in -= written; - } - /* Read one line */ - while(1) { - ssize_t size; - char *newbuf; - - size = sread(conn->ntlm_auth_hlpr_socket, buf + len_out, NTLM_BUFSIZE); - if(size == -1) { - if(errno == EINTR) - continue; - goto done; - } - else if(size == 0) - goto done; - - len_out += size; - if(buf[len_out - 1] == '\n') { - buf[len_out - 1] = '\0'; - break; - } - newbuf = realloc(buf, len_out + NTLM_BUFSIZE); - if(!newbuf) { - free(buf); - return CURLE_OUT_OF_MEMORY; - } - buf = newbuf; - } - - /* Samba/winbind installed but not configured */ - if(state == NTLMSTATE_TYPE1 && - len_out == 3 && - buf[0] == 'P' && buf[1] == 'W') - goto done; - /* invalid response */ - if(len_out < 4) - goto done; - if(state == NTLMSTATE_TYPE1 && - (buf[0]!='Y' || buf[1]!='R' || buf[2]!=' ')) - goto done; - if(state == NTLMSTATE_TYPE2 && - (buf[0]!='K' || buf[1]!='K' || buf[2]!=' ') && - (buf[0]!='A' || buf[1]!='F' || buf[2]!=' ')) - goto done; - - conn->response_header = aprintf("NTLM %.*s", len_out - 4, buf + 3); - free(buf); - return CURLE_OK; -done: - free(buf); - return CURLE_REMOTE_ACCESS_DENIED; -} - -/* - * This is for creating ntlm header output by delegating challenge/response - * to Samba's winbind daemon helper ntlm_auth. - */ -CURLcode Curl_output_ntlm_wb(struct connectdata *conn, - bool proxy) -{ - /* point to the address of the pointer that holds the string to send to the - server, which is for a plain host or for a HTTP proxy */ - char **allocuserpwd; - /* point to the name and password for this */ - const char *userp; - /* point to the correct struct with this */ - struct ntlmdata *ntlm; - struct auth *authp; - - CURLcode res = CURLE_OK; - char *input; - - DEBUGASSERT(conn); - DEBUGASSERT(conn->data); - - if(proxy) { - allocuserpwd = &conn->allocptr.proxyuserpwd; - userp = conn->proxyuser; - ntlm = &conn->proxyntlm; - authp = &conn->data->state.authproxy; - } - else { - allocuserpwd = &conn->allocptr.userpwd; - userp = conn->user; - ntlm = &conn->ntlm; - authp = &conn->data->state.authhost; - } - authp->done = FALSE; - - /* not set means empty */ - if(!userp) - userp=""; - - switch(ntlm->state) { - case NTLMSTATE_TYPE1: - default: - /* Use Samba's 'winbind' daemon to support NTLM authentication, - * by delegating the NTLM challenge/response protocal to a helper - * in ntlm_auth. - * http://devel.squid-cache.org/ntlm/squid_helper_protocol.html - * https://www.samba.org/samba/docs/man/manpages-3/winbindd.8.html - * https://www.samba.org/samba/docs/man/manpages-3/ntlm_auth.1.html - * Preprocessor symbol 'NTLM_WB_ENABLED' is defined when this - * feature is enabled and 'NTLM_WB_FILE' symbol holds absolute - * filename of ntlm_auth helper. - * If NTLM authentication using winbind fails, go back to original - * request handling process. - */ - /* Create communication with ntlm_auth */ - res = ntlm_wb_init(conn, userp); - if(res) - return res; - res = ntlm_wb_response(conn, "YR\n", ntlm->state); - if(res) - return res; - - free(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: %s\r\n", - proxy ? "Proxy-" : "", - conn->response_header); - DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); - free(conn->response_header); - conn->response_header = NULL; - break; - case NTLMSTATE_TYPE2: - input = aprintf("TT %s\n", conn->challenge_header); - if(!input) - return CURLE_OUT_OF_MEMORY; - res = ntlm_wb_response(conn, input, ntlm->state); - free(input); - input = NULL; - if(res) - return res; - - free(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: %s\r\n", - proxy ? "Proxy-" : "", - conn->response_header); - DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); - ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */ - authp->done = TRUE; - Curl_ntlm_wb_cleanup(conn); - break; - case NTLMSTATE_TYPE3: - /* connection is already authenticated, - * don't send a header in future requests */ - free(*allocuserpwd); - *allocuserpwd=NULL; - authp->done = TRUE; - break; - } - - return CURLE_OK; -} - -#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */ diff --git a/Externals/curl/lib/curl_ntlm_wb.h b/Externals/curl/lib/curl_ntlm_wb.h deleted file mode 100644 index aba3d469c3..0000000000 --- a/Externals/curl/lib/curl_ntlm_wb.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef HEADER_CURL_NTLM_WB_H -#define HEADER_CURL_NTLM_WB_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ - defined(NTLM_WB_ENABLED) - -/* this is for creating ntlm header output by delegating challenge/response - to Samba's winbind daemon helper ntlm_auth */ -CURLcode Curl_output_ntlm_wb(struct connectdata *conn, bool proxy); - -void Curl_ntlm_wb_cleanup(struct connectdata *conn); - -#endif /* !CURL_DISABLE_HTTP && USE_NTLM && NTLM_WB_ENABLED */ - -#endif /* HEADER_CURL_NTLM_WB_H */ diff --git a/Externals/curl/lib/curl_printf.h b/Externals/curl/lib/curl_printf.h deleted file mode 100644 index 49857cdb0d..0000000000 --- a/Externals/curl/lib/curl_printf.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef HEADER_CURL_PRINTF_H -#define HEADER_CURL_PRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * This header should be included by ALL code in libcurl that uses any - * *rintf() functions. - */ - -#include - -# undef printf -# undef fprintf -# undef snprintf -# undef vprintf -# undef vfprintf -# undef vsnprintf -# undef aprintf -# undef vaprintf -# define printf curl_mprintf -# define fprintf curl_mfprintf -# define snprintf curl_msnprintf -# define vprintf curl_mvprintf -# define vfprintf curl_mvfprintf -# define vsnprintf curl_mvsnprintf -# define aprintf curl_maprintf -# define vaprintf curl_mvaprintf - -/* We define away the sprintf functions unconditonally since we don't want - internal code to be using them, intentionally or by mistake!*/ -# undef sprintf -# undef vsprintf -# define sprintf sprintf_was_used -# define vsprintf vsprintf_was_used - -#endif /* HEADER_CURL_PRINTF_H */ diff --git a/Externals/curl/lib/curl_rtmp.c b/Externals/curl/lib/curl_rtmp.c deleted file mode 100644 index 06dd047a40..0000000000 --- a/Externals/curl/lib/curl_rtmp.c +++ /dev/null @@ -1,306 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. - * Copyright (C) 2010, Howard Chu, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_LIBRTMP - -#include "urldata.h" -#include "nonblock.h" /* for curlx_nonblock */ -#include "progress.h" /* for Curl_pgrsSetUploadSize */ -#include "transfer.h" -#include "warnless.h" -#include -#include -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#ifdef _WIN32 -#define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e) -#define SET_RCVTIMEO(tv,s) int tv = s*1000 -#else -#define SET_RCVTIMEO(tv,s) struct timeval tv = {s,0} -#endif - -#define DEF_BUFTIME (2*60*60*1000) /* 2 hours */ - -static CURLcode rtmp_setup_connection(struct connectdata *conn); -static CURLcode rtmp_do(struct connectdata *conn, bool *done); -static CURLcode rtmp_done(struct connectdata *conn, CURLcode, bool premature); -static CURLcode rtmp_connect(struct connectdata *conn, bool *done); -static CURLcode rtmp_disconnect(struct connectdata *conn, bool dead); - -static Curl_recv rtmp_recv; -static Curl_send rtmp_send; - -/* - * RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu - */ - -const struct Curl_handler Curl_handler_rtmp = { - "RTMP", /* scheme */ - rtmp_setup_connection, /* setup_connection */ - rtmp_do, /* do_it */ - rtmp_done, /* done */ - ZERO_NULL, /* do_more */ - rtmp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - rtmp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_RTMP, /* defport */ - CURLPROTO_RTMP, /* protocol */ - PROTOPT_NONE /* flags*/ -}; - -const struct Curl_handler Curl_handler_rtmpt = { - "RTMPT", /* scheme */ - rtmp_setup_connection, /* setup_connection */ - rtmp_do, /* do_it */ - rtmp_done, /* done */ - ZERO_NULL, /* do_more */ - rtmp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - rtmp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_RTMPT, /* defport */ - CURLPROTO_RTMPT, /* protocol */ - PROTOPT_NONE /* flags*/ -}; - -const struct Curl_handler Curl_handler_rtmpe = { - "RTMPE", /* scheme */ - rtmp_setup_connection, /* setup_connection */ - rtmp_do, /* do_it */ - rtmp_done, /* done */ - ZERO_NULL, /* do_more */ - rtmp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - rtmp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_RTMP, /* defport */ - CURLPROTO_RTMPE, /* protocol */ - PROTOPT_NONE /* flags*/ -}; - -const struct Curl_handler Curl_handler_rtmpte = { - "RTMPTE", /* scheme */ - rtmp_setup_connection, /* setup_connection */ - rtmp_do, /* do_it */ - rtmp_done, /* done */ - ZERO_NULL, /* do_more */ - rtmp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - rtmp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_RTMPT, /* defport */ - CURLPROTO_RTMPTE, /* protocol */ - PROTOPT_NONE /* flags*/ -}; - -const struct Curl_handler Curl_handler_rtmps = { - "RTMPS", /* scheme */ - rtmp_setup_connection, /* setup_connection */ - rtmp_do, /* do_it */ - rtmp_done, /* done */ - ZERO_NULL, /* do_more */ - rtmp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - rtmp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_RTMPS, /* defport */ - CURLPROTO_RTMPS, /* protocol */ - PROTOPT_NONE /* flags*/ -}; - -const struct Curl_handler Curl_handler_rtmpts = { - "RTMPTS", /* scheme */ - rtmp_setup_connection, /* setup_connection */ - rtmp_do, /* do_it */ - rtmp_done, /* done */ - ZERO_NULL, /* do_more */ - rtmp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - rtmp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_RTMPS, /* defport */ - CURLPROTO_RTMPTS, /* protocol */ - PROTOPT_NONE /* flags*/ -}; - -static CURLcode rtmp_setup_connection(struct connectdata *conn) -{ - RTMP *r = RTMP_Alloc(); - if(!r) - return CURLE_OUT_OF_MEMORY; - - RTMP_Init(r); - RTMP_SetBufferMS(r, DEF_BUFTIME); - if(!RTMP_SetupURL(r, conn->data->change.url)) { - RTMP_Free(r); - return CURLE_URL_MALFORMAT; - } - conn->proto.generic = r; - return CURLE_OK; -} - -static CURLcode rtmp_connect(struct connectdata *conn, bool *done) -{ - RTMP *r = conn->proto.generic; - SET_RCVTIMEO(tv, 10); - - r->m_sb.sb_socket = conn->sock[FIRSTSOCKET]; - - /* We have to know if it's a write before we send the - * connect request packet - */ - if(conn->data->set.upload) - r->Link.protocol |= RTMP_FEATURE_WRITE; - - /* For plain streams, use the buffer toggle trick to keep data flowing */ - if(!(r->Link.lFlags & RTMP_LF_LIVE) && - !(r->Link.protocol & RTMP_FEATURE_HTTP)) - r->Link.lFlags |= RTMP_LF_BUFX; - - (void)curlx_nonblock(r->m_sb.sb_socket, FALSE); - setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_RCVTIMEO, - (char *)&tv, sizeof(tv)); - - if(!RTMP_Connect1(r, NULL)) - return CURLE_FAILED_INIT; - - /* Clients must send a periodic BytesReceived report to the server */ - r->m_bSendCounter = true; - - *done = TRUE; - conn->recv[FIRSTSOCKET] = rtmp_recv; - conn->send[FIRSTSOCKET] = rtmp_send; - return CURLE_OK; -} - -static CURLcode rtmp_do(struct connectdata *conn, bool *done) -{ - RTMP *r = conn->proto.generic; - - if(!RTMP_ConnectStream(r, 0)) - return CURLE_FAILED_INIT; - - if(conn->data->set.upload) { - Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize); - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); - } - else - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); - *done = TRUE; - return CURLE_OK; -} - -static CURLcode rtmp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - (void)conn; /* unused */ - (void)status; /* unused */ - (void)premature; /* unused */ - - return CURLE_OK; -} - -static CURLcode rtmp_disconnect(struct connectdata *conn, - bool dead_connection) -{ - RTMP *r = conn->proto.generic; - (void)dead_connection; - if(r) { - conn->proto.generic = NULL; - RTMP_Close(r); - RTMP_Free(r); - } - return CURLE_OK; -} - -static ssize_t rtmp_recv(struct connectdata *conn, int sockindex, char *buf, - size_t len, CURLcode *err) -{ - RTMP *r = conn->proto.generic; - ssize_t nread; - - (void)sockindex; /* unused */ - - nread = RTMP_Read(r, buf, curlx_uztosi(len)); - if(nread < 0) { - if(r->m_read.status == RTMP_READ_COMPLETE || - r->m_read.status == RTMP_READ_EOF) { - conn->data->req.size = conn->data->req.bytecount; - nread = 0; - } - else - *err = CURLE_RECV_ERROR; - } - return nread; -} - -static ssize_t rtmp_send(struct connectdata *conn, int sockindex, - const void *buf, size_t len, CURLcode *err) -{ - RTMP *r = conn->proto.generic; - ssize_t num; - - (void)sockindex; /* unused */ - - num = RTMP_Write(r, (char *)buf, curlx_uztosi(len)); - if(num < 0) - *err = CURLE_SEND_ERROR; - - return num; -} -#endif /* USE_LIBRTMP */ diff --git a/Externals/curl/lib/curl_rtmp.h b/Externals/curl/lib/curl_rtmp.h deleted file mode 100644 index 3306e22005..0000000000 --- a/Externals/curl/lib/curl_rtmp.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_RTMP_H -#define HEADER_CURL_RTMP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010, Howard Chu, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifdef USE_LIBRTMP -extern const struct Curl_handler Curl_handler_rtmp; -extern const struct Curl_handler Curl_handler_rtmpt; -extern const struct Curl_handler Curl_handler_rtmpe; -extern const struct Curl_handler Curl_handler_rtmpte; -extern const struct Curl_handler Curl_handler_rtmps; -extern const struct Curl_handler Curl_handler_rtmpts; -#endif - -#endif /* HEADER_CURL_RTMP_H */ diff --git a/Externals/curl/lib/curl_sasl.c b/Externals/curl/lib/curl_sasl.c deleted file mode 100644 index 94b39e4a62..0000000000 --- a/Externals/curl/lib/curl_sasl.c +++ /dev/null @@ -1,617 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC2195 CRAM-MD5 authentication - * RFC2617 Basic and Digest Access Authentication - * RFC2831 DIGEST-MD5 authentication - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC6749 OAuth 2.0 Authorization Framework - * RFC7628 A Set of SASL Mechanisms for OAuth - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include -#include "urldata.h" - -#include "curl_base64.h" -#include "curl_md5.h" -#include "vauth/vauth.h" -#include "vtls/vtls.h" -#include "curl_hmac.h" -#include "curl_sasl.h" -#include "warnless.h" -#include "strtok.h" -#include "strequal.h" -#include "rawstr.h" -#include "sendf.h" -#include "non-ascii.h" /* included for Curl_convert_... prototypes */ -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Supported mechanisms */ -const struct { - const char *name; /* Name */ - size_t len; /* Name length */ - unsigned int bit; /* Flag bit */ -} mechtable[] = { - { "LOGIN", 5, SASL_MECH_LOGIN }, - { "PLAIN", 5, SASL_MECH_PLAIN }, - { "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 }, - { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 }, - { "GSSAPI", 6, SASL_MECH_GSSAPI }, - { "EXTERNAL", 8, SASL_MECH_EXTERNAL }, - { "NTLM", 4, SASL_MECH_NTLM }, - { "XOAUTH2", 7, SASL_MECH_XOAUTH2 }, - { "OAUTHBEARER", 11, SASL_MECH_OAUTHBEARER }, - { ZERO_NULL, 0, 0 } -}; - -/* - * Curl_sasl_cleanup() - * - * This is used to cleanup any libraries or curl modules used by the sasl - * functions. - * - * Parameters: - * - * conn [in] - The connection data. - * authused [in] - The authentication mechanism used. - */ -void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) -{ -#if defined(USE_KERBEROS5) - /* Cleanup the gssapi structure */ - if(authused == SASL_MECH_GSSAPI) { - Curl_auth_gssapi_cleanup(&conn->krb5); - } -#endif - -#if defined(USE_NTLM) - /* Cleanup the NTLM structure */ - if(authused == SASL_MECH_NTLM) { - Curl_auth_ntlm_cleanup(&conn->ntlm); - } -#endif - -#if !defined(USE_KERBEROS5) && !defined(USE_NTLM) - /* Reserved for future use */ - (void)conn; - (void)authused; -#endif -} - -/* - * Curl_sasl_decode_mech() - * - * Convert a SASL mechanism name into a token. - * - * Parameters: - * - * ptr [in] - The mechanism string. - * maxlen [in] - Maximum mechanism string length. - * len [out] - If not NULL, effective name length. - * - * Returns the SASL mechanism token or 0 if no match. - */ -unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len) -{ - unsigned int i; - char c; - - for(i = 0; mechtable[i].name; i++) { - if(maxlen >= mechtable[i].len && - !memcmp(ptr, mechtable[i].name, mechtable[i].len)) { - if(len) - *len = mechtable[i].len; - - if(maxlen == mechtable[i].len) - return mechtable[i].bit; - - c = ptr[mechtable[i].len]; - if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_') - return mechtable[i].bit; - } - } - - return 0; -} - -/* - * Curl_sasl_parse_url_auth_option() - * - * Parse the URL login options. - */ -CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, - const char *value, size_t len) -{ - CURLcode result = CURLE_OK; - unsigned int mechbit; - size_t mechlen; - - if(!len) - return CURLE_URL_MALFORMAT; - - if(sasl->resetprefs) { - sasl->resetprefs = FALSE; - sasl->prefmech = SASL_AUTH_NONE; - } - - if(strnequal(value, "*", len)) - sasl->prefmech = SASL_AUTH_DEFAULT; - else { - mechbit = Curl_sasl_decode_mech(value, len, &mechlen); - if(mechbit && mechlen == len) - sasl->prefmech |= mechbit; - else - result = CURLE_URL_MALFORMAT; - } - - return result; -} - -/* - * Curl_sasl_init() - * - * Initializes the SASL structure. - */ -void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params) -{ - sasl->params = params; /* Set protocol dependent parameters */ - sasl->state = SASL_STOP; /* Not yet running */ - sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */ - sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */ - sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */ - sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */ - sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */ - sasl->force_ir = FALSE; /* Respect external option */ -} - -/* - * state() - * - * This is the ONLY way to change SASL state! - */ -static void state(struct SASL *sasl, struct connectdata *conn, - saslstate newstate) -{ -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char * const names[]={ - "STOP", - "PLAIN", - "LOGIN", - "LOGIN_PASSWD", - "EXTERNAL", - "CRAMMD5", - "DIGESTMD5", - "DIGESTMD5_RESP", - "NTLM", - "NTLM_TYPE2MSG", - "GSSAPI", - "GSSAPI_TOKEN", - "GSSAPI_NO_DATA", - "OAUTH2", - "OAUTH2_RESP", - "CANCEL", - "FINAL", - /* LAST */ - }; - - if(sasl->state != newstate) - infof(conn->data, "SASL %p state change from %s to %s\n", - (void *)sasl, names[sasl->state], names[newstate]); -#else - (void) conn; -#endif - - sasl->state = newstate; -} - -/* - * Curl_sasl_can_authenticate() - * - * Check if we have enough auth data and capabilities to authenticate. - */ -bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn) -{ - /* Have credentials been provided? */ - if(conn->bits.user_passwd) - return TRUE; - - /* EXTERNAL can authenticate without a user name and/or password */ - if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL) - return TRUE; - - return FALSE; -} - -/* - * Curl_sasl_start() - * - * Calculate the required login details for SASL authentication. - */ -CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, - bool force_ir, saslprogress *progress) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - unsigned int enabledmechs; - const char *mech = NULL; - char *resp = NULL; - size_t len = 0; - saslstate state1 = SASL_STOP; - saslstate state2 = SASL_FINAL; -#if defined(USE_KERBEROS5) - const char* service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : - sasl->params->service; -#endif - - sasl->force_ir = force_ir; /* Latch for future use */ - sasl->authused = 0; /* No mechanism used yet */ - enabledmechs = sasl->authmechs & sasl->prefmech; - *progress = SASL_IDLE; - - /* Calculate the supported authentication mechanism, by decreasing order of - security, as well as the initial response where appropriate */ - if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) { - mech = SASL_MECH_STRING_EXTERNAL; - state1 = SASL_EXTERNAL; - sasl->authused = SASL_MECH_EXTERNAL; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_external_message(data, conn->user, &resp, - &len); - } - else if(conn->bits.user_passwd) { -#if defined(USE_KERBEROS5) - if(enabledmechs & SASL_MECH_GSSAPI) { - sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */ - mech = SASL_MECH_STRING_GSSAPI; - state1 = SASL_GSSAPI; - state2 = SASL_GSSAPI_TOKEN; - sasl->authused = SASL_MECH_GSSAPI; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_gssapi_user_message(data, conn->user, - conn->passwd, - service, - data->easy_conn-> - host.name, - sasl->mutual_auth, - NULL, &conn->krb5, - &resp, &len); - } - else -#endif -#ifndef CURL_DISABLE_CRYPTO_AUTH - if(enabledmechs & SASL_MECH_DIGEST_MD5) { - mech = SASL_MECH_STRING_DIGEST_MD5; - state1 = SASL_DIGESTMD5; - sasl->authused = SASL_MECH_DIGEST_MD5; - } - else if(enabledmechs & SASL_MECH_CRAM_MD5) { - mech = SASL_MECH_STRING_CRAM_MD5; - state1 = SASL_CRAMMD5; - sasl->authused = SASL_MECH_CRAM_MD5; - } - else -#endif -#ifdef USE_NTLM - if(enabledmechs & SASL_MECH_NTLM) { - mech = SASL_MECH_STRING_NTLM; - state1 = SASL_NTLM; - state2 = SASL_NTLM_TYPE2MSG; - sasl->authused = SASL_MECH_NTLM; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_ntlm_type1_message(conn->user, conn->passwd, - &conn->ntlm, &resp, &len); - } - else -#endif - if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) { - mech = SASL_MECH_STRING_OAUTHBEARER; - state1 = SASL_OAUTH2; - state2 = SASL_OAUTH2_RESP; - sasl->authused = SASL_MECH_OAUTHBEARER; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_oauth_bearer_message(data, conn->user, - conn->host.name, - conn->port, - conn->oauth_bearer, - &resp, &len); - } - else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) { - mech = SASL_MECH_STRING_XOAUTH2; - state1 = SASL_OAUTH2; - sasl->authused = SASL_MECH_XOAUTH2; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_oauth_bearer_message(data, conn->user, - NULL, 0, - conn->oauth_bearer, - &resp, &len); - } - else if(enabledmechs & SASL_MECH_LOGIN) { - mech = SASL_MECH_STRING_LOGIN; - state1 = SASL_LOGIN; - state2 = SASL_LOGIN_PASSWD; - sasl->authused = SASL_MECH_LOGIN; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_login_message(data, conn->user, &resp, &len); - } - else if(enabledmechs & SASL_MECH_PLAIN) { - mech = SASL_MECH_STRING_PLAIN; - state1 = SASL_PLAIN; - sasl->authused = SASL_MECH_PLAIN; - - if(force_ir || data->set.sasl_ir) - result = Curl_auth_create_plain_message(data, conn->user, conn->passwd, - &resp, &len); - } - } - - if(!result && mech) { - if(resp && sasl->params->maxirlen && - strlen(mech) + len > sasl->params->maxirlen) { - free(resp); - resp = NULL; - } - - result = sasl->params->sendauth(conn, mech, resp); - if(!result) { - *progress = SASL_INPROGRESS; - state(sasl, conn, resp ? state2 : state1); - } - } - - free(resp); - - return result; -} - -/* - * Curl_sasl_continue() - * - * Continue the authentication. - */ -CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, - int code, saslprogress *progress) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - saslstate newstate = SASL_FINAL; - char *resp = NULL; -#if !defined(CURL_DISABLE_CRYPTO_AUTH) - char *serverdata; - char *chlg = NULL; - size_t chlglen = 0; -#endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) - const char *service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : - sasl->params->service; -#endif - size_t len = 0; - - *progress = SASL_INPROGRESS; - - if(sasl->state == SASL_FINAL) { - if(code != sasl->params->finalcode) - result = CURLE_LOGIN_DENIED; - *progress = SASL_DONE; - state(sasl, conn, SASL_STOP); - return result; - } - - if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP && - code != sasl->params->contcode) { - *progress = SASL_DONE; - state(sasl, conn, SASL_STOP); - return CURLE_LOGIN_DENIED; - } - - switch(sasl->state) { - case SASL_STOP: - *progress = SASL_DONE; - return result; - case SASL_PLAIN: - result = Curl_auth_create_plain_message(data, conn->user, conn->passwd, - &resp, - &len); - break; - case SASL_LOGIN: - result = Curl_auth_create_login_message(data, conn->user, &resp, &len); - newstate = SASL_LOGIN_PASSWD; - break; - case SASL_LOGIN_PASSWD: - result = Curl_auth_create_login_message(data, conn->passwd, &resp, &len); - break; - case SASL_EXTERNAL: - result = Curl_auth_create_external_message(data, conn->user, &resp, &len); - break; - -#ifndef CURL_DISABLE_CRYPTO_AUTH - case SASL_CRAMMD5: - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_auth_decode_cram_md5_message(serverdata, &chlg, &chlglen); - if(!result) - result = Curl_auth_create_cram_md5_message(data, chlg, conn->user, - conn->passwd, &resp, &len); - free(chlg); - break; - case SASL_DIGESTMD5: - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_auth_create_digest_md5_message(data, serverdata, - conn->user, conn->passwd, - service, - &resp, &len); - newstate = SASL_DIGESTMD5_RESP; - break; - case SASL_DIGESTMD5_RESP: - resp = strdup(""); - if(!resp) - result = CURLE_OUT_OF_MEMORY; - break; -#endif - -#ifdef USE_NTLM - case SASL_NTLM: - /* Create the type-1 message */ - result = Curl_auth_create_ntlm_type1_message(conn->user, conn->passwd, - &conn->ntlm, &resp, &len); - newstate = SASL_NTLM_TYPE2MSG; - break; - case SASL_NTLM_TYPE2MSG: - /* Decode the type-2 message */ - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_auth_decode_ntlm_type2_message(data, serverdata, - &conn->ntlm); - if(!result) - result = Curl_auth_create_ntlm_type3_message(data, conn->user, - conn->passwd, &conn->ntlm, - &resp, &len); - break; -#endif - -#if defined(USE_KERBEROS5) - case SASL_GSSAPI: - result = Curl_auth_create_gssapi_user_message(data, conn->user, - conn->passwd, - service, - data->easy_conn->host.name, - sasl->mutual_auth, NULL, - &conn->krb5, - &resp, &len); - newstate = SASL_GSSAPI_TOKEN; - break; - case SASL_GSSAPI_TOKEN: - sasl->params->getmessage(data->state.buffer, &serverdata); - if(sasl->mutual_auth) { - /* Decode the user token challenge and create the optional response - message */ - result = Curl_auth_create_gssapi_user_message(data, NULL, NULL, - NULL, NULL, - sasl->mutual_auth, - serverdata, &conn->krb5, - &resp, &len); - newstate = SASL_GSSAPI_NO_DATA; - } - else - /* Decode the security challenge and create the response message */ - result = Curl_auth_create_gssapi_security_message(data, serverdata, - &conn->krb5, - &resp, &len); - break; - case SASL_GSSAPI_NO_DATA: - sasl->params->getmessage(data->state.buffer, &serverdata); - /* Decode the security challenge and create the response message */ - result = Curl_auth_create_gssapi_security_message(data, serverdata, - &conn->krb5, - &resp, &len); - break; -#endif - - case SASL_OAUTH2: - /* Create the authorisation message */ - if(sasl->authused == SASL_MECH_OAUTHBEARER) { - result = Curl_auth_create_oauth_bearer_message(data, conn->user, - conn->host.name, - conn->port, - conn->oauth_bearer, - &resp, &len); - - /* Failures maybe sent by the server as continuations for OAUTHBEARER */ - newstate = SASL_OAUTH2_RESP; - } - else - result = Curl_auth_create_oauth_bearer_message(data, conn->user, - NULL, 0, - conn->oauth_bearer, - &resp, &len); - break; - - case SASL_OAUTH2_RESP: - /* The continuation is optional so check the response code */ - if(code == sasl->params->finalcode) { - /* Final response was received so we are done */ - *progress = SASL_DONE; - state(sasl, conn, SASL_STOP); - return result; - } - else if(code == sasl->params->contcode) { - /* Acknowledge the continuation by sending a 0x01 response base64 - encoded */ - resp = strdup("AQ=="); - if(!resp) - result = CURLE_OUT_OF_MEMORY; - break; - } - else { - *progress = SASL_DONE; - state(sasl, conn, SASL_STOP); - return CURLE_LOGIN_DENIED; - } - - case SASL_CANCEL: - /* Remove the offending mechanism from the supported list */ - sasl->authmechs ^= sasl->authused; - - /* Start an alternative SASL authentication */ - result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress); - newstate = sasl->state; /* Use state from Curl_sasl_start() */ - break; - default: - failf(data, "Unsupported SASL authentication mechanism"); - result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */ - break; - } - - switch(result) { - case CURLE_BAD_CONTENT_ENCODING: - /* Cancel dialog */ - result = sasl->params->sendcont(conn, "*"); - newstate = SASL_CANCEL; - break; - case CURLE_OK: - if(resp) - result = sasl->params->sendcont(conn, resp); - break; - default: - newstate = SASL_STOP; /* Stop on error */ - *progress = SASL_DONE; - break; - } - - free(resp); - - state(sasl, conn, newstate); - - return result; -} diff --git a/Externals/curl/lib/curl_sasl.h b/Externals/curl/lib/curl_sasl.h deleted file mode 100644 index 6535fedbc5..0000000000 --- a/Externals/curl/lib/curl_sasl.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef HEADER_CURL_SASL_H -#define HEADER_CURL_SASL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -struct SessionHandle; -struct connectdata; - -/* Authentication mechanism flags */ -#define SASL_MECH_LOGIN (1 << 0) -#define SASL_MECH_PLAIN (1 << 1) -#define SASL_MECH_CRAM_MD5 (1 << 2) -#define SASL_MECH_DIGEST_MD5 (1 << 3) -#define SASL_MECH_GSSAPI (1 << 4) -#define SASL_MECH_EXTERNAL (1 << 5) -#define SASL_MECH_NTLM (1 << 6) -#define SASL_MECH_XOAUTH2 (1 << 7) -#define SASL_MECH_OAUTHBEARER (1 << 8) - -/* Authentication mechanism values */ -#define SASL_AUTH_NONE 0 -#define SASL_AUTH_ANY ~0U -#define SASL_AUTH_DEFAULT (SASL_AUTH_ANY & ~SASL_MECH_EXTERNAL) - -/* Authentication mechanism strings */ -#define SASL_MECH_STRING_LOGIN "LOGIN" -#define SASL_MECH_STRING_PLAIN "PLAIN" -#define SASL_MECH_STRING_CRAM_MD5 "CRAM-MD5" -#define SASL_MECH_STRING_DIGEST_MD5 "DIGEST-MD5" -#define SASL_MECH_STRING_GSSAPI "GSSAPI" -#define SASL_MECH_STRING_EXTERNAL "EXTERNAL" -#define SASL_MECH_STRING_NTLM "NTLM" -#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2" -#define SASL_MECH_STRING_OAUTHBEARER "OAUTHBEARER" - -/* SASL machine states */ -typedef enum { - SASL_STOP, - SASL_PLAIN, - SASL_LOGIN, - SASL_LOGIN_PASSWD, - SASL_EXTERNAL, - SASL_CRAMMD5, - SASL_DIGESTMD5, - SASL_DIGESTMD5_RESP, - SASL_NTLM, - SASL_NTLM_TYPE2MSG, - SASL_GSSAPI, - SASL_GSSAPI_TOKEN, - SASL_GSSAPI_NO_DATA, - SASL_OAUTH2, - SASL_OAUTH2_RESP, - SASL_CANCEL, - SASL_FINAL -} saslstate; - -/* Progress indicator */ -typedef enum { - SASL_IDLE, - SASL_INPROGRESS, - SASL_DONE -} saslprogress; - -/* Protocol dependent SASL parameters */ -struct SASLproto { - const char *service; /* The service name */ - int contcode; /* Code to receive when continuation is expected */ - int finalcode; /* Code to receive upon authentication success */ - size_t maxirlen; /* Maximum initial response length */ - CURLcode (*sendauth)(struct connectdata *conn, - const char *mech, const char *ir); - /* Send authentication command */ - CURLcode (*sendcont)(struct connectdata *conn, const char *contauth); - /* Send authentication continuation */ - void (*getmessage)(char *buffer, char **outptr); - /* Get SASL response message */ -}; - -/* Per-connection parameters */ -struct SASL { - const struct SASLproto *params; /* Protocol dependent parameters */ - saslstate state; /* Current machine state */ - unsigned int authmechs; /* Accepted authentication mechanisms */ - unsigned int prefmech; /* Preferred authentication mechanism */ - unsigned int authused; /* Auth mechanism used for the connection */ - bool resetprefs; /* For URL auth option parsing. */ - bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */ - bool force_ir; /* Protocol always supports initial response */ -}; - -/* This is used to test whether the line starts with the given mechanism */ -#define sasl_mech_equal(line, wordlen, mech) \ - (wordlen == (sizeof(mech) - 1) / sizeof(char) && \ - !memcmp(line, mech, wordlen)) - -/* This is used to cleanup any libraries or curl modules used by the sasl - functions */ -void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused); - -/* Convert a mechanism name to a token */ -unsigned int Curl_sasl_decode_mech(const char *ptr, - size_t maxlen, size_t *len); - -/* Parse the URL login options */ -CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, - const char *value, size_t len); - -/* Initializes an SASL structure */ -void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params); - -/* Check if we have enough auth data and capabilities to authenticate */ -bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn); - -/* Calculate the required login details for SASL authentication */ -CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, - bool force_ir, saslprogress *progress); - -/* Continue an SASL authentication */ -CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, - int code, saslprogress *progress); - -#endif /* HEADER_CURL_SASL_H */ diff --git a/Externals/curl/lib/curl_sec.h b/Externals/curl/lib/curl_sec.h deleted file mode 100644 index 3f94e1444b..0000000000 --- a/Externals/curl/lib/curl_sec.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef HEADER_CURL_SECURITY_H -#define HEADER_CURL_SECURITY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -struct Curl_sec_client_mech { - const char *name; - size_t size; - int (*init)(void *); - int (*auth)(void *, struct connectdata *); - void (*end)(void *); - int (*check_prot)(void *, int); - int (*overhead)(void *, int, int); - int (*encode)(void *, const void*, int, int, void**); - int (*decode)(void *, void*, int, int, struct connectdata *); -}; - -#define AUTH_OK 0 -#define AUTH_CONTINUE 1 -#define AUTH_ERROR 2 - -#ifdef HAVE_GSSAPI -int Curl_sec_read_msg (struct connectdata *conn, char *, - enum protection_level); -void Curl_sec_end (struct connectdata *); -CURLcode Curl_sec_login (struct connectdata *); -int Curl_sec_request_prot (struct connectdata *conn, const char *level); - -extern struct Curl_sec_client_mech Curl_krb5_client_mech; -#endif - -#endif /* HEADER_CURL_SECURITY_H */ diff --git a/Externals/curl/lib/curl_setup.h b/Externals/curl/lib/curl_setup.h deleted file mode 100644 index d78873fe53..0000000000 --- a/Externals/curl/lib/curl_setup.h +++ /dev/null @@ -1,740 +0,0 @@ -#ifndef HEADER_CURL_SETUP_H -#define HEADER_CURL_SETUP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Define WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) && \ - !defined(__SYMBIAN32__) -#define WIN32 -#endif - -/* - * Include configuration script results or hand-crafted - * configuration file for platforms which lack config tool. - */ - -#ifdef HAVE_CONFIG_H - -#include "curl_config.h" - -#else /* HAVE_CONFIG_H */ - -#ifdef _WIN32_WCE -# include "config-win32ce.h" -#else -# ifdef WIN32 -# include "config-win32.h" -# endif -#endif - -#if defined(macintosh) && defined(__MRC__) -# include "config-mac.h" -#endif - -#ifdef __riscos__ -# include "config-riscos.h" -#endif - -#ifdef __AMIGA__ -# include "config-amigaos.h" -#endif - -#ifdef __SYMBIAN32__ -# include "config-symbian.h" -#endif - -#ifdef __OS400__ -# include "config-os400.h" -#endif - -#ifdef TPF -# include "config-tpf.h" -#endif - -#ifdef __VXWORKS__ -# include "config-vxworks.h" -#endif - -#endif /* HAVE_CONFIG_H */ - -/* ================================================================ */ -/* Definition of preprocessor macros/symbols which modify compiler */ -/* behavior or generated code characteristics must be done here, */ -/* as appropriate, before any system header file is included. It is */ -/* also possible to have them defined in the config file included */ -/* before this point. As a result of all this we frown inclusion of */ -/* system header files in our config files, avoid this at any cost. */ -/* ================================================================ */ - -/* - * AIX 4.3 and newer needs _THREAD_SAFE defined to build - * proper reentrant code. Others may also need it. - */ - -#ifdef NEED_THREAD_SAFE -# ifndef _THREAD_SAFE -# define _THREAD_SAFE -# endif -#endif - -/* - * Tru64 needs _REENTRANT set for a few function prototypes and - * things to appear in the system header files. Unixware needs it - * to build proper reentrant code. Others may also need it. - */ - -#ifdef NEED_REENTRANT -# ifndef _REENTRANT -# define _REENTRANT -# endif -#endif - -/* Solaris needs this to get a POSIX-conformant getpwuid_r */ -#if defined(sun) || defined(__sun) -# ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -# endif -#endif - -/* ================================================================ */ -/* If you need to include a system header file for your platform, */ -/* please, do it beyond the point further indicated in this file. */ -/* ================================================================ */ - -/* - * libcurl's external interface definitions are also used internally, - * and might also include required system header files to define them. - */ - -#include - -/* - * Compile time sanity checks must also be done when building the library. - */ - -#include - -/* - * Ensure that no one is using the old SIZEOF_CURL_OFF_T macro - */ - -#ifdef SIZEOF_CURL_OFF_T -# error "SIZEOF_CURL_OFF_T shall not be defined!" - Error Compilation_aborted_SIZEOF_CURL_OFF_T_shall_not_be_defined -#endif - -/* - * Disable other protocols when http is the only one desired. - */ - -#ifdef HTTP_ONLY -# ifndef CURL_DISABLE_TFTP -# define CURL_DISABLE_TFTP -# endif -# ifndef CURL_DISABLE_FTP -# define CURL_DISABLE_FTP -# endif -# ifndef CURL_DISABLE_LDAP -# define CURL_DISABLE_LDAP -# endif -# ifndef CURL_DISABLE_TELNET -# define CURL_DISABLE_TELNET -# endif -# ifndef CURL_DISABLE_DICT -# define CURL_DISABLE_DICT -# endif -# ifndef CURL_DISABLE_FILE -# define CURL_DISABLE_FILE -# endif -# ifndef CURL_DISABLE_RTSP -# define CURL_DISABLE_RTSP -# endif -# ifndef CURL_DISABLE_POP3 -# define CURL_DISABLE_POP3 -# endif -# ifndef CURL_DISABLE_IMAP -# define CURL_DISABLE_IMAP -# endif -# ifndef CURL_DISABLE_SMTP -# define CURL_DISABLE_SMTP -# endif -# ifndef CURL_DISABLE_RTMP -# define CURL_DISABLE_RTMP -# endif -# ifndef CURL_DISABLE_GOPHER -# define CURL_DISABLE_GOPHER -# endif -# ifndef CURL_DISABLE_SMB -# define CURL_DISABLE_SMB -# endif -#endif - -/* - * When http is disabled rtsp is not supported. - */ - -#if defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_RTSP) -# define CURL_DISABLE_RTSP -#endif - -/* ================================================================ */ -/* No system header file shall be included in this file before this */ -/* point. The only allowed ones are those included from curlbuild.h */ -/* ================================================================ */ - -/* - * OS/400 setup file includes some system headers. - */ - -#ifdef __OS400__ -# include "setup-os400.h" -#endif - -/* - * VMS setup file includes some system headers. - */ - -#ifdef __VMS -# include "setup-vms.h" -#endif - -/* - * Include header files for windows builds before redefining anything. - * Use this preprocessor block only to include or exclude windows.h, - * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs - * to any other further and independent block. Under Cygwin things work - * just as under linux (e.g. ) and the winsock headers should - * never be included when __CYGWIN__ is defined. configure script takes - * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H, - * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined. - */ - -#ifdef HAVE_WINDOWS_H -# if defined(UNICODE) && !defined(_UNICODE) -# define _UNICODE -# endif -# if defined(_UNICODE) && !defined(UNICODE) -# define UNICODE -# endif -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# ifdef HAVE_WINSOCK2_H -# include -# ifdef HAVE_WS2TCPIP_H -# include -# endif -# else -# ifdef HAVE_WINSOCK_H -# include -# endif -# endif -# include -# ifdef UNICODE - typedef wchar_t *(*curl_wcsdup_callback)(const wchar_t *str); -# endif -#endif - -/* - * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else - * define USE_WINSOCK to 1 if we have and use WINSOCK API, else - * undefine USE_WINSOCK. - */ - -#undef USE_WINSOCK - -#ifdef HAVE_WINSOCK2_H -# define USE_WINSOCK 2 -#else -# ifdef HAVE_WINSOCK_H -# define USE_WINSOCK 1 -# endif -#endif - -#ifdef USE_LWIPSOCK -# include -# include -# include -#endif - -#ifdef HAVE_EXTRA_STRICMP_H -# include -#endif - -#ifdef HAVE_EXTRA_STRDUP_H -# include -#endif - -#ifdef TPF -# include /* for bzero, strcasecmp, and strncasecmp */ -# include /* for strcpy and strlen */ -# include /* for rand and srand */ -# include /* for select and ioctl*/ -# include /* for in_addr_t definition */ -# include /* for tpf_process_signals */ - /* change which select is used for libcurl */ -# define select(a,b,c,d,e) tpf_select_libcurl(a,b,c,d,e) -#endif - -#ifdef __VXWORKS__ -# include /* for generic BSD socket functions */ -# include /* for basic I/O interface functions */ -#endif - -#ifdef __AMIGA__ -# ifndef __ixemul__ -# include -# include -# include -# include -# define select(a,b,c,d,e) WaitSelect(a,b,c,d,e,0) -# endif -#endif - -#include -#ifdef HAVE_ASSERT_H -#include -#endif - -#ifdef __TANDEM /* for nsr-tandem-nsk systems */ -#include -#endif - -#ifndef STDC_HEADERS /* no standard C headers! */ -#include -#endif - -#ifdef __POCC__ -# include -# include -# define sys_nerr EILSEQ -#endif - -/* - * Salford-C kludge section (mostly borrowed from wxWidgets). - */ -#ifdef __SALFORDC__ - #pragma suppress 353 /* Possible nested comments */ - #pragma suppress 593 /* Define not used */ - #pragma suppress 61 /* enum has no name */ - #pragma suppress 106 /* unnamed, unused parameter */ - #include -#endif - -/* - * Large file (>2Gb) support using WIN32 functions. - */ - -#ifdef USE_WIN32_LARGE_FILES -# include -# include -# include -# undef lseek -# define lseek(fdes,offset,whence) _lseeki64(fdes, offset, whence) -# undef fstat -# define fstat(fdes,stp) _fstati64(fdes, stp) -# undef stat -# define stat(fname,stp) _stati64(fname, stp) -# define struct_stat struct _stati64 -# define LSEEK_ERROR (__int64)-1 -#endif - -/* - * Small file (<2Gb) support using WIN32 functions. - */ - -#ifdef USE_WIN32_SMALL_FILES -# include -# include -# include -# ifndef _WIN32_WCE -# undef lseek -# define lseek(fdes,offset,whence) _lseek(fdes, (long)offset, whence) -# define fstat(fdes,stp) _fstat(fdes, stp) -# define stat(fname,stp) _stat(fname, stp) -# define struct_stat struct _stat -# endif -# define LSEEK_ERROR (long)-1 -#endif - -#ifndef struct_stat -# define struct_stat struct stat -#endif - -#ifndef LSEEK_ERROR -# define LSEEK_ERROR (off_t)-1 -#endif - -/* - * Default sizeof(off_t) in case it hasn't been defined in config file. - */ - -#ifndef SIZEOF_OFF_T -# if defined(__VMS) && !defined(__VAX) -# if defined(_LARGEFILE) -# define SIZEOF_OFF_T 8 -# endif -# elif defined(__OS400__) && defined(__ILEC400__) -# if defined(_LARGE_FILES) -# define SIZEOF_OFF_T 8 -# endif -# elif defined(__MVS__) && defined(__IBMC__) -# if defined(_LP64) || defined(_LARGE_FILES) -# define SIZEOF_OFF_T 8 -# endif -# elif defined(__370__) && defined(__IBMC__) -# if defined(_LP64) || defined(_LARGE_FILES) -# define SIZEOF_OFF_T 8 -# endif -# endif -# ifndef SIZEOF_OFF_T -# define SIZEOF_OFF_T 4 -# endif -#endif - -/* - * Arg 2 type for gethostname in case it hasn't been defined in config file. - */ - -#ifndef GETHOSTNAME_TYPE_ARG2 -# ifdef USE_WINSOCK -# define GETHOSTNAME_TYPE_ARG2 int -# else -# define GETHOSTNAME_TYPE_ARG2 size_t -# endif -#endif - -/* Below we define some functions. They should - - 4. set the SIGALRM signal timeout - 5. set dir/file naming defines - */ - -#ifdef WIN32 - -# define DIR_CHAR "\\" -# define DOT_CHAR "_" - -#else /* WIN32 */ - -# ifdef MSDOS /* Watt-32 */ - -# include -# define select(n,r,w,x,t) select_s(n,r,w,x,t) -# define ioctl(x,y,z) ioctlsocket(x,y,(char *)(z)) -# include -# ifdef word -# undef word -# endif -# ifdef byte -# undef byte -# endif - -# endif /* MSDOS */ - -# ifdef __minix - /* Minix 3 versions up to at least 3.1.3 are missing these prototypes */ - extern char * strtok_r(char *s, const char *delim, char **last); - extern struct tm * gmtime_r(const time_t * const timep, struct tm *tmp); -# endif - -# define DIR_CHAR "/" -# ifndef DOT_CHAR -# define DOT_CHAR "." -# endif - -# ifdef MSDOS -# undef DOT_CHAR -# define DOT_CHAR "_" -# endif - -# ifndef fileno /* sunos 4 have this as a macro! */ - int fileno(FILE *stream); -# endif - -#endif /* WIN32 */ - -/* - * msvc 6.0 requires PSDK in order to have INET6_ADDRSTRLEN - * defined in ws2tcpip.h as well as to provide IPv6 support. - * Does not apply if lwIP is used. - */ - -#if defined(_MSC_VER) && !defined(__POCC__) && !defined(USE_LWIPSOCK) -# if !defined(HAVE_WS2TCPIP_H) || \ - ((_MSC_VER < 1300) && !defined(INET6_ADDRSTRLEN)) -# undef HAVE_GETADDRINFO_THREADSAFE -# undef HAVE_FREEADDRINFO -# undef HAVE_GETADDRINFO -# undef HAVE_GETNAMEINFO -# undef ENABLE_IPV6 -# endif -#endif - -/* ---------------------------------------------------------------- */ -/* resolver specialty compile-time defines */ -/* CURLRES_* defines to use in the host*.c sources */ -/* ---------------------------------------------------------------- */ - -/* - * lcc-win32 doesn't have _beginthreadex(), lacks threads support. - */ - -#if defined(__LCC__) && defined(WIN32) -# undef USE_THREADS_POSIX -# undef USE_THREADS_WIN32 -#endif - -/* - * MSVC threads support requires a multi-threaded runtime library. - * _beginthreadex() is not available in single-threaded ones. - */ - -#if defined(_MSC_VER) && !defined(__POCC__) && !defined(_MT) -# undef USE_THREADS_POSIX -# undef USE_THREADS_WIN32 -#endif - -/* - * Mutually exclusive CURLRES_* definitions. - */ - -#ifdef USE_ARES -# define CURLRES_ASYNCH -# define CURLRES_ARES -/* now undef the stock libc functions just to avoid them being used */ -# undef HAVE_GETADDRINFO -# undef HAVE_FREEADDRINFO -# undef HAVE_GETHOSTBYNAME -#elif defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) -# define CURLRES_ASYNCH -# define CURLRES_THREADED -#else -# define CURLRES_SYNCH -#endif - -#ifdef ENABLE_IPV6 -# define CURLRES_IPV6 -#else -# define CURLRES_IPV4 -#endif - -/* ---------------------------------------------------------------- */ - -/* - * When using WINSOCK, TELNET protocol requires WINSOCK2 API. - */ - -#if defined(USE_WINSOCK) && (USE_WINSOCK != 2) -# define CURL_DISABLE_TELNET 1 -#endif - -/* - * msvc 6.0 does not have struct sockaddr_storage and - * does not define IPPROTO_ESP in winsock2.h. But both - * are available if PSDK is properly installed. - */ - -#if defined(_MSC_VER) && !defined(__POCC__) -# if !defined(HAVE_WINSOCK2_H) || ((_MSC_VER < 1300) && !defined(IPPROTO_ESP)) -# undef HAVE_STRUCT_SOCKADDR_STORAGE -# endif -#endif - -/* - * Intentionally fail to build when using msvc 6.0 without PSDK installed. - * The brave of heart can circumvent this, defining ALLOW_MSVC6_WITHOUT_PSDK - * in lib/config-win32.h although absolutely discouraged and unsupported. - */ - -#if defined(_MSC_VER) && !defined(__POCC__) -# if !defined(HAVE_WINDOWS_H) || ((_MSC_VER < 1300) && !defined(_FILETIME_)) -# if !defined(ALLOW_MSVC6_WITHOUT_PSDK) -# error MSVC 6.0 requires "February 2003 Platform SDK" a.k.a. \ - "Windows Server 2003 PSDK" -# else -# define CURL_DISABLE_LDAP 1 -# endif -# endif -#endif - -#ifdef NETWARE -int netware_init(void); -#ifndef __NOVELL_LIBC__ -#include -#include -#endif -#endif - -#if defined(HAVE_LIBIDN) && defined(HAVE_TLD_H) -/* The lib was present and the tld.h header (which is missing in libidn 0.3.X - but we only work with libidn 0.4.1 or later) */ -#define USE_LIBIDN -#endif - -#ifndef SIZEOF_TIME_T -/* assume default size of time_t to be 32 bit */ -#define SIZEOF_TIME_T 4 -#endif - -#define LIBIDN_REQUIRED_VERSION "0.4.1" - -#if defined(USE_GNUTLS) || defined(USE_OPENSSL) || defined(USE_NSS) || \ - defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_MBEDTLS) || \ - defined(USE_CYASSL) || defined(USE_SCHANNEL) || \ - defined(USE_DARWINSSL) || defined(USE_GSKIT) -#define USE_SSL /* SSL support has been enabled */ -#endif - -/* Single point where USE_SPNEGO definition might be defined */ -#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \ - (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) -#define USE_SPNEGO -#endif - -/* Single point where USE_KERBEROS5 definition might be defined */ -#if !defined(CURL_DISABLE_CRYPTO_AUTH) && \ - (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) -#define USE_KERBEROS5 -#endif - -/* Single point where USE_NTLM definition might be defined */ -#if !defined(CURL_DISABLE_NTLM) && !defined(CURL_DISABLE_CRYPTO_AUTH) -#if defined(USE_OPENSSL) || defined(USE_WINDOWS_SSPI) || \ - defined(USE_GNUTLS) || defined(USE_NSS) || defined(USE_DARWINSSL) || \ - defined(USE_OS400CRYPTO) || defined(USE_WIN32_CRYPTO) - -#define USE_NTLM -#endif -#endif - -/* non-configure builds may define CURL_WANTS_CA_BUNDLE_ENV */ -#if defined(CURL_WANTS_CA_BUNDLE_ENV) && !defined(CURL_CA_BUNDLE) -#define CURL_CA_BUNDLE getenv("CURL_CA_BUNDLE") -#endif - -/* - * Provide a mechanism to silence picky compilers, such as gcc 4.6+. - * Parameters should of course normally not be unused, but for example when - * we have multiple implementations of the same interface it may happen. - */ - -#if defined(__GNUC__) && ((__GNUC__ >= 3) || \ - ((__GNUC__ == 2) && defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 7))) -# define UNUSED_PARAM __attribute__((__unused__)) -# define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -# define UNUSED_PARAM /*NOTHING*/ -# define WARN_UNUSED_RESULT -#endif - -/* - * Include macros and defines that should only be processed once. - */ - -#ifndef HEADER_CURL_SETUP_ONCE_H -#include "curl_setup_once.h" -#endif - -/* - * Definition of our NOP statement Object-like macro - */ - -#ifndef Curl_nop_stmt -# define Curl_nop_stmt do { } WHILE_FALSE -#endif - -/* - * Ensure that Winsock and lwIP TCP/IP stacks are not mixed. - */ - -#if defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H) -# if defined(SOCKET) || \ - defined(USE_WINSOCK) || \ - defined(HAVE_WINSOCK_H) || \ - defined(HAVE_WINSOCK2_H) || \ - defined(HAVE_WS2TCPIP_H) -# error "Winsock and lwIP TCP/IP stack definitions shall not coexist!" -# endif -#endif - -/* - * Portable symbolic names for Winsock shutdown() mode flags. - */ - -#ifdef USE_WINSOCK -# define SHUT_RD 0x00 -# define SHUT_WR 0x01 -# define SHUT_RDWR 0x02 -#endif - -/* Define S_ISREG if not defined by system headers, f.e. MSVC */ -#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -/* Define S_ISDIR if not defined by system headers, f.e. MSVC */ -#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - -/* In Windows the default file mode is text but an application can override it. -Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 -*/ -#if defined(WIN32) || defined(MSDOS) -#define FOPEN_READTEXT "rt" -#define FOPEN_WRITETEXT "wt" -#elif defined(__CYGWIN__) -/* Cygwin has specific behavior we need to address when WIN32 is not defined. -https://cygwin.com/cygwin-ug-net/using-textbinary.html -For write we want our output to have line endings of LF and be compatible with -other Cygwin utilities. For read we want to handle input that may have line -endings either CRLF or LF so 't' is appropriate. -*/ -#define FOPEN_READTEXT "rt" -#define FOPEN_WRITETEXT "w" -#else -#define FOPEN_READTEXT "r" -#define FOPEN_WRITETEXT "w" -#endif - -/* WinSock destroys recv() buffer when send() failed. - * Enabled automatically for Windows and for Cygwin as Cygwin sockets are - * wrappers for WinSock sockets. https://github.com/curl/curl/issues/657 - * Define DONT_USE_RECV_BEFORE_SEND_WORKAROUND to force disable workaround. - */ -#if !defined(DONT_USE_RECV_BEFORE_SEND_WORKAROUND) -# if defined(WIN32) || defined(__CYGWIN__) -# define USE_RECV_BEFORE_SEND_WORKAROUND -# endif -#else /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */ -# ifdef USE_RECV_BEFORE_SEND_WORKAROUND -# undef USE_RECV_BEFORE_SEND_WORKAROUND -# endif -#endif /* DONT_USE_RECV_BEFORE_SEND_WORKAROUNDS */ - -#endif /* HEADER_CURL_SETUP_H */ diff --git a/Externals/curl/lib/curl_setup_once.h b/Externals/curl/lib/curl_setup_once.h deleted file mode 100644 index 4da83499af..0000000000 --- a/Externals/curl/lib/curl_setup_once.h +++ /dev/null @@ -1,551 +0,0 @@ -#ifndef HEADER_CURL_SETUP_ONCE_H -#define HEADER_CURL_SETUP_ONCE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - - -/* - * Inclusion of common header files. - */ - -#include -#include -#include -#include -#include - -#ifdef HAVE_ERRNO_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef NEED_MALLOC_H -#include -#endif - -#ifdef NEED_MEMORY_H -#include -#endif - -#ifdef HAVE_SYS_STAT_H -#include -#endif - -#ifdef HAVE_SYS_TIME_H -#include -#ifdef TIME_WITH_SYS_TIME -#include -#endif -#else -#ifdef HAVE_TIME_H -#include -#endif -#endif - -#ifdef WIN32 -#include -#include -#endif - -#if defined(HAVE_STDBOOL_H) && defined(HAVE_BOOL_T) -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef __hpux -# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) -# ifdef _APP32_64BIT_OFF_T -# define OLD_APP32_64BIT_OFF_T _APP32_64BIT_OFF_T -# undef _APP32_64BIT_OFF_T -# else -# undef OLD_APP32_64BIT_OFF_T -# endif -# endif -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -#ifdef __hpux -# if !defined(_XOPEN_SOURCE_EXTENDED) || defined(_KERNEL) -# ifdef OLD_APP32_64BIT_OFF_T -# define _APP32_64BIT_OFF_T OLD_APP32_64BIT_OFF_T -# undef OLD_APP32_64BIT_OFF_T -# endif -# endif -#endif - - -/* - * Definition of timeval struct for platforms that don't have it. - */ - -#ifndef HAVE_STRUCT_TIMEVAL -struct timeval { - long tv_sec; - long tv_usec; -}; -#endif - - -/* - * If we have the MSG_NOSIGNAL define, make sure we use - * it as the fourth argument of function send() - */ - -#ifdef HAVE_MSG_NOSIGNAL -#define SEND_4TH_ARG MSG_NOSIGNAL -#else -#define SEND_4TH_ARG 0 -#endif - - -#if defined(__minix) -/* Minix doesn't support recv on TCP sockets */ -#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \ - (RECV_TYPE_ARG2)(y), \ - (RECV_TYPE_ARG3)(z)) - -#elif defined(HAVE_RECV) -/* - * The definitions for the return type and arguments types - * of functions recv() and send() belong and come from the - * configuration file. Do not define them in any other place. - * - * HAVE_RECV is defined if you have a function named recv() - * which is used to read incoming data from sockets. If your - * function has another name then don't define HAVE_RECV. - * - * If HAVE_RECV is defined then RECV_TYPE_ARG1, RECV_TYPE_ARG2, - * RECV_TYPE_ARG3, RECV_TYPE_ARG4 and RECV_TYPE_RETV must also - * be defined. - * - * HAVE_SEND is defined if you have a function named send() - * which is used to write outgoing data on a connected socket. - * If yours has another name then don't define HAVE_SEND. - * - * If HAVE_SEND is defined then SEND_TYPE_ARG1, SEND_QUAL_ARG2, - * SEND_TYPE_ARG2, SEND_TYPE_ARG3, SEND_TYPE_ARG4 and - * SEND_TYPE_RETV must also be defined. - */ - -#if !defined(RECV_TYPE_ARG1) || \ - !defined(RECV_TYPE_ARG2) || \ - !defined(RECV_TYPE_ARG3) || \ - !defined(RECV_TYPE_ARG4) || \ - !defined(RECV_TYPE_RETV) - /* */ - Error Missing_definition_of_return_and_arguments_types_of_recv - /* */ -#else -#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \ - (RECV_TYPE_ARG2)(y), \ - (RECV_TYPE_ARG3)(z), \ - (RECV_TYPE_ARG4)(0)) -#endif -#else /* HAVE_RECV */ -#ifndef sread - /* */ - Error Missing_definition_of_macro_sread - /* */ -#endif -#endif /* HAVE_RECV */ - - -#if defined(__minix) -/* Minix doesn't support send on TCP sockets */ -#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \ - (SEND_TYPE_ARG2)(y), \ - (SEND_TYPE_ARG3)(z)) - -#elif defined(HAVE_SEND) -#if !defined(SEND_TYPE_ARG1) || \ - !defined(SEND_QUAL_ARG2) || \ - !defined(SEND_TYPE_ARG2) || \ - !defined(SEND_TYPE_ARG3) || \ - !defined(SEND_TYPE_ARG4) || \ - !defined(SEND_TYPE_RETV) - /* */ - Error Missing_definition_of_return_and_arguments_types_of_send - /* */ -#else -#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ - (SEND_TYPE_ARG2)(y), \ - (SEND_TYPE_ARG3)(z), \ - (SEND_TYPE_ARG4)(SEND_4TH_ARG)) -#endif -#else /* HAVE_SEND */ -#ifndef swrite - /* */ - Error Missing_definition_of_macro_swrite - /* */ -#endif -#endif /* HAVE_SEND */ - - -#if 0 -#if defined(HAVE_RECVFROM) -/* - * Currently recvfrom is only used on udp sockets. - */ -#if !defined(RECVFROM_TYPE_ARG1) || \ - !defined(RECVFROM_TYPE_ARG2) || \ - !defined(RECVFROM_TYPE_ARG3) || \ - !defined(RECVFROM_TYPE_ARG4) || \ - !defined(RECVFROM_TYPE_ARG5) || \ - !defined(RECVFROM_TYPE_ARG6) || \ - !defined(RECVFROM_TYPE_RETV) - /* */ - Error Missing_definition_of_return_and_arguments_types_of_recvfrom - /* */ -#else -#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \ - (RECVFROM_TYPE_ARG2 *)(b), \ - (RECVFROM_TYPE_ARG3) (bl), \ - (RECVFROM_TYPE_ARG4) (0), \ - (RECVFROM_TYPE_ARG5 *)(f), \ - (RECVFROM_TYPE_ARG6 *)(fl)) -#endif -#else /* HAVE_RECVFROM */ -#ifndef sreadfrom - /* */ - Error Missing_definition_of_macro_sreadfrom - /* */ -#endif -#endif /* HAVE_RECVFROM */ - - -#ifdef RECVFROM_TYPE_ARG6_IS_VOID -# define RECVFROM_ARG6_T int -#else -# define RECVFROM_ARG6_T RECVFROM_TYPE_ARG6 -#endif -#endif /* if 0 */ - - -/* - * Function-like macro definition used to close a socket. - */ - -#if defined(HAVE_CLOSESOCKET) -# define sclose(x) closesocket((x)) -#elif defined(HAVE_CLOSESOCKET_CAMEL) -# define sclose(x) CloseSocket((x)) -#elif defined(HAVE_CLOSE_S) -# define sclose(x) close_s((x)) -#elif defined(USE_LWIPSOCK) -# define sclose(x) lwip_close((x)) -#else -# define sclose(x) close((x)) -#endif - -/* - * Stack-independent version of fcntl() on sockets: - */ -#if defined(USE_LWIPSOCK) -# define sfcntl lwip_fcntl -#else -# define sfcntl fcntl -#endif - -/* - * Uppercase macro versions of ANSI/ISO is*() functions/macros which - * avoid negative number inputs with argument byte codes > 127. - */ - -#define ISSPACE(x) (isspace((int) ((unsigned char)x))) -#define ISDIGIT(x) (isdigit((int) ((unsigned char)x))) -#define ISALNUM(x) (isalnum((int) ((unsigned char)x))) -#define ISXDIGIT(x) (isxdigit((int) ((unsigned char)x))) -#define ISGRAPH(x) (isgraph((int) ((unsigned char)x))) -#define ISALPHA(x) (isalpha((int) ((unsigned char)x))) -#define ISPRINT(x) (isprint((int) ((unsigned char)x))) -#define ISUPPER(x) (isupper((int) ((unsigned char)x))) -#define ISLOWER(x) (islower((int) ((unsigned char)x))) -#define ISASCII(x) (isascii((int) ((unsigned char)x))) - -#define ISBLANK(x) (int)((((unsigned char)x) == ' ') || \ - (((unsigned char)x) == '\t')) - -#define TOLOWER(x) (tolower((int) ((unsigned char)x))) - - -/* - * 'bool' stuff compatible with HP-UX headers. - */ - -#if defined(__hpux) && !defined(HAVE_BOOL_T) - typedef int bool; -# define false 0 -# define true 1 -# define HAVE_BOOL_T -#endif - - -/* - * 'bool' exists on platforms with , i.e. C99 platforms. - * On non-C99 platforms there's no bool, so define an enum for that. - * On C99 platforms 'false' and 'true' also exist. Enum uses a - * global namespace though, so use bool_false and bool_true. - */ - -#ifndef HAVE_BOOL_T - typedef enum { - bool_false = 0, - bool_true = 1 - } bool; - -/* - * Use a define to let 'true' and 'false' use those enums. There - * are currently no use of true and false in libcurl proper, but - * there are some in the examples. This will cater for any later - * code happening to use true and false. - */ -# define false bool_false -# define true bool_true -# define HAVE_BOOL_T -#endif - - -/* - * Redefine TRUE and FALSE too, to catch current use. With this - * change, 'bool found = 1' will give a warning on MIPSPro, but - * 'bool found = TRUE' will not. Change tested on IRIX/MIPSPro, - * AIX 5.1/Xlc, Tru64 5.1/cc, w/make test too. - */ - -#ifndef TRUE -#define TRUE true -#endif -#ifndef FALSE -#define FALSE false -#endif - - -/* - * Macro WHILE_FALSE may be used to build single-iteration do-while loops, - * avoiding compiler warnings. Mostly intended for other macro definitions. - */ - -#define WHILE_FALSE while(0) - -#if defined(_MSC_VER) && !defined(__POCC__) -# undef WHILE_FALSE -# if (_MSC_VER < 1500) -# define WHILE_FALSE while(1, 0) -# else -# define WHILE_FALSE \ -__pragma(warning(push)) \ -__pragma(warning(disable:4127)) \ -while(0) \ -__pragma(warning(pop)) -# endif -#endif - - -/* - * Typedef to 'int' if sig_atomic_t is not an available 'typedefed' type. - */ - -#ifndef HAVE_SIG_ATOMIC_T -typedef int sig_atomic_t; -#define HAVE_SIG_ATOMIC_T -#endif - - -/* - * Convenience SIG_ATOMIC_T definition - */ - -#ifdef HAVE_SIG_ATOMIC_T_VOLATILE -#define SIG_ATOMIC_T static sig_atomic_t -#else -#define SIG_ATOMIC_T static volatile sig_atomic_t -#endif - - -/* - * Default return type for signal handlers. - */ - -#ifndef RETSIGTYPE -#define RETSIGTYPE void -#endif - - -/* - * Macro used to include code only in debug builds. - */ - -#ifdef DEBUGBUILD -#define DEBUGF(x) x -#else -#define DEBUGF(x) do { } WHILE_FALSE -#endif - - -/* - * Macro used to include assertion code only in debug builds. - */ - -#if defined(DEBUGBUILD) && defined(HAVE_ASSERT_H) -#define DEBUGASSERT(x) assert(x) -#else -#define DEBUGASSERT(x) do { } WHILE_FALSE -#endif - - -/* - * Macro SOCKERRNO / SET_SOCKERRNO() returns / sets the *socket-related* errno - * (or equivalent) on this platform to hide platform details to code using it. - */ - -#ifdef USE_WINSOCK -#define SOCKERRNO ((int)WSAGetLastError()) -#define SET_SOCKERRNO(x) (WSASetLastError((int)(x))) -#else -#define SOCKERRNO (errno) -#define SET_SOCKERRNO(x) (errno = (x)) -#endif - - -/* - * Macro ERRNO / SET_ERRNO() returns / sets the NOT *socket-related* errno - * (or equivalent) on this platform to hide platform details to code using it. - */ - -#if defined(WIN32) && !defined(USE_LWIPSOCK) -#define ERRNO ((int)GetLastError()) -#define SET_ERRNO(x) (SetLastError((DWORD)(x))) -#else -#define ERRNO (errno) -#define SET_ERRNO(x) (errno = (x)) -#endif - - -/* - * Portable error number symbolic names defined to Winsock error codes. - */ - -#ifdef USE_WINSOCK -#undef EBADF /* override definition in errno.h */ -#define EBADF WSAEBADF -#undef EINTR /* override definition in errno.h */ -#define EINTR WSAEINTR -#undef EINVAL /* override definition in errno.h */ -#define EINVAL WSAEINVAL -#undef EWOULDBLOCK /* override definition in errno.h */ -#define EWOULDBLOCK WSAEWOULDBLOCK -#undef EINPROGRESS /* override definition in errno.h */ -#define EINPROGRESS WSAEINPROGRESS -#undef EALREADY /* override definition in errno.h */ -#define EALREADY WSAEALREADY -#undef ENOTSOCK /* override definition in errno.h */ -#define ENOTSOCK WSAENOTSOCK -#undef EDESTADDRREQ /* override definition in errno.h */ -#define EDESTADDRREQ WSAEDESTADDRREQ -#undef EMSGSIZE /* override definition in errno.h */ -#define EMSGSIZE WSAEMSGSIZE -#undef EPROTOTYPE /* override definition in errno.h */ -#define EPROTOTYPE WSAEPROTOTYPE -#undef ENOPROTOOPT /* override definition in errno.h */ -#define ENOPROTOOPT WSAENOPROTOOPT -#undef EPROTONOSUPPORT /* override definition in errno.h */ -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT -#undef EOPNOTSUPP /* override definition in errno.h */ -#define EOPNOTSUPP WSAEOPNOTSUPP -#define EPFNOSUPPORT WSAEPFNOSUPPORT -#undef EAFNOSUPPORT /* override definition in errno.h */ -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#undef EADDRINUSE /* override definition in errno.h */ -#define EADDRINUSE WSAEADDRINUSE -#undef EADDRNOTAVAIL /* override definition in errno.h */ -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL -#undef ENETDOWN /* override definition in errno.h */ -#define ENETDOWN WSAENETDOWN -#undef ENETUNREACH /* override definition in errno.h */ -#define ENETUNREACH WSAENETUNREACH -#undef ENETRESET /* override definition in errno.h */ -#define ENETRESET WSAENETRESET -#undef ECONNABORTED /* override definition in errno.h */ -#define ECONNABORTED WSAECONNABORTED -#undef ECONNRESET /* override definition in errno.h */ -#define ECONNRESET WSAECONNRESET -#undef ENOBUFS /* override definition in errno.h */ -#define ENOBUFS WSAENOBUFS -#undef EISCONN /* override definition in errno.h */ -#define EISCONN WSAEISCONN -#undef ENOTCONN /* override definition in errno.h */ -#define ENOTCONN WSAENOTCONN -#define ESHUTDOWN WSAESHUTDOWN -#define ETOOMANYREFS WSAETOOMANYREFS -#undef ETIMEDOUT /* override definition in errno.h */ -#define ETIMEDOUT WSAETIMEDOUT -#undef ECONNREFUSED /* override definition in errno.h */ -#define ECONNREFUSED WSAECONNREFUSED -#undef ELOOP /* override definition in errno.h */ -#define ELOOP WSAELOOP -#ifndef ENAMETOOLONG /* possible previous definition in errno.h */ -#define ENAMETOOLONG WSAENAMETOOLONG -#endif -#define EHOSTDOWN WSAEHOSTDOWN -#undef EHOSTUNREACH /* override definition in errno.h */ -#define EHOSTUNREACH WSAEHOSTUNREACH -#ifndef ENOTEMPTY /* possible previous definition in errno.h */ -#define ENOTEMPTY WSAENOTEMPTY -#endif -#define EPROCLIM WSAEPROCLIM -#define EUSERS WSAEUSERS -#define EDQUOT WSAEDQUOT -#define ESTALE WSAESTALE -#define EREMOTE WSAEREMOTE -#endif - -/* - * Macro argv_item_t hides platform details to code using it. - */ - -#ifdef __VMS -#define argv_item_t __char_ptr32 -#else -#define argv_item_t char * -#endif - - -/* - * We use this ZERO_NULL to avoid picky compiler warnings, - * when assigning a NULL pointer to a function pointer var. - */ - -#define ZERO_NULL 0 - - -#endif /* HEADER_CURL_SETUP_ONCE_H */ - diff --git a/Externals/curl/lib/curl_sspi.c b/Externals/curl/lib/curl_sspi.c deleted file mode 100644 index 54bbef6f6d..0000000000 --- a/Externals/curl/lib/curl_sspi.c +++ /dev/null @@ -1,258 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_WINDOWS_SSPI - -#include -#include "curl_sspi.h" -#include "curl_multibyte.h" -#include "system_win32.h" -#include "warnless.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* We use our own typedef here since some headers might lack these */ -typedef PSecurityFunctionTable (APIENTRY *INITSECURITYINTERFACE_FN)(VOID); - -/* See definition of SECURITY_ENTRYPOINT in sspi.h */ -#ifdef UNICODE -# ifdef _WIN32_WCE -# define SECURITYENTRYPOINT L"InitSecurityInterfaceW" -# else -# define SECURITYENTRYPOINT "InitSecurityInterfaceW" -# endif -#else -# define SECURITYENTRYPOINT "InitSecurityInterfaceA" -#endif - -/* Handle of security.dll or secur32.dll, depending on Windows version */ -HMODULE s_hSecDll = NULL; - -/* Pointer to SSPI dispatch table */ -PSecurityFunctionTable s_pSecFn = NULL; - -/* - * Curl_sspi_global_init() - * - * This is used to load the Security Service Provider Interface (SSPI) - * dynamic link library portably across all Windows versions, without - * the need to directly link libcurl, nor the application using it, at - * build time. - * - * Once this function has been executed, Windows SSPI functions can be - * called through the Security Service Provider Interface dispatch table. - */ -CURLcode Curl_sspi_global_init(void) -{ - bool securityDll = FALSE; - INITSECURITYINTERFACE_FN pInitSecurityInterface; - - /* If security interface is not yet initialized try to do this */ - if(!s_hSecDll) { - /* Security Service Provider Interface (SSPI) functions are located in - * security.dll on WinNT 4.0 and in secur32.dll on Win9x. Win2K and XP - * have both these DLLs (security.dll forwards calls to secur32.dll) */ - DWORD majorVersion = 4; - DWORD platformId = VER_PLATFORM_WIN32_NT; - -#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \ - (_WIN32_WINNT < _WIN32_WINNT_WIN2K) - OSVERSIONINFO osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - - /* Find out Windows version */ - if(!GetVersionEx(&osver)) - return CURLE_FAILED_INIT; - - /* Verify the major version number == 4 and platform id == WIN_NT */ - if(osver.dwMajorVersion == majorVersion && - osver.dwPlatformId == platformId) - securityDll = TRUE; -#else - ULONGLONG cm; - OSVERSIONINFOEX osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwMajorVersion = majorVersion; - osver.dwPlatformId = platformId; - - cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); - cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_PLATFORMID, VER_EQUAL); - - /* Verify the major version number == 4 and platform id == WIN_NT */ - if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR | - VER_PLATFORMID), - cm)) - securityDll = TRUE; -#endif - - /* Load SSPI dll into the address space of the calling process */ - if(securityDll) - s_hSecDll = Curl_load_library(TEXT("security.dll")); - else - s_hSecDll = Curl_load_library(TEXT("secur32.dll")); - if(!s_hSecDll) - return CURLE_FAILED_INIT; - - /* Get address of the InitSecurityInterfaceA function from the SSPI dll */ - pInitSecurityInterface = (INITSECURITYINTERFACE_FN) - GetProcAddress(s_hSecDll, SECURITYENTRYPOINT); - if(!pInitSecurityInterface) - return CURLE_FAILED_INIT; - - /* Get pointer to Security Service Provider Interface dispatch table */ - s_pSecFn = pInitSecurityInterface(); - if(!s_pSecFn) - return CURLE_FAILED_INIT; - } - - return CURLE_OK; -} - -/* - * Curl_sspi_global_cleanup() - * - * This deinitializes the Security Service Provider Interface from libcurl. - */ - -void Curl_sspi_global_cleanup(void) -{ - if(s_hSecDll) { - FreeLibrary(s_hSecDll); - s_hSecDll = NULL; - s_pSecFn = NULL; - } -} - -/* - * Curl_create_sspi_identity() - * - * This is used to populate a SSPI identity structure based on the supplied - * username and password. - * - * Parameters: - * - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * identity [in/out] - The identity structure. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, - SEC_WINNT_AUTH_IDENTITY *identity) -{ - xcharp_u useranddomain; - xcharp_u user, dup_user; - xcharp_u domain, dup_domain; - xcharp_u passwd, dup_passwd; - size_t domlen = 0; - - domain.const_tchar_ptr = TEXT(""); - - /* Initialize the identity */ - memset(identity, 0, sizeof(*identity)); - - useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp); - if(!useranddomain.tchar_ptr) - return CURLE_OUT_OF_MEMORY; - - user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\')); - if(!user.const_tchar_ptr) - user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/')); - - if(user.tchar_ptr) { - domain.tchar_ptr = useranddomain.tchar_ptr; - domlen = user.tchar_ptr - useranddomain.tchar_ptr; - user.tchar_ptr++; - } - else { - user.tchar_ptr = useranddomain.tchar_ptr; - domain.const_tchar_ptr = TEXT(""); - domlen = 0; - } - - /* Setup the identity's user and length */ - dup_user.tchar_ptr = _tcsdup(user.tchar_ptr); - if(!dup_user.tchar_ptr) { - Curl_unicodefree(useranddomain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - identity->User = dup_user.tbyte_ptr; - identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr)); - dup_user.tchar_ptr = NULL; - - /* Setup the identity's domain and length */ - dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1)); - if(!dup_domain.tchar_ptr) { - Curl_unicodefree(useranddomain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen); - *(dup_domain.tchar_ptr + domlen) = TEXT('\0'); - identity->Domain = dup_domain.tbyte_ptr; - identity->DomainLength = curlx_uztoul(domlen); - dup_domain.tchar_ptr = NULL; - - Curl_unicodefree(useranddomain.tchar_ptr); - - /* Setup the identity's password and length */ - passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp); - if(!passwd.tchar_ptr) - return CURLE_OUT_OF_MEMORY; - dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr); - if(!dup_passwd.tchar_ptr) { - Curl_unicodefree(passwd.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - identity->Password = dup_passwd.tbyte_ptr; - identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); - dup_passwd.tchar_ptr = NULL; - - Curl_unicodefree(passwd.tchar_ptr); - - /* Setup the identity's flags */ - identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY; - - return CURLE_OK; -} - -void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity) -{ - if(identity) { - Curl_safefree(identity->User); - Curl_safefree(identity->Password); - Curl_safefree(identity->Domain); - } -} - -#endif /* USE_WINDOWS_SSPI */ diff --git a/Externals/curl/lib/curl_sspi.h b/Externals/curl/lib/curl_sspi.h deleted file mode 100644 index 2bbf9477bb..0000000000 --- a/Externals/curl/lib/curl_sspi.h +++ /dev/null @@ -1,350 +0,0 @@ -#ifndef HEADER_CURL_SSPI_H -#define HEADER_CURL_SSPI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_WINDOWS_SSPI - -#include - -/* - * When including the following three headers, it is mandatory to define either - * SECURITY_WIN32 or SECURITY_KERNEL, indicating who is compiling the code. - */ - -#undef SECURITY_WIN32 -#undef SECURITY_KERNEL -#define SECURITY_WIN32 1 -#include -#include -#include - -CURLcode Curl_sspi_global_init(void); -void Curl_sspi_global_cleanup(void); - -/* This is used to populate the domain in a SSPI identity structure */ -CURLcode Curl_override_sspi_http_realm(const char *chlg, - SEC_WINNT_AUTH_IDENTITY *identity); - -/* This is used to generate an SSPI identity structure */ -CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, - SEC_WINNT_AUTH_IDENTITY *identity); - -/* This is used to free an SSPI identity structure */ -void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity); - -/* Forward-declaration of global variables defined in curl_sspi.c */ -extern HMODULE s_hSecDll; -extern PSecurityFunctionTable s_pSecFn; - -/* Provide some definitions missing in old headers */ -#define SP_NAME_DIGEST "WDigest" -#define SP_NAME_NTLM "NTLM" -#define SP_NAME_NEGOTIATE "Negotiate" -#define SP_NAME_KERBEROS "Kerberos" - -#ifndef ISC_REQ_USE_HTTP_STYLE -#define ISC_REQ_USE_HTTP_STYLE 0x01000000 -#endif - -#ifndef ISC_RET_REPLAY_DETECT -#define ISC_RET_REPLAY_DETECT 0x00000004 -#endif - -#ifndef ISC_RET_SEQUENCE_DETECT -#define ISC_RET_SEQUENCE_DETECT 0x00000008 -#endif - -#ifndef ISC_RET_CONFIDENTIALITY -#define ISC_RET_CONFIDENTIALITY 0x00000010 -#endif - -#ifndef ISC_RET_ALLOCATED_MEMORY -#define ISC_RET_ALLOCATED_MEMORY 0x00000100 -#endif - -#ifndef ISC_RET_STREAM -#define ISC_RET_STREAM 0x00008000 -#endif - -#ifndef SEC_E_INSUFFICIENT_MEMORY -# define SEC_E_INSUFFICIENT_MEMORY ((HRESULT)0x80090300L) -#endif -#ifndef SEC_E_INVALID_HANDLE -# define SEC_E_INVALID_HANDLE ((HRESULT)0x80090301L) -#endif -#ifndef SEC_E_UNSUPPORTED_FUNCTION -# define SEC_E_UNSUPPORTED_FUNCTION ((HRESULT)0x80090302L) -#endif -#ifndef SEC_E_TARGET_UNKNOWN -# define SEC_E_TARGET_UNKNOWN ((HRESULT)0x80090303L) -#endif -#ifndef SEC_E_INTERNAL_ERROR -# define SEC_E_INTERNAL_ERROR ((HRESULT)0x80090304L) -#endif -#ifndef SEC_E_SECPKG_NOT_FOUND -# define SEC_E_SECPKG_NOT_FOUND ((HRESULT)0x80090305L) -#endif -#ifndef SEC_E_NOT_OWNER -# define SEC_E_NOT_OWNER ((HRESULT)0x80090306L) -#endif -#ifndef SEC_E_CANNOT_INSTALL -# define SEC_E_CANNOT_INSTALL ((HRESULT)0x80090307L) -#endif -#ifndef SEC_E_INVALID_TOKEN -# define SEC_E_INVALID_TOKEN ((HRESULT)0x80090308L) -#endif -#ifndef SEC_E_CANNOT_PACK -# define SEC_E_CANNOT_PACK ((HRESULT)0x80090309L) -#endif -#ifndef SEC_E_QOP_NOT_SUPPORTED -# define SEC_E_QOP_NOT_SUPPORTED ((HRESULT)0x8009030AL) -#endif -#ifndef SEC_E_NO_IMPERSONATION -# define SEC_E_NO_IMPERSONATION ((HRESULT)0x8009030BL) -#endif -#ifndef SEC_E_LOGON_DENIED -# define SEC_E_LOGON_DENIED ((HRESULT)0x8009030CL) -#endif -#ifndef SEC_E_UNKNOWN_CREDENTIALS -# define SEC_E_UNKNOWN_CREDENTIALS ((HRESULT)0x8009030DL) -#endif -#ifndef SEC_E_NO_CREDENTIALS -# define SEC_E_NO_CREDENTIALS ((HRESULT)0x8009030EL) -#endif -#ifndef SEC_E_MESSAGE_ALTERED -# define SEC_E_MESSAGE_ALTERED ((HRESULT)0x8009030FL) -#endif -#ifndef SEC_E_OUT_OF_SEQUENCE -# define SEC_E_OUT_OF_SEQUENCE ((HRESULT)0x80090310L) -#endif -#ifndef SEC_E_NO_AUTHENTICATING_AUTHORITY -# define SEC_E_NO_AUTHENTICATING_AUTHORITY ((HRESULT)0x80090311L) -#endif -#ifndef SEC_E_BAD_PKGID -# define SEC_E_BAD_PKGID ((HRESULT)0x80090316L) -#endif -#ifndef SEC_E_CONTEXT_EXPIRED -# define SEC_E_CONTEXT_EXPIRED ((HRESULT)0x80090317L) -#endif -#ifndef SEC_E_INCOMPLETE_MESSAGE -# define SEC_E_INCOMPLETE_MESSAGE ((HRESULT)0x80090318L) -#endif -#ifndef SEC_E_INCOMPLETE_CREDENTIALS -# define SEC_E_INCOMPLETE_CREDENTIALS ((HRESULT)0x80090320L) -#endif -#ifndef SEC_E_BUFFER_TOO_SMALL -# define SEC_E_BUFFER_TOO_SMALL ((HRESULT)0x80090321L) -#endif -#ifndef SEC_E_WRONG_PRINCIPAL -# define SEC_E_WRONG_PRINCIPAL ((HRESULT)0x80090322L) -#endif -#ifndef SEC_E_TIME_SKEW -# define SEC_E_TIME_SKEW ((HRESULT)0x80090324L) -#endif -#ifndef SEC_E_UNTRUSTED_ROOT -# define SEC_E_UNTRUSTED_ROOT ((HRESULT)0x80090325L) -#endif -#ifndef SEC_E_ILLEGAL_MESSAGE -# define SEC_E_ILLEGAL_MESSAGE ((HRESULT)0x80090326L) -#endif -#ifndef SEC_E_CERT_UNKNOWN -# define SEC_E_CERT_UNKNOWN ((HRESULT)0x80090327L) -#endif -#ifndef SEC_E_CERT_EXPIRED -# define SEC_E_CERT_EXPIRED ((HRESULT)0x80090328L) -#endif -#ifndef SEC_E_ENCRYPT_FAILURE -# define SEC_E_ENCRYPT_FAILURE ((HRESULT)0x80090329L) -#endif -#ifndef SEC_E_DECRYPT_FAILURE -# define SEC_E_DECRYPT_FAILURE ((HRESULT)0x80090330L) -#endif -#ifndef SEC_E_ALGORITHM_MISMATCH -# define SEC_E_ALGORITHM_MISMATCH ((HRESULT)0x80090331L) -#endif -#ifndef SEC_E_SECURITY_QOS_FAILED -# define SEC_E_SECURITY_QOS_FAILED ((HRESULT)0x80090332L) -#endif -#ifndef SEC_E_UNFINISHED_CONTEXT_DELETED -# define SEC_E_UNFINISHED_CONTEXT_DELETED ((HRESULT)0x80090333L) -#endif -#ifndef SEC_E_NO_TGT_REPLY -# define SEC_E_NO_TGT_REPLY ((HRESULT)0x80090334L) -#endif -#ifndef SEC_E_NO_IP_ADDRESSES -# define SEC_E_NO_IP_ADDRESSES ((HRESULT)0x80090335L) -#endif -#ifndef SEC_E_WRONG_CREDENTIAL_HANDLE -# define SEC_E_WRONG_CREDENTIAL_HANDLE ((HRESULT)0x80090336L) -#endif -#ifndef SEC_E_CRYPTO_SYSTEM_INVALID -# define SEC_E_CRYPTO_SYSTEM_INVALID ((HRESULT)0x80090337L) -#endif -#ifndef SEC_E_MAX_REFERRALS_EXCEEDED -# define SEC_E_MAX_REFERRALS_EXCEEDED ((HRESULT)0x80090338L) -#endif -#ifndef SEC_E_MUST_BE_KDC -# define SEC_E_MUST_BE_KDC ((HRESULT)0x80090339L) -#endif -#ifndef SEC_E_STRONG_CRYPTO_NOT_SUPPORTED -# define SEC_E_STRONG_CRYPTO_NOT_SUPPORTED ((HRESULT)0x8009033AL) -#endif -#ifndef SEC_E_TOO_MANY_PRINCIPALS -# define SEC_E_TOO_MANY_PRINCIPALS ((HRESULT)0x8009033BL) -#endif -#ifndef SEC_E_NO_PA_DATA -# define SEC_E_NO_PA_DATA ((HRESULT)0x8009033CL) -#endif -#ifndef SEC_E_PKINIT_NAME_MISMATCH -# define SEC_E_PKINIT_NAME_MISMATCH ((HRESULT)0x8009033DL) -#endif -#ifndef SEC_E_SMARTCARD_LOGON_REQUIRED -# define SEC_E_SMARTCARD_LOGON_REQUIRED ((HRESULT)0x8009033EL) -#endif -#ifndef SEC_E_SHUTDOWN_IN_PROGRESS -# define SEC_E_SHUTDOWN_IN_PROGRESS ((HRESULT)0x8009033FL) -#endif -#ifndef SEC_E_KDC_INVALID_REQUEST -# define SEC_E_KDC_INVALID_REQUEST ((HRESULT)0x80090340L) -#endif -#ifndef SEC_E_KDC_UNABLE_TO_REFER -# define SEC_E_KDC_UNABLE_TO_REFER ((HRESULT)0x80090341L) -#endif -#ifndef SEC_E_KDC_UNKNOWN_ETYPE -# define SEC_E_KDC_UNKNOWN_ETYPE ((HRESULT)0x80090342L) -#endif -#ifndef SEC_E_UNSUPPORTED_PREAUTH -# define SEC_E_UNSUPPORTED_PREAUTH ((HRESULT)0x80090343L) -#endif -#ifndef SEC_E_DELEGATION_REQUIRED -# define SEC_E_DELEGATION_REQUIRED ((HRESULT)0x80090345L) -#endif -#ifndef SEC_E_BAD_BINDINGS -# define SEC_E_BAD_BINDINGS ((HRESULT)0x80090346L) -#endif -#ifndef SEC_E_MULTIPLE_ACCOUNTS -# define SEC_E_MULTIPLE_ACCOUNTS ((HRESULT)0x80090347L) -#endif -#ifndef SEC_E_NO_KERB_KEY -# define SEC_E_NO_KERB_KEY ((HRESULT)0x80090348L) -#endif -#ifndef SEC_E_CERT_WRONG_USAGE -# define SEC_E_CERT_WRONG_USAGE ((HRESULT)0x80090349L) -#endif -#ifndef SEC_E_DOWNGRADE_DETECTED -# define SEC_E_DOWNGRADE_DETECTED ((HRESULT)0x80090350L) -#endif -#ifndef SEC_E_SMARTCARD_CERT_REVOKED -# define SEC_E_SMARTCARD_CERT_REVOKED ((HRESULT)0x80090351L) -#endif -#ifndef SEC_E_ISSUING_CA_UNTRUSTED -# define SEC_E_ISSUING_CA_UNTRUSTED ((HRESULT)0x80090352L) -#endif -#ifndef SEC_E_REVOCATION_OFFLINE_C -# define SEC_E_REVOCATION_OFFLINE_C ((HRESULT)0x80090353L) -#endif -#ifndef SEC_E_PKINIT_CLIENT_FAILURE -# define SEC_E_PKINIT_CLIENT_FAILURE ((HRESULT)0x80090354L) -#endif -#ifndef SEC_E_SMARTCARD_CERT_EXPIRED -# define SEC_E_SMARTCARD_CERT_EXPIRED ((HRESULT)0x80090355L) -#endif -#ifndef SEC_E_NO_S4U_PROT_SUPPORT -# define SEC_E_NO_S4U_PROT_SUPPORT ((HRESULT)0x80090356L) -#endif -#ifndef SEC_E_CROSSREALM_DELEGATION_FAILURE -# define SEC_E_CROSSREALM_DELEGATION_FAILURE ((HRESULT)0x80090357L) -#endif -#ifndef SEC_E_REVOCATION_OFFLINE_KDC -# define SEC_E_REVOCATION_OFFLINE_KDC ((HRESULT)0x80090358L) -#endif -#ifndef SEC_E_ISSUING_CA_UNTRUSTED_KDC -# define SEC_E_ISSUING_CA_UNTRUSTED_KDC ((HRESULT)0x80090359L) -#endif -#ifndef SEC_E_KDC_CERT_EXPIRED -# define SEC_E_KDC_CERT_EXPIRED ((HRESULT)0x8009035AL) -#endif -#ifndef SEC_E_KDC_CERT_REVOKED -# define SEC_E_KDC_CERT_REVOKED ((HRESULT)0x8009035BL) -#endif -#ifndef SEC_E_INVALID_PARAMETER -# define SEC_E_INVALID_PARAMETER ((HRESULT)0x8009035DL) -#endif -#ifndef SEC_E_DELEGATION_POLICY -# define SEC_E_DELEGATION_POLICY ((HRESULT)0x8009035EL) -#endif -#ifndef SEC_E_POLICY_NLTM_ONLY -# define SEC_E_POLICY_NLTM_ONLY ((HRESULT)0x8009035FL) -#endif - -#ifndef SEC_I_CONTINUE_NEEDED -# define SEC_I_CONTINUE_NEEDED ((HRESULT)0x00090312L) -#endif -#ifndef SEC_I_COMPLETE_NEEDED -# define SEC_I_COMPLETE_NEEDED ((HRESULT)0x00090313L) -#endif -#ifndef SEC_I_COMPLETE_AND_CONTINUE -# define SEC_I_COMPLETE_AND_CONTINUE ((HRESULT)0x00090314L) -#endif -#ifndef SEC_I_LOCAL_LOGON -# define SEC_I_LOCAL_LOGON ((HRESULT)0x00090315L) -#endif -#ifndef SEC_I_CONTEXT_EXPIRED -# define SEC_I_CONTEXT_EXPIRED ((HRESULT)0x00090317L) -#endif -#ifndef SEC_I_INCOMPLETE_CREDENTIALS -# define SEC_I_INCOMPLETE_CREDENTIALS ((HRESULT)0x00090320L) -#endif -#ifndef SEC_I_RENEGOTIATE -# define SEC_I_RENEGOTIATE ((HRESULT)0x00090321L) -#endif -#ifndef SEC_I_NO_LSA_CONTEXT -# define SEC_I_NO_LSA_CONTEXT ((HRESULT)0x00090323L) -#endif -#ifndef SEC_I_SIGNATURE_NEEDED -# define SEC_I_SIGNATURE_NEEDED ((HRESULT)0x0009035CL) -#endif - -#ifndef CRYPT_E_REVOKED -# define CRYPT_E_REVOKED ((HRESULT)0x80092010L) -#endif - -#ifdef UNICODE -# define SECFLAG_WINNT_AUTH_IDENTITY \ - (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE -#else -# define SECFLAG_WINNT_AUTH_IDENTITY \ - (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI -#endif - -/* - * Definitions required from ntsecapi.h are directly provided below this point - * to avoid including ntsecapi.h due to a conflict with OpenSSL's safestack.h - */ -#define KERB_WRAP_NO_ENCRYPT 0x80000001 - -#endif /* USE_WINDOWS_SSPI */ - -#endif /* HEADER_CURL_SSPI_H */ diff --git a/Externals/curl/lib/curl_threads.c b/Externals/curl/lib/curl_threads.c deleted file mode 100644 index c98d8bbad1..0000000000 --- a/Externals/curl/lib/curl_threads.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#if defined(USE_THREADS_POSIX) -# ifdef HAVE_PTHREAD_H -# include -# endif -#elif defined(USE_THREADS_WIN32) -# ifdef HAVE_PROCESS_H -# include -# endif -#endif - -#include "curl_threads.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#if defined(USE_THREADS_POSIX) - -struct curl_actual_call { - unsigned int (*func)(void *); - void *arg; -}; - -static void *curl_thread_create_thunk(void *arg) -{ - struct curl_actual_call * ac = arg; - unsigned int (*func)(void *) = ac->func; - void *real_arg = ac->arg; - - free(ac); - - (*func)(real_arg); - - return 0; -} - -curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg) -{ - curl_thread_t t = malloc(sizeof(pthread_t)); - struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call)); - if(!(ac && t)) - goto err; - - ac->func = func; - ac->arg = arg; - - if(pthread_create(t, NULL, curl_thread_create_thunk, ac) != 0) - goto err; - - return t; - -err: - free(t); - free(ac); - return curl_thread_t_null; -} - -void Curl_thread_destroy(curl_thread_t hnd) -{ - if(hnd != curl_thread_t_null) { - pthread_detach(*hnd); - free(hnd); - } -} - -int Curl_thread_join(curl_thread_t *hnd) -{ - int ret = (pthread_join(**hnd, NULL) == 0); - - free(*hnd); - *hnd = curl_thread_t_null; - - return ret; -} - -#elif defined(USE_THREADS_WIN32) - -curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*), - void *arg) -{ -#ifdef _WIN32_WCE - return CreateThread(NULL, 0, func, arg, 0, NULL); -#else - curl_thread_t t; - t = (curl_thread_t)_beginthreadex(NULL, 0, func, arg, 0, NULL); - if((t == 0) || (t == (curl_thread_t)-1L)) - return curl_thread_t_null; - return t; -#endif -} - -void Curl_thread_destroy(curl_thread_t hnd) -{ - CloseHandle(hnd); -} - -int Curl_thread_join(curl_thread_t *hnd) -{ -#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ - (_WIN32_WINNT < _WIN32_WINNT_VISTA) - int ret = (WaitForSingleObject(*hnd, INFINITE) == WAIT_OBJECT_0); -#else - int ret = (WaitForSingleObjectEx(*hnd, INFINITE, FALSE) == WAIT_OBJECT_0); -#endif - - Curl_thread_destroy(*hnd); - - *hnd = curl_thread_t_null; - - return ret; -} - -#endif /* USE_THREADS_* */ diff --git a/Externals/curl/lib/curl_threads.h b/Externals/curl/lib/curl_threads.h deleted file mode 100644 index 8cbac63a78..0000000000 --- a/Externals/curl/lib/curl_threads.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef HEADER_CURL_THREADS_H -#define HEADER_CURL_THREADS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(USE_THREADS_POSIX) -# define CURL_STDCALL -# define curl_mutex_t pthread_mutex_t -# define curl_thread_t pthread_t * -# define curl_thread_t_null (pthread_t *)0 -# define Curl_mutex_init(m) pthread_mutex_init(m, NULL) -# define Curl_mutex_acquire(m) pthread_mutex_lock(m) -# define Curl_mutex_release(m) pthread_mutex_unlock(m) -# define Curl_mutex_destroy(m) pthread_mutex_destroy(m) -#elif defined(USE_THREADS_WIN32) -# define CURL_STDCALL __stdcall -# define curl_mutex_t CRITICAL_SECTION -# define curl_thread_t HANDLE -# define curl_thread_t_null (HANDLE)0 -# if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ - (_WIN32_WINNT < _WIN32_WINNT_VISTA) -# define Curl_mutex_init(m) InitializeCriticalSection(m) -# else -# define Curl_mutex_init(m) InitializeCriticalSectionEx(m, 0, 1) -# endif -# define Curl_mutex_acquire(m) EnterCriticalSection(m) -# define Curl_mutex_release(m) LeaveCriticalSection(m) -# define Curl_mutex_destroy(m) DeleteCriticalSection(m) -#endif - -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) - -curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*), - void *arg); - -void Curl_thread_destroy(curl_thread_t hnd); - -int Curl_thread_join(curl_thread_t *hnd); - -#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */ - -#endif /* HEADER_CURL_THREADS_H */ diff --git a/Externals/curl/lib/curlx.h b/Externals/curl/lib/curlx.h deleted file mode 100644 index 448a34ff38..0000000000 --- a/Externals/curl/lib/curlx.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef HEADER_CURL_CURLX_H -#define HEADER_CURL_CURLX_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Defines protos and includes all header files that provide the curlx_* - * functions. The curlx_* functions are not part of the libcurl API, but are - * stand-alone functions whose sources can be built and linked by apps if need - * be. - */ - -#include -/* this is still a public header file that provides the curl_mprintf() - functions while they still are offered publicly. They will be made library- - private one day */ - -#include "strequal.h" -/* "strequal.h" provides the strequal protos */ - -#include "strtoofft.h" -/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a - curl_off_t number from a given string. -*/ - -#include "timeval.h" -/* - "timeval.h" sets up a 'struct timeval' even for platforms that otherwise - don't have one and has protos for these functions: - - curlx_tvnow() - curlx_tvdiff() - curlx_tvdiff_secs() -*/ - -#include "nonblock.h" -/* "nonblock.h" provides curlx_nonblock() */ - -#include "warnless.h" -/* "warnless.h" provides functions: - - curlx_ultous() - curlx_ultouc() - curlx_uztosi() -*/ - -/* Now setup curlx_ * names for the functions that are to become curlx_ and - be removed from a future libcurl official API: - curlx_getenv - curlx_mprintf (and its variations) - curlx_strequal - curlx_strnequal - -*/ - -#define curlx_getenv curl_getenv -#define curlx_strequal curl_strequal -#define curlx_strnequal curl_strnequal -#define curlx_raw_equal Curl_raw_equal -#define curlx_mvsnprintf curl_mvsnprintf -#define curlx_msnprintf curl_msnprintf -#define curlx_maprintf curl_maprintf -#define curlx_mvaprintf curl_mvaprintf -#define curlx_msprintf curl_msprintf -#define curlx_mprintf curl_mprintf -#define curlx_mfprintf curl_mfprintf -#define curlx_mvsprintf curl_mvsprintf -#define curlx_mvprintf curl_mvprintf -#define curlx_mvfprintf curl_mvfprintf - -#ifdef ENABLE_CURLX_PRINTF -/* If this define is set, we define all "standard" printf() functions to use - the curlx_* version instead. It makes the source code transparent and - easier to understand/patch. Undefine them first. */ -# undef printf -# undef fprintf -# undef sprintf -# undef snprintf -# undef vprintf -# undef vfprintf -# undef vsprintf -# undef vsnprintf -# undef aprintf -# undef vaprintf - -# define printf curlx_mprintf -# define fprintf curlx_mfprintf -# define sprintf curlx_msprintf -# define snprintf curlx_msnprintf -# define vprintf curlx_mvprintf -# define vfprintf curlx_mvfprintf -# define vsprintf curlx_mvsprintf -# define vsnprintf curlx_mvsnprintf -# define aprintf curlx_maprintf -# define vaprintf curlx_mvaprintf -#endif /* ENABLE_CURLX_PRINTF */ - -#endif /* HEADER_CURL_CURLX_H */ - diff --git a/Externals/curl/lib/dict.c b/Externals/curl/lib/dict.c deleted file mode 100644 index 2e7cb4778d..0000000000 --- a/Externals/curl/lib/dict.c +++ /dev/null @@ -1,279 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_DICT - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#include "urldata.h" -#include -#include "transfer.h" -#include "sendf.h" - -#include "progress.h" -#include "strequal.h" -#include "dict.h" -#include "rawstr.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * Forward declarations. - */ - -static CURLcode dict_do(struct connectdata *conn, bool *done); - -/* - * DICT protocol handler. - */ - -const struct Curl_handler Curl_handler_dict = { - "DICT", /* scheme */ - ZERO_NULL, /* setup_connection */ - dict_do, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_DICT, /* defport */ - CURLPROTO_DICT, /* protocol */ - PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ -}; - -static char *unescape_word(struct SessionHandle *data, const char *inputbuff) -{ - char *newp; - char *dictp; - char *ptr; - int len; - char ch; - int olen=0; - - newp = curl_easy_unescape(data, inputbuff, 0, &len); - if(!newp) - return NULL; - - dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */ - if(dictp) { - /* According to RFC2229 section 2.2, these letters need to be escaped with - \[letter] */ - for(ptr = newp; - (ch = *ptr) != 0; - ptr++) { - if((ch <= 32) || (ch == 127) || - (ch == '\'') || (ch == '\"') || (ch == '\\')) { - dictp[olen++] = '\\'; - } - dictp[olen++] = ch; - } - dictp[olen]=0; - } - free(newp); - return dictp; -} - -static CURLcode dict_do(struct connectdata *conn, bool *done) -{ - char *word; - char *eword; - char *ppath; - char *database = NULL; - char *strategy = NULL; - char *nthdef = NULL; /* This is not part of the protocol, but required - by RFC 2229 */ - CURLcode result=CURLE_OK; - struct SessionHandle *data=conn->data; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - - char *path = data->state.path; - curl_off_t *bytecount = &data->req.bytecount; - - *done = TRUE; /* unconditionally */ - - if(conn->bits.user_passwd) { - /* AUTH is missing */ - } - - if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) || - Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) || - Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) { - - word = strchr(path, ':'); - if(word) { - word++; - database = strchr(word, ':'); - if(database) { - *database++ = (char)0; - strategy = strchr(database, ':'); - if(strategy) { - *strategy++ = (char)0; - nthdef = strchr(strategy, ':'); - if(nthdef) { - *nthdef = (char)0; - } - } - } - } - - if((word == NULL) || (*word == (char)0)) { - infof(data, "lookup word is missing\n"); - word=(char *)"default"; - } - if((database == NULL) || (*database == (char)0)) { - database = (char *)"!"; - } - if((strategy == NULL) || (*strategy == (char)0)) { - strategy = (char *)"."; - } - - eword = unescape_word(data, word); - if(!eword) - return CURLE_OUT_OF_MEMORY; - - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "MATCH " - "%s " /* database */ - "%s " /* strategy */ - "%s\r\n" /* word */ - "QUIT\r\n", - - database, - strategy, - eword - ); - - free(eword); - - if(result) { - failf(data, "Failed sending DICT request"); - return result; - } - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); /* no upload */ - } - else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) || - Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) || - Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) { - - word = strchr(path, ':'); - if(word) { - word++; - database = strchr(word, ':'); - if(database) { - *database++ = (char)0; - nthdef = strchr(database, ':'); - if(nthdef) { - *nthdef = (char)0; - } - } - } - - if((word == NULL) || (*word == (char)0)) { - infof(data, "lookup word is missing\n"); - word=(char *)"default"; - } - if((database == NULL) || (*database == (char)0)) { - database = (char *)"!"; - } - - eword = unescape_word(data, word); - if(!eword) - return CURLE_OUT_OF_MEMORY; - - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "DEFINE " - "%s " /* database */ - "%s\r\n" /* word */ - "QUIT\r\n", - database, - eword); - - free(eword); - - if(result) { - failf(data, "Failed sending DICT request"); - return result; - } - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, - -1, NULL); /* no upload */ - } - else { - - ppath = strchr(path, '/'); - if(ppath) { - int i; - - ppath++; - for(i = 0; ppath[i]; i++) { - if(ppath[i] == ':') - ppath[i] = ' '; - } - result = Curl_sendf(sockfd, conn, - "CLIENT " LIBCURL_NAME " " LIBCURL_VERSION "\r\n" - "%s\r\n" - "QUIT\r\n", ppath); - if(result) { - failf(data, "Failed sending DICT request"); - return result; - } - - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount, -1, NULL); - } - } - - return CURLE_OK; -} -#endif /*CURL_DISABLE_DICT*/ diff --git a/Externals/curl/lib/dict.h b/Externals/curl/lib/dict.h deleted file mode 100644 index 12c0f3394d..0000000000 --- a/Externals/curl/lib/dict.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HEADER_CURL_DICT_H -#define HEADER_CURL_DICT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifndef CURL_DISABLE_DICT -extern const struct Curl_handler Curl_handler_dict; -#endif - -#endif /* HEADER_CURL_DICT_H */ diff --git a/Externals/curl/lib/dotdot.c b/Externals/curl/lib/dotdot.c deleted file mode 100644 index ea7c8a04f6..0000000000 --- a/Externals/curl/lib/dotdot.c +++ /dev/null @@ -1,179 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "dotdot.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * "Remove Dot Segments" - * https://tools.ietf.org/html/rfc3986#section-5.2.4 - */ - -/* - * Curl_dedotdotify() - * @unittest: 1395 - * - * This function gets a zero-terminated path with dot and dotdot sequences - * passed in and strips them off according to the rules in RFC 3986 section - * 5.2.4. - * - * The function handles a query part ('?' + stuff) appended but it expects - * that fragments ('#' + stuff) have already been cut off. - * - * RETURNS - * - * an allocated dedotdotified output string - */ -char *Curl_dedotdotify(const char *input) -{ - size_t inlen = strlen(input); - char *clone; - size_t clen = inlen; /* the length of the cloned input */ - char *out = malloc(inlen+1); - char *outptr; - char *orgclone; - char *queryp; - if(!out) - return NULL; /* out of memory */ - - /* get a cloned copy of the input */ - clone = strdup(input); - if(!clone) { - free(out); - return NULL; - } - orgclone = clone; - outptr = out; - - if(!*clone) { - /* zero length string, return that */ - free(out); - return clone; - } - - /* - * To handle query-parts properly, we must find it and remove it during the - * dotdot-operation and then append it again at the end to the output - * string. - */ - queryp = strchr(clone, '?'); - if(queryp) - *queryp = 0; - - do { - - /* A. If the input buffer begins with a prefix of "../" or "./", then - remove that prefix from the input buffer; otherwise, */ - - if(!strncmp("./", clone, 2)) { - clone+=2; - clen-=2; - } - else if(!strncmp("../", clone, 3)) { - clone+=3; - clen-=3; - } - - /* B. if the input buffer begins with a prefix of "/./" or "/.", where - "." is a complete path segment, then replace that prefix with "/" in - the input buffer; otherwise, */ - else if(!strncmp("/./", clone, 3)) { - clone+=2; - clen-=2; - } - else if(!strcmp("/.", clone)) { - clone[1]='/'; - clone++; - clen-=1; - } - - /* C. if the input buffer begins with a prefix of "/../" or "/..", where - ".." is a complete path segment, then replace that prefix with "/" in - the input buffer and remove the last segment and its preceding "/" (if - any) from the output buffer; otherwise, */ - - else if(!strncmp("/../", clone, 4)) { - clone+=3; - clen-=3; - /* remove the last segment from the output buffer */ - while(outptr > out) { - outptr--; - if(*outptr == '/') - break; - } - *outptr = 0; /* zero-terminate where it stops */ - } - else if(!strcmp("/..", clone)) { - clone[2]='/'; - clone+=2; - clen-=2; - /* remove the last segment from the output buffer */ - while(outptr > out) { - outptr--; - if(*outptr == '/') - break; - } - *outptr = 0; /* zero-terminate where it stops */ - } - - /* D. if the input buffer consists only of "." or "..", then remove - that from the input buffer; otherwise, */ - - else if(!strcmp(".", clone) || !strcmp("..", clone)) { - *clone=0; - } - - else { - /* E. move the first path segment in the input buffer to the end of - the output buffer, including the initial "/" character (if any) and - any subsequent characters up to, but not including, the next "/" - character or the end of the input buffer. */ - - do { - *outptr++ = *clone++; - clen--; - } while(*clone && (*clone != '/')); - *outptr = 0; - } - - } while(*clone); - - if(queryp) { - size_t qlen; - /* There was a query part, append that to the output. The 'clone' string - may now have been altered so we copy from the original input string - from the correct index. */ - size_t oindex = queryp - orgclone; - qlen = strlen(&input[oindex]); - memcpy(outptr, &input[oindex], qlen+1); /* include the ending zero byte */ - } - - free(orgclone); - return out; -} diff --git a/Externals/curl/lib/dotdot.h b/Externals/curl/lib/dotdot.h deleted file mode 100644 index fac8e6f2ad..0000000000 --- a/Externals/curl/lib/dotdot.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef HEADER_CURL_DOTDOT_H -#define HEADER_CURL_DOTDOT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -char *Curl_dedotdotify(const char *input); -#endif diff --git a/Externals/curl/lib/easy.c b/Externals/curl/lib/easy.c deleted file mode 100644 index ea7af5e524..0000000000 --- a/Externals/curl/lib/easy.c +++ /dev/null @@ -1,1140 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -/* - * See comment in curl_memory.h for the explanation of this sanity check. - */ - -#ifdef CURLX_NO_MEMORY_CALLBACKS -#error "libcurl shall not ever be built with CURLX_NO_MEMORY_CALLBACKS defined" -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "strequal.h" -#include "urldata.h" -#include -#include "transfer.h" -#include "vtls/vtls.h" -#include "url.h" -#include "getinfo.h" -#include "hostip.h" -#include "share.h" -#include "strdup.h" -#include "progress.h" -#include "easyif.h" -#include "select.h" -#include "sendf.h" /* for failf function prototype */ -#include "connect.h" /* for Curl_getconnectinfo */ -#include "slist.h" -#include "amigaos.h" -#include "non-ascii.h" -#include "warnless.h" -#include "conncache.h" -#include "multiif.h" -#include "sigpipe.h" -#include "ssh.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -void Curl_version_init(void); - -/* win32_cleanup() is for win32 socket cleanup functionality, the opposite - of win32_init() */ -static void win32_cleanup(void) -{ -#ifdef USE_WINSOCK - WSACleanup(); -#endif -#ifdef USE_WINDOWS_SSPI - Curl_sspi_global_cleanup(); -#endif -} - -/* win32_init() performs win32 socket initialization to properly setup the - stack to allow networking */ -static CURLcode win32_init(void) -{ -#ifdef USE_WINSOCK - WORD wVersionRequested; - WSADATA wsaData; - int res; - -#if defined(ENABLE_IPV6) && (USE_WINSOCK < 2) - Error IPV6_requires_winsock2 -#endif - - wVersionRequested = MAKEWORD(USE_WINSOCK, USE_WINSOCK); - - res = WSAStartup(wVersionRequested, &wsaData); - - if(res != 0) - /* Tell the user that we couldn't find a useable */ - /* winsock.dll. */ - return CURLE_FAILED_INIT; - - /* Confirm that the Windows Sockets DLL supports what we need.*/ - /* Note that if the DLL supports versions greater */ - /* than wVersionRequested, it will still return */ - /* wVersionRequested in wVersion. wHighVersion contains the */ - /* highest supported version. */ - - if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested) ) { - /* Tell the user that we couldn't find a useable */ - - /* winsock.dll. */ - WSACleanup(); - return CURLE_FAILED_INIT; - } - /* The Windows Sockets DLL is acceptable. Proceed. */ -#elif defined(USE_LWIPSOCK) - lwip_init(); -#endif - -#ifdef USE_WINDOWS_SSPI - { - CURLcode result = Curl_sspi_global_init(); - if(result) - return result; - } -#endif - - return CURLE_OK; -} - -#ifdef USE_LIBIDN -/* - * Initialise use of IDNA library. - * It falls back to ASCII if $CHARSET isn't defined. This doesn't work for - * idna_to_ascii_lz(). - */ -static void idna_init (void) -{ -#ifdef WIN32 - char buf[60]; - UINT cp = GetACP(); - - if(!getenv("CHARSET") && cp > 0) { - snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp); - putenv(buf); - } -#else - /* to do? */ -#endif -} -#endif /* USE_LIBIDN */ - -/* true globals -- for curl_global_init() and curl_global_cleanup() */ -static unsigned int initialized; -static long init_flags; - -/* - * strdup (and other memory functions) is redefined in complicated - * ways, but at this point it must be defined as the system-supplied strdup - * so the callback pointer is initialized correctly. - */ -#if defined(_WIN32_WCE) -#define system_strdup _strdup -#elif !defined(HAVE_STRDUP) -#define system_strdup curlx_strdup -#else -#define system_strdup strdup -#endif - -#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) -# pragma warning(disable:4232) /* MSVC extension, dllimport identity */ -#endif - -#ifndef __SYMBIAN32__ -/* - * If a memory-using function (like curl_getenv) is used before - * curl_global_init() is called, we need to have these pointers set already. - */ -curl_malloc_callback Curl_cmalloc = (curl_malloc_callback)malloc; -curl_free_callback Curl_cfree = (curl_free_callback)free; -curl_realloc_callback Curl_crealloc = (curl_realloc_callback)realloc; -curl_strdup_callback Curl_cstrdup = (curl_strdup_callback)system_strdup; -curl_calloc_callback Curl_ccalloc = (curl_calloc_callback)calloc; -#if defined(WIN32) && defined(UNICODE) -curl_wcsdup_callback Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; -#endif -#else -/* - * Symbian OS doesn't support initialization to code in writeable static data. - * Initialization will occur in the curl_global_init() call. - */ -curl_malloc_callback Curl_cmalloc; -curl_free_callback Curl_cfree; -curl_realloc_callback Curl_crealloc; -curl_strdup_callback Curl_cstrdup; -curl_calloc_callback Curl_ccalloc; -#endif - -#if defined(_MSC_VER) && defined(_DLL) && !defined(__POCC__) -# pragma warning(default:4232) /* MSVC extension, dllimport identity */ -#endif - -/** - * curl_global_init() globally initializes cURL given a bitwise set of the - * different features of what to initialize. - */ -static CURLcode global_init(long flags, bool memoryfuncs) -{ - if(initialized++) - return CURLE_OK; - - if(memoryfuncs) { - /* Setup the default memory functions here (again) */ - Curl_cmalloc = (curl_malloc_callback)malloc; - Curl_cfree = (curl_free_callback)free; - Curl_crealloc = (curl_realloc_callback)realloc; - Curl_cstrdup = (curl_strdup_callback)system_strdup; - Curl_ccalloc = (curl_calloc_callback)calloc; -#if defined(WIN32) && defined(UNICODE) - Curl_cwcsdup = (curl_wcsdup_callback)_wcsdup; -#endif - } - - if(flags & CURL_GLOBAL_SSL) - if(!Curl_ssl_init()) { - DEBUGF(fprintf(stderr, "Error: Curl_ssl_init failed\n")); - return CURLE_FAILED_INIT; - } - - if(flags & CURL_GLOBAL_WIN32) - if(win32_init()) { - DEBUGF(fprintf(stderr, "Error: win32_init failed\n")); - return CURLE_FAILED_INIT; - } - -#ifdef __AMIGA__ - if(!Curl_amiga_init()) { - DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); - return CURLE_FAILED_INIT; - } -#endif - -#ifdef NETWARE - if(netware_init()) { - DEBUGF(fprintf(stderr, "Warning: LONG namespace not available\n")); - } -#endif - -#ifdef USE_LIBIDN - idna_init(); -#endif - - if(Curl_resolver_global_init()) { - DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n")); - return CURLE_FAILED_INIT; - } - -#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT) - if(libssh2_init(0)) { - DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n")); - return CURLE_FAILED_INIT; - } -#endif - - if(flags & CURL_GLOBAL_ACK_EINTR) - Curl_ack_eintr = 1; - - init_flags = flags; - - Curl_version_init(); - - return CURLE_OK; -} - - -/** - * curl_global_init() globally initializes cURL given a bitwise set of the - * different features of what to initialize. - */ -CURLcode curl_global_init(long flags) -{ - return global_init(flags, TRUE); -} - -/* - * curl_global_init_mem() globally initializes cURL and also registers the - * user provided callback routines. - */ -CURLcode curl_global_init_mem(long flags, curl_malloc_callback m, - curl_free_callback f, curl_realloc_callback r, - curl_strdup_callback s, curl_calloc_callback c) -{ - /* Invalid input, return immediately */ - if(!m || !f || !r || !s || !c) - return CURLE_FAILED_INIT; - - if(initialized) { - /* Already initialized, don't do it again, but bump the variable anyway to - work like curl_global_init() and require the same amount of cleanup - calls. */ - initialized++; - return CURLE_OK; - } - - /* set memory functions before global_init() in case it wants memory - functions */ - Curl_cmalloc = m; - Curl_cfree = f; - Curl_cstrdup = s; - Curl_crealloc = r; - Curl_ccalloc = c; - - /* Call the actual init function, but without setting */ - return global_init(flags, FALSE); -} - -/** - * curl_global_cleanup() globally cleanups cURL, uses the value of - * "init_flags" to determine what needs to be cleaned up and what doesn't. - */ -void curl_global_cleanup(void) -{ - if(!initialized) - return; - - if(--initialized) - return; - - Curl_global_host_cache_dtor(); - - if(init_flags & CURL_GLOBAL_SSL) - Curl_ssl_cleanup(); - - Curl_resolver_global_cleanup(); - - if(init_flags & CURL_GLOBAL_WIN32) - win32_cleanup(); - - Curl_amiga_cleanup(); - -#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_EXIT) - (void)libssh2_exit(); -#endif - - init_flags = 0; -} - -/* - * curl_easy_init() is the external interface to alloc, setup and init an - * easy handle that is returned. If anything goes wrong, NULL is returned. - */ -CURL *curl_easy_init(void) -{ - CURLcode result; - struct SessionHandle *data; - - /* Make sure we inited the global SSL stuff */ - if(!initialized) { - result = curl_global_init(CURL_GLOBAL_DEFAULT); - if(result) { - /* something in the global init failed, return nothing */ - DEBUGF(fprintf(stderr, "Error: curl_global_init failed\n")); - return NULL; - } - } - - /* We use curl_open() with undefined URL so far */ - result = Curl_open(&data); - if(result) { - DEBUGF(fprintf(stderr, "Error: Curl_open failed\n")); - return NULL; - } - - return data; -} - -/* - * curl_easy_setopt() is the external interface for setting options on an - * easy handle. - */ - -#undef curl_easy_setopt -CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...) -{ - va_list arg; - struct SessionHandle *data = curl; - CURLcode result; - - if(!curl) - return CURLE_BAD_FUNCTION_ARGUMENT; - - va_start(arg, tag); - - result = Curl_setopt(data, tag, arg); - - va_end(arg); - return result; -} - -#ifdef CURLDEBUG - -struct socketmonitor { - struct socketmonitor *next; /* the next node in the list or NULL */ - struct pollfd socket; /* socket info of what to monitor */ -}; - -struct events { - long ms; /* timeout, run the timeout function when reached */ - bool msbump; /* set TRUE when timeout is set by callback */ - int num_sockets; /* number of nodes in the monitor list */ - struct socketmonitor *list; /* list of sockets to monitor */ - int running_handles; /* store the returned number */ -}; - -/* events_timer - * - * Callback that gets called with a new value when the timeout should be - * updated. - */ - -static int events_timer(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp) /* private callback pointer */ -{ - struct events *ev = userp; - (void)multi; - if(timeout_ms == -1) - /* timeout removed */ - timeout_ms = 0; - else if(timeout_ms == 0) - /* timeout is already reached! */ - timeout_ms = 1; /* trigger asap */ - - ev->ms = timeout_ms; - ev->msbump = TRUE; - return 0; -} - - -/* poll2cselect - * - * convert from poll() bit definitions to libcurl's CURL_CSELECT_* ones - */ -static int poll2cselect(int pollmask) -{ - int omask=0; - if(pollmask & POLLIN) - omask |= CURL_CSELECT_IN; - if(pollmask & POLLOUT) - omask |= CURL_CSELECT_OUT; - if(pollmask & POLLERR) - omask |= CURL_CSELECT_ERR; - return omask; -} - - -/* socketcb2poll - * - * convert from libcurl' CURL_POLL_* bit definitions to poll()'s - */ -static short socketcb2poll(int pollmask) -{ - short omask=0; - if(pollmask & CURL_POLL_IN) - omask |= POLLIN; - if(pollmask & CURL_POLL_OUT) - omask |= POLLOUT; - return omask; -} - -/* events_socket - * - * Callback that gets called with information about socket activity to - * monitor. - */ -static int events_socket(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp) /* private socket - pointer */ -{ - struct events *ev = userp; - struct socketmonitor *m; - struct socketmonitor *prev=NULL; - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) easy; -#endif - (void)socketp; - - m = ev->list; - while(m) { - if(m->socket.fd == s) { - - if(what == CURL_POLL_REMOVE) { - struct socketmonitor *nxt = m->next; - /* remove this node from the list of monitored sockets */ - if(prev) - prev->next = nxt; - else - ev->list = nxt; - free(m); - m = nxt; - infof(easy, "socket cb: socket %d REMOVED\n", s); - } - else { - /* The socket 's' is already being monitored, update the activity - mask. Convert from libcurl bitmask to the poll one. */ - m->socket.events = socketcb2poll(what); - infof(easy, "socket cb: socket %d UPDATED as %s%s\n", s, - what&CURL_POLL_IN?"IN":"", - what&CURL_POLL_OUT?"OUT":""); - } - break; - } - prev = m; - m = m->next; /* move to next node */ - } - if(!m) { - if(what == CURL_POLL_REMOVE) { - /* this happens a bit too often, libcurl fix perhaps? */ - /* fprintf(stderr, - "%s: socket %d asked to be REMOVED but not present!\n", - __func__, s); */ - } - else { - m = malloc(sizeof(struct socketmonitor)); - if(m) { - m->next = ev->list; - m->socket.fd = s; - m->socket.events = socketcb2poll(what); - m->socket.revents = 0; - ev->list = m; - infof(easy, "socket cb: socket %d ADDED as %s%s\n", s, - what&CURL_POLL_IN?"IN":"", - what&CURL_POLL_OUT?"OUT":""); - } - else - return CURLE_OUT_OF_MEMORY; - } - } - - return 0; -} - - -/* - * events_setup() - * - * Do the multi handle setups that only event-based transfers need. - */ -static void events_setup(CURLM *multi, struct events *ev) -{ - /* timer callback */ - curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer); - curl_multi_setopt(multi, CURLMOPT_TIMERDATA, ev); - - /* socket callback */ - curl_multi_setopt(multi, CURLMOPT_SOCKETFUNCTION, events_socket); - curl_multi_setopt(multi, CURLMOPT_SOCKETDATA, ev); -} - - -/* wait_or_timeout() - * - * waits for activity on any of the given sockets, or the timeout to trigger. - */ - -static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev) -{ - bool done = FALSE; - CURLMcode mcode; - CURLcode result = CURLE_OK; - - while(!done) { - CURLMsg *msg; - struct socketmonitor *m; - struct pollfd *f; - struct pollfd fds[4]; - int numfds=0; - int pollrc; - int i; - struct timeval before; - struct timeval after; - - /* populate the fds[] array */ - for(m = ev->list, f=&fds[0]; m; m = m->next) { - f->fd = m->socket.fd; - f->events = m->socket.events; - f->revents = 0; - /* fprintf(stderr, "poll() %d check socket %d\n", numfds, f->fd); */ - f++; - numfds++; - } - - /* get the time stamp to use to figure out how long poll takes */ - before = curlx_tvnow(); - - /* wait for activity or timeout */ - pollrc = Curl_poll(fds, numfds, (int)ev->ms); - - after = curlx_tvnow(); - - ev->msbump = FALSE; /* reset here */ - - if(0 == pollrc) { - /* timeout! */ - ev->ms = 0; - /* fprintf(stderr, "call curl_multi_socket_action(TIMEOUT)\n"); */ - mcode = curl_multi_socket_action(multi, CURL_SOCKET_TIMEOUT, 0, - &ev->running_handles); - } - else if(pollrc > 0) { - /* loop over the monitored sockets to see which ones had activity */ - for(i = 0; i< numfds; i++) { - if(fds[i].revents) { - /* socket activity, tell libcurl */ - int act = poll2cselect(fds[i].revents); /* convert */ - infof(multi->easyp, "call curl_multi_socket_action(socket %d)\n", - fds[i].fd); - mcode = curl_multi_socket_action(multi, fds[i].fd, act, - &ev->running_handles); - } - } - - if(!ev->msbump) - /* If nothing updated the timeout, we decrease it by the spent time. - * If it was updated, it has the new timeout time stored already. - */ - ev->ms += curlx_tvdiff(after, before); - - } - else - return CURLE_RECV_ERROR; - - if(mcode) - return CURLE_URL_MALFORMAT; /* TODO: return a proper error! */ - - /* we don't really care about the "msgs_in_queue" value returned in the - second argument */ - msg = curl_multi_info_read(multi, &pollrc); - if(msg) { - result = msg->data.result; - done = TRUE; - } - } - - return result; -} - - -/* easy_events() - * - * Runs a transfer in a blocking manner using the events-based API - */ -static CURLcode easy_events(CURLM *multi) -{ - struct events evs= {2, FALSE, 0, NULL, 0}; - - /* if running event-based, do some further multi inits */ - events_setup(multi, &evs); - - return wait_or_timeout(multi, &evs); -} -#else /* CURLDEBUG */ -/* when not built with debug, this function doesn't exist */ -#define easy_events(x) CURLE_NOT_BUILT_IN -#endif - -static CURLcode easy_transfer(CURLM *multi) -{ - bool done = FALSE; - CURLMcode mcode = CURLM_OK; - CURLcode result = CURLE_OK; - struct timeval before; - int without_fds = 0; /* count number of consecutive returns from - curl_multi_wait() without any filedescriptors */ - - while(!done && !mcode) { - int still_running = 0; - int rc; - - before = curlx_tvnow(); - mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc); - - if(!mcode) { - if(!rc) { - struct timeval after = curlx_tvnow(); - - /* If it returns without any filedescriptor instantly, we need to - avoid busy-looping during periods where it has nothing particular - to wait for */ - if(curlx_tvdiff(after, before) <= 10) { - without_fds++; - if(without_fds > 2) { - int sleep_ms = without_fds < 10 ? (1 << (without_fds - 1)) : 1000; - Curl_wait_ms(sleep_ms); - } - } - else - /* it wasn't "instant", restart counter */ - without_fds = 0; - } - else - /* got file descriptor, restart counter */ - without_fds = 0; - - mcode = curl_multi_perform(multi, &still_running); - } - - /* only read 'still_running' if curl_multi_perform() return OK */ - if(!mcode && !still_running) { - CURLMsg *msg = curl_multi_info_read(multi, &rc); - if(msg) { - result = msg->data.result; - done = TRUE; - } - } - } - - /* Make sure to return some kind of error if there was a multi problem */ - if(mcode) { - result = (mcode == CURLM_OUT_OF_MEMORY) ? CURLE_OUT_OF_MEMORY : - /* The other multi errors should never happen, so return - something suitably generic */ - CURLE_BAD_FUNCTION_ARGUMENT; - } - - return result; -} - - -/* - * easy_perform() is the external interface that performs a blocking - * transfer as previously setup. - * - * CONCEPT: This function creates a multi handle, adds the easy handle to it, - * runs curl_multi_perform() until the transfer is done, then detaches the - * easy handle, destroys the multi handle and returns the easy handle's return - * code. - * - * REALITY: it can't just create and destroy the multi handle that easily. It - * needs to keep it around since if this easy handle is used again by this - * function, the same multi handle must be re-used so that the same pools and - * caches can be used. - * - * DEBUG: if 'events' is set TRUE, this function will use a replacement engine - * instead of curl_multi_perform() and use curl_multi_socket_action(). - */ -static CURLcode easy_perform(struct SessionHandle *data, bool events) -{ - CURLM *multi; - CURLMcode mcode; - CURLcode result = CURLE_OK; - SIGPIPE_VARIABLE(pipe_st); - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - if(data->multi) { - failf(data, "easy handle already used in multi handle"); - return CURLE_FAILED_INIT; - } - - if(data->multi_easy) - multi = data->multi_easy; - else { - /* this multi handle will only ever have a single easy handled attached - to it, so make it use minimal hashes */ - multi = Curl_multi_handle(1, 3); - if(!multi) - return CURLE_OUT_OF_MEMORY; - data->multi_easy = multi; - } - - /* Copy the MAXCONNECTS option to the multi handle */ - curl_multi_setopt(multi, CURLMOPT_MAXCONNECTS, data->set.maxconnects); - - mcode = curl_multi_add_handle(multi, data); - if(mcode) { - curl_multi_cleanup(multi); - if(mcode == CURLM_OUT_OF_MEMORY) - return CURLE_OUT_OF_MEMORY; - else - return CURLE_FAILED_INIT; - } - - sigpipe_ignore(data, &pipe_st); - - /* assign this after curl_multi_add_handle() since that function checks for - it and rejects this handle otherwise */ - data->multi = multi; - - /* run the transfer */ - result = events ? easy_events(multi) : easy_transfer(multi); - - /* ignoring the return code isn't nice, but atm we can't really handle - a failure here, room for future improvement! */ - (void)curl_multi_remove_handle(multi, data); - - sigpipe_restore(&pipe_st); - - /* The multi handle is kept alive, owned by the easy handle */ - return result; -} - - -/* - * curl_easy_perform() is the external interface that performs a blocking - * transfer as previously setup. - */ -CURLcode curl_easy_perform(CURL *easy) -{ - return easy_perform(easy, FALSE); -} - -#ifdef CURLDEBUG -/* - * curl_easy_perform_ev() is the external interface that performs a blocking - * transfer using the event-based API internally. - */ -CURLcode curl_easy_perform_ev(CURL *easy) -{ - return easy_perform(easy, TRUE); -} - -#endif - -/* - * curl_easy_cleanup() is the external interface to cleaning/freeing the given - * easy handle. - */ -void curl_easy_cleanup(CURL *curl) -{ - struct SessionHandle *data = (struct SessionHandle *)curl; - SIGPIPE_VARIABLE(pipe_st); - - if(!data) - return; - - sigpipe_ignore(data, &pipe_st); - Curl_close(data); - sigpipe_restore(&pipe_st); -} - -/* - * curl_easy_getinfo() is an external interface that allows an app to retrieve - * information from a performed transfer and similar. - */ -#undef curl_easy_getinfo -CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...) -{ - va_list arg; - void *paramp; - CURLcode result; - struct SessionHandle *data = (struct SessionHandle *)curl; - - va_start(arg, info); - paramp = va_arg(arg, void *); - - result = Curl_getinfo(data, info, paramp); - - va_end(arg); - return result; -} - -/* - * curl_easy_duphandle() is an external interface to allow duplication of a - * given input easy handle. The returned handle will be a new working handle - * with all options set exactly as the input source handle. - */ -CURL *curl_easy_duphandle(CURL *incurl) -{ - struct SessionHandle *data=(struct SessionHandle *)incurl; - - struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle)); - if(NULL == outcurl) - goto fail; - - /* - * We setup a few buffers we need. We should probably make them - * get setup on-demand in the code, as that would probably decrease - * the likeliness of us forgetting to init a buffer here in the future. - */ - outcurl->state.headerbuff = malloc(HEADERSIZE); - if(!outcurl->state.headerbuff) - goto fail; - outcurl->state.headersize = HEADERSIZE; - - /* copy all userdefined values */ - if(Curl_dupset(outcurl, data)) - goto fail; - - /* the connection cache is setup on demand */ - outcurl->state.conn_cache = NULL; - - outcurl->state.lastconnect = NULL; - - outcurl->progress.flags = data->progress.flags; - outcurl->progress.callback = data->progress.callback; - - if(data->cookies) { - /* If cookies are enabled in the parent handle, we enable them - in the clone as well! */ - outcurl->cookies = Curl_cookie_init(data, - data->cookies->filename, - outcurl->cookies, - data->set.cookiesession); - if(!outcurl->cookies) - goto fail; - } - - /* duplicate all values in 'change' */ - if(data->change.cookielist) { - outcurl->change.cookielist = - Curl_slist_duplicate(data->change.cookielist); - if(!outcurl->change.cookielist) - goto fail; - } - - if(data->change.url) { - outcurl->change.url = strdup(data->change.url); - if(!outcurl->change.url) - goto fail; - outcurl->change.url_alloc = TRUE; - } - - if(data->change.referer) { - outcurl->change.referer = strdup(data->change.referer); - if(!outcurl->change.referer) - goto fail; - outcurl->change.referer_alloc = TRUE; - } - - /* Clone the resolver handle, if present, for the new handle */ - if(Curl_resolver_duphandle(&outcurl->state.resolver, - data->state.resolver)) - goto fail; - - Curl_convert_setup(outcurl); - - outcurl->magic = CURLEASY_MAGIC_NUMBER; - - /* we reach this point and thus we are OK */ - - return outcurl; - - fail: - - if(outcurl) { - curl_slist_free_all(outcurl->change.cookielist); - outcurl->change.cookielist = NULL; - Curl_safefree(outcurl->state.headerbuff); - Curl_safefree(outcurl->change.url); - Curl_safefree(outcurl->change.referer); - Curl_freeset(outcurl); - free(outcurl); - } - - return NULL; -} - -/* - * curl_easy_reset() is an external interface that allows an app to re- - * initialize a session handle to the default values. - */ -void curl_easy_reset(CURL *curl) -{ - struct SessionHandle *data = (struct SessionHandle *)curl; - - Curl_safefree(data->state.pathbuffer); - - data->state.path = NULL; - - Curl_free_request_state(data); - - /* zero out UserDefined data: */ - Curl_freeset(data); - memset(&data->set, 0, sizeof(struct UserDefined)); - (void)Curl_init_userdefined(&data->set); - - /* zero out Progress data: */ - memset(&data->progress, 0, sizeof(struct Progress)); - - data->progress.flags |= PGRS_HIDE; - data->state.current_speed = -1; /* init to negative == impossible */ -} - -/* - * curl_easy_pause() allows an application to pause or unpause a specific - * transfer and direction. This function sets the full new state for the - * current connection this easy handle operates on. - * - * NOTE: if you have the receiving paused and you call this function to remove - * the pausing, you may get your write callback called at this point. - * - * Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h - */ -CURLcode curl_easy_pause(CURL *curl, int action) -{ - struct SessionHandle *data = (struct SessionHandle *)curl; - struct SingleRequest *k = &data->req; - CURLcode result = CURLE_OK; - - /* first switch off both pause bits */ - int newstate = k->keepon &~ (KEEP_RECV_PAUSE| KEEP_SEND_PAUSE); - - /* set the new desired pause bits */ - newstate |= ((action & CURLPAUSE_RECV)?KEEP_RECV_PAUSE:0) | - ((action & CURLPAUSE_SEND)?KEEP_SEND_PAUSE:0); - - /* put it back in the keepon */ - k->keepon = newstate; - - if(!(newstate & KEEP_RECV_PAUSE) && data->state.tempwrite) { - /* we have a buffer for sending that we now seem to be able to deliver - since the receive pausing is lifted! */ - - /* get the pointer in local copy since the function may return PAUSE - again and then we'll get a new copy allocted and stored in - the tempwrite variables */ - char *tempwrite = data->state.tempwrite; - - data->state.tempwrite = NULL; - result = Curl_client_chop_write(data->easy_conn, data->state.tempwritetype, - tempwrite, data->state.tempwritesize); - free(tempwrite); - } - - /* if there's no error and we're not pausing both directions, we want - to have this handle checked soon */ - if(!result && - ((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) != - (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) ) - Curl_expire(data, 1); /* get this handle going again */ - - return result; -} - - -static CURLcode easy_connection(struct SessionHandle *data, - curl_socket_t *sfd, - struct connectdata **connp) -{ - if(data == NULL) - return CURLE_BAD_FUNCTION_ARGUMENT; - - /* only allow these to be called on handles with CURLOPT_CONNECT_ONLY */ - if(!data->set.connect_only) { - failf(data, "CONNECT_ONLY is required!"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - *sfd = Curl_getconnectinfo(data, connp); - - if(*sfd == CURL_SOCKET_BAD) { - failf(data, "Failed to get recent socket"); - return CURLE_UNSUPPORTED_PROTOCOL; - } - - return CURLE_OK; -} - -/* - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - * Returns CURLE_OK on success, error code on error. - */ -CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n) -{ - curl_socket_t sfd; - CURLcode result; - ssize_t n1; - struct connectdata *c; - struct SessionHandle *data = (struct SessionHandle *)curl; - - result = easy_connection(data, &sfd, &c); - if(result) - return result; - - *n = 0; - result = Curl_read(c, sfd, buffer, buflen, &n1); - - if(result) - return result; - - *n = (size_t)n1; - - return CURLE_OK; -} - -/* - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen, - size_t *n) -{ - curl_socket_t sfd; - CURLcode result; - ssize_t n1; - struct connectdata *c = NULL; - struct SessionHandle *data = (struct SessionHandle *)curl; - - result = easy_connection(data, &sfd, &c); - if(result) - return result; - - *n = 0; - result = Curl_write(c, sfd, buffer, buflen, &n1); - - if(n1 == -1) - return CURLE_SEND_ERROR; - - /* detect EAGAIN */ - if(!result && !n1) - return CURLE_AGAIN; - - *n = (size_t)n1; - - return result; -} diff --git a/Externals/curl/lib/easyif.h b/Externals/curl/lib/easyif.h deleted file mode 100644 index 65333494c1..0000000000 --- a/Externals/curl/lib/easyif.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_EASYIF_H -#define HEADER_CURL_EASYIF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Prototypes for library-wide functions provided by easy.c - */ -#ifdef CURLDEBUG -CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy); -#endif - -#endif /* HEADER_CURL_EASYIF_H */ - diff --git a/Externals/curl/lib/escape.c b/Externals/curl/lib/escape.c deleted file mode 100644 index 2c6a7f6554..0000000000 --- a/Externals/curl/lib/escape.c +++ /dev/null @@ -1,230 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* Escape and unescape URL encoding in strings. The functions return a new - * allocated string or NULL if an error occurred. */ - -#include "curl_setup.h" - -#include - -#include "urldata.h" -#include "warnless.h" -#include "non-ascii.h" -#include "escape.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Portable character check (remember EBCDIC). Do not use isalnum() because - its behavior is altered by the current locale. - See https://tools.ietf.org/html/rfc3986#section-2.3 -*/ -static bool Curl_isunreserved(unsigned char in) -{ - switch (in) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'a': case 'b': case 'c': case 'd': case 'e': - case 'f': case 'g': case 'h': case 'i': case 'j': - case 'k': case 'l': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'r': case 's': case 't': - case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': case 'L': case 'M': case 'N': case 'O': - case 'P': case 'Q': case 'R': case 'S': case 'T': - case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': - case '-': case '.': case '_': case '~': - return TRUE; - default: - break; - } - return FALSE; -} - -/* for ABI-compatibility with previous versions */ -char *curl_escape(const char *string, int inlength) -{ - return curl_easy_escape(NULL, string, inlength); -} - -/* for ABI-compatibility with previous versions */ -char *curl_unescape(const char *string, int length) -{ - return curl_easy_unescape(NULL, string, length, NULL); -} - -char *curl_easy_escape(CURL *handle, const char *string, int inlength) -{ - size_t alloc = (inlength?(size_t)inlength:strlen(string))+1; - char *ns; - char *testing_ptr = NULL; - unsigned char in; /* we need to treat the characters unsigned */ - size_t newlen = alloc; - size_t strindex=0; - size_t length; - CURLcode result; - - ns = malloc(alloc); - if(!ns) - return NULL; - - length = alloc-1; - while(length--) { - in = *string; - - if(Curl_isunreserved(in)) - /* just copy this */ - ns[strindex++]=in; - else { - /* encode it */ - newlen += 2; /* the size grows with two, since this'll become a %XX */ - if(newlen > alloc) { - alloc *= 2; - testing_ptr = realloc(ns, alloc); - if(!testing_ptr) { - free(ns); - return NULL; - } - else { - ns = testing_ptr; - } - } - - result = Curl_convert_to_network(handle, &in, 1); - if(result) { - /* Curl_convert_to_network calls failf if unsuccessful */ - free(ns); - return NULL; - } - - snprintf(&ns[strindex], 4, "%%%02X", in); - - strindex+=3; - } - string++; - } - ns[strindex]=0; /* terminate it */ - return ns; -} - -/* - * Curl_urldecode() URL decodes the given string. - * - * Optionally detects control characters (byte codes lower than 32) in the - * data and rejects such data. - * - * Returns a pointer to a malloced string in *ostring with length given in - * *olen. If length == 0, the length is assumed to be strlen(string). - * - */ -CURLcode Curl_urldecode(struct SessionHandle *data, - const char *string, size_t length, - char **ostring, size_t *olen, - bool reject_ctrl) -{ - size_t alloc = (length?length:strlen(string))+1; - char *ns = malloc(alloc); - unsigned char in; - size_t strindex=0; - unsigned long hex; - CURLcode result; - - if(!ns) - return CURLE_OUT_OF_MEMORY; - - while(--alloc > 0) { - in = *string; - if(('%' == in) && (alloc > 2) && - ISXDIGIT(string[1]) && ISXDIGIT(string[2])) { - /* this is two hexadecimal digits following a '%' */ - char hexstr[3]; - char *ptr; - hexstr[0] = string[1]; - hexstr[1] = string[2]; - hexstr[2] = 0; - - hex = strtoul(hexstr, &ptr, 16); - - in = curlx_ultouc(hex); /* this long is never bigger than 255 anyway */ - - result = Curl_convert_from_network(data, &in, 1); - if(result) { - /* Curl_convert_from_network calls failf if unsuccessful */ - free(ns); - return result; - } - - string+=2; - alloc-=2; - } - - if(reject_ctrl && (in < 0x20)) { - free(ns); - return CURLE_URL_MALFORMAT; - } - - ns[strindex++] = in; - string++; - } - ns[strindex]=0; /* terminate it */ - - if(olen) - /* store output size */ - *olen = strindex; - - /* store output string */ - *ostring = ns; - - return CURLE_OK; -} - -/* - * Unescapes the given URL escaped string of given length. Returns a - * pointer to a malloced string with length given in *olen. - * If length == 0, the length is assumed to be strlen(string). - * If olen == NULL, no output length is stored. - */ -char *curl_easy_unescape(CURL *handle, const char *string, int length, - int *olen) -{ - char *str = NULL; - size_t inputlen = length; - size_t outputlen; - CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen, - FALSE); - if(res) - return NULL; - if(olen) - *olen = curlx_uztosi(outputlen); - return str; -} - -/* For operating systems/environments that use different malloc/free - systems for the app and for this library, we provide a free that uses - the library's memory system */ -void curl_free(void *p) -{ - free(p); -} diff --git a/Externals/curl/lib/escape.h b/Externals/curl/lib/escape.h deleted file mode 100644 index a6e2967b3a..0000000000 --- a/Externals/curl/lib/escape.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_ESCAPE_H -#define HEADER_CURL_ESCAPE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* Escape and unescape URL encoding in strings. The functions return a new - * allocated string or NULL if an error occurred. */ - -CURLcode Curl_urldecode(struct SessionHandle *data, - const char *string, size_t length, - char **ostring, size_t *olen, - bool reject_crlf); - -#endif /* HEADER_CURL_ESCAPE_H */ - diff --git a/Externals/curl/lib/file.c b/Externals/curl/lib/file.c deleted file mode 100644 index 1eeb84d5a9..0000000000 --- a/Externals/curl/lib/file.c +++ /dev/null @@ -1,593 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FILE - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif - -#include "strtoofft.h" -#include "urldata.h" -#include -#include "progress.h" -#include "sendf.h" -#include "escape.h" -#include "file.h" -#include "speedcheck.h" -#include "getinfo.h" -#include "transfer.h" -#include "url.h" -#include "parsedate.h" /* for the week day and month names */ -#include "warnless.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#if defined(WIN32) || defined(MSDOS) || defined(__EMX__) || \ - defined(__SYMBIAN32__) -#define DOS_FILESYSTEM 1 -#endif - -#ifdef OPEN_NEEDS_ARG3 -# define open_readonly(p,f) open((p),(f),(0)) -#else -# define open_readonly(p,f) open((p),(f)) -#endif - -/* - * Forward declarations. - */ - -static CURLcode file_do(struct connectdata *, bool *done); -static CURLcode file_done(struct connectdata *conn, - CURLcode status, bool premature); -static CURLcode file_connect(struct connectdata *conn, bool *done); -static CURLcode file_disconnect(struct connectdata *conn, - bool dead_connection); -static CURLcode file_setup_connection(struct connectdata *conn); - -/* - * FILE scheme handler. - */ - -const struct Curl_handler Curl_handler_file = { - "FILE", /* scheme */ - file_setup_connection, /* setup_connection */ - file_do, /* do_it */ - file_done, /* done */ - ZERO_NULL, /* do_more */ - file_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - file_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - 0, /* defport */ - CURLPROTO_FILE, /* protocol */ - PROTOPT_NONETWORK | PROTOPT_NOURLQUERY /* flags */ -}; - - -static CURLcode file_setup_connection(struct connectdata *conn) -{ - /* allocate the FILE specific struct */ - conn->data->req.protop = calloc(1, sizeof(struct FILEPROTO)); - if(!conn->data->req.protop) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - - /* - Check if this is a range download, and if so, set the internal variables - properly. This code is copied from the FTP implementation and might as - well be factored out. - */ -static CURLcode file_range(struct connectdata *conn) -{ - curl_off_t from, to; - curl_off_t totalsize=-1; - char *ptr; - char *ptr2; - struct SessionHandle *data = conn->data; - - if(data->state.use_range && data->state.range) { - from=curlx_strtoofft(data->state.range, &ptr, 0); - while(*ptr && (ISSPACE(*ptr) || (*ptr=='-'))) - ptr++; - to=curlx_strtoofft(ptr, &ptr2, 0); - if(ptr == ptr2) { - /* we didn't get any digit */ - to=-1; - } - if((-1 == to) && (from>=0)) { - /* X - */ - data->state.resume_from = from; - DEBUGF(infof(data, "RANGE %" CURL_FORMAT_CURL_OFF_T " to end of file\n", - from)); - } - else if(from < 0) { - /* -Y */ - data->req.maxdownload = -from; - data->state.resume_from = from; - DEBUGF(infof(data, "RANGE the last %" CURL_FORMAT_CURL_OFF_T " bytes\n", - -from)); - } - else { - /* X-Y */ - totalsize = to-from; - data->req.maxdownload = totalsize+1; /* include last byte */ - data->state.resume_from = from; - DEBUGF(infof(data, "RANGE from %" CURL_FORMAT_CURL_OFF_T - " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", - from, data->req.maxdownload)); - } - DEBUGF(infof(data, "range-download from %" CURL_FORMAT_CURL_OFF_T - " to %" CURL_FORMAT_CURL_OFF_T ", totally %" - CURL_FORMAT_CURL_OFF_T " bytes\n", - from, to, data->req.maxdownload)); - } - else - data->req.maxdownload = -1; - return CURLE_OK; -} - -/* - * file_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. We emulate a - * connect-then-transfer protocol and "connect" to the file here - */ -static CURLcode file_connect(struct connectdata *conn, bool *done) -{ - struct SessionHandle *data = conn->data; - char *real_path; - struct FILEPROTO *file = data->req.protop; - int fd; -#ifdef DOS_FILESYSTEM - int i; - char *actual_path; -#endif - int real_path_len; - - real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len); - if(!real_path) - return CURLE_OUT_OF_MEMORY; - -#ifdef DOS_FILESYSTEM - /* If the first character is a slash, and there's - something that looks like a drive at the beginning of - the path, skip the slash. If we remove the initial - slash in all cases, paths without drive letters end up - relative to the current directory which isn't how - browsers work. - - Some browsers accept | instead of : as the drive letter - separator, so we do too. - - On other platforms, we need the slash to indicate an - absolute pathname. On Windows, absolute paths start - with a drive letter. - */ - actual_path = real_path; - if((actual_path[0] == '/') && - actual_path[1] && - (actual_path[2] == ':' || actual_path[2] == '|')) { - actual_path[2] = ':'; - actual_path++; - real_path_len--; - } - - /* change path separators from '/' to '\\' for DOS, Windows and OS/2 */ - for(i=0; i < real_path_len; ++i) - if(actual_path[i] == '/') - actual_path[i] = '\\'; - else if(!actual_path[i]) /* binary zero */ - return CURLE_URL_MALFORMAT; - - fd = open_readonly(actual_path, O_RDONLY|O_BINARY); - file->path = actual_path; -#else - if(memchr(real_path, 0, real_path_len)) - /* binary zeroes indicate foul play */ - return CURLE_URL_MALFORMAT; - - fd = open_readonly(real_path, O_RDONLY); - file->path = real_path; -#endif - file->freepath = real_path; /* free this when done */ - - file->fd = fd; - if(!data->set.upload && (fd == -1)) { - failf(data, "Couldn't open file %s", data->state.path); - file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE); - return CURLE_FILE_COULDNT_READ_FILE; - } - *done = TRUE; - - return CURLE_OK; -} - -static CURLcode file_done(struct connectdata *conn, - CURLcode status, bool premature) -{ - struct FILEPROTO *file = conn->data->req.protop; - (void)status; /* not used */ - (void)premature; /* not used */ - - if(file) { - Curl_safefree(file->freepath); - file->path = NULL; - if(file->fd != -1) - close(file->fd); - file->fd = -1; - } - - return CURLE_OK; -} - -static CURLcode file_disconnect(struct connectdata *conn, - bool dead_connection) -{ - struct FILEPROTO *file = conn->data->req.protop; - (void)dead_connection; /* not used */ - - if(file) { - Curl_safefree(file->freepath); - file->path = NULL; - if(file->fd != -1) - close(file->fd); - file->fd = -1; - } - - return CURLE_OK; -} - -#ifdef DOS_FILESYSTEM -#define DIRSEP '\\' -#else -#define DIRSEP '/' -#endif - -static CURLcode file_upload(struct connectdata *conn) -{ - struct FILEPROTO *file = conn->data->req.protop; - const char *dir = strchr(file->path, DIRSEP); - int fd; - int mode; - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - char *buf = data->state.buffer; - size_t nread; - size_t nwrite; - curl_off_t bytecount = 0; - struct timeval now = Curl_tvnow(); - struct_stat file_stat; - const char* buf2; - - /* - * Since FILE: doesn't do the full init, we need to provide some extra - * assignments here. - */ - conn->data->req.upload_fromhere = buf; - - if(!dir) - return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ - - if(!dir[1]) - return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */ - -#ifdef O_BINARY -#define MODE_DEFAULT O_WRONLY|O_CREAT|O_BINARY -#else -#define MODE_DEFAULT O_WRONLY|O_CREAT -#endif - - if(data->state.resume_from) - mode = MODE_DEFAULT|O_APPEND; - else - mode = MODE_DEFAULT|O_TRUNC; - - fd = open(file->path, mode, conn->data->set.new_file_perms); - if(fd < 0) { - failf(data, "Can't open %s for writing", file->path); - return CURLE_WRITE_ERROR; - } - - if(-1 != data->state.infilesize) - /* known size of data to "upload" */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* treat the negative resume offset value as the case of "-" */ - if(data->state.resume_from < 0) { - if(fstat(fd, &file_stat)) { - close(fd); - failf(data, "Can't get the size of %s", file->path); - return CURLE_WRITE_ERROR; - } - else - data->state.resume_from = (curl_off_t)file_stat.st_size; - } - - while(!result) { - int readcount; - result = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); - if(result) - break; - - if(readcount <= 0) /* fix questionable compare error. curlvms */ - break; - - nread = (size_t)readcount; - - /*skip bytes before resume point*/ - if(data->state.resume_from) { - if((curl_off_t)nread <= data->state.resume_from) { - data->state.resume_from -= nread; - nread = 0; - buf2 = buf; - } - else { - buf2 = buf + data->state.resume_from; - nread -= (size_t)data->state.resume_from; - data->state.resume_from = 0; - } - } - else - buf2 = buf; - - /* write the data to the target */ - nwrite = write(fd, buf2, nread); - if(nwrite != nread) { - result = CURLE_SEND_ERROR; - break; - } - - bytecount += nread; - - Curl_pgrsSetUploadCounter(data, bytecount); - - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - else - result = Curl_speedcheck(data, now); - } - if(!result && Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - - close(fd); - - return result; -} - -/* - * file_do() is the protocol-specific function for the do-phase, separated - * from the connect-phase above. Other protocols merely setup the transfer in - * the do-phase, to have it done in the main transfer loop but since some - * platforms we support don't allow select()ing etc on file handles (as - * opposed to sockets) we instead perform the whole do-operation in this - * function. - */ -static CURLcode file_do(struct connectdata *conn, bool *done) -{ - /* This implementation ignores the host name in conformance with - RFC 1738. Only local files (reachable via the standard file system) - are supported. This means that files on remotely mounted directories - (via NFS, Samba, NT sharing) can be accessed through a file:// URL - */ - CURLcode result = CURLE_OK; - struct_stat statbuf; /* struct_stat instead of struct stat just to allow the - Windows version to have a different struct without - having to redefine the simple word 'stat' */ - curl_off_t expected_size=0; - bool size_known; - bool fstated=FALSE; - ssize_t nread; - struct SessionHandle *data = conn->data; - char *buf = data->state.buffer; - curl_off_t bytecount = 0; - int fd; - struct timeval now = Curl_tvnow(); - struct FILEPROTO *file; - - *done = TRUE; /* unconditionally */ - - Curl_initinfo(data); - Curl_pgrsStartNow(data); - - if(data->set.upload) - return file_upload(conn); - - file = conn->data->req.protop; - - /* get the fd from the connection phase */ - fd = file->fd; - - /* VMS: This only works reliable for STREAMLF files */ - if(-1 != fstat(fd, &statbuf)) { - /* we could stat it, then read out the size */ - expected_size = statbuf.st_size; - /* and store the modification time */ - data->info.filetime = (long)statbuf.st_mtime; - fstated = TRUE; - } - - if(fstated && !data->state.range && data->set.timecondition) { - if(!Curl_meets_timecondition(data, (time_t)data->info.filetime)) { - *done = TRUE; - return CURLE_OK; - } - } - - /* If we have selected NOBODY and HEADER, it means that we only want file - information. Which for FILE can't be much more than the file size and - date. */ - if(data->set.opt_no_body && data->set.include_header && fstated) { - time_t filetime; - struct tm buffer; - const struct tm *tm = &buffer; - snprintf(buf, sizeof(data->state.buffer), - "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", expected_size); - result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); - if(result) - return result; - - result = Curl_client_write(conn, CLIENTWRITE_BOTH, - (char *)"Accept-ranges: bytes\r\n", 0); - if(result) - return result; - - filetime = (time_t)statbuf.st_mtime; - result = Curl_gmtime(filetime, &buffer); - if(result) - return result; - - /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - snprintf(buf, BUFSIZE-1, - "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", - Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); - if(!result) - /* set the file size to make it available post transfer */ - Curl_pgrsSetDownloadSize(data, expected_size); - return result; - } - - /* Check whether file range has been specified */ - file_range(conn); - - /* Adjust the start offset in case we want to get the N last bytes - * of the stream iff the filesize could be determined */ - if(data->state.resume_from < 0) { - if(!fstated) { - failf(data, "Can't get the size of file."); - return CURLE_READ_ERROR; - } - else - data->state.resume_from += (curl_off_t)statbuf.st_size; - } - - if(data->state.resume_from <= expected_size) - expected_size -= data->state.resume_from; - else { - failf(data, "failed to resume file:// transfer"); - return CURLE_BAD_DOWNLOAD_RESUME; - } - - /* A high water mark has been specified so we obey... */ - if(data->req.maxdownload > 0) - expected_size = data->req.maxdownload; - - if(!fstated || (expected_size == 0)) - size_known = FALSE; - else - size_known = TRUE; - - /* The following is a shortcut implementation of file reading - this is both more efficient than the former call to download() and - it avoids problems with select() and recv() on file descriptors - in Winsock */ - if(fstated) - Curl_pgrsSetDownloadSize(data, expected_size); - - if(data->state.resume_from) { - if(data->state.resume_from != - lseek(fd, data->state.resume_from, SEEK_SET)) - return CURLE_BAD_DOWNLOAD_RESUME; - } - - Curl_pgrsTime(data, TIMER_STARTTRANSFER); - - while(!result) { - /* Don't fill a whole buffer if we want less than all data */ - size_t bytestoread; - - if(size_known) { - bytestoread = - (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ? - curlx_sotouz(expected_size) : BUFSIZE - 1; - } - else - bytestoread = BUFSIZE-1; - - nread = read(fd, buf, bytestoread); - - if(nread > 0) - buf[nread] = 0; - - if(nread <= 0 || (size_known && (expected_size == 0))) - break; - - bytecount += nread; - if(size_known) - expected_size -= nread; - - result = Curl_client_write(conn, CLIENTWRITE_BODY, buf, nread); - if(result) - return result; - - Curl_pgrsSetDownloadCounter(data, bytecount); - - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - else - result = Curl_speedcheck(data, now); - } - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - - return result; -} - -#endif diff --git a/Externals/curl/lib/file.h b/Externals/curl/lib/file.h deleted file mode 100644 index c12ae0e09e..0000000000 --- a/Externals/curl/lib/file.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef HEADER_CURL_FILE_H -#define HEADER_CURL_FILE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - - -/**************************************************************************** - * FILE unique setup - ***************************************************************************/ -struct FILEPROTO { - char *path; /* the path we operate on */ - char *freepath; /* pointer to the allocated block we must free, this might - differ from the 'path' pointer */ - int fd; /* open file descriptor to read from! */ -}; - -#ifndef CURL_DISABLE_FILE -extern const struct Curl_handler Curl_handler_file; -#endif - -#endif /* HEADER_CURL_FILE_H */ - diff --git a/Externals/curl/lib/fileinfo.c b/Externals/curl/lib/fileinfo.c deleted file mode 100644 index 144c65b1d8..0000000000 --- a/Externals/curl/lib/fileinfo.c +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "strdup.h" -#include "fileinfo.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -struct curl_fileinfo *Curl_fileinfo_alloc(void) -{ - struct curl_fileinfo *tmp = malloc(sizeof(struct curl_fileinfo)); - if(!tmp) - return NULL; - memset(tmp, 0, sizeof(struct curl_fileinfo)); - return tmp; -} - -void Curl_fileinfo_dtor(void *user, void *element) -{ - struct curl_fileinfo *finfo = element; - (void) user; - if(!finfo) - return; - - Curl_safefree(finfo->b_data); - - free(finfo); -} diff --git a/Externals/curl/lib/fileinfo.h b/Externals/curl/lib/fileinfo.h deleted file mode 100644 index 5324f1a404..0000000000 --- a/Externals/curl/lib/fileinfo.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_FILEINFO_H -#define HEADER_CURL_FILEINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -struct curl_fileinfo *Curl_fileinfo_alloc(void); - -void Curl_fileinfo_dtor(void *, void *); - -struct curl_fileinfo *Curl_fileinfo_dup(const struct curl_fileinfo *src); - -#endif /* HEADER_CURL_FILEINFO_H */ diff --git a/Externals/curl/lib/firefox-db2pem.sh b/Externals/curl/lib/firefox-db2pem.sh deleted file mode 100644 index 7d691ff6b9..0000000000 --- a/Externals/curl/lib/firefox-db2pem.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -# *************************************************************************** -# * _ _ ____ _ -# * Project ___| | | | _ \| | -# * / __| | | | |_) | | -# * | (__| |_| | _ <| |___ -# * \___|\___/|_| \_\_____| -# * -# * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. -# * -# * This software is licensed as described in the file COPYING, which -# * you should have received as part of this distribution. The terms -# * are also available at https://curl.haxx.se/docs/copyright.html. -# * -# * You may opt to use, copy, modify, merge, publish, distribute and/or sell -# * copies of the Software, and permit persons to whom the Software is -# * furnished to do so, under the terms of the COPYING file. -# * -# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# * KIND, either express or implied. -# * -# *************************************************************************** -# This shell script creates a fresh ca-bundle.crt file for use with libcurl. -# It extracts all ca certs it finds in the local Firefox database and converts -# them all into PEM format. -# -db=`ls -1d $HOME/.mozilla/firefox/*default*` -out=$1 - -if test -z "$out"; then - out="ca-bundle.crt" # use a sensible default -fi - -currentdate=`date` - -cat >$out <> $out - diff --git a/Externals/curl/lib/formdata.c b/Externals/curl/lib/formdata.c deleted file mode 100644 index a71f099c8a..0000000000 --- a/Externals/curl/lib/formdata.c +++ /dev/null @@ -1,1586 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#ifndef CURL_DISABLE_HTTP - -#if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) -#include -#endif - -#include "urldata.h" /* for struct SessionHandle */ -#include "formdata.h" -#include "vtls/vtls.h" -#include "strequal.h" -#include "sendf.h" -#include "strdup.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifndef HAVE_BASENAME -static char *Curl_basename(char *path); -#define basename(x) Curl_basename((x)) -#endif - -static size_t readfromfile(struct Form *form, char *buffer, size_t size); -static char *formboundary(struct SessionHandle *data); - -/* What kind of Content-Type to use on un-specified files with unrecognized - extensions. */ -#define HTTPPOST_CONTENTTYPE_DEFAULT "application/octet-stream" - -#define FORM_FILE_SEPARATOR ',' -#define FORM_TYPE_SEPARATOR ';' - -#define HTTPPOST_PTRNAME CURL_HTTPPOST_PTRNAME -#define HTTPPOST_FILENAME CURL_HTTPPOST_FILENAME -#define HTTPPOST_PTRCONTENTS CURL_HTTPPOST_PTRCONTENTS -#define HTTPPOST_READFILE CURL_HTTPPOST_READFILE -#define HTTPPOST_PTRBUFFER CURL_HTTPPOST_PTRBUFFER -#define HTTPPOST_CALLBACK CURL_HTTPPOST_CALLBACK -#define HTTPPOST_BUFFER CURL_HTTPPOST_BUFFER - -/*************************************************************************** - * - * AddHttpPost() - * - * Adds a HttpPost structure to the list, if parent_post is given becomes - * a subpost of parent_post instead of a direct list element. - * - * Returns newly allocated HttpPost on success and NULL if malloc failed. - * - ***************************************************************************/ -static struct curl_httppost * -AddHttpPost(char *name, size_t namelength, - char *value, curl_off_t contentslength, - char *buffer, size_t bufferlength, - char *contenttype, - long flags, - struct curl_slist* contentHeader, - char *showfilename, char *userp, - struct curl_httppost *parent_post, - struct curl_httppost **httppost, - struct curl_httppost **last_post) -{ - struct curl_httppost *post; - post = calloc(1, sizeof(struct curl_httppost)); - if(post) { - post->name = name; - post->namelength = (long)(name?(namelength?namelength:strlen(name)):0); - post->contents = value; - post->contentlen = contentslength; - post->buffer = buffer; - post->bufferlength = (long)bufferlength; - post->contenttype = contenttype; - post->contentheader = contentHeader; - post->showfilename = showfilename; - post->userp = userp, - post->flags = flags | CURL_HTTPPOST_LARGE; - } - else - return NULL; - - if(parent_post) { - /* now, point our 'more' to the original 'more' */ - post->more = parent_post->more; - - /* then move the original 'more' to point to ourselves */ - parent_post->more = post; - } - else { - /* make the previous point to this */ - if(*last_post) - (*last_post)->next = post; - else - (*httppost) = post; - - (*last_post) = post; - } - return post; -} - -/*************************************************************************** - * - * AddFormInfo() - * - * Adds a FormInfo structure to the list presented by parent_form_info. - * - * Returns newly allocated FormInfo on success and NULL if malloc failed/ - * parent_form_info is NULL. - * - ***************************************************************************/ -static FormInfo * AddFormInfo(char *value, - char *contenttype, - FormInfo *parent_form_info) -{ - FormInfo *form_info; - form_info = calloc(1, sizeof(struct FormInfo)); - if(form_info) { - if(value) - form_info->value = value; - if(contenttype) - form_info->contenttype = contenttype; - form_info->flags = HTTPPOST_FILENAME; - } - else - return NULL; - - if(parent_form_info) { - /* now, point our 'more' to the original 'more' */ - form_info->more = parent_form_info->more; - - /* then move the original 'more' to point to ourselves */ - parent_form_info->more = form_info; - } - - return form_info; -} - -/*************************************************************************** - * - * ContentTypeForFilename() - * - * Provides content type for filename if one of the known types (else - * (either the prevtype or the default is returned). - * - * Returns some valid contenttype for filename. - * - ***************************************************************************/ -static const char *ContentTypeForFilename(const char *filename, - const char *prevtype) -{ - const char *contenttype = NULL; - unsigned int i; - /* - * No type was specified, we scan through a few well-known - * extensions and pick the first we match! - */ - struct ContentType { - const char *extension; - const char *type; - }; - static const struct ContentType ctts[]={ - {".gif", "image/gif"}, - {".jpg", "image/jpeg"}, - {".jpeg", "image/jpeg"}, - {".txt", "text/plain"}, - {".html", "text/html"}, - {".xml", "application/xml"} - }; - - if(prevtype) - /* default to the previously set/used! */ - contenttype = prevtype; - else - contenttype = HTTPPOST_CONTENTTYPE_DEFAULT; - - if(filename) { /* in case a NULL was passed in */ - for(i=0; i= strlen(ctts[i].extension)) { - if(strequal(filename + - strlen(filename) - strlen(ctts[i].extension), - ctts[i].extension)) { - contenttype = ctts[i].type; - break; - } - } - } - } - /* we have a contenttype by now */ - return contenttype; -} - -/*************************************************************************** - * - * FormAdd() - * - * Stores a formpost parameter and builds the appropriate linked list. - * - * Has two principal functionalities: using files and byte arrays as - * post parts. Byte arrays are either copied or just the pointer is stored - * (as the user requests) while for files only the filename and not the - * content is stored. - * - * While you may have only one byte array for each name, multiple filenames - * are allowed (and because of this feature CURLFORM_END is needed after - * using CURLFORM_FILE). - * - * Examples: - * - * Simple name/value pair with copied contents: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_COPYCONTENTS, "value", CURLFORM_END); - * - * name/value pair where only the content pointer is remembered: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_PTRCONTENTS, ptr, CURLFORM_CONTENTSLENGTH, 10, CURLFORM_END); - * (if CURLFORM_CONTENTSLENGTH is missing strlen () is used) - * - * storing a filename (CONTENTTYPE is optional!): - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_CONTENTTYPE, "plain/text", - * CURLFORM_END); - * - * storing multiple filenames: - * curl_formadd (&post, &last, CURLFORM_COPYNAME, "name", - * CURLFORM_FILE, "filename1", CURLFORM_FILE, "filename2", CURLFORM_END); - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a HttpPost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ - -static -CURLFORMcode FormAdd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - va_list params) -{ - FormInfo *first_form, *current_form, *form = NULL; - CURLFORMcode return_value = CURL_FORMADD_OK; - const char *prevtype = NULL; - struct curl_httppost *post = NULL; - CURLformoption option; - struct curl_forms *forms = NULL; - char *array_value=NULL; /* value read from an array */ - - /* This is a state variable, that if TRUE means that we're parsing an - array that we got passed to us. If FALSE we're parsing the input - va_list arguments. */ - bool array_state = FALSE; - - /* - * We need to allocate the first struct to fill in. - */ - first_form = calloc(1, sizeof(struct FormInfo)); - if(!first_form) - return CURL_FORMADD_MEMORY; - - current_form = first_form; - - /* - * Loop through all the options set. Break if we have an error to report. - */ - while(return_value == CURL_FORMADD_OK) { - - /* first see if we have more parts of the array param */ - if(array_state && forms) { - /* get the upcoming option from the given array */ - option = forms->option; - array_value = (char *)forms->value; - - forms++; /* advance this to next entry */ - if(CURLFORM_END == option) { - /* end of array state */ - array_state = FALSE; - continue; - } - } - else { - /* This is not array-state, get next option */ - option = va_arg(params, CURLformoption); - if(CURLFORM_END == option) - break; - } - - switch (option) { - case CURLFORM_ARRAY: - if(array_state) - /* we don't support an array from within an array */ - return_value = CURL_FORMADD_ILLEGAL_ARRAY; - else { - forms = va_arg(params, struct curl_forms *); - if(forms) - array_state = TRUE; - else - return_value = CURL_FORMADD_NULL; - } - break; - - /* - * Set the Name property. - */ - case CURLFORM_PTRNAME: -#ifdef CURL_DOES_CONVERSIONS - /* Treat CURLFORM_PTR like CURLFORM_COPYNAME so that libcurl will copy - * the data in all cases so that we'll have safe memory for the eventual - * conversion. - */ -#else - current_form->flags |= HTTPPOST_PTRNAME; /* fall through */ -#endif - case CURLFORM_COPYNAME: - if(current_form->name) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - char *name = array_state? - array_value:va_arg(params, char *); - if(name) - current_form->name = name; /* store for the moment */ - else - return_value = CURL_FORMADD_NULL; - } - break; - case CURLFORM_NAMELENGTH: - if(current_form->namelength) - return_value = CURL_FORMADD_OPTION_TWICE; - else - current_form->namelength = - array_state?(size_t)array_value:(size_t)va_arg(params, long); - break; - - /* - * Set the contents property. - */ - case CURLFORM_PTRCONTENTS: - current_form->flags |= HTTPPOST_PTRCONTENTS; /* fall through */ - case CURLFORM_COPYCONTENTS: - if(current_form->value) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - char *value = - array_state?array_value:va_arg(params, char *); - if(value) - current_form->value = value; /* store for the moment */ - else - return_value = CURL_FORMADD_NULL; - } - break; - case CURLFORM_CONTENTSLENGTH: - current_form->contentslength = - array_state?(size_t)array_value:(size_t)va_arg(params, long); - break; - - case CURLFORM_CONTENTLEN: - current_form->flags |= CURL_HTTPPOST_LARGE; - current_form->contentslength = - array_state?(curl_off_t)(size_t)array_value:va_arg(params, curl_off_t); - break; - - /* Get contents from a given file name */ - case CURLFORM_FILECONTENT: - if(current_form->flags & (HTTPPOST_PTRCONTENTS|HTTPPOST_READFILE)) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - const char *filename = array_state? - array_value:va_arg(params, char *); - if(filename) { - current_form->value = strdup(filename); - if(!current_form->value) - return_value = CURL_FORMADD_MEMORY; - else { - current_form->flags |= HTTPPOST_READFILE; - current_form->value_alloc = TRUE; - } - } - else - return_value = CURL_FORMADD_NULL; - } - break; - - /* We upload a file */ - case CURLFORM_FILE: - { - const char *filename = array_state?array_value: - va_arg(params, char *); - - if(current_form->value) { - if(current_form->flags & HTTPPOST_FILENAME) { - if(filename) { - char *fname = strdup(filename); - if(!fname) - return_value = CURL_FORMADD_MEMORY; - else { - form = AddFormInfo(fname, NULL, current_form); - if(!form) { - free(fname); - return_value = CURL_FORMADD_MEMORY; - } - else { - form->value_alloc = TRUE; - current_form = form; - form = NULL; - } - } - } - else - return_value = CURL_FORMADD_NULL; - } - else - return_value = CURL_FORMADD_OPTION_TWICE; - } - else { - if(filename) { - current_form->value = strdup(filename); - if(!current_form->value) - return_value = CURL_FORMADD_MEMORY; - else { - current_form->flags |= HTTPPOST_FILENAME; - current_form->value_alloc = TRUE; - } - } - else - return_value = CURL_FORMADD_NULL; - } - break; - } - - case CURLFORM_BUFFERPTR: - current_form->flags |= HTTPPOST_PTRBUFFER|HTTPPOST_BUFFER; - if(current_form->buffer) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - char *buffer = - array_state?array_value:va_arg(params, char *); - if(buffer) { - current_form->buffer = buffer; /* store for the moment */ - current_form->value = buffer; /* make it non-NULL to be accepted - as fine */ - } - else - return_value = CURL_FORMADD_NULL; - } - break; - - case CURLFORM_BUFFERLENGTH: - if(current_form->bufferlength) - return_value = CURL_FORMADD_OPTION_TWICE; - else - current_form->bufferlength = - array_state?(size_t)array_value:(size_t)va_arg(params, long); - break; - - case CURLFORM_STREAM: - current_form->flags |= HTTPPOST_CALLBACK; - if(current_form->userp) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - char *userp = - array_state?array_value:va_arg(params, char *); - if(userp) { - current_form->userp = userp; - current_form->value = userp; /* this isn't strictly true but we - derive a value from this later on - and we need this non-NULL to be - accepted as a fine form part */ - } - else - return_value = CURL_FORMADD_NULL; - } - break; - - case CURLFORM_CONTENTTYPE: - { - const char *contenttype = - array_state?array_value:va_arg(params, char *); - if(current_form->contenttype) { - if(current_form->flags & HTTPPOST_FILENAME) { - if(contenttype) { - char *type = strdup(contenttype); - if(!type) - return_value = CURL_FORMADD_MEMORY; - else { - form = AddFormInfo(NULL, type, current_form); - if(!form) { - free(type); - return_value = CURL_FORMADD_MEMORY; - } - else { - form->contenttype_alloc = TRUE; - current_form = form; - form = NULL; - } - } - } - else - return_value = CURL_FORMADD_NULL; - } - else - return_value = CURL_FORMADD_OPTION_TWICE; - } - else { - if(contenttype) { - current_form->contenttype = strdup(contenttype); - if(!current_form->contenttype) - return_value = CURL_FORMADD_MEMORY; - else - current_form->contenttype_alloc = TRUE; - } - else - return_value = CURL_FORMADD_NULL; - } - break; - } - case CURLFORM_CONTENTHEADER: - { - /* this "cast increases required alignment of target type" but - we consider it OK anyway */ - struct curl_slist* list = array_state? - (struct curl_slist*)(void*)array_value: - va_arg(params, struct curl_slist*); - - if(current_form->contentheader) - return_value = CURL_FORMADD_OPTION_TWICE; - else - current_form->contentheader = list; - - break; - } - case CURLFORM_FILENAME: - case CURLFORM_BUFFER: - { - const char *filename = array_state?array_value: - va_arg(params, char *); - if(current_form->showfilename) - return_value = CURL_FORMADD_OPTION_TWICE; - else { - current_form->showfilename = strdup(filename); - if(!current_form->showfilename) - return_value = CURL_FORMADD_MEMORY; - else - current_form->showfilename_alloc = TRUE; - } - break; - } - default: - return_value = CURL_FORMADD_UNKNOWN_OPTION; - break; - } - } - - if(CURL_FORMADD_OK != return_value) { - /* On error, free allocated fields for all nodes of the FormInfo linked - list without deallocating nodes. List nodes are deallocated later on */ - FormInfo *ptr; - for(ptr = first_form; ptr != NULL; ptr = ptr->more) { - if(ptr->name_alloc) { - Curl_safefree(ptr->name); - ptr->name_alloc = FALSE; - } - if(ptr->value_alloc) { - Curl_safefree(ptr->value); - ptr->value_alloc = FALSE; - } - if(ptr->contenttype_alloc) { - Curl_safefree(ptr->contenttype); - ptr->contenttype_alloc = FALSE; - } - if(ptr->showfilename_alloc) { - Curl_safefree(ptr->showfilename); - ptr->showfilename_alloc = FALSE; - } - } - } - - if(CURL_FORMADD_OK == return_value) { - /* go through the list, check for completeness and if everything is - * alright add the HttpPost item otherwise set return_value accordingly */ - - post = NULL; - for(form = first_form; - form != NULL; - form = form->more) { - if(((!form->name || !form->value) && !post) || - ( (form->contentslength) && - (form->flags & HTTPPOST_FILENAME) ) || - ( (form->flags & HTTPPOST_FILENAME) && - (form->flags & HTTPPOST_PTRCONTENTS) ) || - - ( (!form->buffer) && - (form->flags & HTTPPOST_BUFFER) && - (form->flags & HTTPPOST_PTRBUFFER) ) || - - ( (form->flags & HTTPPOST_READFILE) && - (form->flags & HTTPPOST_PTRCONTENTS) ) - ) { - return_value = CURL_FORMADD_INCOMPLETE; - break; - } - else { - if(((form->flags & HTTPPOST_FILENAME) || - (form->flags & HTTPPOST_BUFFER)) && - !form->contenttype) { - char *f = form->flags & HTTPPOST_BUFFER? - form->showfilename : form->value; - - /* our contenttype is missing */ - form->contenttype = strdup(ContentTypeForFilename(f, prevtype)); - if(!form->contenttype) { - return_value = CURL_FORMADD_MEMORY; - break; - } - form->contenttype_alloc = TRUE; - } - if(!(form->flags & HTTPPOST_PTRNAME) && - (form == first_form) ) { - /* Note that there's small risk that form->name is NULL here if the - app passed in a bad combo, so we better check for that first. */ - if(form->name) { - /* copy name (without strdup; possibly contains null characters) */ - form->name = Curl_memdup(form->name, form->namelength? - form->namelength: - strlen(form->name)+1); - } - if(!form->name) { - return_value = CURL_FORMADD_MEMORY; - break; - } - form->name_alloc = TRUE; - } - if(!(form->flags & (HTTPPOST_FILENAME | HTTPPOST_READFILE | - HTTPPOST_PTRCONTENTS | HTTPPOST_PTRBUFFER | - HTTPPOST_CALLBACK)) && form->value) { - /* copy value (without strdup; possibly contains null characters) */ - size_t clen = (size_t) form->contentslength; - if(!clen) - clen = strlen(form->value)+1; - - form->value = Curl_memdup(form->value, clen); - - if(!form->value) { - return_value = CURL_FORMADD_MEMORY; - break; - } - form->value_alloc = TRUE; - } - post = AddHttpPost(form->name, form->namelength, - form->value, form->contentslength, - form->buffer, form->bufferlength, - form->contenttype, form->flags, - form->contentheader, form->showfilename, - form->userp, - post, httppost, - last_post); - - if(!post) { - return_value = CURL_FORMADD_MEMORY; - break; - } - - if(form->contenttype) - prevtype = form->contenttype; - } - } - if(CURL_FORMADD_OK != return_value) { - /* On error, free allocated fields for nodes of the FormInfo linked - list which are not already owned by the httppost linked list - without deallocating nodes. List nodes are deallocated later on */ - FormInfo *ptr; - for(ptr = form; ptr != NULL; ptr = ptr->more) { - if(ptr->name_alloc) { - Curl_safefree(ptr->name); - ptr->name_alloc = FALSE; - } - if(ptr->value_alloc) { - Curl_safefree(ptr->value); - ptr->value_alloc = FALSE; - } - if(ptr->contenttype_alloc) { - Curl_safefree(ptr->contenttype); - ptr->contenttype_alloc = FALSE; - } - if(ptr->showfilename_alloc) { - Curl_safefree(ptr->showfilename); - ptr->showfilename_alloc = FALSE; - } - } - } - } - - /* Always deallocate FormInfo linked list nodes without touching node - fields given that these have either been deallocated or are owned - now by the httppost linked list */ - while(first_form) { - FormInfo *ptr = first_form->more; - free(first_form); - first_form = ptr; - } - - return return_value; -} - -/* - * curl_formadd() is a public API to add a section to the multipart formpost. - * - * @unittest: 1308 - */ - -CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...) -{ - va_list arg; - CURLFORMcode result; - va_start(arg, last_post); - result = FormAdd(httppost, last_post, arg); - va_end(arg); - return result; -} - -#ifdef __VMS -#include -/* - * get_vms_file_size does what it takes to get the real size of the file - * - * For fixed files, find out the size of the EOF block and adjust. - * - * For all others, have to read the entire file in, discarding the contents. - * Most posted text files will be small, and binary files like zlib archives - * and CD/DVD images should be either a STREAM_LF format or a fixed format. - * - */ -curl_off_t VmsRealFileSize(const char * name, - const struct_stat * stat_buf) -{ - char buffer[8192]; - curl_off_t count; - int ret_stat; - FILE * file; - - file = fopen(name, FOPEN_READTEXT); /* VMS */ - if(file == NULL) - return 0; - - count = 0; - ret_stat = 1; - while(ret_stat > 0) { - ret_stat = fread(buffer, 1, sizeof(buffer), file); - if(ret_stat != 0) - count += ret_stat; - } - fclose(file); - - return count; -} - -/* - * - * VmsSpecialSize checks to see if the stat st_size can be trusted and - * if not to call a routine to get the correct size. - * - */ -static curl_off_t VmsSpecialSize(const char * name, - const struct_stat * stat_buf) -{ - switch(stat_buf->st_fab_rfm) { - case FAB$C_VAR: - case FAB$C_VFC: - return VmsRealFileSize(name, stat_buf); - break; - default: - return stat_buf->st_size; - } -} - -#endif - -#ifndef __VMS -#define filesize(name, stat_data) (stat_data.st_size) -#else - /* Getting the expected file size needs help on VMS */ -#define filesize(name, stat_data) VmsSpecialSize(name, &stat_data) -#endif - -/* - * AddFormData() adds a chunk of data to the FormData linked list. - * - * size is incremented by the chunk length, unless it is NULL - */ -static CURLcode AddFormData(struct FormData **formp, - enum formtype type, - const void *line, - curl_off_t length, - curl_off_t *size) -{ - struct FormData *newform; - char *alloc2 = NULL; - CURLcode result = CURLE_OK; - if(length < 0 || (size && *size < 0)) - return CURLE_BAD_FUNCTION_ARGUMENT; - - newform = malloc(sizeof(struct FormData)); - if(!newform) - return CURLE_OUT_OF_MEMORY; - newform->next = NULL; - - if(type <= FORM_CONTENT) { - /* we make it easier for plain strings: */ - if(!length) - length = strlen((char *)line); -#if (SIZEOF_SIZE_T < CURL_SIZEOF_CURL_OFF_T) - else if(length >= (curl_off_t)(size_t)-1) { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto error; - } -#endif - - newform->line = malloc((size_t)length+1); - if(!newform->line) { - result = CURLE_OUT_OF_MEMORY; - goto error; - } - alloc2 = newform->line; - memcpy(newform->line, line, (size_t)length); - newform->length = (size_t)length; - newform->line[(size_t)length]=0; /* zero terminate for easier debugging */ - } - else - /* For callbacks and files we don't have any actual data so we just keep a - pointer to whatever this points to */ - newform->line = (char *)line; - - newform->type = type; - - if(*formp) { - (*formp)->next = newform; - *formp = newform; - } - else - *formp = newform; - - if(size) { - if(type != FORM_FILE) - /* for static content as well as callback data we add the size given - as input argument */ - *size += length; - else { - /* Since this is a file to be uploaded here, add the size of the actual - file */ - if(!strequal("-", newform->line)) { - struct_stat file; - if(!stat(newform->line, &file) && !S_ISDIR(file.st_mode)) - *size += filesize(newform->line, file); - else { - result = CURLE_BAD_FUNCTION_ARGUMENT; - goto error; - } - } - } - } - return CURLE_OK; - error: - if(newform) - free(newform); - if(alloc2) - free(alloc2); - return result; -} - -/* - * AddFormDataf() adds printf()-style formatted data to the formdata chain. - */ - -static CURLcode AddFormDataf(struct FormData **formp, - curl_off_t *size, - const char *fmt, ...) -{ - char s[4096]; - va_list ap; - va_start(ap, fmt); - vsnprintf(s, sizeof(s), fmt, ap); - va_end(ap); - - return AddFormData(formp, FORM_DATA, s, 0, size); -} - -/* - * Curl_formclean() is used from http.c, this cleans a built FormData linked - * list - */ -void Curl_formclean(struct FormData **form_ptr) -{ - struct FormData *next, *form; - - form = *form_ptr; - if(!form) - return; - - do { - next=form->next; /* the following form line */ - if(form->type <= FORM_CONTENT) - free(form->line); /* free the line */ - free(form); /* free the struct */ - - } while((form = next) != NULL); /* continue */ - - *form_ptr = NULL; -} - -/* - * curl_formget() - * Serialize a curl_httppost struct. - * Returns 0 on success. - * - * @unittest: 1308 - */ -int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append) -{ - CURLcode result; - curl_off_t size; - struct FormData *data, *ptr; - - result = Curl_getformdata(NULL, &data, form, NULL, &size); - if(result) - return (int)result; - - for(ptr = data; ptr; ptr = ptr->next) { - if((ptr->type == FORM_FILE) || (ptr->type == FORM_CALLBACK)) { - char buffer[8192]; - size_t nread; - struct Form temp; - - Curl_FormInit(&temp, ptr); - - do { - nread = readfromfile(&temp, buffer, sizeof(buffer)); - if((nread == (size_t) -1) || - (nread > sizeof(buffer)) || - (nread != append(arg, buffer, nread))) { - if(temp.fp) - fclose(temp.fp); - Curl_formclean(&data); - return -1; - } - } while(nread); - } - else { - if(ptr->length != append(arg, ptr->line, ptr->length)) { - Curl_formclean(&data); - return -1; - } - } - } - Curl_formclean(&data); - return 0; -} - -/* - * curl_formfree() is an external function to free up a whole form post - * chain - */ -void curl_formfree(struct curl_httppost *form) -{ - struct curl_httppost *next; - - if(!form) - /* no form to free, just get out of this */ - return; - - do { - next=form->next; /* the following form line */ - - /* recurse to sub-contents */ - curl_formfree(form->more); - - if(!(form->flags & HTTPPOST_PTRNAME)) - free(form->name); /* free the name */ - if(!(form->flags & - (HTTPPOST_PTRCONTENTS|HTTPPOST_BUFFER|HTTPPOST_CALLBACK)) - ) - free(form->contents); /* free the contents */ - free(form->contenttype); /* free the content type */ - free(form->showfilename); /* free the faked file name */ - free(form); /* free the struct */ - - } while((form = next) != NULL); /* continue */ -} - -#ifndef HAVE_BASENAME -/* - (Quote from The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 - Edition) - - The basename() function shall take the pathname pointed to by path and - return a pointer to the final component of the pathname, deleting any - trailing '/' characters. - - If the string pointed to by path consists entirely of the '/' character, - basename() shall return a pointer to the string "/". If the string pointed - to by path is exactly "//", it is implementation-defined whether '/' or "//" - is returned. - - If path is a null pointer or points to an empty string, basename() shall - return a pointer to the string ".". - - The basename() function may modify the string pointed to by path, and may - return a pointer to static storage that may then be overwritten by a - subsequent call to basename(). - - The basename() function need not be reentrant. A function that is not - required to be reentrant is not required to be thread-safe. - -*/ -static char *Curl_basename(char *path) -{ - /* Ignore all the details above for now and make a quick and simple - implementaion here */ - char *s1; - char *s2; - - s1=strrchr(path, '/'); - s2=strrchr(path, '\\'); - - if(s1 && s2) { - path = (s1 > s2? s1 : s2)+1; - } - else if(s1) - path = s1 + 1; - else if(s2) - path = s2 + 1; - - return path; -} -#endif - -static char *strippath(const char *fullfile) -{ - char *filename; - char *base; - filename = strdup(fullfile); /* duplicate since basename() may ruin the - buffer it works on */ - if(!filename) - return NULL; - base = strdup(basename(filename)); - - free(filename); /* free temporary buffer */ - - return base; /* returns an allocated string or NULL ! */ -} - -static CURLcode formdata_add_filename(const struct curl_httppost *file, - struct FormData **form, - curl_off_t *size) -{ - CURLcode result = CURLE_OK; - char *filename = file->showfilename; - char *filebasename = NULL; - char *filename_escaped = NULL; - - if(!filename) { - filebasename = strippath(file->contents); - if(!filebasename) - return CURLE_OUT_OF_MEMORY; - filename = filebasename; - } - - if(strchr(filename, '\\') || strchr(filename, '"')) { - char *p0, *p1; - - /* filename need be escaped */ - filename_escaped = malloc(strlen(filename)*2+1); - if(!filename_escaped) { - free(filebasename); - return CURLE_OUT_OF_MEMORY; - } - p0 = filename_escaped; - p1 = filename; - while(*p1) { - if(*p1 == '\\' || *p1 == '"') - *p0++ = '\\'; - *p0++ = *p1++; - } - *p0 = '\0'; - filename = filename_escaped; - } - result = AddFormDataf(form, size, - "; filename=\"%s\"", - filename); - free(filename_escaped); - free(filebasename); - return result; -} - -/* - * Curl_getformdata() converts a linked list of "meta data" into a complete - * (possibly huge) multipart formdata. The input list is in 'post', while the - * output resulting linked lists gets stored in '*finalform'. *sizep will get - * the total size of the whole POST. - * A multipart/form_data content-type is built, unless a custom content-type - * is passed in 'custom_content_type'. - * - * This function will not do a failf() for the potential memory failures but - * should for all other errors it spots. Just note that this function MAY get - * a NULL pointer in the 'data' argument. - */ - -CURLcode Curl_getformdata(struct SessionHandle *data, - struct FormData **finalform, - struct curl_httppost *post, - const char *custom_content_type, - curl_off_t *sizep) -{ - struct FormData *form = NULL; - struct FormData *firstform; - struct curl_httppost *file; - CURLcode result = CURLE_OK; - - curl_off_t size = 0; /* support potentially ENORMOUS formposts */ - char *boundary; - char *fileboundary = NULL; - struct curl_slist* curList; - - *finalform = NULL; /* default form is empty */ - - if(!post) - return result; /* no input => no output! */ - - boundary = formboundary(data); - if(!boundary) - return CURLE_OUT_OF_MEMORY; - - /* Make the first line of the output */ - result = AddFormDataf(&form, NULL, - "%s; boundary=%s\r\n", - custom_content_type?custom_content_type: - "Content-Type: multipart/form-data", - boundary); - - if(result) { - free(boundary); - return result; - } - /* we DO NOT include that line in the total size of the POST, since it'll be - part of the header! */ - - firstform = form; - - do { - - if(size) { - result = AddFormDataf(&form, &size, "\r\n"); - if(result) - break; - } - - /* boundary */ - result = AddFormDataf(&form, &size, "--%s\r\n", boundary); - if(result) - break; - - /* Maybe later this should be disabled when a custom_content_type is - passed, since Content-Disposition is not meaningful for all multipart - types. - */ - result = AddFormDataf(&form, &size, - "Content-Disposition: form-data; name=\""); - if(result) - break; - - result = AddFormData(&form, FORM_DATA, post->name, post->namelength, - &size); - if(result) - break; - - result = AddFormDataf(&form, &size, "\""); - if(result) - break; - - if(post->more) { - /* If used, this is a link to more file names, we must then do - the magic to include several files with the same field name */ - - free(fileboundary); - fileboundary = formboundary(data); - if(!fileboundary) { - result = CURLE_OUT_OF_MEMORY; - break; - } - - result = AddFormDataf(&form, &size, - "\r\nContent-Type: multipart/mixed;" - " boundary=%s\r\n", - fileboundary); - if(result) - break; - } - - file = post; - - do { - - /* If 'showfilename' is set, that is a faked name passed on to us - to use to in the formpost. If that is not set, the actually used - local file name should be added. */ - - if(post->more) { - /* if multiple-file */ - result = AddFormDataf(&form, &size, - "\r\n--%s\r\nContent-Disposition: " - "attachment", - fileboundary); - if(result) - break; - result = formdata_add_filename(file, &form, &size); - if(result) - break; - } - else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER| - HTTPPOST_CALLBACK)) { - /* it should be noted that for the HTTPPOST_FILENAME and - HTTPPOST_CALLBACK cases the ->showfilename struct member is always - assigned at this point */ - if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) { - result = formdata_add_filename(post, &form, &size); - } - - if(result) - break; - } - - if(file->contenttype) { - /* we have a specified type */ - result = AddFormDataf(&form, &size, - "\r\nContent-Type: %s", - file->contenttype); - if(result) - break; - } - - curList = file->contentheader; - while(curList) { - /* Process the additional headers specified for this form */ - result = AddFormDataf(&form, &size, "\r\n%s", curList->data); - if(result) - break; - curList = curList->next; - } - if(result) - break; - - result = AddFormDataf(&form, &size, "\r\n\r\n"); - if(result) - break; - - if((post->flags & HTTPPOST_FILENAME) || - (post->flags & HTTPPOST_READFILE)) { - /* we should include the contents from the specified file */ - FILE *fileread; - - fileread = strequal("-", file->contents)? - stdin:fopen(file->contents, "rb"); /* binary read for win32 */ - - /* - * VMS: This only allows for stream files on VMS. Stream files are - * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC, - * every record needs to have a \n appended & 1 added to SIZE - */ - - if(fileread) { - if(fileread != stdin) { - /* close the file */ - fclose(fileread); - /* add the file name only - for later reading from this */ - result = AddFormData(&form, FORM_FILE, file->contents, 0, &size); - } - else { - /* When uploading from stdin, we can't know the size of the file, - * thus must read the full file as before. We *could* use chunked - * transfer-encoding, but that only works for HTTP 1.1 and we - * can't be sure we work with such a server. - */ - size_t nread; - char buffer[512]; - while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) { - result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size); - if(result) - break; - } - } - } - else { - if(data) - failf(data, "couldn't open file \"%s\"", file->contents); - *finalform = NULL; - result = CURLE_READ_ERROR; - } - } - else if(post->flags & HTTPPOST_BUFFER) - /* include contents of buffer */ - result = AddFormData(&form, FORM_CONTENT, post->buffer, - post->bufferlength, &size); - else if(post->flags & HTTPPOST_CALLBACK) - /* the contents should be read with the callback and the size is set - with the contentslength */ - result = AddFormData(&form, FORM_CALLBACK, post->userp, - post->flags&CURL_HTTPPOST_LARGE? - post->contentlen:post->contentslength, &size); - else - /* include the contents we got */ - result = AddFormData(&form, FORM_CONTENT, post->contents, - post->flags&CURL_HTTPPOST_LARGE? - post->contentlen:post->contentslength, &size); - file = file->more; - } while(file && !result); /* for each specified file for this field */ - - if(result) - break; - - if(post->more) { - /* this was a multiple-file inclusion, make a termination file - boundary: */ - result = AddFormDataf(&form, &size, - "\r\n--%s--", - fileboundary); - if(result) - break; - } - - } while((post = post->next) != NULL); /* for each field */ - - /* end-boundary for everything */ - if(!result) - result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary); - - if(result) { - Curl_formclean(&firstform); - free(fileboundary); - free(boundary); - return result; - } - - *sizep = size; - - free(fileboundary); - free(boundary); - - *finalform = firstform; - - return result; -} - -/* - * Curl_FormInit() inits the struct 'form' points to with the 'formdata' - * and resets the 'sent' counter. - */ -int Curl_FormInit(struct Form *form, struct FormData *formdata) -{ - if(!formdata) - return 1; /* error */ - - form->data = formdata; - form->sent = 0; - form->fp = NULL; - form->fread_func = ZERO_NULL; - - return 0; -} - -#ifndef __VMS -# define fopen_read fopen -#else - /* - * vmsfopenread - * - * For upload to work as expected on VMS, different optional - * parameters must be added to the fopen command based on - * record format of the file. - * - */ -# define fopen_read vmsfopenread -static FILE * vmsfopenread(const char *file, const char *mode) { - struct_stat statbuf; - int result; - - result = stat(file, &statbuf); - - switch (statbuf.st_fab_rfm) { - case FAB$C_VAR: - case FAB$C_VFC: - case FAB$C_STMCR: - return fopen(file, FOPEN_READTEXT); /* VMS */ - break; - default: - return fopen(file, FOPEN_READTEXT, "rfm=stmlf", "ctx=stm"); - } -} -#endif - -/* - * readfromfile() - * - * The read callback that this function may use can return a value larger than - * 'size' (which then this function returns) that indicates a problem and it - * must be properly dealt with - */ -static size_t readfromfile(struct Form *form, char *buffer, - size_t size) -{ - size_t nread; - bool callback = (form->data->type == FORM_CALLBACK)?TRUE:FALSE; - - if(callback) { - if(form->fread_func == ZERO_NULL) - return 0; - else - nread = form->fread_func(buffer, 1, size, form->data->line); - } - else { - if(!form->fp) { - /* this file hasn't yet been opened */ - form->fp = fopen_read(form->data->line, "rb"); /* b is for binary */ - if(!form->fp) - return (size_t)-1; /* failure */ - } - nread = fread(buffer, 1, size, form->fp); - } - if(!nread) { - /* this is the last chunk from the file, move on */ - if(form->fp) { - fclose(form->fp); - form->fp = NULL; - } - form->data = form->data->next; - } - - return nread; -} - -/* - * Curl_FormReader() is the fread() emulation function that will be used to - * deliver the formdata to the transfer loop and then sent away to the peer. - */ -size_t Curl_FormReader(char *buffer, - size_t size, - size_t nitems, - FILE *mydata) -{ - struct Form *form; - size_t wantedsize; - size_t gotsize = 0; - - form=(struct Form *)mydata; - - wantedsize = size * nitems; - - if(!form->data) - return 0; /* nothing, error, empty */ - - if((form->data->type == FORM_FILE) || - (form->data->type == FORM_CALLBACK)) { - gotsize = readfromfile(form, buffer, wantedsize); - - if(gotsize) - /* If positive or -1, return. If zero, continue! */ - return gotsize; - } - do { - - if((form->data->length - form->sent) > wantedsize - gotsize) { - - memcpy(buffer + gotsize, form->data->line + form->sent, - wantedsize - gotsize); - - form->sent += wantedsize-gotsize; - - return wantedsize; - } - - memcpy(buffer+gotsize, - form->data->line + form->sent, - (form->data->length - form->sent) ); - gotsize += form->data->length - form->sent; - - form->sent = 0; - - form->data = form->data->next; /* advance */ - - } while(form->data && (form->data->type < FORM_CALLBACK)); - /* If we got an empty line and we have more data, we proceed to the next - line immediately to avoid returning zero before we've reached the end. */ - - return gotsize; -} - -/* - * Curl_formpostheader() returns the first line of the formpost, the - * request-header part (which is not part of the request-body like the rest of - * the post). - */ -char *Curl_formpostheader(void *formp, size_t *len) -{ - char *header; - struct Form *form=(struct Form *)formp; - - if(!form->data) - return 0; /* nothing, ERROR! */ - - header = form->data->line; - *len = form->data->length; - - form->data = form->data->next; /* advance */ - - return header; -} - -/* - * formboundary() creates a suitable boundary string and returns an allocated - * one. - */ -static char *formboundary(struct SessionHandle *data) -{ - /* 24 dashes and 16 hexadecimal digits makes 64 bit (18446744073709551615) - combinations */ - return aprintf("------------------------%08x%08x", - Curl_rand(data), Curl_rand(data)); -} - -#else /* CURL_DISABLE_HTTP */ -CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...) -{ - (void)httppost; - (void)last_post; - return CURL_FORMADD_DISABLED; -} - -int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append) -{ - (void) form; - (void) arg; - (void) append; - return CURL_FORMADD_DISABLED; -} - -void curl_formfree(struct curl_httppost *form) -{ - (void)form; - /* does nothing HTTP is disabled */ -} - - -#endif /* !defined(CURL_DISABLE_HTTP) */ diff --git a/Externals/curl/lib/formdata.h b/Externals/curl/lib/formdata.h deleted file mode 100644 index a5ebc1d451..0000000000 --- a/Externals/curl/lib/formdata.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef HEADER_CURL_FORMDATA_H -#define HEADER_CURL_FORMDATA_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -enum formtype { - FORM_DATA, /* form metadata (convert to network encoding if necessary) */ - FORM_CONTENT, /* form content (never convert) */ - FORM_CALLBACK, /* 'line' points to the custom pointer we pass to the callback - */ - FORM_FILE /* 'line' points to a file name we should read from - to create the form data (never convert) */ -}; - -/* plain and simple linked list with lines to send */ -struct FormData { - struct FormData *next; - enum formtype type; - char *line; - size_t length; -}; - -struct Form { - struct FormData *data; /* current form line to send */ - size_t sent; /* number of bytes of the current line that has - already been sent in a previous invoke */ - FILE *fp; /* file to read from */ - curl_read_callback fread_func; /* fread callback pointer */ -}; - -/* used by FormAdd for temporary storage */ -typedef struct FormInfo { - char *name; - bool name_alloc; - size_t namelength; - char *value; - bool value_alloc; - curl_off_t contentslength; - char *contenttype; - bool contenttype_alloc; - long flags; - char *buffer; /* pointer to existing buffer used for file upload */ - size_t bufferlength; - char *showfilename; /* The file name to show. If not set, the actual - file name will be used */ - bool showfilename_alloc; - char *userp; /* pointer for the read callback */ - struct curl_slist* contentheader; - struct FormInfo *more; -} FormInfo; - -int Curl_FormInit(struct Form *form, struct FormData *formdata); - -CURLcode Curl_getformdata(struct SessionHandle *data, - struct FormData **, - struct curl_httppost *post, - const char *custom_contenttype, - curl_off_t *size); - -/* fread() emulation */ -size_t Curl_FormReader(char *buffer, - size_t size, - size_t nitems, - FILE *mydata); - -/* - * Curl_formpostheader() returns the first line of the formpost, the - * request-header part (which is not part of the request-body like the rest of - * the post). - */ -char *Curl_formpostheader(void *formp, size_t *len); - -char *Curl_FormBoundary(void); - -void Curl_formclean(struct FormData **); - -CURLcode Curl_formconvert(struct SessionHandle *, struct FormData *); - -#endif /* HEADER_CURL_FORMDATA_H */ diff --git a/Externals/curl/lib/ftp.c b/Externals/curl/lib/ftp.c deleted file mode 100644 index cfa1bbb805..0000000000 --- a/Externals/curl/lib/ftp.c +++ /dev/null @@ -1,4615 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_UTSNAME_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include -#include "urldata.h" -#include "sendf.h" -#include "if2ip.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "socks.h" -#include "ftp.h" -#include "fileinfo.h" -#include "ftplistparser.h" -#include "curl_sec.h" -#include "strtoofft.h" -#include "strequal.h" -#include "vtls/vtls.h" -#include "connect.h" -#include "strerror.h" -#include "inet_ntop.h" -#include "inet_pton.h" -#include "select.h" -#include "parsedate.h" /* for the week day and month names */ -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "multiif.h" -#include "url.h" -#include "rawstr.h" -#include "speedcheck.h" -#include "warnless.h" -#include "http_proxy.h" -#include "non-ascii.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#endif -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - -#ifdef CURL_DISABLE_VERBOSE_STRINGS -#define ftp_pasv_verbose(a,b,c,d) Curl_nop_stmt -#endif - -/* Local API functions */ -#ifndef DEBUGBUILD -static void _state(struct connectdata *conn, - ftpstate newstate); -#define state(x,y) _state(x,y) -#else -static void _state(struct connectdata *conn, - ftpstate newstate, - int lineno); -#define state(x,y) _state(x,y,__LINE__) -#endif - -static CURLcode ftp_sendquote(struct connectdata *conn, - struct curl_slist *quote); -static CURLcode ftp_quit(struct connectdata *conn); -static CURLcode ftp_parse_url_path(struct connectdata *conn); -static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done); -#ifndef CURL_DISABLE_VERBOSE_STRINGS -static void ftp_pasv_verbose(struct connectdata *conn, - Curl_addrinfo *ai, - char *newhost, /* ascii version */ - int port); -#endif -static CURLcode ftp_state_prepare_transfer(struct connectdata *conn); -static CURLcode ftp_state_mdtm(struct connectdata *conn); -static CURLcode ftp_state_quote(struct connectdata *conn, - bool init, ftpstate instate); -static CURLcode ftp_nb_type(struct connectdata *conn, - bool ascii, ftpstate newstate); -static int ftp_need_type(struct connectdata *conn, - bool ascii); -static CURLcode ftp_do(struct connectdata *conn, bool *done); -static CURLcode ftp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode ftp_connect(struct connectdata *conn, bool *done); -static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection); -static CURLcode ftp_do_more(struct connectdata *conn, int *completed); -static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done); -static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks); -static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks); -static CURLcode ftp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode ftp_setup_connection(struct connectdata * conn); - -static CURLcode init_wc_data(struct connectdata *conn); -static CURLcode wc_statemach(struct connectdata *conn); - -static void wc_data_dtor(void *ptr); - -static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize); - -static CURLcode ftp_readresp(curl_socket_t sockfd, - struct pingpong *pp, - int *ftpcode, - size_t *size); -static CURLcode ftp_dophase_done(struct connectdata *conn, - bool connected); - -/* easy-to-use macro: */ -#define PPSENDF(x,y,z) result = Curl_pp_sendf(x,y,z); \ - if(result) \ - return result - - -/* - * FTP protocol handler. - */ - -const struct Curl_handler Curl_handler_ftp = { - "FTP", /* scheme */ - ftp_setup_connection, /* setup_connection */ - ftp_do, /* do_it */ - ftp_done, /* done */ - ftp_do_more, /* do_more */ - ftp_connect, /* connect_it */ - ftp_multi_statemach, /* connecting */ - ftp_doing, /* doing */ - ftp_getsock, /* proto_getsock */ - ftp_getsock, /* doing_getsock */ - ftp_domore_getsock, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ftp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_FTP, /* defport */ - CURLPROTO_FTP, /* protocol */ - PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD - | PROTOPT_NOURLQUERY /* flags */ -}; - - -#ifdef USE_SSL -/* - * FTPS protocol handler. - */ - -const struct Curl_handler Curl_handler_ftps = { - "FTPS", /* scheme */ - ftp_setup_connection, /* setup_connection */ - ftp_do, /* do_it */ - ftp_done, /* done */ - ftp_do_more, /* do_more */ - ftp_connect, /* connect_it */ - ftp_multi_statemach, /* connecting */ - ftp_doing, /* doing */ - ftp_getsock, /* proto_getsock */ - ftp_getsock, /* doing_getsock */ - ftp_domore_getsock, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ftp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_FTPS, /* defport */ - CURLPROTO_FTPS, /* protocol */ - PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | - PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY /* flags */ -}; -#endif - -#ifndef CURL_DISABLE_HTTP -/* - * HTTP-proxyed FTP protocol handler. - */ - -static const struct Curl_handler Curl_handler_ftp_proxy = { - "FTP", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_FTP, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - - -#ifdef USE_SSL -/* - * HTTP-proxyed FTPS protocol handler. - */ - -static const struct Curl_handler Curl_handler_ftps_proxy = { - "FTPS", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_FTPS, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; -#endif -#endif - -static void close_secondarysocket(struct connectdata *conn) -{ - if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) { - Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; - } - conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE; - conn->tunnel_state[SECONDARYSOCKET] = TUNNEL_INIT; -} - -/* - * NOTE: back in the old days, we added code in the FTP code that made NOBODY - * requests on files respond with headers passed to the client/stdout that - * looked like HTTP ones. - * - * This approach is not very elegant, it causes confusion and is error-prone. - * It is subject for removal at the next (or at least a future) soname bump. - * Until then you can test the effects of the removal by undefining the - * following define named CURL_FTP_HTTPSTYLE_HEAD. - */ -#define CURL_FTP_HTTPSTYLE_HEAD 1 - -static void freedirs(struct ftp_conn *ftpc) -{ - int i; - if(ftpc->dirs) { - for(i=0; i < ftpc->dirdepth; i++) { - free(ftpc->dirs[i]); - ftpc->dirs[i]=NULL; - } - free(ftpc->dirs); - ftpc->dirs = NULL; - ftpc->dirdepth = 0; - } - Curl_safefree(ftpc->file); - - /* no longer of any use */ - Curl_safefree(ftpc->newhost); -} - -/* Returns non-zero if the given string contains CR (\r) or LF (\n), - which are not allowed within RFC 959 . - Note: The input string is in the client's encoding which might - not be ASCII, so escape sequences \r & \n must be used instead - of hex values 0x0d & 0x0a. -*/ -static bool isBadFtpString(const char *string) -{ - return ((NULL != strchr(string, '\r')) || - (NULL != strchr(string, '\n'))) ? TRUE : FALSE; -} - -/*********************************************************************** - * - * AcceptServerConnect() - * - * After connection request is received from the server this function is - * called to accept the connection and close the listening socket - * - */ -static CURLcode AcceptServerConnect(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - curl_socket_t sock = conn->sock[SECONDARYSOCKET]; - curl_socket_t s = CURL_SOCKET_BAD; -#ifdef ENABLE_IPV6 - struct Curl_sockaddr_storage add; -#else - struct sockaddr_in add; -#endif - curl_socklen_t size = (curl_socklen_t) sizeof(add); - - if(0 == getsockname(sock, (struct sockaddr *) &add, &size)) { - size = sizeof(add); - - s=accept(sock, (struct sockaddr *) &add, &size); - } - Curl_closesocket(conn, sock); /* close the first socket */ - - if(CURL_SOCKET_BAD == s) { - failf(data, "Error accept()ing server connect"); - return CURLE_FTP_PORT_FAILED; - } - infof(data, "Connection accepted from server\n"); - /* when this happens within the DO state it is important that we mark us as - not needing DO_MORE anymore */ - conn->bits.do_more = FALSE; - - conn->sock[SECONDARYSOCKET] = s; - (void)curlx_nonblock(s, TRUE); /* enable non-blocking */ - conn->sock_accepted[SECONDARYSOCKET] = TRUE; - - if(data->set.fsockopt) { - int error = 0; - - /* activate callback for setting socket options */ - error = data->set.fsockopt(data->set.sockopt_client, - s, - CURLSOCKTYPE_ACCEPT); - - if(error) { - close_secondarysocket(conn); - return CURLE_ABORTED_BY_CALLBACK; - } - } - - return CURLE_OK; - -} - -/* - * ftp_timeleft_accept() returns the amount of milliseconds left allowed for - * waiting server to connect. If the value is negative, the timeout time has - * already elapsed. - * - * The start time is stored in progress.t_acceptdata - as set with - * Curl_pgrsTime(..., TIMER_STARTACCEPT); - * - */ -static long ftp_timeleft_accept(struct SessionHandle *data) -{ - long timeout_ms = DEFAULT_ACCEPT_TIMEOUT; - long other; - struct timeval now; - - if(data->set.accepttimeout > 0) - timeout_ms = data->set.accepttimeout; - - now = Curl_tvnow(); - - /* check if the generic timeout possibly is set shorter */ - other = Curl_timeleft(data, &now, FALSE); - if(other && (other < timeout_ms)) - /* note that this also works fine for when other happens to be negative - due to it already having elapsed */ - timeout_ms = other; - else { - /* subtract elapsed time */ - timeout_ms -= Curl_tvdiff(now, data->progress.t_acceptdata); - if(!timeout_ms) - /* avoid returning 0 as that means no timeout! */ - return -1; - } - - return timeout_ms; -} - - -/*********************************************************************** - * - * ReceivedServerConnect() - * - * After allowing server to connect to us from data port, this function - * checks both data connection for connection establishment and ctrl - * connection for a negative response regarding a failure in connecting - * - */ -static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received) -{ - struct SessionHandle *data = conn->data; - curl_socket_t ctrl_sock = conn->sock[FIRSTSOCKET]; - curl_socket_t data_sock = conn->sock[SECONDARYSOCKET]; - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - int result; - long timeout_ms; - ssize_t nread; - int ftpcode; - - *received = FALSE; - - timeout_ms = ftp_timeleft_accept(data); - infof(data, "Checking for server connect\n"); - if(timeout_ms < 0) { - /* if a timeout was already reached, bail out */ - failf(data, "Accept timeout occurred while waiting server connect"); - return CURLE_FTP_ACCEPT_TIMEOUT; - } - - /* First check whether there is a cached response from server */ - if(pp->cache_size && pp->cache && pp->cache[0] > '3') { - /* Data connection could not be established, let's return */ - infof(data, "There is negative response in cache while serv connect\n"); - Curl_GetFTPResponse(&nread, conn, &ftpcode); - return CURLE_FTP_ACCEPT_FAILED; - } - - result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0); - - /* see if the connection request is already here */ - switch (result) { - case -1: /* error */ - /* let's die here */ - failf(data, "Error while waiting for server connect"); - return CURLE_FTP_ACCEPT_FAILED; - case 0: /* Server connect is not received yet */ - break; /* loop */ - default: - - if(result & CURL_CSELECT_IN2) { - infof(data, "Ready to accept data connection from server\n"); - *received = TRUE; - } - else if(result & CURL_CSELECT_IN) { - infof(data, "Ctrl conn has data while waiting for data conn\n"); - Curl_GetFTPResponse(&nread, conn, &ftpcode); - - if(ftpcode/100 > 3) - return CURLE_FTP_ACCEPT_FAILED; - - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - - break; - } /* switch() */ - - return CURLE_OK; -} - - -/*********************************************************************** - * - * InitiateTransfer() - * - * After connection from server is accepted this function is called to - * setup transfer parameters and initiate the data transfer. - * - */ -static CURLcode InitiateTransfer(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - struct FTP *ftp = data->req.protop; - CURLcode result = CURLE_OK; - - if(conn->ssl[SECONDARYSOCKET].use) { - /* since we only have a plaintext TCP connection here, we must now - * do the TLS stuff */ - infof(data, "Doing the SSL/TLS handshake on the data stream\n"); - result = Curl_ssl_connect(conn, SECONDARYSOCKET); - if(result) - return result; - } - - if(conn->proto.ftpc.state_saved == FTP_STOR) { - *(ftp->bytecountp)=0; - - /* When we know we're uploading a specified file, we can get the file - size prior to the actual upload. */ - - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* set the SO_SNDBUF for the secondary socket for those who need it */ - Curl_sndbufset(conn->sock[SECONDARYSOCKET]); - - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ - SECONDARYSOCKET, ftp->bytecountp); - } - else { - /* FTP download: */ - Curl_setup_transfer(conn, SECONDARYSOCKET, - conn->proto.ftpc.retr_size_saved, FALSE, - ftp->bytecountp, -1, NULL); /* no upload here */ - } - - conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */ - state(conn, FTP_STOP); - - return CURLE_OK; -} - -/*********************************************************************** - * - * AllowServerConnect() - * - * When we've issue the PORT command, we have told the server to connect to - * us. This function checks whether data connection is established if so it is - * accepted. - * - */ -static CURLcode AllowServerConnect(struct connectdata *conn, bool *connected) -{ - struct SessionHandle *data = conn->data; - long timeout_ms; - CURLcode result = CURLE_OK; - - *connected = FALSE; - infof(data, "Preparing for accepting server on data port\n"); - - /* Save the time we start accepting server connect */ - Curl_pgrsTime(data, TIMER_STARTACCEPT); - - timeout_ms = ftp_timeleft_accept(data); - if(timeout_ms < 0) { - /* if a timeout was already reached, bail out */ - failf(data, "Accept timeout occurred while waiting server connect"); - return CURLE_FTP_ACCEPT_TIMEOUT; - } - - /* see if the connection request is already here */ - result = ReceivedServerConnect(conn, connected); - if(result) - return result; - - if(*connected) { - result = AcceptServerConnect(conn); - if(result) - return result; - - result = InitiateTransfer(conn); - if(result) - return result; - } - else { - /* Add timeout to multi handle and break out of the loop */ - if(!result && *connected == FALSE) { - if(data->set.accepttimeout > 0) - Curl_expire(data, data->set.accepttimeout); - else - Curl_expire(data, DEFAULT_ACCEPT_TIMEOUT); - } - } - - return result; -} - -/* macro to check for a three-digit ftp status code at the start of the - given string */ -#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) && \ - ISDIGIT(line[2])) - -/* macro to check for the last line in an FTP server response */ -#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3])) - -static bool ftp_endofresp(struct connectdata *conn, char *line, size_t len, - int *code) -{ - (void)conn; - - if((len > 3) && LASTLINE(line)) { - *code = curlx_sltosi(strtol(line, NULL, 10)); - return TRUE; - } - - return FALSE; -} - -static CURLcode ftp_readresp(curl_socket_t sockfd, - struct pingpong *pp, - int *ftpcode, /* return the ftp-code if done */ - size_t *size) /* size of the response */ -{ - struct connectdata *conn = pp->conn; - struct SessionHandle *data = conn->data; -#ifdef HAVE_GSSAPI - char * const buf = data->state.buffer; -#endif - CURLcode result = CURLE_OK; - int code; - - result = Curl_pp_readresp(sockfd, pp, &code, size); - -#if defined(HAVE_GSSAPI) - /* handle the security-oriented responses 6xx ***/ - /* FIXME: some errorchecking perhaps... ***/ - switch(code) { - case 631: - code = Curl_sec_read_msg(conn, buf, PROT_SAFE); - break; - case 632: - code = Curl_sec_read_msg(conn, buf, PROT_PRIVATE); - break; - case 633: - code = Curl_sec_read_msg(conn, buf, PROT_CONFIDENTIAL); - break; - default: - /* normal ftp stuff we pass through! */ - break; - } -#endif - - /* store the latest code for later retrieval */ - data->info.httpcode=code; - - if(ftpcode) - *ftpcode = code; - - if(421 == code) { - /* 421 means "Service not available, closing control connection." and FTP - * servers use it to signal that idle session timeout has been exceeded. - * If we ignored the response, it could end up hanging in some cases. - * - * This response code can come at any point so having it treated - * generically is a good idea. - */ - infof(data, "We got a 421 - timeout!\n"); - state(conn, FTP_STOP); - return CURLE_OPERATION_TIMEDOUT; - } - - return result; -} - -/* --- parse FTP server responses --- */ - -/* - * Curl_GetFTPResponse() is a BLOCKING function to read the full response - * from a server after a command. - * - */ - -CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */ - struct connectdata *conn, - int *ftpcode) /* return the ftp-code */ -{ - /* - * We cannot read just one byte per read() and then go back to select() as - * the OpenSSL read() doesn't grok that properly. - * - * Alas, read as much as possible, split up into lines, use the ending - * line in a response or continue reading. */ - - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - long timeout; /* timeout in milliseconds */ - long interval_ms; - struct SessionHandle *data = conn->data; - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - size_t nread; - int cache_skip=0; - int value_to_be_ignored=0; - - if(ftpcode) - *ftpcode = 0; /* 0 for errors */ - else - /* make the pointer point to something for the rest of this function */ - ftpcode = &value_to_be_ignored; - - *nreadp=0; - - while(!*ftpcode && !result) { - /* check and reset timeout value every lap */ - timeout = Curl_pp_state_timeout(pp); - - if(timeout <=0) { - failf(data, "FTP response timeout"); - return CURLE_OPERATION_TIMEDOUT; /* already too little time */ - } - - interval_ms = 1000; /* use 1 second timeout intervals */ - if(timeout < interval_ms) - interval_ms = timeout; - - /* - * Since this function is blocking, we need to wait here for input on the - * connection and only then we call the response reading function. We do - * timeout at least every second to make the timeout check run. - * - * A caution here is that the ftp_readresp() function has a cache that may - * contain pieces of a response from the previous invoke and we need to - * make sure we don't just wait for input while there is unhandled data in - * that cache. But also, if the cache is there, we call ftp_readresp() and - * the cache wasn't good enough to continue we must not just busy-loop - * around this function. - * - */ - - if(pp->cache && (cache_skip < 2)) { - /* - * There's a cache left since before. We then skipping the wait for - * socket action, unless this is the same cache like the previous round - * as then the cache was deemed not enough to act on and we then need to - * wait for more data anyway. - */ - } - else { - switch (Curl_socket_ready(sockfd, CURL_SOCKET_BAD, interval_ms)) { - case -1: /* select() error, stop reading */ - failf(data, "FTP response aborted due to select/poll error: %d", - SOCKERRNO); - return CURLE_RECV_ERROR; - - case 0: /* timeout */ - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; - continue; /* just continue in our loop for the timeout duration */ - - default: /* for clarity */ - break; - } - } - result = ftp_readresp(sockfd, pp, ftpcode, &nread); - if(result) - break; - - if(!nread && pp->cache) - /* bump cache skip counter as on repeated skips we must wait for more - data */ - cache_skip++; - else - /* when we got data or there is no cache left, we reset the cache skip - counter */ - cache_skip=0; - - *nreadp += nread; - - } /* while there's buffer left and loop is requested */ - - pp->pending_resp = FALSE; - - return result; -} - -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ -static const char * const ftp_state_names[]={ - "STOP", - "WAIT220", - "AUTH", - "USER", - "PASS", - "ACCT", - "PBSZ", - "PROT", - "CCC", - "PWD", - "SYST", - "NAMEFMT", - "QUOTE", - "RETR_PREQUOTE", - "STOR_PREQUOTE", - "POSTQUOTE", - "CWD", - "MKD", - "MDTM", - "TYPE", - "LIST_TYPE", - "RETR_TYPE", - "STOR_TYPE", - "SIZE", - "RETR_SIZE", - "STOR_SIZE", - "REST", - "RETR_REST", - "PORT", - "PRET", - "PASV", - "LIST", - "RETR", - "STOR", - "QUIT" -}; -#endif - -/* This is the ONLY way to change FTP state! */ -static void _state(struct connectdata *conn, - ftpstate newstate -#ifdef DEBUGBUILD - , int lineno -#endif - ) -{ - struct ftp_conn *ftpc = &conn->proto.ftpc; - -#if defined(DEBUGBUILD) - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) lineno; -#else - if(ftpc->state != newstate) - infof(conn->data, "FTP %p (line %d) state change from %s to %s\n", - (void *)ftpc, lineno, ftp_state_names[ftpc->state], - ftp_state_names[newstate]); -#endif -#endif - - ftpc->state = newstate; -} - -static CURLcode ftp_state_user(struct connectdata *conn) -{ - CURLcode result; - struct FTP *ftp = conn->data->req.protop; - /* send USER */ - PPSENDF(&conn->proto.ftpc.pp, "USER %s", ftp->user?ftp->user:""); - - state(conn, FTP_USER); - conn->data->state.ftp_trying_alternative = FALSE; - - return CURLE_OK; -} - -static CURLcode ftp_state_pwd(struct connectdata *conn) -{ - CURLcode result; - - /* send PWD to discover our entry point */ - PPSENDF(&conn->proto.ftpc.pp, "%s", "PWD"); - state(conn, FTP_PWD); - - return CURLE_OK; -} - -/* For the FTP "protocol connect" and "doing" phases only */ -static int ftp_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); -} - -/* For the FTP "DO_MORE" phase only */ -static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks) -{ - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if(!numsocks) - return GETSOCK_BLANK; - - /* When in DO_MORE state, we could be either waiting for us to connect to a - * remote site, or we could wait for that site to connect to us. Or just - * handle ordinary commands. - */ - - if(FTP_STOP == ftpc->state) { - int bits = GETSOCK_READSOCK(0); - - /* if stopped and still in this state, then we're also waiting for a - connect on the secondary connection */ - socks[0] = conn->sock[FIRSTSOCKET]; - - if(!conn->data->set.ftp_use_port) { - int s; - int i; - /* PORT is used to tell the server to connect to us, and during that we - don't do happy eyeballs, but we do if we connect to the server */ - for(s=1, i=0; i<2; i++) { - if(conn->tempsock[i] != CURL_SOCKET_BAD) { - socks[s] = conn->tempsock[i]; - bits |= GETSOCK_WRITESOCK(s++); - } - } - } - else { - socks[1] = conn->sock[SECONDARYSOCKET]; - bits |= GETSOCK_WRITESOCK(1); - } - - return bits; - } - else - return Curl_pp_getsock(&conn->proto.ftpc.pp, socks, numsocks); -} - -/* This is called after the FTP_QUOTE state is passed. - - ftp_state_cwd() sends the range of CWD commands to the server to change to - the correct directory. It may also need to send MKD commands to create - missing ones, if that option is enabled. -*/ -static CURLcode ftp_state_cwd(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if(ftpc->cwddone) - /* already done and fine */ - result = ftp_state_mdtm(conn); - else { - ftpc->count2 = 0; /* count2 counts failed CWDs */ - - /* count3 is set to allow a MKD to fail once. In the case when first CWD - fails and then MKD fails (due to another session raced it to create the - dir) this then allows for a second try to CWD to it */ - ftpc->count3 = (conn->data->set.ftp_create_missing_dirs==2)?1:0; - - if(conn->bits.reuse && ftpc->entrypath) { - /* This is a re-used connection. Since we change directory to where the - transfer is taking place, we must first get back to the original dir - where we ended up after login: */ - ftpc->count1 = 0; /* we count this as the first path, then we add one - for all upcoming ones in the ftp->dirs[] array */ - PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->entrypath); - state(conn, FTP_CWD); - } - else { - if(ftpc->dirdepth) { - ftpc->count1 = 1; - /* issue the first CWD, the rest is sent when the CWD responses are - received... */ - PPSENDF(&conn->proto.ftpc.pp, "CWD %s", ftpc->dirs[ftpc->count1 -1]); - state(conn, FTP_CWD); - } - else { - /* No CWD necessary */ - result = ftp_state_mdtm(conn); - } - } - } - return result; -} - -typedef enum { - EPRT, - PORT, - DONE -} ftpport; - -static CURLcode ftp_state_use_port(struct connectdata *conn, - ftpport fcmd) /* start with this */ - -{ - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct SessionHandle *data=conn->data; - curl_socket_t portsock= CURL_SOCKET_BAD; - char myhost[256] = ""; - - struct Curl_sockaddr_storage ss; - Curl_addrinfo *res, *ai; - curl_socklen_t sslen; - char hbuf[NI_MAXHOST]; - struct sockaddr *sa=(struct sockaddr *)&ss; - struct sockaddr_in * const sa4 = (void *)sa; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 * const sa6 = (void *)sa; -#endif - char tmp[1024]; - static const char mode[][5] = { "EPRT", "PORT" }; - int rc; - int error; - char *host = NULL; - char *string_ftpport = data->set.str[STRING_FTPPORT]; - struct Curl_dns_entry *h=NULL; - unsigned short port_min = 0; - unsigned short port_max = 0; - unsigned short port; - bool possibly_non_local = TRUE; - - char *addr = NULL; - - /* Step 1, figure out what is requested, - * accepted format : - * (ipv4|ipv6|domain|interface)?(:port(-range)?)? - */ - - if(data->set.str[STRING_FTPPORT] && - (strlen(data->set.str[STRING_FTPPORT]) > 1)) { - -#ifdef ENABLE_IPV6 - size_t addrlen = INET6_ADDRSTRLEN > strlen(string_ftpport) ? - INET6_ADDRSTRLEN : strlen(string_ftpport); -#else - size_t addrlen = INET_ADDRSTRLEN > strlen(string_ftpport) ? - INET_ADDRSTRLEN : strlen(string_ftpport); -#endif - char *ip_start = string_ftpport; - char *ip_end = NULL; - char *port_start = NULL; - char *port_sep = NULL; - - addr = calloc(addrlen+1, 1); - if(!addr) - return CURLE_OUT_OF_MEMORY; - -#ifdef ENABLE_IPV6 - if(*string_ftpport == '[') { - /* [ipv6]:port(-range) */ - ip_start = string_ftpport + 1; - if((ip_end = strchr(string_ftpport, ']')) != NULL) - strncpy(addr, ip_start, ip_end - ip_start); - } - else -#endif - if(*string_ftpport == ':') { - /* :port */ - ip_end = string_ftpport; - } - else if((ip_end = strchr(string_ftpport, ':')) != NULL) { - /* either ipv6 or (ipv4|domain|interface):port(-range) */ -#ifdef ENABLE_IPV6 - if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) { - /* ipv6 */ - port_min = port_max = 0; - strcpy(addr, string_ftpport); - ip_end = NULL; /* this got no port ! */ - } - else -#endif - /* (ipv4|domain|interface):port(-range) */ - strncpy(addr, string_ftpport, ip_end - ip_start); - } - else - /* ipv4|interface */ - strcpy(addr, string_ftpport); - - /* parse the port */ - if(ip_end != NULL) { - if((port_start = strchr(ip_end, ':')) != NULL) { - port_min = curlx_ultous(strtoul(port_start+1, NULL, 10)); - if((port_sep = strchr(port_start, '-')) != NULL) { - port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10)); - } - else - port_max = port_min; - } - } - - /* correct errors like: - * :1234-1230 - * :-4711, in this case port_min is (unsigned)-1, - * therefore port_min > port_max for all cases - * but port_max = (unsigned)-1 - */ - if(port_min > port_max) - port_min = port_max = 0; - - - if(*addr != '\0') { - /* attempt to get the address of the given interface name */ - switch(Curl_if2ip(conn->ip_addr->ai_family, - Curl_ipv6_scope(conn->ip_addr->ai_addr), - conn->scope_id, addr, hbuf, sizeof(hbuf))) { - case IF2IP_NOT_FOUND: - /* not an interface, use the given string as host name instead */ - host = addr; - break; - case IF2IP_AF_NOT_SUPPORTED: - return CURLE_FTP_PORT_FAILED; - case IF2IP_FOUND: - host = hbuf; /* use the hbuf for host name */ - } - } - else - /* there was only a port(-range) given, default the host */ - host = NULL; - } /* data->set.ftpport */ - - if(!host) { - /* not an interface and not a host name, get default by extracting - the IP from the control connection */ - - sslen = sizeof(ss); - if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { - failf(data, "getsockname() failed: %s", - Curl_strerror(conn, SOCKERRNO) ); - free(addr); - return CURLE_FTP_PORT_FAILED; - } - switch(sa->sa_family) { -#ifdef ENABLE_IPV6 - case AF_INET6: - Curl_inet_ntop(sa->sa_family, &sa6->sin6_addr, hbuf, sizeof(hbuf)); - break; -#endif - default: - Curl_inet_ntop(sa->sa_family, &sa4->sin_addr, hbuf, sizeof(hbuf)); - break; - } - host = hbuf; /* use this host name */ - possibly_non_local = FALSE; /* we know it is local now */ - } - - /* resolv ip/host to ip */ - rc = Curl_resolv(conn, host, 0, &h); - if(rc == CURLRESOLV_PENDING) - (void)Curl_resolver_wait_resolv(conn, &h); - if(h) { - res = h->addr; - /* when we return from this function, we can forget about this entry - to we can unlock it now already */ - Curl_resolv_unlock(data, h); - } /* (h) */ - else - res = NULL; /* failure! */ - - if(res == NULL) { - failf(data, "failed to resolve the address provided to PORT: %s", host); - free(addr); - return CURLE_FTP_PORT_FAILED; - } - - free(addr); - host = NULL; - - /* step 2, create a socket for the requested address */ - - portsock = CURL_SOCKET_BAD; - error = 0; - for(ai = res; ai; ai = ai->ai_next) { - result = Curl_socket(conn, ai, NULL, &portsock); - if(result) { - error = SOCKERRNO; - continue; - } - break; - } - if(!ai) { - failf(data, "socket failure: %s", Curl_strerror(conn, error)); - return CURLE_FTP_PORT_FAILED; - } - - /* step 3, bind to a suitable local address */ - - memcpy(sa, ai->ai_addr, ai->ai_addrlen); - sslen = ai->ai_addrlen; - - for(port = port_min; port <= port_max;) { - if(sa->sa_family == AF_INET) - sa4->sin_port = htons(port); -#ifdef ENABLE_IPV6 - else - sa6->sin6_port = htons(port); -#endif - /* Try binding the given address. */ - if(bind(portsock, sa, sslen) ) { - /* It failed. */ - error = SOCKERRNO; - if(possibly_non_local && (error == EADDRNOTAVAIL)) { - /* The requested bind address is not local. Use the address used for - * the control connection instead and restart the port loop - */ - - infof(data, "bind(port=%hu) on non-local address failed: %s\n", port, - Curl_strerror(conn, error) ); - - sslen = sizeof(ss); - if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) { - failf(data, "getsockname() failed: %s", - Curl_strerror(conn, SOCKERRNO) ); - Curl_closesocket(conn, portsock); - return CURLE_FTP_PORT_FAILED; - } - port = port_min; - possibly_non_local = FALSE; /* don't try this again */ - continue; - } - else if(error != EADDRINUSE && error != EACCES) { - failf(data, "bind(port=%hu) failed: %s", port, - Curl_strerror(conn, error) ); - Curl_closesocket(conn, portsock); - return CURLE_FTP_PORT_FAILED; - } - } - else - break; - - port++; - } - - /* maybe all ports were in use already*/ - if(port > port_max) { - failf(data, "bind() failed, we ran out of ports!"); - Curl_closesocket(conn, portsock); - return CURLE_FTP_PORT_FAILED; - } - - /* get the name again after the bind() so that we can extract the - port number it uses now */ - sslen = sizeof(ss); - if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) { - failf(data, "getsockname() failed: %s", - Curl_strerror(conn, SOCKERRNO) ); - Curl_closesocket(conn, portsock); - return CURLE_FTP_PORT_FAILED; - } - - /* step 4, listen on the socket */ - - if(listen(portsock, 1)) { - failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO)); - Curl_closesocket(conn, portsock); - return CURLE_FTP_PORT_FAILED; - } - - /* step 5, send the proper FTP command */ - - /* get a plain printable version of the numerical address to work with - below */ - Curl_printable_address(ai, myhost, sizeof(myhost)); - -#ifdef ENABLE_IPV6 - if(!conn->bits.ftp_use_eprt && conn->bits.ipv6) - /* EPRT is disabled but we are connected to a IPv6 host, so we ignore the - request and enable EPRT again! */ - conn->bits.ftp_use_eprt = TRUE; -#endif - - for(; fcmd != DONE; fcmd++) { - - if(!conn->bits.ftp_use_eprt && (EPRT == fcmd)) - /* if disabled, goto next */ - continue; - - if((PORT == fcmd) && sa->sa_family != AF_INET) - /* PORT is IPv4 only */ - continue; - - switch(sa->sa_family) { - case AF_INET: - port = ntohs(sa4->sin_port); - break; -#ifdef ENABLE_IPV6 - case AF_INET6: - port = ntohs(sa6->sin6_port); - break; -#endif - default: - continue; /* might as well skip this */ - } - - if(EPRT == fcmd) { - /* - * Two fine examples from RFC2428; - * - * EPRT |1|132.235.1.2|6275| - * - * EPRT |2|1080::8:800:200C:417A|5282| - */ - - result = Curl_pp_sendf(&ftpc->pp, "%s |%d|%s|%hu|", mode[fcmd], - sa->sa_family == AF_INET?1:2, - myhost, port); - if(result) { - failf(data, "Failure sending EPRT command: %s", - curl_easy_strerror(result)); - Curl_closesocket(conn, portsock); - /* don't retry using PORT */ - ftpc->count1 = PORT; - /* bail out */ - state(conn, FTP_STOP); - return result; - } - break; - } - else if(PORT == fcmd) { - char *source = myhost; - char *dest = tmp; - - /* translate x.x.x.x to x,x,x,x */ - while(source && *source) { - if(*source == '.') - *dest=','; - else - *dest = *source; - dest++; - source++; - } - *dest = 0; - snprintf(dest, 20, ",%d,%d", (int)(port>>8), (int)(port&0xff)); - - result = Curl_pp_sendf(&ftpc->pp, "%s %s", mode[fcmd], tmp); - if(result) { - failf(data, "Failure sending PORT command: %s", - curl_easy_strerror(result)); - Curl_closesocket(conn, portsock); - /* bail out */ - state(conn, FTP_STOP); - return result; - } - break; - } - } - - /* store which command was sent */ - ftpc->count1 = fcmd; - - close_secondarysocket(conn); - - /* we set the secondary socket variable to this for now, it is only so that - the cleanup function will close it in case we fail before the true - secondary stuff is made */ - conn->sock[SECONDARYSOCKET] = portsock; - - /* this tcpconnect assignment below is a hackish work-around to make the - multi interface with active FTP work - as it will not wait for a - (passive) connect in Curl_is_connected(). - - The *proper* fix is to make sure that the active connection from the - server is done in a non-blocking way. Currently, it is still BLOCKING. - */ - conn->bits.tcpconnect[SECONDARYSOCKET] = TRUE; - - state(conn, FTP_PORT); - return result; -} - -static CURLcode ftp_state_use_pasv(struct connectdata *conn) -{ - struct ftp_conn *ftpc = &conn->proto.ftpc; - CURLcode result = CURLE_OK; - /* - Here's the excecutive summary on what to do: - - PASV is RFC959, expect: - 227 Entering Passive Mode (a1,a2,a3,a4,p1,p2) - - LPSV is RFC1639, expect: - 228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2) - - EPSV is RFC2428, expect: - 229 Entering Extended Passive Mode (|||port|) - - */ - - static const char mode[][5] = { "EPSV", "PASV" }; - int modeoff; - -#ifdef PF_INET6 - if(!conn->bits.ftp_use_epsv && conn->bits.ipv6) - /* EPSV is disabled but we are connected to a IPv6 host, so we ignore the - request and enable EPSV again! */ - conn->bits.ftp_use_epsv = TRUE; -#endif - - modeoff = conn->bits.ftp_use_epsv?0:1; - - PPSENDF(&ftpc->pp, "%s", mode[modeoff]); - - ftpc->count1 = modeoff; - state(conn, FTP_PASV); - infof(conn->data, "Connect data stream passively\n"); - - return result; -} - -/* - * ftp_state_prepare_transfer() starts PORT, PASV or PRET etc. - * - * REST is the last command in the chain of commands when a "head"-like - * request is made. Thus, if an actual transfer is to be made this is where we - * take off for real. - */ -static CURLcode ftp_state_prepare_transfer(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct FTP *ftp = conn->data->req.protop; - struct SessionHandle *data = conn->data; - - if(ftp->transfer != FTPTRANSFER_BODY) { - /* doesn't transfer any data */ - - /* still possibly do PRE QUOTE jobs */ - state(conn, FTP_RETR_PREQUOTE); - result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); - } - else if(data->set.ftp_use_port) { - /* We have chosen to use the PORT (or similar) command */ - result = ftp_state_use_port(conn, EPRT); - } - else { - /* We have chosen (this is default) to use the PASV (or similar) command */ - if(data->set.ftp_use_pret) { - /* The user has requested that we send a PRET command - to prepare the server for the upcoming PASV */ - if(!conn->proto.ftpc.file) { - PPSENDF(&conn->proto.ftpc.pp, "PRET %s", - data->set.str[STRING_CUSTOMREQUEST]? - data->set.str[STRING_CUSTOMREQUEST]: - (data->set.ftp_list_only?"NLST":"LIST")); - } - else if(data->set.upload) { - PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file); - } - else { - PPSENDF(&conn->proto.ftpc.pp, "PRET RETR %s", conn->proto.ftpc.file); - } - state(conn, FTP_PRET); - } - else { - result = ftp_state_use_pasv(conn); - } - } - return result; -} - -static CURLcode ftp_state_rest(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct FTP *ftp = conn->data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if((ftp->transfer != FTPTRANSFER_BODY) && ftpc->file) { - /* if a "head"-like request is being made (on a file) */ - - /* Determine if server can respond to REST command and therefore - whether it supports range */ - PPSENDF(&conn->proto.ftpc.pp, "REST %d", 0); - - state(conn, FTP_REST); - } - else - result = ftp_state_prepare_transfer(conn); - - return result; -} - -static CURLcode ftp_state_size(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct FTP *ftp = conn->data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if((ftp->transfer == FTPTRANSFER_INFO) && ftpc->file) { - /* if a "head"-like request is being made (on a file) */ - - /* we know ftpc->file is a valid pointer to a file name */ - PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); - - state(conn, FTP_SIZE); - } - else - result = ftp_state_rest(conn); - - return result; -} - -static CURLcode ftp_state_list(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - /* If this output is to be machine-parsed, the NLST command might be better - to use, since the LIST command output is not specified or standard in any - way. It has turned out that the NLST list output is not the same on all - servers either... */ - - /* - if FTPFILE_NOCWD was specified, we are currently in - the user's home directory, so we should add the path - as argument for the LIST / NLST / or custom command. - Whether the server will support this, is uncertain. - - The other ftp_filemethods will CWD into dir/dir/ first and - then just do LIST (in that case: nothing to do here) - */ - char *cmd, *lstArg, *slashPos; - - lstArg = NULL; - if((data->set.ftp_filemethod == FTPFILE_NOCWD) && - data->state.path && - data->state.path[0] && - strchr(data->state.path, '/')) { - - lstArg = strdup(data->state.path); - if(!lstArg) - return CURLE_OUT_OF_MEMORY; - - /* Check if path does not end with /, as then we cut off the file part */ - if(lstArg[strlen(lstArg) - 1] != '/') { - - /* chop off the file part if format is dir/dir/file */ - slashPos = strrchr(lstArg, '/'); - if(slashPos) - *(slashPos+1) = '\0'; - } - } - - cmd = aprintf("%s%s%s", - data->set.str[STRING_CUSTOMREQUEST]? - data->set.str[STRING_CUSTOMREQUEST]: - (data->set.ftp_list_only?"NLST":"LIST"), - lstArg? " ": "", - lstArg? lstArg: ""); - - if(!cmd) { - free(lstArg); - return CURLE_OUT_OF_MEMORY; - } - - result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", cmd); - - free(lstArg); - free(cmd); - - if(result) - return result; - - state(conn, FTP_LIST); - - return result; -} - -static CURLcode ftp_state_retr_prequote(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* We've sent the TYPE, now we must send the list of prequote strings */ - - result = ftp_state_quote(conn, TRUE, FTP_RETR_PREQUOTE); - - return result; -} - -static CURLcode ftp_state_stor_prequote(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* We've sent the TYPE, now we must send the list of prequote strings */ - - result = ftp_state_quote(conn, TRUE, FTP_STOR_PREQUOTE); - - return result; -} - -static CURLcode ftp_state_type(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct FTP *ftp = conn->data->req.protop; - struct SessionHandle *data = conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - /* If we have selected NOBODY and HEADER, it means that we only want file - information. Which in FTP can't be much more than the file size and - date. */ - if(data->set.opt_no_body && ftpc->file && - ftp_need_type(conn, data->set.prefer_ascii)) { - /* The SIZE command is _not_ RFC 959 specified, and therefor many servers - may not support it! It is however the only way we have to get a file's - size! */ - - ftp->transfer = FTPTRANSFER_INFO; - /* this means no actual transfer will be made */ - - /* Some servers return different sizes for different modes, and thus we - must set the proper type before we check the size */ - result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_TYPE); - if(result) - return result; - } - else - result = ftp_state_size(conn); - - return result; -} - -/* This is called after the CWD commands have been done in the beginning of - the DO phase */ -static CURLcode ftp_state_mdtm(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - /* Requested time of file or time-depended transfer? */ - if((data->set.get_filetime || data->set.timecondition) && ftpc->file) { - - /* we have requested to get the modified-time of the file, this is a white - spot as the MDTM is not mentioned in RFC959 */ - PPSENDF(&ftpc->pp, "MDTM %s", ftpc->file); - - state(conn, FTP_MDTM); - } - else - result = ftp_state_type(conn); - - return result; -} - - -/* This is called after the TYPE and possible quote commands have been sent */ -static CURLcode ftp_state_ul_setup(struct connectdata *conn, - bool sizechecked) -{ - CURLcode result = CURLE_OK; - struct FTP *ftp = conn->data->req.protop; - struct SessionHandle *data = conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - int seekerr = CURL_SEEKFUNC_OK; - - if((data->state.resume_from && !sizechecked) || - ((data->state.resume_from > 0) && sizechecked)) { - /* we're about to continue the uploading of a file */ - /* 1. get already existing file's size. We use the SIZE command for this - which may not exist in the server! The SIZE command is not in - RFC959. */ - - /* 2. This used to set REST. But since we can do append, we - don't another ftp command. We just skip the source file - offset and then we APPEND the rest on the file instead */ - - /* 3. pass file-size number of bytes in the source file */ - /* 4. lower the infilesize counter */ - /* => transfer as usual */ - - if(data->state.resume_from < 0) { - /* Got no given size to start from, figure it out */ - PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); - state(conn, FTP_STOR_SIZE); - return result; - } - - /* enable append */ - data->set.ftp_append = TRUE; - - /* Let's read off the proper amount of bytes from the input. */ - if(conn->seek_func) { - seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, - SEEK_SET); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_FTP_COULDNT_USE_REST; - } - /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ - else { - curl_off_t passed=0; - do { - size_t readthisamountnow = - (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? - BUFSIZE : curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread = - data->state.fread_func(data->state.buffer, 1, readthisamountnow, - data->state.in); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Failed to read data"); - return CURLE_FTP_COULDNT_USE_REST; - } - } while(passed < data->state.resume_from); - } - } - /* now, decrease the size of the read */ - if(data->state.infilesize>0) { - data->state.infilesize -= data->state.resume_from; - - if(data->state.infilesize <= 0) { - infof(data, "File already completely uploaded\n"); - - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - - /* Set ->transfer so that we won't get any error in - * ftp_done() because we didn't transfer anything! */ - ftp->transfer = FTPTRANSFER_NONE; - - state(conn, FTP_STOP); - return CURLE_OK; - } - } - /* we've passed, proceed as normal */ - } /* resume_from */ - - PPSENDF(&ftpc->pp, data->set.ftp_append?"APPE %s":"STOR %s", - ftpc->file); - - state(conn, FTP_STOR); - - return result; -} - -static CURLcode ftp_state_quote(struct connectdata *conn, - bool init, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct FTP *ftp = data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - bool quote=FALSE; - struct curl_slist *item; - - switch(instate) { - case FTP_QUOTE: - default: - item = data->set.quote; - break; - case FTP_RETR_PREQUOTE: - case FTP_STOR_PREQUOTE: - item = data->set.prequote; - break; - case FTP_POSTQUOTE: - item = data->set.postquote; - break; - } - - /* - * This state uses: - * 'count1' to iterate over the commands to send - * 'count2' to store wether to allow commands to fail - */ - - if(init) - ftpc->count1 = 0; - else - ftpc->count1++; - - if(item) { - int i = 0; - - /* Skip count1 items in the linked list */ - while((i< ftpc->count1) && item) { - item = item->next; - i++; - } - if(item) { - char *cmd = item->data; - if(cmd[0] == '*') { - cmd++; - ftpc->count2 = 1; /* the sent command is allowed to fail */ - } - else - ftpc->count2 = 0; /* failure means cancel operation */ - - PPSENDF(&ftpc->pp, "%s", cmd); - state(conn, instate); - quote = TRUE; - } - } - - if(!quote) { - /* No more quote to send, continue to ... */ - switch(instate) { - case FTP_QUOTE: - default: - result = ftp_state_cwd(conn); - break; - case FTP_RETR_PREQUOTE: - if(ftp->transfer != FTPTRANSFER_BODY) - state(conn, FTP_STOP); - else { - if(ftpc->known_filesize != -1) { - Curl_pgrsSetDownloadSize(data, ftpc->known_filesize); - result = ftp_state_retr(conn, ftpc->known_filesize); - } - else { - if(data->set.ignorecl) { - /* This code is to support download of growing files. It prevents - the state machine from requesting the file size from the - server. With an unknown file size the download continues until - the server terminates it, otherwise the client stops if the - received byte count exceeds the reported file size. Set option - CURLOPT_IGNORE_CONTENT_LENGTH to 1 to enable this behavior.*/ - PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); - state(conn, FTP_RETR); - } - else { - PPSENDF(&ftpc->pp, "SIZE %s", ftpc->file); - state(conn, FTP_RETR_SIZE); - } - } - } - break; - case FTP_STOR_PREQUOTE: - result = ftp_state_ul_setup(conn, FALSE); - break; - case FTP_POSTQUOTE: - break; - } - } - - return result; -} - -/* called from ftp_state_pasv_resp to switch to PASV in case of EPSV - problems */ -static CURLcode ftp_epsv_disable(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - if(conn->bits.ipv6) { - /* We can't disable EPSV when doing IPv6, so this is instead a fail */ - failf(conn->data, "Failed EPSV attempt, exiting\n"); - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - - infof(conn->data, "Failed EPSV attempt. Disabling EPSV\n"); - /* disable it for next transfer */ - conn->bits.ftp_use_epsv = FALSE; - conn->data->state.errorbuf = FALSE; /* allow error message to get - rewritten */ - PPSENDF(&conn->proto.ftpc.pp, "%s", "PASV"); - conn->proto.ftpc.count1++; - /* remain in/go to the FTP_PASV state */ - state(conn, FTP_PASV); - return result; -} - -/* - * Perform the necessary magic that needs to be done once the TCP connection - * to the proxy has completed. - */ -static CURLcode proxy_magic(struct connectdata *conn, - char *newhost, unsigned short newport, - bool *magicdone) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - -#if defined(CURL_DISABLE_PROXY) - (void) newhost; - (void) newport; -#endif - - *magicdone = FALSE; - - switch(conn->proxytype) { - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: - result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, newhost, - newport, SECONDARYSOCKET, conn); - *magicdone = TRUE; - break; - case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, newhost, newport, - SECONDARYSOCKET, conn, FALSE); - *magicdone = TRUE; - break; - case CURLPROXY_SOCKS4A: - result = Curl_SOCKS4(conn->proxyuser, newhost, newport, - SECONDARYSOCKET, conn, TRUE); - *magicdone = TRUE; - break; - case CURLPROXY_HTTP: - case CURLPROXY_HTTP_1_0: - /* do nothing here. handled later. */ - break; - default: - failf(data, "unknown proxytype option given"); - result = CURLE_COULDNT_CONNECT; - break; - } - - if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { - /* BLOCKING */ - /* We want "seamless" FTP operations through HTTP proxy tunnel */ - - /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the - * member conn->proto.http; we want FTP through HTTP and we have to - * change the member temporarily for connecting to the HTTP proxy. After - * Curl_proxyCONNECT we have to set back the member to the original - * struct FTP pointer - */ - struct HTTP http_proxy; - struct FTP *ftp_save = data->req.protop; - memset(&http_proxy, 0, sizeof(http_proxy)); - data->req.protop = &http_proxy; - - result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, newhost, newport, TRUE); - - data->req.protop = ftp_save; - - if(result) - return result; - - if(conn->tunnel_state[SECONDARYSOCKET] != TUNNEL_COMPLETE) { - /* the CONNECT procedure is not complete, the tunnel is not yet up */ - state(conn, FTP_STOP); /* this phase is completed */ - return result; - } - else - *magicdone = TRUE; - } - - return result; -} - -static char *control_address(struct connectdata *conn) -{ - /* Returns the control connection IP address. - If a proxy tunnel is used, returns the original host name instead, because - the effective control connection address is the proxy address, - not the ftp host. */ - if(conn->bits.tunnel_proxy || - conn->proxytype == CURLPROXY_SOCKS5 || - conn->proxytype == CURLPROXY_SOCKS5_HOSTNAME || - conn->proxytype == CURLPROXY_SOCKS4 || - conn->proxytype == CURLPROXY_SOCKS4A) - return conn->host.name; - - return conn->ip_addr_str; -} - -static CURLcode ftp_state_pasv_resp(struct connectdata *conn, - int ftpcode) -{ - struct ftp_conn *ftpc = &conn->proto.ftpc; - CURLcode result; - struct SessionHandle *data=conn->data; - struct Curl_dns_entry *addr=NULL; - int rc; - unsigned short connectport; /* the local port connect() should use! */ - char *str=&data->state.buffer[4]; /* start on the first letter */ - - /* if we come here again, make sure the former name is cleared */ - Curl_safefree(ftpc->newhost); - - if((ftpc->count1 == 0) && - (ftpcode == 229)) { - /* positive EPSV response */ - char *ptr = strchr(str, '('); - if(ptr) { - unsigned int num; - char separator[4]; - ptr++; - if(5 == sscanf(ptr, "%c%c%c%u%c", - &separator[0], - &separator[1], - &separator[2], - &num, - &separator[3])) { - const char sep1 = separator[0]; - int i; - - /* The four separators should be identical, or else this is an oddly - formatted reply and we bail out immediately. */ - for(i=1; i<4; i++) { - if(separator[i] != sep1) { - ptr=NULL; /* set to NULL to signal error */ - break; - } - } - if(num > 0xffff) { - failf(data, "Illegal port number in EPSV reply"); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - if(ptr) { - ftpc->newport = (unsigned short)(num & 0xffff); - ftpc->newhost = strdup(control_address(conn)); - if(!ftpc->newhost) - return CURLE_OUT_OF_MEMORY; - } - } - else - ptr=NULL; - } - if(!ptr) { - failf(data, "Weirdly formatted EPSV reply"); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - } - else if((ftpc->count1 == 1) && - (ftpcode == 227)) { - /* positive PASV response */ - int ip[4]; - int port[2]; - - /* - * Scan for a sequence of six comma-separated numbers and use them as - * IP+port indicators. - * - * Found reply-strings include: - * "227 Entering Passive Mode (127,0,0,1,4,51)" - * "227 Data transfer will passively listen to 127,0,0,1,4,51" - * "227 Entering passive mode. 127,0,0,1,4,51" - */ - while(*str) { - if(6 == sscanf(str, "%d,%d,%d,%d,%d,%d", - &ip[0], &ip[1], &ip[2], &ip[3], - &port[0], &port[1])) - break; - str++; - } - - if(!*str) { - failf(data, "Couldn't interpret the 227-response"); - return CURLE_FTP_WEIRD_227_FORMAT; - } - - /* we got OK from server */ - if(data->set.ftp_skip_ip) { - /* told to ignore the remotely given IP but instead use the host we used - for the control connection */ - infof(data, "Skip %d.%d.%d.%d for data connection, re-use %s instead\n", - ip[0], ip[1], ip[2], ip[3], - conn->host.name); - ftpc->newhost = strdup(control_address(conn)); - } - else - ftpc->newhost = aprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); - - if(!ftpc->newhost) - return CURLE_OUT_OF_MEMORY; - - ftpc->newport = (unsigned short)(((port[0]<<8) + port[1]) & 0xffff); - } - else if(ftpc->count1 == 0) { - /* EPSV failed, move on to PASV */ - return ftp_epsv_disable(conn); - } - else { - failf(data, "Bad PASV/EPSV response: %03d", ftpcode); - return CURLE_FTP_WEIRD_PASV_REPLY; - } - - if(conn->bits.proxy) { - /* - * This connection uses a proxy and we need to connect to the proxy again - * here. We don't want to rely on a former host lookup that might've - * expired now, instead we remake the lookup here and now! - */ - rc = Curl_resolv(conn, conn->proxy.name, (int)conn->port, &addr); - if(rc == CURLRESOLV_PENDING) - /* BLOCKING, ignores the return code but 'addr' will be NULL in - case of failure */ - (void)Curl_resolver_wait_resolv(conn, &addr); - - connectport = - (unsigned short)conn->port; /* we connect to the proxy's port */ - - if(!addr) { - failf(data, "Can't resolve proxy host %s:%hu", - conn->proxy.name, connectport); - return CURLE_FTP_CANT_GET_HOST; - } - } - else { - /* normal, direct, ftp connection */ - rc = Curl_resolv(conn, ftpc->newhost, ftpc->newport, &addr); - if(rc == CURLRESOLV_PENDING) - /* BLOCKING */ - (void)Curl_resolver_wait_resolv(conn, &addr); - - connectport = ftpc->newport; /* we connect to the remote port */ - - if(!addr) { - failf(data, "Can't resolve new host %s:%hu", ftpc->newhost, connectport); - return CURLE_FTP_CANT_GET_HOST; - } - } - - conn->bits.tcpconnect[SECONDARYSOCKET] = FALSE; - result = Curl_connecthost(conn, addr); - - if(result) { - Curl_resolv_unlock(data, addr); /* we're done using this address */ - if(ftpc->count1 == 0 && ftpcode == 229) - return ftp_epsv_disable(conn); - - return result; - } - - - /* - * When this is used from the multi interface, this might've returned with - * the 'connected' set to FALSE and thus we are now awaiting a non-blocking - * connect to connect. - */ - - if(data->set.verbose) - /* this just dumps information about this second connection */ - ftp_pasv_verbose(conn, addr->addr, ftpc->newhost, connectport); - - Curl_resolv_unlock(data, addr); /* we're done using this address */ - conn->bits.do_more = TRUE; - state(conn, FTP_STOP); /* this phase is completed */ - - return result; -} - -static CURLcode ftp_state_port_resp(struct connectdata *conn, - int ftpcode) -{ - struct SessionHandle *data = conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - ftpport fcmd = (ftpport)ftpc->count1; - CURLcode result = CURLE_OK; - - /* The FTP spec tells a positive response should have code 200. - Be more permissive here to tolerate deviant servers. */ - if(ftpcode / 100 != 2) { - /* the command failed */ - - if(EPRT == fcmd) { - infof(data, "disabling EPRT usage\n"); - conn->bits.ftp_use_eprt = FALSE; - } - fcmd++; - - if(fcmd == DONE) { - failf(data, "Failed to do PORT"); - result = CURLE_FTP_PORT_FAILED; - } - else - /* try next */ - result = ftp_state_use_port(conn, fcmd); - } - else { - infof(data, "Connect data stream actively\n"); - state(conn, FTP_STOP); /* end of DO phase */ - result = ftp_dophase_done(conn, FALSE); - } - - return result; -} - -static CURLcode ftp_state_mdtm_resp(struct connectdata *conn, - int ftpcode) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data=conn->data; - struct FTP *ftp = data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - switch(ftpcode) { - case 213: - { - /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the - last .sss part is optional and means fractions of a second */ - int year, month, day, hour, minute, second; - char *buf = data->state.buffer; - if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d", - &year, &month, &day, &hour, &minute, &second)) { - /* we have a time, reformat it */ - time_t secs=time(NULL); - /* using the good old yacc/bison yuck */ - snprintf(buf, sizeof(conn->data->state.buffer), - "%04d%02d%02d %02d:%02d:%02d GMT", - year, month, day, hour, minute, second); - /* now, convert this into a time() value: */ - data->info.filetime = (long)curl_getdate(buf, &secs); - } - -#ifdef CURL_FTP_HTTPSTYLE_HEAD - /* If we asked for a time of the file and we actually got one as well, - we "emulate" a HTTP-style header in our output. */ - - if(data->set.opt_no_body && - ftpc->file && - data->set.get_filetime && - (data->info.filetime>=0) ) { - time_t filetime = (time_t)data->info.filetime; - struct tm buffer; - const struct tm *tm = &buffer; - - result = Curl_gmtime(filetime, &buffer); - if(result) - return result; - - /* format: "Tue, 15 Nov 1994 12:45:26" */ - snprintf(buf, BUFSIZE-1, - "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", - Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); - if(result) - return result; - } /* end of a ridiculous amount of conditionals */ -#endif - } - break; - default: - infof(data, "unsupported MDTM reply format\n"); - break; - case 550: /* "No such file or directory" */ - failf(data, "Given file does not exist"); - result = CURLE_FTP_COULDNT_RETR_FILE; - break; - } - - if(data->set.timecondition) { - if((data->info.filetime > 0) && (data->set.timevalue > 0)) { - switch(data->set.timecondition) { - case CURL_TIMECOND_IFMODSINCE: - default: - if(data->info.filetime <= data->set.timevalue) { - infof(data, "The requested document is not new enough\n"); - ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ - data->info.timecond = TRUE; - state(conn, FTP_STOP); - return CURLE_OK; - } - break; - case CURL_TIMECOND_IFUNMODSINCE: - if(data->info.filetime > data->set.timevalue) { - infof(data, "The requested document is not old enough\n"); - ftp->transfer = FTPTRANSFER_NONE; /* mark to not transfer data */ - data->info.timecond = TRUE; - state(conn, FTP_STOP); - return CURLE_OK; - } - break; - } /* switch */ - } - else { - infof(data, "Skipping time comparison\n"); - } - } - - if(!result) - result = ftp_state_type(conn); - - return result; -} - -static CURLcode ftp_state_type_resp(struct connectdata *conn, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data=conn->data; - - if(ftpcode/100 != 2) { - /* "sasserftpd" and "(u)r(x)bot ftpd" both responds with 226 after a - successful 'TYPE I'. While that is not as RFC959 says, it is still a - positive response code and we allow that. */ - failf(data, "Couldn't set desired mode"); - return CURLE_FTP_COULDNT_SET_TYPE; - } - if(ftpcode != 200) - infof(data, "Got a %03d response code instead of the assumed 200\n", - ftpcode); - - if(instate == FTP_TYPE) - result = ftp_state_size(conn); - else if(instate == FTP_LIST_TYPE) - result = ftp_state_list(conn); - else if(instate == FTP_RETR_TYPE) - result = ftp_state_retr_prequote(conn); - else if(instate == FTP_STOR_TYPE) - result = ftp_state_stor_prequote(conn); - - return result; -} - -static CURLcode ftp_state_retr(struct connectdata *conn, - curl_off_t filesize) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data=conn->data; - struct FTP *ftp = data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if(data->set.max_filesize && (filesize > data->set.max_filesize)) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - ftp->downloadsize = filesize; - - if(data->state.resume_from) { - /* We always (attempt to) get the size of downloads, so it is done before - this even when not doing resumes. */ - if(filesize == -1) { - infof(data, "ftp server doesn't support SIZE\n"); - /* We couldn't get the size and therefore we can't know if there really - is a part of the file left to get, although the server will just - close the connection when we start the connection so it won't cause - us any harm, just not make us exit as nicely. */ - } - else { - /* We got a file size report, so we check that there actually is a - part of the file left to get, or else we go home. */ - if(data->state.resume_from< 0) { - /* We're supposed to download the last abs(from) bytes */ - if(filesize < -data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* convert to size to download */ - ftp->downloadsize = -data->state.resume_from; - /* download from where? */ - data->state.resume_from = filesize - ftp->downloadsize; - } - else { - if(filesize < data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* Now store the number of bytes we are expected to download */ - ftp->downloadsize = filesize-data->state.resume_from; - } - } - - if(ftp->downloadsize == 0) { - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - infof(data, "File already completely downloaded\n"); - - /* Set ->transfer so that we won't get any error in ftp_done() - * because we didn't transfer the any file */ - ftp->transfer = FTPTRANSFER_NONE; - state(conn, FTP_STOP); - return CURLE_OK; - } - - /* Set resume file transfer offset */ - infof(data, "Instructs server to resume from offset %" - CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); - - PPSENDF(&ftpc->pp, "REST %" CURL_FORMAT_CURL_OFF_T, - data->state.resume_from); - - state(conn, FTP_RETR_REST); - } - else { - /* no resume */ - PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); - state(conn, FTP_RETR); - } - - return result; -} - -static CURLcode ftp_state_size_resp(struct connectdata *conn, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data=conn->data; - curl_off_t filesize; - char *buf = data->state.buffer; - - /* get the size from the ascii string: */ - filesize = (ftpcode == 213)?curlx_strtoofft(buf+4, NULL, 0):-1; - - if(instate == FTP_SIZE) { -#ifdef CURL_FTP_HTTPSTYLE_HEAD - if(-1 != filesize) { - snprintf(buf, sizeof(data->state.buffer), - "Content-Length: %" CURL_FORMAT_CURL_OFF_T "\r\n", filesize); - result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0); - if(result) - return result; - } -#endif - Curl_pgrsSetDownloadSize(data, filesize); - result = ftp_state_rest(conn); - } - else if(instate == FTP_RETR_SIZE) { - Curl_pgrsSetDownloadSize(data, filesize); - result = ftp_state_retr(conn, filesize); - } - else if(instate == FTP_STOR_SIZE) { - data->state.resume_from = filesize; - result = ftp_state_ul_setup(conn, TRUE); - } - - return result; -} - -static CURLcode ftp_state_rest_resp(struct connectdata *conn, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - switch(instate) { - case FTP_REST: - default: -#ifdef CURL_FTP_HTTPSTYLE_HEAD - if(ftpcode == 350) { - char buffer[24]= { "Accept-ranges: bytes\r\n" }; - result = Curl_client_write(conn, CLIENTWRITE_BOTH, buffer, 0); - if(result) - return result; - } -#endif - result = ftp_state_prepare_transfer(conn); - break; - - case FTP_RETR_REST: - if(ftpcode != 350) { - failf(conn->data, "Couldn't use REST"); - result = CURLE_FTP_COULDNT_USE_REST; - } - else { - PPSENDF(&ftpc->pp, "RETR %s", ftpc->file); - state(conn, FTP_RETR); - } - break; - } - - return result; -} - -static CURLcode ftp_state_stor_resp(struct connectdata *conn, - int ftpcode, ftpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - if(ftpcode>=400) { - failf(data, "Failed FTP upload: %0d", ftpcode); - state(conn, FTP_STOP); - /* oops, we never close the sockets! */ - return CURLE_UPLOAD_FAILED; - } - - conn->proto.ftpc.state_saved = instate; - - /* PORT means we are now awaiting the server to connect to us. */ - if(data->set.ftp_use_port) { - bool connected; - - state(conn, FTP_STOP); /* no longer in STOR state */ - - result = AllowServerConnect(conn, &connected); - if(result) - return result; - - if(!connected) { - struct ftp_conn *ftpc = &conn->proto.ftpc; - infof(data, "Data conn was not available immediately\n"); - ftpc->wait_data_conn = TRUE; - } - - return CURLE_OK; - } - else - return InitiateTransfer(conn); -} - -/* for LIST and RETR responses */ -static CURLcode ftp_state_get_resp(struct connectdata *conn, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct FTP *ftp = data->req.protop; - char *buf = data->state.buffer; - - if((ftpcode == 150) || (ftpcode == 125)) { - - /* - A; - 150 Opening BINARY mode data connection for /etc/passwd (2241 - bytes). (ok, the file is being transferred) - - B: - 150 Opening ASCII mode data connection for /bin/ls - - C: - 150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes). - - D: - 150 Opening ASCII mode data connection for [file] (0.0.0.0,0) (545 bytes) - - E: - 125 Data connection already open; Transfer starting. */ - - curl_off_t size=-1; /* default unknown size */ - - - /* - * It appears that there are FTP-servers that return size 0 for files when - * SIZE is used on the file while being in BINARY mode. To work around - * that (stupid) behavior, we attempt to parse the RETR response even if - * the SIZE returned size zero. - * - * Debugging help from Salvatore Sorrentino on February 26, 2003. - */ - - if((instate != FTP_LIST) && - !data->set.prefer_ascii && - (ftp->downloadsize < 1)) { - /* - * It seems directory listings either don't show the size or very - * often uses size 0 anyway. ASCII transfers may very well turn out - * that the transferred amount of data is not the same as this line - * tells, why using this number in those cases only confuses us. - * - * Example D above makes this parsing a little tricky */ - char *bytes; - bytes=strstr(buf, " bytes"); - if(bytes--) { - long in=(long)(bytes-buf); - /* this is a hint there is size information in there! ;-) */ - while(--in) { - /* scan for the left parenthesis and break there */ - if('(' == *bytes) - break; - /* skip only digits */ - if(!ISDIGIT(*bytes)) { - bytes=NULL; - break; - } - /* one more estep backwards */ - bytes--; - } - /* if we have nothing but digits: */ - if(bytes++) { - /* get the number! */ - size = curlx_strtoofft(bytes, NULL, 0); - } - } - } - else if(ftp->downloadsize > -1) - size = ftp->downloadsize; - - if(size > data->req.maxdownload && data->req.maxdownload > 0) - size = data->req.size = data->req.maxdownload; - else if((instate != FTP_LIST) && (data->set.prefer_ascii)) - size = -1; /* kludge for servers that understate ASCII mode file size */ - - infof(data, "Maxdownload = %" CURL_FORMAT_CURL_OFF_T "\n", - data->req.maxdownload); - - if(instate != FTP_LIST) - infof(data, "Getting file with size: %" CURL_FORMAT_CURL_OFF_T "\n", - size); - - /* FTP download: */ - conn->proto.ftpc.state_saved = instate; - conn->proto.ftpc.retr_size_saved = size; - - if(data->set.ftp_use_port) { - bool connected; - - result = AllowServerConnect(conn, &connected); - if(result) - return result; - - if(!connected) { - struct ftp_conn *ftpc = &conn->proto.ftpc; - infof(data, "Data conn was not available immediately\n"); - state(conn, FTP_STOP); - ftpc->wait_data_conn = TRUE; - } - } - else - return InitiateTransfer(conn); - } - else { - if((instate == FTP_LIST) && (ftpcode == 450)) { - /* simply no matching files in the dir listing */ - ftp->transfer = FTPTRANSFER_NONE; /* don't download anything */ - state(conn, FTP_STOP); /* this phase is over */ - } - else { - failf(data, "RETR response: %03d", ftpcode); - return instate == FTP_RETR && ftpcode == 550? - CURLE_REMOTE_FILE_NOT_FOUND: - CURLE_FTP_COULDNT_RETR_FILE; - } - } - - return result; -} - -/* after USER, PASS and ACCT */ -static CURLcode ftp_state_loggedin(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - if(conn->ssl[FIRSTSOCKET].use) { - /* PBSZ = PROTECTION BUFFER SIZE. - - The 'draft-murray-auth-ftp-ssl' (draft 12, page 7) says: - - Specifically, the PROT command MUST be preceded by a PBSZ - command and a PBSZ command MUST be preceded by a successful - security data exchange (the TLS negotiation in this case) - - ... (and on page 8): - - Thus the PBSZ command must still be issued, but must have a - parameter of '0' to indicate that no buffering is taking place - and the data connection should not be encapsulated. - */ - PPSENDF(&conn->proto.ftpc.pp, "PBSZ %d", 0); - state(conn, FTP_PBSZ); - } - else { - result = ftp_state_pwd(conn); - } - return result; -} - -/* for USER and PASS responses */ -static CURLcode ftp_state_user_resp(struct connectdata *conn, - int ftpcode, - ftpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct FTP *ftp = data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - (void)instate; /* no use for this yet */ - - /* some need password anyway, and others just return 2xx ignored */ - if((ftpcode == 331) && (ftpc->state == FTP_USER)) { - /* 331 Password required for ... - (the server requires to send the user's password too) */ - PPSENDF(&ftpc->pp, "PASS %s", ftp->passwd?ftp->passwd:""); - state(conn, FTP_PASS); - } - else if(ftpcode/100 == 2) { - /* 230 User ... logged in. - (the user logged in with or without password) */ - result = ftp_state_loggedin(conn); - } - else if(ftpcode == 332) { - if(data->set.str[STRING_FTP_ACCOUNT]) { - PPSENDF(&ftpc->pp, "ACCT %s", data->set.str[STRING_FTP_ACCOUNT]); - state(conn, FTP_ACCT); - } - else { - failf(data, "ACCT requested but none available"); - result = CURLE_LOGIN_DENIED; - } - } - else { - /* All other response codes, like: - - 530 User ... access denied - (the server denies to log the specified user) */ - - if(conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER] && - !conn->data->state.ftp_trying_alternative) { - /* Ok, USER failed. Let's try the supplied command. */ - PPSENDF(&conn->proto.ftpc.pp, "%s", - conn->data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]); - conn->data->state.ftp_trying_alternative = TRUE; - state(conn, FTP_USER); - result = CURLE_OK; - } - else { - failf(data, "Access denied: %03d", ftpcode); - result = CURLE_LOGIN_DENIED; - } - } - return result; -} - -/* for ACCT response */ -static CURLcode ftp_state_acct_resp(struct connectdata *conn, - int ftpcode) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - if(ftpcode != 230) { - failf(data, "ACCT rejected by server: %03d", ftpcode); - result = CURLE_FTP_WEIRD_PASS_REPLY; /* FIX */ - } - else - result = ftp_state_loggedin(conn); - - return result; -} - - -static CURLcode ftp_statemach_act(struct connectdata *conn) -{ - CURLcode result; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - struct SessionHandle *data=conn->data; - int ftpcode; - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - static const char ftpauth[][4] = { "SSL", "TLS" }; - size_t nread = 0; - - if(pp->sendleft) - return Curl_pp_flushsend(pp); - - result = ftp_readresp(sock, pp, &ftpcode, &nread); - if(result) - return result; - - if(ftpcode) { - /* we have now received a full FTP server response */ - switch(ftpc->state) { - case FTP_WAIT220: - if(ftpcode == 230) - /* 230 User logged in - already! */ - return ftp_state_user_resp(conn, ftpcode, ftpc->state); - else if(ftpcode != 220) { - failf(data, "Got a %03d ftp-server response when 220 was expected", - ftpcode); - return CURLE_FTP_WEIRD_SERVER_REPLY; - } - - /* We have received a 220 response fine, now we proceed. */ -#ifdef HAVE_GSSAPI - if(data->set.krb) { - /* If not anonymous login, try a secure login. Note that this - procedure is still BLOCKING. */ - - Curl_sec_request_prot(conn, "private"); - /* We set private first as default, in case the line below fails to - set a valid level */ - Curl_sec_request_prot(conn, data->set.str[STRING_KRB_LEVEL]); - - if(Curl_sec_login(conn)) - infof(data, "Logging in with password in cleartext!\n"); - else - infof(data, "Authentication successful\n"); - } -#endif - - if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { - /* We don't have a SSL/TLS connection yet, but FTPS is - requested. Try a FTPS connection now */ - - ftpc->count3=0; - switch(data->set.ftpsslauth) { - case CURLFTPAUTH_DEFAULT: - case CURLFTPAUTH_SSL: - ftpc->count2 = 1; /* add one to get next */ - ftpc->count1 = 0; - break; - case CURLFTPAUTH_TLS: - ftpc->count2 = -1; /* subtract one to get next */ - ftpc->count1 = 1; - break; - default: - failf(data, "unsupported parameter to CURLOPT_FTPSSLAUTH: %d", - (int)data->set.ftpsslauth); - return CURLE_UNKNOWN_OPTION; /* we don't know what to do */ - } - PPSENDF(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); - state(conn, FTP_AUTH); - } - else { - result = ftp_state_user(conn); - if(result) - return result; - } - - break; - - case FTP_AUTH: - /* we have gotten the response to a previous AUTH command */ - - /* RFC2228 (page 5) says: - * - * If the server is willing to accept the named security mechanism, - * and does not require any security data, it must respond with - * reply code 234/334. - */ - - if((ftpcode == 234) || (ftpcode == 334)) { - /* Curl_ssl_connect is BLOCKING */ - result = Curl_ssl_connect(conn, FIRSTSOCKET); - if(!result) { - conn->ssl[SECONDARYSOCKET].use = FALSE; /* clear-text data */ - result = ftp_state_user(conn); - } - } - else if(ftpc->count3 < 1) { - ftpc->count3++; - ftpc->count1 += ftpc->count2; /* get next attempt */ - result = Curl_pp_sendf(&ftpc->pp, "AUTH %s", ftpauth[ftpc->count1]); - /* remain in this same state */ - } - else { - if(data->set.use_ssl > CURLUSESSL_TRY) - /* we failed and CURLUSESSL_CONTROL or CURLUSESSL_ALL is set */ - result = CURLE_USE_SSL_FAILED; - else - /* ignore the failure and continue */ - result = ftp_state_user(conn); - } - - if(result) - return result; - break; - - case FTP_USER: - case FTP_PASS: - result = ftp_state_user_resp(conn, ftpcode, ftpc->state); - break; - - case FTP_ACCT: - result = ftp_state_acct_resp(conn, ftpcode); - break; - - case FTP_PBSZ: - PPSENDF(&ftpc->pp, "PROT %c", - data->set.use_ssl == CURLUSESSL_CONTROL ? 'C' : 'P'); - state(conn, FTP_PROT); - - break; - - case FTP_PROT: - if(ftpcode/100 == 2) - /* We have enabled SSL for the data connection! */ - conn->ssl[SECONDARYSOCKET].use = - (data->set.use_ssl != CURLUSESSL_CONTROL) ? TRUE : FALSE; - /* FTP servers typically responds with 500 if they decide to reject - our 'P' request */ - else if(data->set.use_ssl > CURLUSESSL_CONTROL) - /* we failed and bails out */ - return CURLE_USE_SSL_FAILED; - - if(data->set.ftp_ccc) { - /* CCC - Clear Command Channel - */ - PPSENDF(&ftpc->pp, "%s", "CCC"); - state(conn, FTP_CCC); - } - else { - result = ftp_state_pwd(conn); - if(result) - return result; - } - break; - - case FTP_CCC: - if(ftpcode < 500) { - /* First shut down the SSL layer (note: this call will block) */ - result = Curl_ssl_shutdown(conn, FIRSTSOCKET); - - if(result) { - failf(conn->data, "Failed to clear the command channel (CCC)"); - return result; - } - } - - /* Then continue as normal */ - result = ftp_state_pwd(conn); - if(result) - return result; - break; - - case FTP_PWD: - if(ftpcode == 257) { - char *ptr=&data->state.buffer[4]; /* start on the first letter */ - char *dir; - char *store; - - dir = malloc(nread + 1); - if(!dir) - return CURLE_OUT_OF_MEMORY; - - /* Reply format is like - 257[rubbish]"" and the - RFC959 says - - The directory name can contain any character; embedded - double-quotes should be escaped by double-quotes (the - "quote-doubling" convention). - */ - - /* scan for the first double-quote for non-standard responses */ - while(ptr < &data->state.buffer[sizeof(data->state.buffer)] - && *ptr != '\n' && *ptr != '\0' && *ptr != '"') - ptr++; - - if('\"' == *ptr) { - /* it started good */ - ptr++; - for(store = dir; *ptr;) { - if('\"' == *ptr) { - if('\"' == ptr[1]) { - /* "quote-doubling" */ - *store = ptr[1]; - ptr++; - } - else { - /* end of path */ - *store = '\0'; /* zero terminate */ - break; /* get out of this loop */ - } - } - else - *store = *ptr; - store++; - ptr++; - } - - /* If the path name does not look like an absolute path (i.e.: it - does not start with a '/'), we probably need some server-dependent - adjustments. For example, this is the case when connecting to - an OS400 FTP server: this server supports two name syntaxes, - the default one being incompatible with standard pathes. In - addition, this server switches automatically to the regular path - syntax when one is encountered in a command: this results in - having an entrypath in the wrong syntax when later used in CWD. - The method used here is to check the server OS: we do it only - if the path name looks strange to minimize overhead on other - systems. */ - - if(!ftpc->server_os && dir[0] != '/') { - - result = Curl_pp_sendf(&ftpc->pp, "%s", "SYST"); - if(result) { - free(dir); - return result; - } - Curl_safefree(ftpc->entrypath); - ftpc->entrypath = dir; /* remember this */ - infof(data, "Entry path is '%s'\n", ftpc->entrypath); - /* also save it where getinfo can access it: */ - data->state.most_recent_ftp_entrypath = ftpc->entrypath; - state(conn, FTP_SYST); - break; - } - - Curl_safefree(ftpc->entrypath); - ftpc->entrypath = dir; /* remember this */ - infof(data, "Entry path is '%s'\n", ftpc->entrypath); - /* also save it where getinfo can access it: */ - data->state.most_recent_ftp_entrypath = ftpc->entrypath; - } - else { - /* couldn't get the path */ - free(dir); - infof(data, "Failed to figure out path\n"); - } - } - state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ - DEBUGF(infof(data, "protocol connect phase DONE\n")); - break; - - case FTP_SYST: - if(ftpcode == 215) { - char *ptr=&data->state.buffer[4]; /* start on the first letter */ - char *os; - char *store; - - os = malloc(nread + 1); - if(!os) - return CURLE_OUT_OF_MEMORY; - - /* Reply format is like - 215 - */ - while(*ptr == ' ') - ptr++; - for(store = os; *ptr && *ptr != ' ';) - *store++ = *ptr++; - *store = '\0'; /* zero terminate */ - - /* Check for special servers here. */ - - if(strequal(os, "OS/400")) { - /* Force OS400 name format 1. */ - result = Curl_pp_sendf(&ftpc->pp, "%s", "SITE NAMEFMT 1"); - if(result) { - free(os); - return result; - } - /* remember target server OS */ - Curl_safefree(ftpc->server_os); - ftpc->server_os = os; - state(conn, FTP_NAMEFMT); - break; - } - else { - /* Nothing special for the target server. */ - /* remember target server OS */ - Curl_safefree(ftpc->server_os); - ftpc->server_os = os; - } - } - else { - /* Cannot identify server OS. Continue anyway and cross fingers. */ - } - - state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ - DEBUGF(infof(data, "protocol connect phase DONE\n")); - break; - - case FTP_NAMEFMT: - if(ftpcode == 250) { - /* Name format change successful: reload initial path. */ - ftp_state_pwd(conn); - break; - } - - state(conn, FTP_STOP); /* we are done with the CONNECT phase! */ - DEBUGF(infof(data, "protocol connect phase DONE\n")); - break; - - case FTP_QUOTE: - case FTP_POSTQUOTE: - case FTP_RETR_PREQUOTE: - case FTP_STOR_PREQUOTE: - if((ftpcode >= 400) && !ftpc->count2) { - /* failure response code, and not allowed to fail */ - failf(conn->data, "QUOT command failed with %03d", ftpcode); - return CURLE_QUOTE_ERROR; - } - result = ftp_state_quote(conn, FALSE, ftpc->state); - if(result) - return result; - - break; - - case FTP_CWD: - if(ftpcode/100 != 2) { - /* failure to CWD there */ - if(conn->data->set.ftp_create_missing_dirs && - ftpc->count1 && !ftpc->count2) { - /* try making it */ - ftpc->count2++; /* counter to prevent CWD-MKD loops */ - PPSENDF(&ftpc->pp, "MKD %s", ftpc->dirs[ftpc->count1 - 1]); - state(conn, FTP_MKD); - } - else { - /* return failure */ - failf(data, "Server denied you to change to the given directory"); - ftpc->cwdfail = TRUE; /* don't remember this path as we failed - to enter it */ - return CURLE_REMOTE_ACCESS_DENIED; - } - } - else { - /* success */ - ftpc->count2=0; - if(++ftpc->count1 <= ftpc->dirdepth) { - /* send next CWD */ - PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]); - } - else { - result = ftp_state_mdtm(conn); - if(result) - return result; - } - } - break; - - case FTP_MKD: - if((ftpcode/100 != 2) && !ftpc->count3--) { - /* failure to MKD the dir */ - failf(data, "Failed to MKD dir: %03d", ftpcode); - return CURLE_REMOTE_ACCESS_DENIED; - } - state(conn, FTP_CWD); - /* send CWD */ - PPSENDF(&ftpc->pp, "CWD %s", ftpc->dirs[ftpc->count1 - 1]); - break; - - case FTP_MDTM: - result = ftp_state_mdtm_resp(conn, ftpcode); - break; - - case FTP_TYPE: - case FTP_LIST_TYPE: - case FTP_RETR_TYPE: - case FTP_STOR_TYPE: - result = ftp_state_type_resp(conn, ftpcode, ftpc->state); - break; - - case FTP_SIZE: - case FTP_RETR_SIZE: - case FTP_STOR_SIZE: - result = ftp_state_size_resp(conn, ftpcode, ftpc->state); - break; - - case FTP_REST: - case FTP_RETR_REST: - result = ftp_state_rest_resp(conn, ftpcode, ftpc->state); - break; - - case FTP_PRET: - if(ftpcode != 200) { - /* there only is this one standard OK return code. */ - failf(data, "PRET command not accepted: %03d", ftpcode); - return CURLE_FTP_PRET_FAILED; - } - result = ftp_state_use_pasv(conn); - break; - - case FTP_PASV: - result = ftp_state_pasv_resp(conn, ftpcode); - break; - - case FTP_PORT: - result = ftp_state_port_resp(conn, ftpcode); - break; - - case FTP_LIST: - case FTP_RETR: - result = ftp_state_get_resp(conn, ftpcode, ftpc->state); - break; - - case FTP_STOR: - result = ftp_state_stor_resp(conn, ftpcode, ftpc->state); - break; - - case FTP_QUIT: - /* fallthrough, just stop! */ - default: - /* internal error */ - state(conn, FTP_STOP); - break; - } - } /* if(ftpcode) */ - - return result; -} - - -/* called repeatedly until done from multi.c */ -static CURLcode ftp_multi_statemach(struct connectdata *conn, - bool *done) -{ - struct ftp_conn *ftpc = &conn->proto.ftpc; - CURLcode result = Curl_pp_statemach(&ftpc->pp, FALSE); - - /* Check for the state outside of the Curl_socket_ready() return code checks - since at times we are in fact already in this state when this function - gets called. */ - *done = (ftpc->state == FTP_STOP) ? TRUE : FALSE; - - return result; -} - -static CURLcode ftp_block_statemach(struct connectdata *conn) -{ - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - CURLcode result = CURLE_OK; - - while(ftpc->state != FTP_STOP) { - result = Curl_pp_statemach(pp, TRUE); - if(result) - break; - } - - return result; -} - -/* - * ftp_connect() should do everything that is to be considered a part of - * the connection phase. - * - * The variable 'done' points to will be TRUE if the protocol-layer connect - * phase is done when this function returns, or FALSE if not. - * - */ -static CURLcode ftp_connect(struct connectdata *conn, - bool *done) /* see description above */ -{ - CURLcode result; - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - - *done = FALSE; /* default to not done yet */ - - /* We always support persistent connections on ftp */ - connkeep(conn, "FTP default"); - - pp->response_time = RESP_TIMEOUT; /* set default response time-out */ - pp->statemach_act = ftp_statemach_act; - pp->endofresp = ftp_endofresp; - pp->conn = conn; - - if(conn->handler->flags & PROTOPT_SSL) { - /* BLOCKING */ - result = Curl_ssl_connect(conn, FIRSTSOCKET); - if(result) - return result; - } - - Curl_pp_init(pp); /* init the generic pingpong data */ - - /* When we connect, we start in the state where we await the 220 - response */ - state(conn, FTP_WAIT220); - - result = ftp_multi_statemach(conn, done); - - return result; -} - -/*********************************************************************** - * - * ftp_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode ftp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - struct SessionHandle *data = conn->data; - struct FTP *ftp = data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - ssize_t nread; - int ftpcode; - CURLcode result = CURLE_OK; - bool was_ctl_valid = ftpc->ctl_valid; - char *path; - const char *path_to_use = data->state.path; - - if(!ftp) - return CURLE_OK; - - switch(status) { - case CURLE_BAD_DOWNLOAD_RESUME: - case CURLE_FTP_WEIRD_PASV_REPLY: - case CURLE_FTP_PORT_FAILED: - case CURLE_FTP_ACCEPT_FAILED: - case CURLE_FTP_ACCEPT_TIMEOUT: - case CURLE_FTP_COULDNT_SET_TYPE: - case CURLE_FTP_COULDNT_RETR_FILE: - case CURLE_PARTIAL_FILE: - case CURLE_UPLOAD_FAILED: - case CURLE_REMOTE_ACCESS_DENIED: - case CURLE_FILESIZE_EXCEEDED: - case CURLE_REMOTE_FILE_NOT_FOUND: - case CURLE_WRITE_ERROR: - /* the connection stays alive fine even though this happened */ - /* fall-through */ - case CURLE_OK: /* doesn't affect the control connection's status */ - if(!premature) { - ftpc->ctl_valid = was_ctl_valid; - break; - } - /* until we cope better with prematurely ended requests, let them - * fallback as if in complete failure */ - default: /* by default, an error means the control connection is - wedged and should not be used anymore */ - ftpc->ctl_valid = FALSE; - ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the - current path, as this connection is going */ - connclose(conn, "FTP ended with bad error code"); - result = status; /* use the already set error code */ - break; - } - - /* now store a copy of the directory we are in */ - free(ftpc->prevpath); - - if(data->set.wildcardmatch) { - if(data->set.chunk_end && ftpc->file) { - data->set.chunk_end(data->wildcard.customptr); - } - ftpc->known_filesize = -1; - } - - /* get the "raw" path */ - path = curl_easy_unescape(data, path_to_use, 0, NULL); - if(!path) { - /* out of memory, but we can limp along anyway (and should try to - * since we may already be in the out of memory cleanup path) */ - if(!result) - result = CURLE_OUT_OF_MEMORY; - ftpc->ctl_valid = FALSE; /* mark control connection as bad */ - connclose(conn, "FTP: out of memory!"); /* mark for connection closure */ - ftpc->prevpath = NULL; /* no path remembering */ - } - else { - size_t flen = ftpc->file?strlen(ftpc->file):0; /* file is "raw" already */ - size_t dlen = strlen(path)-flen; - if(!ftpc->cwdfail) { - if(dlen && (data->set.ftp_filemethod != FTPFILE_NOCWD)) { - ftpc->prevpath = path; - if(flen) - /* if 'path' is not the whole string */ - ftpc->prevpath[dlen]=0; /* terminate */ - } - else { - /* we never changed dir */ - ftpc->prevpath=strdup(""); - free(path); - } - if(ftpc->prevpath) - infof(data, "Remembering we are in dir \"%s\"\n", ftpc->prevpath); - } - else { - ftpc->prevpath = NULL; /* no path */ - free(path); - } - } - /* free the dir tree and file parts */ - freedirs(ftpc); - - /* shut down the socket to inform the server we're done */ - -#ifdef _WIN32_WCE - shutdown(conn->sock[SECONDARYSOCKET], 2); /* SD_BOTH */ -#endif - - if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) { - if(!result && ftpc->dont_check && data->req.maxdownload > 0) { - /* partial download completed */ - result = Curl_pp_sendf(pp, "%s", "ABOR"); - if(result) { - failf(data, "Failure sending ABOR command: %s", - curl_easy_strerror(result)); - ftpc->ctl_valid = FALSE; /* mark control connection as bad */ - connclose(conn, "ABOR command failed"); /* connection closure */ - } - } - - if(conn->ssl[SECONDARYSOCKET].use) { - /* The secondary socket is using SSL so we must close down that part - first before we close the socket for real */ - Curl_ssl_close(conn, SECONDARYSOCKET); - - /* Note that we keep "use" set to TRUE since that (next) connection is - still requested to use SSL */ - } - close_secondarysocket(conn); - } - - if(!result && (ftp->transfer == FTPTRANSFER_BODY) && ftpc->ctl_valid && - pp->pending_resp && !premature) { - /* - * Let's see what the server says about the transfer we just performed, - * but lower the timeout as sometimes this connection has died while the - * data has been transferred. This happens when doing through NATs etc that - * abandon old silent connections. - */ - long old_time = pp->response_time; - - pp->response_time = 60*1000; /* give it only a minute for now */ - pp->response = Curl_tvnow(); /* timeout relative now */ - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - - pp->response_time = old_time; /* set this back to previous value */ - - if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) { - failf(data, "control connection looks dead"); - ftpc->ctl_valid = FALSE; /* mark control connection as bad */ - connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */ - } - - if(result) - return result; - - if(ftpc->dont_check && data->req.maxdownload > 0) { - /* we have just sent ABOR and there is no reliable way to check if it was - * successful or not; we have to close the connection now */ - infof(data, "partial download completed, closing connection\n"); - connclose(conn, "Partial download with no ability to check"); - return result; - } - - if(!ftpc->dont_check) { - /* 226 Transfer complete, 250 Requested file action okay, completed. */ - if((ftpcode != 226) && (ftpcode != 250)) { - failf(data, "server did not report OK, got %d", ftpcode); - result = CURLE_PARTIAL_FILE; - } - } - } - - if(result || premature) - /* the response code from the transfer showed an error already so no - use checking further */ - ; - else if(data->set.upload) { - if((-1 != data->state.infilesize) && - (data->state.infilesize != *ftp->bytecountp) && - !data->set.crlf && - (ftp->transfer == FTPTRANSFER_BODY)) { - failf(data, "Uploaded unaligned file size (%" CURL_FORMAT_CURL_OFF_T - " out of %" CURL_FORMAT_CURL_OFF_T " bytes)", - *ftp->bytecountp, data->state.infilesize); - result = CURLE_PARTIAL_FILE; - } - } - else { - if((-1 != data->req.size) && - (data->req.size != *ftp->bytecountp) && -#ifdef CURL_DO_LINEEND_CONV - /* Most FTP servers don't adjust their file SIZE response for CRLFs, so - * we'll check to see if the discrepancy can be explained by the number - * of CRLFs we've changed to LFs. - */ - ((data->req.size + data->state.crlf_conversions) != - *ftp->bytecountp) && -#endif /* CURL_DO_LINEEND_CONV */ - (data->req.maxdownload != *ftp->bytecountp)) { - failf(data, "Received only partial file: %" CURL_FORMAT_CURL_OFF_T - " bytes", *ftp->bytecountp); - result = CURLE_PARTIAL_FILE; - } - else if(!ftpc->dont_check && - !*ftp->bytecountp && - (data->req.size>0)) { - failf(data, "No data was received!"); - result = CURLE_FTP_COULDNT_RETR_FILE; - } - } - - /* clear these for next connection */ - ftp->transfer = FTPTRANSFER_BODY; - ftpc->dont_check = FALSE; - - /* Send any post-transfer QUOTE strings? */ - if(!status && !result && !premature && data->set.postquote) - result = ftp_sendquote(conn, data->set.postquote); - - return result; -} - -/*********************************************************************** - * - * ftp_sendquote() - * - * Where a 'quote' means a list of custom commands to send to the server. - * The quote list is passed as an argument. - * - * BLOCKING - */ - -static -CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote) -{ - struct curl_slist *item; - ssize_t nread; - int ftpcode; - CURLcode result; - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - - item = quote; - while(item) { - if(item->data) { - char *cmd = item->data; - bool acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal FTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ - - if(cmd[0] == '*') { - cmd++; - acceptfail = TRUE; - } - - PPSENDF(&conn->proto.ftpc.pp, "%s", cmd); - - pp->response = Curl_tvnow(); /* timeout relative now */ - - result = Curl_GetFTPResponse(&nread, conn, &ftpcode); - if(result) - return result; - - if(!acceptfail && (ftpcode >= 400)) { - failf(conn->data, "QUOT string not accepted: %s", cmd); - return CURLE_QUOTE_ERROR; - } - } - - item = item->next; - } - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_need_type() - * - * Returns TRUE if we in the current situation should send TYPE - */ -static int ftp_need_type(struct connectdata *conn, - bool ascii_wanted) -{ - return conn->proto.ftpc.transfertype != (ascii_wanted?'A':'I'); -} - -/*********************************************************************** - * - * ftp_nb_type() - * - * Set TYPE. We only deal with ASCII or BINARY so this function - * sets one of them. - * If the transfer type is not sent, simulate on OK response in newstate - */ -static CURLcode ftp_nb_type(struct connectdata *conn, - bool ascii, ftpstate newstate) -{ - struct ftp_conn *ftpc = &conn->proto.ftpc; - CURLcode result; - char want = (char)(ascii?'A':'I'); - - if(ftpc->transfertype == want) { - state(conn, newstate); - return ftp_state_type_resp(conn, 200, newstate); - } - - PPSENDF(&ftpc->pp, "TYPE %c", want); - state(conn, newstate); - - /* keep track of our current transfer type */ - ftpc->transfertype = want; - return CURLE_OK; -} - -/*************************************************************************** - * - * ftp_pasv_verbose() - * - * This function only outputs some informationals about this second connection - * when we've issued a PASV command before and thus we have connected to a - * possibly new IP address. - * - */ -#ifndef CURL_DISABLE_VERBOSE_STRINGS -static void -ftp_pasv_verbose(struct connectdata *conn, - Curl_addrinfo *ai, - char *newhost, /* ascii version */ - int port) -{ - char buf[256]; - Curl_printable_address(ai, buf, sizeof(buf)); - infof(conn->data, "Connecting to %s (%s) port %d\n", newhost, buf, port); -} -#endif - -/* - Check if this is a range download, and if so, set the internal variables - properly. - */ - -static CURLcode ftp_range(struct connectdata *conn) -{ - curl_off_t from, to; - char *ptr; - char *ptr2; - struct SessionHandle *data = conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if(data->state.use_range && data->state.range) { - from=curlx_strtoofft(data->state.range, &ptr, 0); - while(*ptr && (ISSPACE(*ptr) || (*ptr=='-'))) - ptr++; - to=curlx_strtoofft(ptr, &ptr2, 0); - if(ptr == ptr2) { - /* we didn't get any digit */ - to=-1; - } - if((-1 == to) && (from>=0)) { - /* X - */ - data->state.resume_from = from; - DEBUGF(infof(conn->data, "FTP RANGE %" CURL_FORMAT_CURL_OFF_T - " to end of file\n", from)); - } - else if(from < 0) { - /* -Y */ - data->req.maxdownload = -from; - data->state.resume_from = from; - DEBUGF(infof(conn->data, "FTP RANGE the last %" CURL_FORMAT_CURL_OFF_T - " bytes\n", -from)); - } - else { - /* X-Y */ - data->req.maxdownload = (to-from)+1; /* include last byte */ - data->state.resume_from = from; - DEBUGF(infof(conn->data, "FTP RANGE from %" CURL_FORMAT_CURL_OFF_T - " getting %" CURL_FORMAT_CURL_OFF_T " bytes\n", - from, data->req.maxdownload)); - } - DEBUGF(infof(conn->data, "range-download from %" CURL_FORMAT_CURL_OFF_T - " to %" CURL_FORMAT_CURL_OFF_T ", totally %" - CURL_FORMAT_CURL_OFF_T " bytes\n", - from, to, data->req.maxdownload)); - ftpc->dont_check = TRUE; /* dont check for successful transfer */ - } - else - data->req.maxdownload = -1; - return CURLE_OK; -} - - -/* - * ftp_do_more() - * - * This function shall be called when the second FTP (data) connection is - * connected. - * - * 'complete' can return 0 for incomplete, 1 for done and -1 for go back - * (which basically is only for when PASV is being sent to retry a failed - * EPSV). - */ - -static CURLcode ftp_do_more(struct connectdata *conn, int *completep) -{ - struct SessionHandle *data=conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - CURLcode result = CURLE_OK; - bool connected = FALSE; - bool complete = FALSE; - - /* the ftp struct is inited in ftp_connect() */ - struct FTP *ftp = data->req.protop; - - /* if the second connection isn't done yet, wait for it */ - if(!conn->bits.tcpconnect[SECONDARYSOCKET]) { - if(conn->tunnel_state[SECONDARYSOCKET] == TUNNEL_CONNECT) { - /* As we're in TUNNEL_CONNECT state now, we know the proxy name and port - aren't used so we blank their arguments. TODO: make this nicer */ - result = Curl_proxyCONNECT(conn, SECONDARYSOCKET, NULL, 0, FALSE); - - return result; - } - - result = Curl_is_connected(conn, SECONDARYSOCKET, &connected); - - /* Ready to do more? */ - if(connected) { - DEBUGF(infof(data, "DO-MORE connected phase starts\n")); - if(conn->bits.proxy) { - infof(data, "Connection to proxy confirmed\n"); - result = proxy_magic(conn, ftpc->newhost, ftpc->newport, &connected); - } - } - else { - if(result && (ftpc->count1 == 0)) { - *completep = -1; /* go back to DOING please */ - /* this is a EPSV connect failing, try PASV instead */ - return ftp_epsv_disable(conn); - } - return result; - } - } - - if(ftpc->state) { - /* already in a state so skip the intial commands. - They are only done to kickstart the do_more state */ - result = ftp_multi_statemach(conn, &complete); - - *completep = (int)complete; - - /* if we got an error or if we don't wait for a data connection return - immediately */ - if(result || (ftpc->wait_data_conn != TRUE)) - return result; - - if(ftpc->wait_data_conn) - /* if we reach the end of the FTP state machine here, *complete will be - TRUE but so is ftpc->wait_data_conn, which says we need to wait for - the data connection and therefore we're not actually complete */ - *completep = 0; - } - - if(ftp->transfer <= FTPTRANSFER_INFO) { - /* a transfer is about to take place, or if not a file name was given - so we'll do a SIZE on it later and then we need the right TYPE first */ - - if(ftpc->wait_data_conn == TRUE) { - bool serv_conned; - - result = ReceivedServerConnect(conn, &serv_conned); - if(result) - return result; /* Failed to accept data connection */ - - if(serv_conned) { - /* It looks data connection is established */ - result = AcceptServerConnect(conn); - ftpc->wait_data_conn = FALSE; - if(!result) - result = InitiateTransfer(conn); - - if(result) - return result; - - *completep = 1; /* this state is now complete when the server has - connected back to us */ - } - } - else if(data->set.upload) { - result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE); - if(result) - return result; - - result = ftp_multi_statemach(conn, &complete); - if(ftpc->wait_data_conn) - /* if we reach the end of the FTP state machine here, *complete will be - TRUE but so is ftpc->wait_data_conn, which says we need to wait for - the data connection and therefore we're not actually complete */ - *completep = 0; - else - *completep = (int)complete; - } - else { - /* download */ - ftp->downloadsize = -1; /* unknown as of yet */ - - result = ftp_range(conn); - if(result) - ; - else if(data->set.ftp_list_only || !ftpc->file) { - /* The specified path ends with a slash, and therefore we think this - is a directory that is requested, use LIST. But before that we - need to set ASCII transfer mode. */ - - /* But only if a body transfer was requested. */ - if(ftp->transfer == FTPTRANSFER_BODY) { - result = ftp_nb_type(conn, TRUE, FTP_LIST_TYPE); - if(result) - return result; - } - /* otherwise just fall through */ - } - else { - result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_RETR_TYPE); - if(result) - return result; - } - - result = ftp_multi_statemach(conn, &complete); - *completep = (int)complete; - } - return result; - } - - if(!result && (ftp->transfer != FTPTRANSFER_BODY)) - /* no data to transfer. FIX: it feels like a kludge to have this here - too! */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - - if(!ftpc->wait_data_conn) { - /* no waiting for the data connection so this is now complete */ - *completep = 1; - DEBUGF(infof(data, "DO-MORE phase ends with %d\n", (int)result)); - } - - return result; -} - - - -/*********************************************************************** - * - * ftp_perform() - * - * This is the actual DO function for FTP. Get a file/directory according to - * the options previously setup. - */ - -static -CURLcode ftp_perform(struct connectdata *conn, - bool *connected, /* connect status after PASV / PORT */ - bool *dophase_done) -{ - /* this is FTP and no proxy */ - CURLcode result=CURLE_OK; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - if(conn->data->set.opt_no_body) { - /* requested no body means no transfer... */ - struct FTP *ftp = conn->data->req.protop; - ftp->transfer = FTPTRANSFER_INFO; - } - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - result = ftp_state_quote(conn, TRUE, FTP_QUOTE); - if(result) - return result; - - /* run the state-machine */ - result = ftp_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[SECONDARYSOCKET]; - - infof(conn->data, "ftp_perform ends with SECONDARY: %d\n", *connected); - - if(*dophase_done) - DEBUGF(infof(conn->data, "DO phase is complete1\n")); - - return result; -} - -static void wc_data_dtor(void *ptr) -{ - struct ftp_wc_tmpdata *tmp = ptr; - if(tmp) - Curl_ftp_parselist_data_free(&tmp->parser); - free(tmp); -} - -static CURLcode init_wc_data(struct connectdata *conn) -{ - char *last_slash; - char *path = conn->data->state.path; - struct WildcardData *wildcard = &(conn->data->wildcard); - CURLcode result = CURLE_OK; - struct ftp_wc_tmpdata *ftp_tmp; - - last_slash = strrchr(conn->data->state.path, '/'); - if(last_slash) { - last_slash++; - if(last_slash[0] == '\0') { - wildcard->state = CURLWC_CLEAN; - result = ftp_parse_url_path(conn); - return result; - } - else { - wildcard->pattern = strdup(last_slash); - if(!wildcard->pattern) - return CURLE_OUT_OF_MEMORY; - last_slash[0] = '\0'; /* cut file from path */ - } - } - else { /* there is only 'wildcard pattern' or nothing */ - if(path[0]) { - wildcard->pattern = strdup(path); - if(!wildcard->pattern) - return CURLE_OUT_OF_MEMORY; - path[0] = '\0'; - } - else { /* only list */ - wildcard->state = CURLWC_CLEAN; - result = ftp_parse_url_path(conn); - return result; - } - } - - /* program continues only if URL is not ending with slash, allocate needed - resources for wildcard transfer */ - - /* allocate ftp protocol specific temporary wildcard data */ - ftp_tmp = calloc(1, sizeof(struct ftp_wc_tmpdata)); - if(!ftp_tmp) { - Curl_safefree(wildcard->pattern); - return CURLE_OUT_OF_MEMORY; - } - - /* INITIALIZE parselist structure */ - ftp_tmp->parser = Curl_ftp_parselist_data_alloc(); - if(!ftp_tmp->parser) { - Curl_safefree(wildcard->pattern); - free(ftp_tmp); - return CURLE_OUT_OF_MEMORY; - } - - wildcard->tmp = ftp_tmp; /* put it to the WildcardData tmp pointer */ - wildcard->tmp_dtor = wc_data_dtor; - - /* wildcard does not support NOCWD option (assert it?) */ - if(conn->data->set.ftp_filemethod == FTPFILE_NOCWD) - conn->data->set.ftp_filemethod = FTPFILE_MULTICWD; - - /* try to parse ftp url */ - result = ftp_parse_url_path(conn); - if(result) { - Curl_safefree(wildcard->pattern); - wildcard->tmp_dtor(wildcard->tmp); - wildcard->tmp_dtor = ZERO_NULL; - wildcard->tmp = NULL; - return result; - } - - wildcard->path = strdup(conn->data->state.path); - if(!wildcard->path) { - Curl_safefree(wildcard->pattern); - wildcard->tmp_dtor(wildcard->tmp); - wildcard->tmp_dtor = ZERO_NULL; - wildcard->tmp = NULL; - return CURLE_OUT_OF_MEMORY; - } - - /* backup old write_function */ - ftp_tmp->backup.write_function = conn->data->set.fwrite_func; - /* parsing write function */ - conn->data->set.fwrite_func = Curl_ftp_parselist; - /* backup old file descriptor */ - ftp_tmp->backup.file_descriptor = conn->data->set.out; - /* let the writefunc callback know what curl pointer is working with */ - conn->data->set.out = conn; - - infof(conn->data, "Wildcard - Parsing started\n"); - return CURLE_OK; -} - -/* This is called recursively */ -static CURLcode wc_statemach(struct connectdata *conn) -{ - struct WildcardData * const wildcard = &(conn->data->wildcard); - CURLcode result = CURLE_OK; - - switch (wildcard->state) { - case CURLWC_INIT: - result = init_wc_data(conn); - if(wildcard->state == CURLWC_CLEAN) - /* only listing! */ - break; - else - wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING; - break; - - case CURLWC_MATCHING: { - /* In this state is LIST response successfully parsed, so lets restore - previous WRITEFUNCTION callback and WRITEDATA pointer */ - struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp; - conn->data->set.fwrite_func = ftp_tmp->backup.write_function; - conn->data->set.out = ftp_tmp->backup.file_descriptor; - ftp_tmp->backup.write_function = ZERO_NULL; - ftp_tmp->backup.file_descriptor = NULL; - wildcard->state = CURLWC_DOWNLOADING; - - if(Curl_ftp_parselist_geterror(ftp_tmp->parser)) { - /* error found in LIST parsing */ - wildcard->state = CURLWC_CLEAN; - return wc_statemach(conn); - } - else if(wildcard->filelist->size == 0) { - /* no corresponding file */ - wildcard->state = CURLWC_CLEAN; - return CURLE_REMOTE_FILE_NOT_FOUND; - } - return wc_statemach(conn); - } - - case CURLWC_DOWNLOADING: { - /* filelist has at least one file, lets get first one */ - struct ftp_conn *ftpc = &conn->proto.ftpc; - struct curl_fileinfo *finfo = wildcard->filelist->head->ptr; - - char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename); - if(!tmp_path) - return CURLE_OUT_OF_MEMORY; - - /* switch default "state.pathbuffer" and tmp_path, good to see - ftp_parse_url_path function to understand this trick */ - Curl_safefree(conn->data->state.pathbuffer); - conn->data->state.pathbuffer = tmp_path; - conn->data->state.path = tmp_path; - - infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename); - if(conn->data->set.chunk_bgn) { - long userresponse = conn->data->set.chunk_bgn( - finfo, wildcard->customptr, (int)wildcard->filelist->size); - switch(userresponse) { - case CURL_CHUNK_BGN_FUNC_SKIP: - infof(conn->data, "Wildcard - \"%s\" skipped by user\n", - finfo->filename); - wildcard->state = CURLWC_SKIP; - return wc_statemach(conn); - case CURL_CHUNK_BGN_FUNC_FAIL: - return CURLE_CHUNK_FAILED; - } - } - - if(finfo->filetype != CURLFILETYPE_FILE) { - wildcard->state = CURLWC_SKIP; - return wc_statemach(conn); - } - - if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE) - ftpc->known_filesize = finfo->size; - - result = ftp_parse_url_path(conn); - if(result) - return result; - - /* we don't need the Curl_fileinfo of first file anymore */ - Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL); - - if(wildcard->filelist->size == 0) { /* remains only one file to down. */ - wildcard->state = CURLWC_CLEAN; - /* after that will be ftp_do called once again and no transfer - will be done because of CURLWC_CLEAN state */ - return CURLE_OK; - } - } break; - - case CURLWC_SKIP: { - if(conn->data->set.chunk_end) - conn->data->set.chunk_end(conn->data->wildcard.customptr); - Curl_llist_remove(wildcard->filelist, wildcard->filelist->head, NULL); - wildcard->state = (wildcard->filelist->size == 0) ? - CURLWC_CLEAN : CURLWC_DOWNLOADING; - return wc_statemach(conn); - } - - case CURLWC_CLEAN: { - struct ftp_wc_tmpdata *ftp_tmp = wildcard->tmp; - result = CURLE_OK; - if(ftp_tmp) - result = Curl_ftp_parselist_geterror(ftp_tmp->parser); - - wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE; - } break; - - case CURLWC_DONE: - case CURLWC_ERROR: - break; - } - - return result; -} - -/*********************************************************************** - * - * ftp_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (ftp_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode ftp_do(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - *done = FALSE; /* default to false */ - ftpc->wait_data_conn = FALSE; /* default to no such wait */ - - if(conn->data->set.wildcardmatch) { - result = wc_statemach(conn); - if(conn->data->wildcard.state == CURLWC_SKIP || - conn->data->wildcard.state == CURLWC_DONE) { - /* do not call ftp_regular_transfer */ - return CURLE_OK; - } - if(result) /* error, loop or skipping the file */ - return result; - } - else { /* no wildcard FSM needed */ - result = ftp_parse_url_path(conn); - if(result) - return result; - } - - result = ftp_regular_transfer(conn, done); - - return result; -} - - -CURLcode Curl_ftpsendf(struct connectdata *conn, - const char *fmt, ...) -{ - ssize_t bytes_written; -#define SBUF_SIZE 1024 - char s[SBUF_SIZE]; - size_t write_len; - char *sptr=s; - CURLcode result = CURLE_OK; -#ifdef HAVE_GSSAPI - enum protection_level data_sec = conn->data_prot; -#endif - - va_list ap; - va_start(ap, fmt); - write_len = vsnprintf(s, SBUF_SIZE-3, fmt, ap); - va_end(ap); - - strcpy(&s[write_len], "\r\n"); /* append a trailing CRLF */ - write_len +=2; - - bytes_written=0; - - result = Curl_convert_to_network(conn->data, s, write_len); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) - return result; - - for(;;) { -#ifdef HAVE_GSSAPI - conn->data_prot = PROT_CMD; -#endif - result = Curl_write(conn, conn->sock[FIRSTSOCKET], sptr, write_len, - &bytes_written); -#ifdef HAVE_GSSAPI - DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); - conn->data_prot = data_sec; -#endif - - if(result) - break; - - if(conn->data->set.verbose) - Curl_debug(conn->data, CURLINFO_HEADER_OUT, - sptr, (size_t)bytes_written, conn); - - if(bytes_written != (ssize_t)write_len) { - write_len -= bytes_written; - sptr += bytes_written; - } - else - break; - } - - return result; -} - -/*********************************************************************** - * - * ftp_quit() - * - * This should be called before calling sclose() on an ftp control connection - * (not data connections). We should then wait for the response from the - * server before returning. The calling code should then try to close the - * connection. - * - */ -static CURLcode ftp_quit(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - if(conn->proto.ftpc.ctl_valid) { - result = Curl_pp_sendf(&conn->proto.ftpc.pp, "%s", "QUIT"); - if(result) { - failf(conn->data, "Failure sending QUIT command: %s", - curl_easy_strerror(result)); - conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */ - connclose(conn, "QUIT command failed"); /* mark for connection closure */ - state(conn, FTP_STOP); - return result; - } - - state(conn, FTP_QUIT); - - result = ftp_block_statemach(conn); - } - - return result; -} - -/*********************************************************************** - * - * ftp_disconnect() - * - * Disconnect from an FTP server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection) -{ - struct ftp_conn *ftpc= &conn->proto.ftpc; - struct pingpong *pp = &ftpc->pp; - - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. - - ftp_quit() will check the state of ftp->ctl_valid. If it's ok it - will try to send the QUIT command, otherwise it will just return. - */ - if(dead_connection) - ftpc->ctl_valid = FALSE; - - /* The FTP session may or may not have been allocated/setup at this point! */ - (void)ftp_quit(conn); /* ignore errors on the QUIT */ - - if(ftpc->entrypath) { - struct SessionHandle *data = conn->data; - if(data->state.most_recent_ftp_entrypath == ftpc->entrypath) { - data->state.most_recent_ftp_entrypath = NULL; - } - free(ftpc->entrypath); - ftpc->entrypath = NULL; - } - - freedirs(ftpc); - free(ftpc->prevpath); - ftpc->prevpath = NULL; - free(ftpc->server_os); - ftpc->server_os = NULL; - - Curl_pp_disconnect(pp); - -#ifdef HAVE_GSSAPI - Curl_sec_end(conn); -#endif - - return CURLE_OK; -} - -/*********************************************************************** - * - * ftp_parse_url_path() - * - * Parse the URL path into separate path components. - * - */ -static -CURLcode ftp_parse_url_path(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - /* the ftp struct is already inited in ftp_connect() */ - struct FTP *ftp = data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - const char *slash_pos; /* position of the first '/' char in curpos */ - const char *path_to_use = data->state.path; - const char *cur_pos; - const char *filename = NULL; - - cur_pos = path_to_use; /* current position in path. point at the begin - of next path component */ - - ftpc->ctl_valid = FALSE; - ftpc->cwdfail = FALSE; - - switch(data->set.ftp_filemethod) { - case FTPFILE_NOCWD: - /* fastest, but less standard-compliant */ - - /* - The best time to check whether the path is a file or directory is right - here. so: - - the first condition in the if() right here, is there just in case - someone decides to set path to NULL one day - */ - if(path_to_use[0] && - (path_to_use[strlen(path_to_use) - 1] != '/') ) - filename = path_to_use; /* this is a full file path */ - /* - else { - ftpc->file is not used anywhere other than for operations on a file. - In other words, never for directory operations. - So we can safely leave filename as NULL here and use it as a - argument in dir/file decisions. - } - */ - break; - - case FTPFILE_SINGLECWD: - /* get the last slash */ - if(!path_to_use[0]) { - /* no dir, no file */ - ftpc->dirdepth = 0; - break; - } - slash_pos=strrchr(cur_pos, '/'); - if(slash_pos || !*cur_pos) { - size_t dirlen = slash_pos-cur_pos; - - ftpc->dirs = calloc(1, sizeof(ftpc->dirs[0])); - if(!ftpc->dirs) - return CURLE_OUT_OF_MEMORY; - - if(!dirlen) - dirlen++; - - ftpc->dirs[0] = curl_easy_unescape(conn->data, slash_pos ? cur_pos : "/", - slash_pos ? curlx_uztosi(dirlen) : 1, - NULL); - if(!ftpc->dirs[0]) { - freedirs(ftpc); - return CURLE_OUT_OF_MEMORY; - } - ftpc->dirdepth = 1; /* we consider it to be a single dir */ - filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */ - } - else - filename = cur_pos; /* this is a file name only */ - break; - - default: /* allow pretty much anything */ - case FTPFILE_MULTICWD: - ftpc->dirdepth = 0; - ftpc->diralloc = 5; /* default dir depth to allocate */ - ftpc->dirs = calloc(ftpc->diralloc, sizeof(ftpc->dirs[0])); - if(!ftpc->dirs) - return CURLE_OUT_OF_MEMORY; - - /* we have a special case for listing the root dir only */ - if(strequal(path_to_use, "/")) { - cur_pos++; /* make it point to the zero byte */ - ftpc->dirs[0] = strdup("/"); - ftpc->dirdepth++; - } - else { - /* parse the URL path into separate path components */ - while((slash_pos = strchr(cur_pos, '/')) != NULL) { - /* 1 or 0 pointer offset to indicate absolute directory */ - ssize_t absolute_dir = ((cur_pos - data->state.path > 0) && - (ftpc->dirdepth == 0))?1:0; - - /* seek out the next path component */ - if(slash_pos-cur_pos) { - /* we skip empty path components, like "x//y" since the FTP command - CWD requires a parameter and a non-existent parameter a) doesn't - work on many servers and b) has no effect on the others. */ - int len = curlx_sztosi(slash_pos - cur_pos + absolute_dir); - ftpc->dirs[ftpc->dirdepth] = - curl_easy_unescape(conn->data, cur_pos - absolute_dir, len, NULL); - if(!ftpc->dirs[ftpc->dirdepth]) { /* run out of memory ... */ - failf(data, "no memory"); - freedirs(ftpc); - return CURLE_OUT_OF_MEMORY; - } - if(isBadFtpString(ftpc->dirs[ftpc->dirdepth])) { - free(ftpc->dirs[ftpc->dirdepth]); - freedirs(ftpc); - return CURLE_URL_MALFORMAT; - } - } - else { - cur_pos = slash_pos + 1; /* jump to the rest of the string */ - if(!ftpc->dirdepth) { - /* path starts with a slash, add that as a directory */ - ftpc->dirs[ftpc->dirdepth] = strdup("/"); - if(!ftpc->dirs[ftpc->dirdepth++]) { /* run out of memory ... */ - failf(data, "no memory"); - freedirs(ftpc); - return CURLE_OUT_OF_MEMORY; - } - } - continue; - } - - cur_pos = slash_pos + 1; /* jump to the rest of the string */ - if(++ftpc->dirdepth >= ftpc->diralloc) { - /* enlarge array */ - char **bigger; - ftpc->diralloc *= 2; /* double the size each time */ - bigger = realloc(ftpc->dirs, ftpc->diralloc * sizeof(ftpc->dirs[0])); - if(!bigger) { - freedirs(ftpc); - return CURLE_OUT_OF_MEMORY; - } - ftpc->dirs = bigger; - } - } - } - filename = cur_pos; /* the rest is the file name */ - break; - } /* switch */ - - if(filename && *filename) { - ftpc->file = curl_easy_unescape(conn->data, filename, 0, NULL); - if(NULL == ftpc->file) { - freedirs(ftpc); - failf(data, "no memory"); - return CURLE_OUT_OF_MEMORY; - } - if(isBadFtpString(ftpc->file)) { - freedirs(ftpc); - return CURLE_URL_MALFORMAT; - } - } - else - ftpc->file=NULL; /* instead of point to a zero byte, we make it a NULL - pointer */ - - if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) { - /* We need a file name when uploading. Return error! */ - failf(data, "Uploading to a URL without a file name!"); - return CURLE_URL_MALFORMAT; - } - - ftpc->cwddone = FALSE; /* default to not done */ - - if(ftpc->prevpath) { - /* prevpath is "raw" so we convert the input path before we compare the - strings */ - int dlen; - char *path = curl_easy_unescape(conn->data, data->state.path, 0, &dlen); - if(!path) { - freedirs(ftpc); - return CURLE_OUT_OF_MEMORY; - } - - dlen -= ftpc->file?curlx_uztosi(strlen(ftpc->file)):0; - if((dlen == curlx_uztosi(strlen(ftpc->prevpath))) && - strnequal(path, ftpc->prevpath, dlen)) { - infof(data, "Request has same path as previous transfer\n"); - ftpc->cwddone = TRUE; - } - free(path); - } - - return CURLE_OK; -} - -/* call this when the DO phase has completed */ -static CURLcode ftp_dophase_done(struct connectdata *conn, - bool connected) -{ - struct FTP *ftp = conn->data->req.protop; - struct ftp_conn *ftpc = &conn->proto.ftpc; - - if(connected) { - int completed; - CURLcode result = ftp_do_more(conn, &completed); - - if(result) { - close_secondarysocket(conn); - return result; - } - } - - if(ftp->transfer != FTPTRANSFER_BODY) - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - else if(!connected) - /* since we didn't connect now, we want do_more to get called */ - conn->bits.do_more = TRUE; - - ftpc->ctl_valid = TRUE; /* seems good */ - - return CURLE_OK; -} - -/* called from multi.c while DOing */ -static CURLcode ftp_doing(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result = ftp_multi_statemach(conn, dophase_done); - - if(result) - DEBUGF(infof(conn->data, "DO phase failed\n")); - else if(*dophase_done) { - result = ftp_dophase_done(conn, FALSE /* not connected */); - - DEBUGF(infof(conn->data, "DO phase is complete2\n")); - } - return result; -} - -/*********************************************************************** - * - * ftp_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - * - * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the - * ftp_done() function without finding any major problem. - */ -static -CURLcode ftp_regular_transfer(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result=CURLE_OK; - bool connected=FALSE; - struct SessionHandle *data = conn->data; - struct ftp_conn *ftpc = &conn->proto.ftpc; - data->req.size = -1; /* make sure this is unknown at this point */ - - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - - ftpc->ctl_valid = TRUE; /* starts good */ - - result = ftp_perform(conn, - &connected, /* have we connected after PASV/PORT */ - dophase_done); /* all commands in the DO-phase done? */ - - if(!result) { - - if(!*dophase_done) - /* the DO phase has not completed yet */ - return CURLE_OK; - - result = ftp_dophase_done(conn, connected); - - if(result) - return result; - } - else - freedirs(ftpc); - - return result; -} - -static CURLcode ftp_setup_connection(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - char *type; - char command; - struct FTP *ftp; - - if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) { - /* Unless we have asked to tunnel ftp operations through the proxy, we - switch and use HTTP operations only */ -#ifndef CURL_DISABLE_HTTP - if(conn->handler == &Curl_handler_ftp) - conn->handler = &Curl_handler_ftp_proxy; - else { -#ifdef USE_SSL - conn->handler = &Curl_handler_ftps_proxy; -#else - failf(data, "FTPS not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - /* set it up as a HTTP connection instead */ - return conn->handler->setup_connection(conn); -#else - failf(data, "FTP over http proxy requires HTTP support built-in!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - conn->data->req.protop = ftp = malloc(sizeof(struct FTP)); - if(NULL == ftp) - return CURLE_OUT_OF_MEMORY; - - data->state.path++; /* don't include the initial slash */ - data->state.slash_removed = TRUE; /* we've skipped the slash */ - - /* FTP URLs support an extension like ";type=" that - * we'll try to get now! */ - type = strstr(data->state.path, ";type="); - - if(!type) - type = strstr(conn->host.rawalloc, ";type="); - - if(type) { - *type = 0; /* it was in the middle of the hostname */ - command = Curl_raw_toupper(type[6]); - conn->bits.type_set = TRUE; - - switch (command) { - case 'A': /* ASCII mode */ - data->set.prefer_ascii = TRUE; - break; - - case 'D': /* directory mode */ - data->set.ftp_list_only = TRUE; - break; - - case 'I': /* binary mode */ - default: - /* switch off ASCII */ - data->set.prefer_ascii = FALSE; - break; - } - } - - /* get some initial data into the ftp struct */ - ftp->bytecountp = &conn->data->req.bytecount; - ftp->transfer = FTPTRANSFER_BODY; - ftp->downloadsize = 0; - - /* No need to duplicate user+password, the connectdata struct won't change - during a session, but we re-init them here since on subsequent inits - since the conn struct may have changed or been replaced. - */ - ftp->user = conn->user; - ftp->passwd = conn->passwd; - if(isBadFtpString(ftp->user)) - return CURLE_URL_MALFORMAT; - if(isBadFtpString(ftp->passwd)) - return CURLE_URL_MALFORMAT; - - conn->proto.ftpc.known_filesize = -1; /* unknown size for now */ - - return CURLE_OK; -} - -#endif /* CURL_DISABLE_FTP */ diff --git a/Externals/curl/lib/ftp.h b/Externals/curl/lib/ftp.h deleted file mode 100644 index 7495e3e079..0000000000 --- a/Externals/curl/lib/ftp.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef HEADER_CURL_FTP_H -#define HEADER_CURL_FTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "pingpong.h" - -#ifndef CURL_DISABLE_FTP -extern const struct Curl_handler Curl_handler_ftp; - -#ifdef USE_SSL -extern const struct Curl_handler Curl_handler_ftps; -#endif - -CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...); -CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn, - int *ftpcode); -#endif /* CURL_DISABLE_FTP */ - -/**************************************************************************** - * FTP unique setup - ***************************************************************************/ -typedef enum { - FTP_STOP, /* do nothing state, stops the state machine */ - FTP_WAIT220, /* waiting for the initial 220 response immediately after - a connect */ - FTP_AUTH, - FTP_USER, - FTP_PASS, - FTP_ACCT, - FTP_PBSZ, - FTP_PROT, - FTP_CCC, - FTP_PWD, - FTP_SYST, - FTP_NAMEFMT, - FTP_QUOTE, /* waiting for a response to a command sent in a quote list */ - FTP_RETR_PREQUOTE, - FTP_STOR_PREQUOTE, - FTP_POSTQUOTE, - FTP_CWD, /* change dir */ - FTP_MKD, /* if the dir didn't exist */ - FTP_MDTM, /* to figure out the datestamp */ - FTP_TYPE, /* to set type when doing a head-like request */ - FTP_LIST_TYPE, /* set type when about to do a dir list */ - FTP_RETR_TYPE, /* set type when about to RETR a file */ - FTP_STOR_TYPE, /* set type when about to STOR a file */ - FTP_SIZE, /* get the remote file's size for head-like request */ - FTP_RETR_SIZE, /* get the remote file's size for RETR */ - FTP_STOR_SIZE, /* get the size for STOR */ - FTP_REST, /* when used to check if the server supports it in head-like */ - FTP_RETR_REST, /* when asking for "resume" in for RETR */ - FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */ - FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */ - FTP_PASV, /* generic state for PASV and EPSV, check count1 */ - FTP_LIST, /* generic state for LIST, NLST or a custom list command */ - FTP_RETR, - FTP_STOR, /* generic state for STOR and APPE */ - FTP_QUIT, - FTP_LAST /* never used */ -} ftpstate; - -struct ftp_parselist_data; /* defined later in ftplistparser.c */ - -struct ftp_wc_tmpdata { - struct ftp_parselist_data *parser; - - struct { - curl_write_callback write_function; - FILE *file_descriptor; - } backup; -}; - -typedef enum { - FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */ - FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */ - FTPFILE_SINGLECWD = 3 /* make one CWD, then SIZE / RETR / STOR on the - file */ -} curl_ftpfile; - -/* This FTP struct is used in the SessionHandle. All FTP data that is - connection-oriented must be in FTP_conn to properly deal with the fact that - perhaps the SessionHandle is changed between the times the connection is - used. */ -struct FTP { - curl_off_t *bytecountp; - char *user; /* user name string */ - char *passwd; /* password string */ - - /* transfer a file/body or not, done as a typedefed enum just to make - debuggers display the full symbol and not just the numerical value */ - curl_pp_transfer transfer; - curl_off_t downloadsize; -}; - - -/* ftp_conn is used for struct connection-oriented data in the connectdata - struct */ -struct ftp_conn { - struct pingpong pp; - char *entrypath; /* the PWD reply when we logged on */ - char **dirs; /* realloc()ed array for path components */ - int dirdepth; /* number of entries used in the 'dirs' array */ - int diralloc; /* number of entries allocated for the 'dirs' array */ - char *file; /* decoded file */ - bool dont_check; /* Set to TRUE to prevent the final (post-transfer) - file size and 226/250 status check. It should still - read the line, just ignore the result. */ - bool ctl_valid; /* Tells Curl_ftp_quit() whether or not to do anything. If - the connection has timed out or been closed, this - should be FALSE when it gets to Curl_ftp_quit() */ - bool cwddone; /* if it has been determined that the proper CWD combo - already has been done */ - bool cwdfail; /* set TRUE if a CWD command fails, as then we must prevent - caching the current directory */ - bool wait_data_conn; /* this is set TRUE if data connection is waited */ - char *prevpath; /* conn->path from the previous transfer */ - char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a - and others (A/I or zero) */ - int count1; /* general purpose counter for the state machine */ - int count2; /* general purpose counter for the state machine */ - int count3; /* general purpose counter for the state machine */ - ftpstate state; /* always use ftp.c:state() to change state! */ - ftpstate state_saved; /* transfer type saved to be reloaded after - data connection is established */ - curl_off_t retr_size_saved; /* Size of retrieved file saved */ - char * server_os; /* The target server operating system. */ - curl_off_t known_filesize; /* file size is different from -1, if wildcard - LIST parsing was done and wc_statemach set - it */ - /* newhost is the (allocated) IP addr or host name to connect the data - connection to */ - char *newhost; /* this is the pair to connect the DATA... */ - unsigned short newport; /* connection to */ - -}; - -#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */ - -#endif /* HEADER_CURL_FTP_H */ diff --git a/Externals/curl/lib/ftplistparser.c b/Externals/curl/lib/ftplistparser.c deleted file mode 100644 index abbf76e27d..0000000000 --- a/Externals/curl/lib/ftplistparser.c +++ /dev/null @@ -1,1028 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/** - * Now implemented: - * - * 1) Unix version 1 - * drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog - * 2) Unix version 2 - * drwxr-xr-x 1 user01 ftp 512 Jan 29 1997 prog - * 3) Unix version 3 - * drwxr-xr-x 1 1 1 512 Jan 29 23:32 prog - * 4) Unix symlink - * lrwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog -> prog2000 - * 5) DOS style - * 01-29-97 11:32PM prog - */ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP - -#include - -#include "urldata.h" -#include "fileinfo.h" -#include "llist.h" -#include "strtoofft.h" -#include "rawstr.h" -#include "ftp.h" -#include "ftplistparser.h" -#include "curl_fnmatch.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* allocs buffer which will contain one line of LIST command response */ -#define FTP_BUFFER_ALLOCSIZE 160 - -typedef enum { - PL_UNIX_TOTALSIZE = 0, - PL_UNIX_FILETYPE, - PL_UNIX_PERMISSION, - PL_UNIX_HLINKS, - PL_UNIX_USER, - PL_UNIX_GROUP, - PL_UNIX_SIZE, - PL_UNIX_TIME, - PL_UNIX_FILENAME, - PL_UNIX_SYMLINK -} pl_unix_mainstate; - -typedef union { - enum { - PL_UNIX_TOTALSIZE_INIT = 0, - PL_UNIX_TOTALSIZE_READING - } total_dirsize; - - enum { - PL_UNIX_HLINKS_PRESPACE = 0, - PL_UNIX_HLINKS_NUMBER - } hlinks; - - enum { - PL_UNIX_USER_PRESPACE = 0, - PL_UNIX_USER_PARSING - } user; - - enum { - PL_UNIX_GROUP_PRESPACE = 0, - PL_UNIX_GROUP_NAME - } group; - - enum { - PL_UNIX_SIZE_PRESPACE = 0, - PL_UNIX_SIZE_NUMBER - } size; - - enum { - PL_UNIX_TIME_PREPART1 = 0, - PL_UNIX_TIME_PART1, - PL_UNIX_TIME_PREPART2, - PL_UNIX_TIME_PART2, - PL_UNIX_TIME_PREPART3, - PL_UNIX_TIME_PART3 - } time; - - enum { - PL_UNIX_FILENAME_PRESPACE = 0, - PL_UNIX_FILENAME_NAME, - PL_UNIX_FILENAME_WINDOWSEOL - } filename; - - enum { - PL_UNIX_SYMLINK_PRESPACE = 0, - PL_UNIX_SYMLINK_NAME, - PL_UNIX_SYMLINK_PRETARGET1, - PL_UNIX_SYMLINK_PRETARGET2, - PL_UNIX_SYMLINK_PRETARGET3, - PL_UNIX_SYMLINK_PRETARGET4, - PL_UNIX_SYMLINK_TARGET, - PL_UNIX_SYMLINK_WINDOWSEOL - } symlink; -} pl_unix_substate; - -typedef enum { - PL_WINNT_DATE = 0, - PL_WINNT_TIME, - PL_WINNT_DIRORSIZE, - PL_WINNT_FILENAME -} pl_winNT_mainstate; - -typedef union { - enum { - PL_WINNT_TIME_PRESPACE = 0, - PL_WINNT_TIME_TIME - } time; - enum { - PL_WINNT_DIRORSIZE_PRESPACE = 0, - PL_WINNT_DIRORSIZE_CONTENT - } dirorsize; - enum { - PL_WINNT_FILENAME_PRESPACE = 0, - PL_WINNT_FILENAME_CONTENT, - PL_WINNT_FILENAME_WINEOL - } filename; -} pl_winNT_substate; - -/* This struct is used in wildcard downloading - for parsing LIST response */ -struct ftp_parselist_data { - enum { - OS_TYPE_UNKNOWN = 0, - OS_TYPE_UNIX, - OS_TYPE_WIN_NT - } os_type; - - union { - struct { - pl_unix_mainstate main; - pl_unix_substate sub; - } UNIX; - - struct { - pl_winNT_mainstate main; - pl_winNT_substate sub; - } NT; - } state; - - CURLcode error; - struct curl_fileinfo *file_data; - unsigned int item_length; - size_t item_offset; - struct { - size_t filename; - size_t user; - size_t group; - size_t time; - size_t perm; - size_t symlink_target; - } offsets; -}; - -struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void) -{ - return calloc(1, sizeof(struct ftp_parselist_data)); -} - - -void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data) -{ - free(*pl_data); - *pl_data = NULL; -} - - -CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data) -{ - return pl_data->error; -} - - -#define FTP_LP_MALFORMATED_PERM 0x01000000 - -static int ftp_pl_get_permission(const char *str) -{ - int permissions = 0; - /* USER */ - if(str[0] == 'r') - permissions |= 1 << 8; - else if(str[0] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[1] == 'w') - permissions |= 1 << 7; - else if(str[1] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - - if(str[2] == 'x') - permissions |= 1 << 6; - else if(str[2] == 's') { - permissions |= 1 << 6; - permissions |= 1 << 11; - } - else if(str[2] == 'S') - permissions |= 1 << 11; - else if(str[2] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - /* GROUP */ - if(str[3] == 'r') - permissions |= 1 << 5; - else if(str[3] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[4] == 'w') - permissions |= 1 << 4; - else if(str[4] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[5] == 'x') - permissions |= 1 << 3; - else if(str[5] == 's') { - permissions |= 1 << 3; - permissions |= 1 << 10; - } - else if(str[5] == 'S') - permissions |= 1 << 10; - else if(str[5] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - /* others */ - if(str[6] == 'r') - permissions |= 1 << 2; - else if(str[6] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[7] == 'w') - permissions |= 1 << 1; - else if(str[7] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - if(str[8] == 'x') - permissions |= 1; - else if(str[8] == 't') { - permissions |= 1; - permissions |= 1 << 9; - } - else if(str[8] == 'T') - permissions |= 1 << 9; - else if(str[8] != '-') - permissions |= FTP_LP_MALFORMATED_PERM; - - return permissions; -} - -static void PL_ERROR(struct connectdata *conn, CURLcode err) -{ - struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp; - struct ftp_parselist_data *parser = tmpdata->parser; - if(parser->file_data) - Curl_fileinfo_dtor(NULL, parser->file_data); - parser->file_data = NULL; - parser->error = err; -} - -static CURLcode ftp_pl_insert_finfo(struct connectdata *conn, - struct curl_fileinfo *finfo) -{ - curl_fnmatch_callback compare; - struct WildcardData *wc = &conn->data->wildcard; - struct ftp_wc_tmpdata *tmpdata = wc->tmp; - struct curl_llist *llist = wc->filelist; - struct ftp_parselist_data *parser = tmpdata->parser; - bool add = TRUE; - - /* move finfo pointers to b_data */ - char *str = finfo->b_data; - finfo->filename = str + parser->offsets.filename; - finfo->strings.group = parser->offsets.group ? - str + parser->offsets.group : NULL; - finfo->strings.perm = parser->offsets.perm ? - str + parser->offsets.perm : NULL; - finfo->strings.target = parser->offsets.symlink_target ? - str + parser->offsets.symlink_target : NULL; - finfo->strings.time = str + parser->offsets.time; - finfo->strings.user = parser->offsets.user ? - str + parser->offsets.user : NULL; - - /* get correct fnmatch callback */ - compare = conn->data->set.fnmatch; - if(!compare) - compare = Curl_fnmatch; - - /* filter pattern-corresponding filenames */ - if(compare(conn->data->set.fnmatch_data, wc->pattern, - finfo->filename) == 0) { - /* discard symlink which is containing multiple " -> " */ - if((finfo->filetype == CURLFILETYPE_SYMLINK) && finfo->strings.target && - (strstr(finfo->strings.target, " -> "))) { - add = FALSE; - } - } - else { - add = FALSE; - } - - if(add) { - if(!Curl_llist_insert_next(llist, llist->tail, finfo)) { - Curl_fileinfo_dtor(NULL, finfo); - tmpdata->parser->file_data = NULL; - return CURLE_OUT_OF_MEMORY; - } - } - else { - Curl_fileinfo_dtor(NULL, finfo); - } - - tmpdata->parser->file_data = NULL; - return CURLE_OK; -} - -size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, - void *connptr) -{ - size_t bufflen = size*nmemb; - struct connectdata *conn = (struct connectdata *)connptr; - struct ftp_wc_tmpdata *tmpdata = conn->data->wildcard.tmp; - struct ftp_parselist_data *parser = tmpdata->parser; - struct curl_fileinfo *finfo; - unsigned long i = 0; - CURLcode result; - - if(parser->error) { /* error in previous call */ - /* scenario: - * 1. call => OK.. - * 2. call => OUT_OF_MEMORY (or other error) - * 3. (last) call => is skipped RIGHT HERE and the error is hadled later - * in wc_statemach() - */ - return bufflen; - } - - if(parser->os_type == OS_TYPE_UNKNOWN && bufflen > 0) { - /* considering info about FILE response format */ - parser->os_type = (buffer[0] >= '0' && buffer[0] <= '9') ? - OS_TYPE_WIN_NT : OS_TYPE_UNIX; - } - - while(i < bufflen) { /* FSM */ - - char c = buffer[i]; - if(!parser->file_data) { /* tmp file data is not allocated yet */ - parser->file_data = Curl_fileinfo_alloc(); - if(!parser->file_data) { - parser->error = CURLE_OUT_OF_MEMORY; - return bufflen; - } - parser->file_data->b_data = malloc(FTP_BUFFER_ALLOCSIZE); - if(!parser->file_data->b_data) { - PL_ERROR(conn, CURLE_OUT_OF_MEMORY); - return bufflen; - } - parser->file_data->b_size = FTP_BUFFER_ALLOCSIZE; - parser->item_offset = 0; - parser->item_length = 0; - } - - finfo = parser->file_data; - finfo->b_data[finfo->b_used++] = c; - - if(finfo->b_used >= finfo->b_size - 1) { - /* if it is important, extend buffer space for file data */ - char *tmp = realloc(finfo->b_data, - finfo->b_size + FTP_BUFFER_ALLOCSIZE); - if(tmp) { - finfo->b_size += FTP_BUFFER_ALLOCSIZE; - finfo->b_data = tmp; - } - else { - Curl_fileinfo_dtor(NULL, parser->file_data); - parser->file_data = NULL; - parser->error = CURLE_OUT_OF_MEMORY; - PL_ERROR(conn, CURLE_OUT_OF_MEMORY); - return bufflen; - } - } - - switch (parser->os_type) { - case OS_TYPE_UNIX: - switch (parser->state.UNIX.main) { - case PL_UNIX_TOTALSIZE: - switch(parser->state.UNIX.sub.total_dirsize) { - case PL_UNIX_TOTALSIZE_INIT: - if(c == 't') { - parser->state.UNIX.sub.total_dirsize = PL_UNIX_TOTALSIZE_READING; - parser->item_length++; - } - else { - parser->state.UNIX.main = PL_UNIX_FILETYPE; - /* start FSM again not considering size of directory */ - finfo->b_used = 0; - i--; - } - break; - case PL_UNIX_TOTALSIZE_READING: - parser->item_length++; - if(c == '\r') { - parser->item_length--; - finfo->b_used--; - } - else if(c == '\n') { - finfo->b_data[parser->item_length - 1] = 0; - if(strncmp("total ", finfo->b_data, 6) == 0) { - char *endptr = finfo->b_data+6; - /* here we can deal with directory size, pass the leading white - spaces and then the digits */ - while(ISSPACE(*endptr)) - endptr++; - while(ISDIGIT(*endptr)) - endptr++; - if(*endptr != 0) { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - else { - parser->state.UNIX.main = PL_UNIX_FILETYPE; - finfo->b_used = 0; - } - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - break; - } - break; - case PL_UNIX_FILETYPE: - switch (c) { - case '-': - finfo->filetype = CURLFILETYPE_FILE; - break; - case 'd': - finfo->filetype = CURLFILETYPE_DIRECTORY; - break; - case 'l': - finfo->filetype = CURLFILETYPE_SYMLINK; - break; - case 'p': - finfo->filetype = CURLFILETYPE_NAMEDPIPE; - break; - case 's': - finfo->filetype = CURLFILETYPE_SOCKET; - break; - case 'c': - finfo->filetype = CURLFILETYPE_DEVICE_CHAR; - break; - case 'b': - finfo->filetype = CURLFILETYPE_DEVICE_BLOCK; - break; - case 'D': - finfo->filetype = CURLFILETYPE_DOOR; - break; - default: - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - parser->state.UNIX.main = PL_UNIX_PERMISSION; - parser->item_length = 0; - parser->item_offset = 1; - break; - case PL_UNIX_PERMISSION: - parser->item_length++; - if(parser->item_length <= 9) { - if(!strchr("rwx-tTsS", c)) { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - else if(parser->item_length == 10) { - unsigned int perm; - if(c != ' ') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - finfo->b_data[10] = 0; /* terminate permissions */ - perm = ftp_pl_get_permission(finfo->b_data + parser->item_offset); - if(perm & FTP_LP_MALFORMATED_PERM) { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - parser->file_data->flags |= CURLFINFOFLAG_KNOWN_PERM; - parser->file_data->perm = perm; - parser->offsets.perm = parser->item_offset; - - parser->item_length = 0; - parser->state.UNIX.main = PL_UNIX_HLINKS; - parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_PRESPACE; - } - break; - case PL_UNIX_HLINKS: - switch(parser->state.UNIX.sub.hlinks) { - case PL_UNIX_HLINKS_PRESPACE: - if(c != ' ') { - if(c >= '0' && c <= '9') { - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - parser->state.UNIX.sub.hlinks = PL_UNIX_HLINKS_NUMBER; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - break; - case PL_UNIX_HLINKS_NUMBER: - parser->item_length ++; - if(c == ' ') { - char *p; - long int hlinks; - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - hlinks = strtol(finfo->b_data + parser->item_offset, &p, 10); - if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) { - parser->file_data->flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT; - parser->file_data->hardlinks = hlinks; - } - parser->item_length = 0; - parser->item_offset = 0; - parser->state.UNIX.main = PL_UNIX_USER; - parser->state.UNIX.sub.user = PL_UNIX_USER_PRESPACE; - } - else if(c < '0' || c > '9') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - } - break; - case PL_UNIX_USER: - switch(parser->state.UNIX.sub.user) { - case PL_UNIX_USER_PRESPACE: - if(c != ' ') { - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - parser->state.UNIX.sub.user = PL_UNIX_USER_PARSING; - } - break; - case PL_UNIX_USER_PARSING: - parser->item_length++; - if(c == ' ') { - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.user = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_GROUP; - parser->state.UNIX.sub.group = PL_UNIX_GROUP_PRESPACE; - parser->item_offset = 0; - parser->item_length = 0; - } - break; - } - break; - case PL_UNIX_GROUP: - switch(parser->state.UNIX.sub.group) { - case PL_UNIX_GROUP_PRESPACE: - if(c != ' ') { - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - parser->state.UNIX.sub.group = PL_UNIX_GROUP_NAME; - } - break; - case PL_UNIX_GROUP_NAME: - parser->item_length++; - if(c == ' ') { - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.group = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_SIZE; - parser->state.UNIX.sub.size = PL_UNIX_SIZE_PRESPACE; - parser->item_offset = 0; - parser->item_length = 0; - } - break; - } - break; - case PL_UNIX_SIZE: - switch(parser->state.UNIX.sub.size) { - case PL_UNIX_SIZE_PRESPACE: - if(c != ' ') { - if(c >= '0' && c <= '9') { - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - parser->state.UNIX.sub.size = PL_UNIX_SIZE_NUMBER; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - break; - case PL_UNIX_SIZE_NUMBER: - parser->item_length++; - if(c == ' ') { - char *p; - curl_off_t fsize; - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - fsize = curlx_strtoofft(finfo->b_data+parser->item_offset, &p, 10); - if(p[0] == '\0' && fsize != CURL_OFF_T_MAX && - fsize != CURL_OFF_T_MIN) { - parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE; - parser->file_data->size = fsize; - } - parser->item_length = 0; - parser->item_offset = 0; - parser->state.UNIX.main = PL_UNIX_TIME; - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART1; - } - else if(!ISDIGIT(c)) { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - } - break; - case PL_UNIX_TIME: - switch(parser->state.UNIX.sub.time) { - case PL_UNIX_TIME_PREPART1: - if(c != ' ') { - if(ISALNUM(c)) { - parser->item_offset = finfo->b_used -1; - parser->item_length = 1; - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART1; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - break; - case PL_UNIX_TIME_PART1: - parser->item_length++; - if(c == ' ') { - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART2; - } - else if(!ISALNUM(c) && c != '.') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - case PL_UNIX_TIME_PREPART2: - parser->item_length++; - if(c != ' ') { - if(ISALNUM(c)) { - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART2; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - break; - case PL_UNIX_TIME_PART2: - parser->item_length++; - if(c == ' ') { - parser->state.UNIX.sub.time = PL_UNIX_TIME_PREPART3; - } - else if(!ISALNUM(c) && c != '.') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - case PL_UNIX_TIME_PREPART3: - parser->item_length++; - if(c != ' ') { - if(ISALNUM(c)) { - parser->state.UNIX.sub.time = PL_UNIX_TIME_PART3; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - break; - case PL_UNIX_TIME_PART3: - parser->item_length++; - if(c == ' ') { - finfo->b_data[parser->item_offset + parser->item_length -1] = 0; - parser->offsets.time = parser->item_offset; - /* - if(ftp_pl_gettime(parser, finfo->b_data + parser->item_offset)) { - parser->file_data->flags |= CURLFINFOFLAG_KNOWN_TIME; - } - */ - if(finfo->filetype == CURLFILETYPE_SYMLINK) { - parser->state.UNIX.main = PL_UNIX_SYMLINK; - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRESPACE; - } - else { - parser->state.UNIX.main = PL_UNIX_FILENAME; - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_PRESPACE; - } - } - else if(!ISALNUM(c) && c != '.' && c != ':') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - } - break; - case PL_UNIX_FILENAME: - switch(parser->state.UNIX.sub.filename) { - case PL_UNIX_FILENAME_PRESPACE: - if(c != ' ') { - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_NAME; - } - break; - case PL_UNIX_FILENAME_NAME: - parser->item_length++; - if(c == '\r') { - parser->state.UNIX.sub.filename = PL_UNIX_FILENAME_WINDOWSEOL; - } - else if(c == '\n') { - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.filename = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(conn, finfo); - if(result) { - PL_ERROR(conn, result); - return bufflen; - } - } - break; - case PL_UNIX_FILENAME_WINDOWSEOL: - if(c == '\n') { - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.filename = parser->item_offset; - parser->state.UNIX.main = PL_UNIX_FILETYPE; - result = ftp_pl_insert_finfo(conn, finfo); - if(result) { - PL_ERROR(conn, result); - return bufflen; - } - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - } - break; - case PL_UNIX_SYMLINK: - switch(parser->state.UNIX.sub.symlink) { - case PL_UNIX_SYMLINK_PRESPACE: - if(c != ' ') { - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - break; - case PL_UNIX_SYMLINK_NAME: - parser->item_length++; - if(c == ' ') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET1; - } - else if(c == '\r' || c == '\n') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - case PL_UNIX_SYMLINK_PRETARGET1: - parser->item_length++; - if(c == '-') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET2; - } - else if(c == '\r' || c == '\n') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - else { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - break; - case PL_UNIX_SYMLINK_PRETARGET2: - parser->item_length++; - if(c == '>') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET3; - } - else if(c == '\r' || c == '\n') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - else { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - break; - case PL_UNIX_SYMLINK_PRETARGET3: - parser->item_length++; - if(c == ' ') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_PRETARGET4; - /* now place where is symlink following */ - finfo->b_data[parser->item_offset + parser->item_length - 4] = 0; - parser->offsets.filename = parser->item_offset; - parser->item_length = 0; - parser->item_offset = 0; - } - else if(c == '\r' || c == '\n') { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - else { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_NAME; - } - break; - case PL_UNIX_SYMLINK_PRETARGET4: - if(c != '\r' && c != '\n') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_TARGET; - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - case PL_UNIX_SYMLINK_TARGET: - parser->item_length++; - if(c == '\r') { - parser->state.UNIX.sub.symlink = PL_UNIX_SYMLINK_WINDOWSEOL; - } - else if(c == '\n') { - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.symlink_target = parser->item_offset; - result = ftp_pl_insert_finfo(conn, finfo); - if(result) { - PL_ERROR(conn, result); - return bufflen; - } - parser->state.UNIX.main = PL_UNIX_FILETYPE; - } - break; - case PL_UNIX_SYMLINK_WINDOWSEOL: - if(c == '\n') { - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - parser->offsets.symlink_target = parser->item_offset; - result = ftp_pl_insert_finfo(conn, finfo); - if(result) { - PL_ERROR(conn, result); - return bufflen; - } - parser->state.UNIX.main = PL_UNIX_FILETYPE; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - } - break; - } - break; - case OS_TYPE_WIN_NT: - switch(parser->state.NT.main) { - case PL_WINNT_DATE: - parser->item_length++; - if(parser->item_length < 9) { - if(!strchr("0123456789-", c)) { /* only simple control */ - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - else if(parser->item_length == 9) { - if(c == ' ') { - parser->state.NT.main = PL_WINNT_TIME; - parser->state.NT.sub.time = PL_WINNT_TIME_PRESPACE; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - case PL_WINNT_TIME: - parser->item_length++; - switch(parser->state.NT.sub.time) { - case PL_WINNT_TIME_PRESPACE: - if(!ISSPACE(c)) { - parser->state.NT.sub.time = PL_WINNT_TIME_TIME; - } - break; - case PL_WINNT_TIME_TIME: - if(c == ' ') { - parser->offsets.time = parser->item_offset; - finfo->b_data[parser->item_offset + parser->item_length -1] = 0; - parser->state.NT.main = PL_WINNT_DIRORSIZE; - parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_PRESPACE; - parser->item_length = 0; - } - else if(!strchr("APM0123456789:", c)) { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - } - break; - case PL_WINNT_DIRORSIZE: - switch(parser->state.NT.sub.dirorsize) { - case PL_WINNT_DIRORSIZE_PRESPACE: - if(c == ' ') { - - } - else { - parser->item_offset = finfo->b_used - 1; - parser->item_length = 1; - parser->state.NT.sub.dirorsize = PL_WINNT_DIRORSIZE_CONTENT; - } - break; - case PL_WINNT_DIRORSIZE_CONTENT: - parser->item_length ++; - if(c == ' ') { - finfo->b_data[parser->item_offset + parser->item_length - 1] = 0; - if(strcmp("", finfo->b_data + parser->item_offset) == 0) { - finfo->filetype = CURLFILETYPE_DIRECTORY; - finfo->size = 0; - } - else { - char *endptr; - finfo->size = curlx_strtoofft(finfo->b_data + - parser->item_offset, - &endptr, 10); - if(!*endptr) { - if(finfo->size == CURL_OFF_T_MAX || - finfo->size == CURL_OFF_T_MIN) { - if(errno == ERANGE) { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - } - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - /* correct file type */ - parser->file_data->filetype = CURLFILETYPE_FILE; - } - - parser->file_data->flags |= CURLFINFOFLAG_KNOWN_SIZE; - parser->item_length = 0; - parser->state.NT.main = PL_WINNT_FILENAME; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; - } - break; - } - break; - case PL_WINNT_FILENAME: - switch (parser->state.NT.sub.filename) { - case PL_WINNT_FILENAME_PRESPACE: - if(c != ' ') { - parser->item_offset = finfo->b_used -1; - parser->item_length = 1; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_CONTENT; - } - break; - case PL_WINNT_FILENAME_CONTENT: - parser->item_length++; - if(c == '\r') { - parser->state.NT.sub.filename = PL_WINNT_FILENAME_WINEOL; - finfo->b_data[finfo->b_used - 1] = 0; - } - else if(c == '\n') { - parser->offsets.filename = parser->item_offset; - finfo->b_data[finfo->b_used - 1] = 0; - parser->offsets.filename = parser->item_offset; - result = ftp_pl_insert_finfo(conn, finfo); - if(result) { - PL_ERROR(conn, result); - return bufflen; - } - parser->state.NT.main = PL_WINNT_DATE; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; - } - break; - case PL_WINNT_FILENAME_WINEOL: - if(c == '\n') { - parser->offsets.filename = parser->item_offset; - result = ftp_pl_insert_finfo(conn, finfo); - if(result) { - PL_ERROR(conn, result); - return bufflen; - } - parser->state.NT.main = PL_WINNT_DATE; - parser->state.NT.sub.filename = PL_WINNT_FILENAME_PRESPACE; - } - else { - PL_ERROR(conn, CURLE_FTP_BAD_FILE_LIST); - return bufflen; - } - break; - } - break; - } - break; - default: - return bufflen + 1; - } - - i++; - } - - return bufflen; -} - -#endif /* CURL_DISABLE_FTP */ diff --git a/Externals/curl/lib/ftplistparser.h b/Externals/curl/lib/ftplistparser.h deleted file mode 100644 index 8128887c0b..0000000000 --- a/Externals/curl/lib/ftplistparser.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef HEADER_CURL_FTPLISTPARSER_H -#define HEADER_CURL_FTPLISTPARSER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP - -/* WRITEFUNCTION callback for parsing LIST responses */ -size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb, - void *connptr); - -struct ftp_parselist_data; /* defined inside ftplibparser.c */ - -CURLcode Curl_ftp_parselist_geterror(struct ftp_parselist_data *pl_data); - -struct ftp_parselist_data *Curl_ftp_parselist_data_alloc(void); - -void Curl_ftp_parselist_data_free(struct ftp_parselist_data **pl_data); - -#endif /* CURL_DISABLE_FTP */ -#endif /* HEADER_CURL_FTPLISTPARSER_H */ diff --git a/Externals/curl/lib/getenv.c b/Externals/curl/lib/getenv.c deleted file mode 100644 index 50bb79f536..0000000000 --- a/Externals/curl/lib/getenv.c +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include -#include "curl_memory.h" - -#include "memdebug.h" - -static -char *GetEnv(const char *variable) -{ -#ifdef _WIN32_WCE - return NULL; -#else -#ifdef WIN32 - char env[MAX_PATH]; /* MAX_PATH is from windef.h */ - char *temp = getenv(variable); - env[0] = '\0'; - if(temp != NULL) - ExpandEnvironmentStringsA(temp, env, sizeof(env)); - return (env[0] != '\0')?strdup(env):NULL; -#else - char *env = getenv(variable); - return (env && env[0])?strdup(env):NULL; -#endif -#endif -} - -char *curl_getenv(const char *v) -{ - return GetEnv(v); -} diff --git a/Externals/curl/lib/getinfo.c b/Externals/curl/lib/getinfo.c deleted file mode 100644 index d4b01bf299..0000000000 --- a/Externals/curl/lib/getinfo.c +++ /dev/null @@ -1,402 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "urldata.h" -#include "getinfo.h" - -#include "vtls/vtls.h" -#include "connect.h" /* Curl_getconnectinfo() */ -#include "progress.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * This is supposed to be called in the beginning of a perform() session - * and should reset all session-info variables - */ -CURLcode Curl_initinfo(struct SessionHandle *data) -{ - struct Progress *pro = &data->progress; - struct PureInfo *info = &data->info; - - pro->t_nslookup = 0; - pro->t_connect = 0; - pro->t_appconnect = 0; - pro->t_pretransfer = 0; - pro->t_starttransfer = 0; - pro->timespent = 0; - pro->t_redirect = 0; - - info->httpcode = 0; - info->httpproxycode = 0; - info->httpversion = 0; - info->filetime = -1; /* -1 is an illegal time and thus means unknown */ - info->timecond = FALSE; - - free(info->contenttype); - info->contenttype = NULL; - - info->header_size = 0; - info->request_size = 0; - info->numconnects = 0; - - info->conn_primary_ip[0] = '\0'; - info->conn_local_ip[0] = '\0'; - info->conn_primary_port = 0; - info->conn_local_port = 0; - - return CURLE_OK; -} - -static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info, - char **param_charp) -{ - switch(info) { - case CURLINFO_EFFECTIVE_URL: - *param_charp = data->change.url?data->change.url:(char *)""; - break; - case CURLINFO_CONTENT_TYPE: - *param_charp = data->info.contenttype; - break; - case CURLINFO_PRIVATE: - *param_charp = (char *) data->set.private_data; - break; - case CURLINFO_FTP_ENTRY_PATH: - /* Return the entrypath string from the most recent connection. - This pointer was copied from the connectdata structure by FTP. - The actual string may be free()ed by subsequent libcurl calls so - it must be copied to a safer area before the next libcurl call. - Callers must never free it themselves. */ - *param_charp = data->state.most_recent_ftp_entrypath; - break; - case CURLINFO_REDIRECT_URL: - /* Return the URL this request would have been redirected to if that - option had been enabled! */ - *param_charp = data->info.wouldredirect; - break; - case CURLINFO_PRIMARY_IP: - /* Return the ip address of the most recent (primary) connection */ - *param_charp = data->info.conn_primary_ip; - break; - case CURLINFO_LOCAL_IP: - /* Return the source/local ip address of the most recent (primary) - connection */ - *param_charp = data->info.conn_local_ip; - break; - case CURLINFO_RTSP_SESSION_ID: - *param_charp = data->set.str[STRING_RTSP_SESSION_ID]; - break; - - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info, - long *param_longp) -{ - curl_socket_t sockfd; - - union { - unsigned long *to_ulong; - long *to_long; - } lptr; - - switch(info) { - case CURLINFO_RESPONSE_CODE: - *param_longp = data->info.httpcode; - break; - case CURLINFO_HTTP_CONNECTCODE: - *param_longp = data->info.httpproxycode; - break; - case CURLINFO_FILETIME: - *param_longp = data->info.filetime; - break; - case CURLINFO_HEADER_SIZE: - *param_longp = data->info.header_size; - break; - case CURLINFO_REQUEST_SIZE: - *param_longp = data->info.request_size; - break; - case CURLINFO_SSL_VERIFYRESULT: - *param_longp = data->set.ssl.certverifyresult; - break; - case CURLINFO_REDIRECT_COUNT: - *param_longp = data->set.followlocation; - break; - case CURLINFO_HTTPAUTH_AVAIL: - lptr.to_long = param_longp; - *lptr.to_ulong = data->info.httpauthavail; - break; - case CURLINFO_PROXYAUTH_AVAIL: - lptr.to_long = param_longp; - *lptr.to_ulong = data->info.proxyauthavail; - break; - case CURLINFO_OS_ERRNO: - *param_longp = data->state.os_errno; - break; - case CURLINFO_NUM_CONNECTS: - *param_longp = data->info.numconnects; - break; - case CURLINFO_LASTSOCKET: - sockfd = Curl_getconnectinfo(data, NULL); - - /* note: this is not a good conversion for systems with 64 bit sockets and - 32 bit longs */ - if(sockfd != CURL_SOCKET_BAD) - *param_longp = (long)sockfd; - else - /* this interface is documented to return -1 in case of badness, which - may not be the same as the CURL_SOCKET_BAD value */ - *param_longp = -1; - break; - case CURLINFO_PRIMARY_PORT: - /* Return the (remote) port of the most recent (primary) connection */ - *param_longp = data->info.conn_primary_port; - break; - case CURLINFO_LOCAL_PORT: - /* Return the local port of the most recent (primary) connection */ - *param_longp = data->info.conn_local_port; - break; - case CURLINFO_CONDITION_UNMET: - /* return if the condition prevented the document to get transferred */ - *param_longp = data->info.timecond ? 1L : 0L; - break; - case CURLINFO_RTSP_CLIENT_CSEQ: - *param_longp = data->state.rtsp_next_client_CSeq; - break; - case CURLINFO_RTSP_SERVER_CSEQ: - *param_longp = data->state.rtsp_next_server_CSeq; - break; - case CURLINFO_RTSP_CSEQ_RECV: - *param_longp = data->state.rtsp_CSeq_recv; - break; - - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info, - double *param_doublep) -{ - switch(info) { - case CURLINFO_TOTAL_TIME: - *param_doublep = data->progress.timespent; - break; - case CURLINFO_NAMELOOKUP_TIME: - *param_doublep = data->progress.t_nslookup; - break; - case CURLINFO_CONNECT_TIME: - *param_doublep = data->progress.t_connect; - break; - case CURLINFO_APPCONNECT_TIME: - *param_doublep = data->progress.t_appconnect; - break; - case CURLINFO_PRETRANSFER_TIME: - *param_doublep = data->progress.t_pretransfer; - break; - case CURLINFO_STARTTRANSFER_TIME: - *param_doublep = data->progress.t_starttransfer; - break; - case CURLINFO_SIZE_UPLOAD: - *param_doublep = (double)data->progress.uploaded; - break; - case CURLINFO_SIZE_DOWNLOAD: - *param_doublep = (double)data->progress.downloaded; - break; - case CURLINFO_SPEED_DOWNLOAD: - *param_doublep = (double)data->progress.dlspeed; - break; - case CURLINFO_SPEED_UPLOAD: - *param_doublep = (double)data->progress.ulspeed; - break; - case CURLINFO_CONTENT_LENGTH_DOWNLOAD: - *param_doublep = (data->progress.flags & PGRS_DL_SIZE_KNOWN)? - (double)data->progress.size_dl:-1; - break; - case CURLINFO_CONTENT_LENGTH_UPLOAD: - *param_doublep = (data->progress.flags & PGRS_UL_SIZE_KNOWN)? - (double)data->progress.size_ul:-1; - break; - case CURLINFO_REDIRECT_TIME: - *param_doublep = data->progress.t_redirect; - break; - - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info, - struct curl_slist **param_slistp) -{ - union { - struct curl_certinfo *to_certinfo; - struct curl_slist *to_slist; - } ptr; - - switch(info) { - case CURLINFO_SSL_ENGINES: - *param_slistp = Curl_ssl_engines_list(data); - break; - case CURLINFO_COOKIELIST: - *param_slistp = Curl_cookie_list(data); - break; - case CURLINFO_CERTINFO: - /* Return the a pointer to the certinfo struct. Not really an slist - pointer but we can pretend it is here */ - ptr.to_certinfo = &data->info.certs; - *param_slistp = ptr.to_slist; - break; - case CURLINFO_TLS_SESSION: - case CURLINFO_TLS_SSL_PTR: - { - struct curl_tlssessioninfo **tsip = (struct curl_tlssessioninfo **) - param_slistp; - struct curl_tlssessioninfo *tsi = &data->tsi; - struct connectdata *conn = data->easy_conn; - - *tsip = tsi; - tsi->backend = Curl_ssl_backend(); - tsi->internals = NULL; - - if(conn && tsi->backend != CURLSSLBACKEND_NONE) { - unsigned int i; - for(i = 0; i < (sizeof(conn->ssl) / sizeof(conn->ssl[0])); ++i) { - if(conn->ssl[i].use) { -#if defined(USE_AXTLS) - tsi->internals = (void *)conn->ssl[i].ssl; -#elif defined(USE_CYASSL) - tsi->internals = (void *)conn->ssl[i].handle; -#elif defined(USE_DARWINSSL) - tsi->internals = (void *)conn->ssl[i].ssl_ctx; -#elif defined(USE_GNUTLS) - tsi->internals = (void *)conn->ssl[i].session; -#elif defined(USE_GSKIT) - tsi->internals = (void *)conn->ssl[i].handle; -#elif defined(USE_MBEDTLS) - tsi->internals = (void *)&conn->ssl[i].ssl; -#elif defined(USE_NSS) - tsi->internals = (void *)conn->ssl[i].handle; -#elif defined(USE_OPENSSL) - /* Legacy: CURLINFO_TLS_SESSION must return an SSL_CTX pointer. */ - tsi->internals = ((info == CURLINFO_TLS_SESSION) ? - (void *)conn->ssl[i].ctx : - (void *)conn->ssl[i].handle); -#elif defined(USE_POLARSSL) - tsi->internals = (void *)&conn->ssl[i].ssl; -#elif defined(USE_SCHANNEL) - tsi->internals = (void *)&conn->ssl[i].ctxt->ctxt_handle; -#elif defined(USE_SSL) -#error "SSL backend specific information missing for CURLINFO_TLS_SSL_PTR" -#endif - break; - } - } - } - } - break; - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -static CURLcode getinfo_socket(struct SessionHandle *data, CURLINFO info, - curl_socket_t *param_socketp) -{ - switch(info) { - case CURLINFO_ACTIVESOCKET: - *param_socketp = Curl_getconnectinfo(data, NULL); - break; - default: - return CURLE_UNKNOWN_OPTION; - } - - return CURLE_OK; -} - -CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...) -{ - va_list arg; - long *param_longp = NULL; - double *param_doublep = NULL; - char **param_charp = NULL; - struct curl_slist **param_slistp = NULL; - curl_socket_t *param_socketp = NULL; - int type; - CURLcode result = CURLE_UNKNOWN_OPTION; - - if(!data) - return result; - - va_start(arg, info); - - type = CURLINFO_TYPEMASK & (int)info; - switch(type) { - case CURLINFO_STRING: - param_charp = va_arg(arg, char **); - if(param_charp) - result = getinfo_char(data, info, param_charp); - break; - case CURLINFO_LONG: - param_longp = va_arg(arg, long *); - if(param_longp) - result = getinfo_long(data, info, param_longp); - break; - case CURLINFO_DOUBLE: - param_doublep = va_arg(arg, double *); - if(param_doublep) - result = getinfo_double(data, info, param_doublep); - break; - case CURLINFO_SLIST: - param_slistp = va_arg(arg, struct curl_slist **); - if(param_slistp) - result = getinfo_slist(data, info, param_slistp); - break; - case CURLINFO_SOCKET: - param_socketp = va_arg(arg, curl_socket_t *); - if(param_socketp) - result = getinfo_socket(data, info, param_socketp); - break; - default: - break; - } - - va_end(arg); - - return result; -} diff --git a/Externals/curl/lib/getinfo.h b/Externals/curl/lib/getinfo.h deleted file mode 100644 index 4c2c16848d..0000000000 --- a/Externals/curl/lib/getinfo.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef HEADER_CURL_GETINFO_H -#define HEADER_CURL_GETINFO_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...); -CURLcode Curl_initinfo(struct SessionHandle *data); - -#endif /* HEADER_CURL_GETINFO_H */ diff --git a/Externals/curl/lib/gopher.c b/Externals/curl/lib/gopher.c deleted file mode 100644 index 19f2f5a890..0000000000 --- a/Externals/curl/lib/gopher.c +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_GOPHER - -#include "urldata.h" -#include -#include "transfer.h" -#include "sendf.h" - -#include "progress.h" -#include "strequal.h" -#include "gopher.h" -#include "rawstr.h" -#include "select.h" -#include "url.h" -#include "warnless.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * Forward declarations. - */ - -static CURLcode gopher_do(struct connectdata *conn, bool *done); - -/* - * Gopher protocol handler. - * This is also a nice simple template to build off for simple - * connect-command-download protocols. - */ - -const struct Curl_handler Curl_handler_gopher = { - "GOPHER", /* scheme */ - ZERO_NULL, /* setup_connection */ - gopher_do, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_GOPHER, /* defport */ - CURLPROTO_GOPHER, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -static CURLcode gopher_do(struct connectdata *conn, bool *done) -{ - CURLcode result=CURLE_OK; - struct SessionHandle *data=conn->data; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; - - curl_off_t *bytecount = &data->req.bytecount; - char *path = data->state.path; - char *sel; - char *sel_org = NULL; - ssize_t amount, k; - int len; - - *done = TRUE; /* unconditionally */ - - /* Create selector. Degenerate cases: / and /1 => convert to "" */ - if(strlen(path) <= 2) { - sel = (char *)""; - len = (int)strlen(sel); - } - else { - char *newp; - size_t j, i; - - /* Otherwise, drop / and the first character (i.e., item type) ... */ - newp = path; - newp+=2; - - /* ... then turn ? into TAB for search servers, Veronica, etc. ... */ - j = strlen(newp); - for(i=0; i, et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifndef CURL_DISABLE_GOPHER -extern const struct Curl_handler Curl_handler_gopher; -#endif - -#endif /* HEADER_CURL_GOPHER_H */ diff --git a/Externals/curl/lib/hash.c b/Externals/curl/lib/hash.c deleted file mode 100644 index 937381b659..0000000000 --- a/Externals/curl/lib/hash.c +++ /dev/null @@ -1,390 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "hash.h" -#include "llist.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -static void -hash_element_dtor(void *user, void *element) -{ - struct curl_hash *h = (struct curl_hash *) user; - struct curl_hash_element *e = (struct curl_hash_element *) element; - - Curl_safefree(e->key); - - if(e->ptr) { - h->dtor(e->ptr); - e->ptr = NULL; - } - - e->key_len = 0; - - free(e); -} - -/* Initializes a hash structure. - * Return 1 on error, 0 is fine. - * - * @unittest: 1602 - * @unittest: 1603 - */ -int -Curl_hash_init(struct curl_hash *h, - int slots, - hash_function hfunc, - comp_function comparator, - curl_hash_dtor dtor) -{ - int i; - - if(!slots || !hfunc || !comparator ||!dtor) { - return 1; /* failure */ - } - - h->hash_func = hfunc; - h->comp_func = comparator; - h->dtor = dtor; - h->size = 0; - h->slots = slots; - - h->table = malloc(slots * sizeof(struct curl_llist *)); - if(h->table) { - for(i = 0; i < slots; ++i) { - h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor); - if(!h->table[i]) { - while(i--) { - Curl_llist_destroy(h->table[i], NULL); - h->table[i] = NULL; - } - free(h->table); - h->table = NULL; - h->slots = 0; - return 1; /* failure */ - } - } - return 0; /* fine */ - } - else { - h->slots = 0; - return 1; /* failure */ - } -} - -static struct curl_hash_element * -mk_hash_element(const void *key, size_t key_len, const void *p) -{ - struct curl_hash_element *he = malloc(sizeof(struct curl_hash_element)); - - if(he) { - void *dupkey = malloc(key_len); - if(dupkey) { - /* copy the key */ - memcpy(dupkey, key, key_len); - - he->key = dupkey; - he->key_len = key_len; - he->ptr = (void *) p; - } - else { - /* failed to duplicate the key, free memory and fail */ - free(he); - he = NULL; - } - } - return he; -} - -#define FETCH_LIST(x,y,z) x->table[x->hash_func(y, z, x->slots)] - -/* Insert the data in the hash. If there already was a match in the hash, - * that data is replaced. - * - * @unittest: 1305 - * @unittest: 1602 - * @unittest: 1603 - */ -void * -Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p) -{ - struct curl_hash_element *he; - struct curl_llist_element *le; - struct curl_llist *l = FETCH_LIST (h, key, key_len); - - for(le = l->head; le; le = le->next) { - he = (struct curl_hash_element *) le->ptr; - if(h->comp_func(he->key, he->key_len, key, key_len)) { - Curl_llist_remove(l, le, (void *)h); - --h->size; - break; - } - } - - he = mk_hash_element(key, key_len, p); - if(he) { - if(Curl_llist_insert_next(l, l->tail, he)) { - ++h->size; - return p; /* return the new entry */ - } - /* - * Couldn't insert it, destroy the 'he' element and the key again. We - * don't call hash_element_dtor() since that would also call the - * "destructor" for the actual data 'p'. When we fail, we shall not touch - * that data. - */ - free(he->key); - free(he); - } - - return NULL; /* failure */ -} - -/* Remove the identified hash entry. - * Returns non-zero on failure. - * - * @unittest: 1603 - */ -int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len) -{ - struct curl_llist_element *le; - struct curl_hash_element *he; - struct curl_llist *l = FETCH_LIST(h, key, key_len); - - for(le = l->head; le; le = le->next) { - he = le->ptr; - if(h->comp_func(he->key, he->key_len, key, key_len)) { - Curl_llist_remove(l, le, (void *) h); - --h->size; - return 0; - } - } - return 1; -} - -/* Retrieves a hash element. - * - * @unittest: 1603 - */ -void * -Curl_hash_pick(struct curl_hash *h, void *key, size_t key_len) -{ - struct curl_llist_element *le; - struct curl_hash_element *he; - struct curl_llist *l; - - if(h) { - l = FETCH_LIST(h, key, key_len); - for(le = l->head; le; le = le->next) { - he = le->ptr; - if(h->comp_func(he->key, he->key_len, key, key_len)) { - return he->ptr; - } - } - } - - return NULL; -} - -#if defined(DEBUGBUILD) && defined(AGGRESIVE_TEST) -void -Curl_hash_apply(curl_hash *h, void *user, - void (*cb)(void *user, void *ptr)) -{ - struct curl_llist_element *le; - int i; - - for(i = 0; i < h->slots; ++i) { - for(le = (h->table[i])->head; - le; - le = le->next) { - curl_hash_element *el = le->ptr; - cb(user, el->ptr); - } - } -} -#endif - -/* Destroys all the entries in the given hash and resets its attributes, - * prepping the given hash for [static|dynamic] deallocation. - * - * @unittest: 1305 - * @unittest: 1602 - * @unittest: 1603 - */ -void -Curl_hash_destroy(struct curl_hash *h) -{ - int i; - - for(i = 0; i < h->slots; ++i) { - Curl_llist_destroy(h->table[i], (void *) h); - h->table[i] = NULL; - } - - Curl_safefree(h->table); - h->size = 0; - h->slots = 0; -} - -/* Removes all the entries in the given hash. - * - * @unittest: 1602 - */ -void -Curl_hash_clean(struct curl_hash *h) -{ - Curl_hash_clean_with_criterium(h, NULL, NULL); -} - -/* Cleans all entries that pass the comp function criteria. */ -void -Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, - int (*comp)(void *, void *)) -{ - struct curl_llist_element *le; - struct curl_llist_element *lnext; - struct curl_llist *list; - int i; - - if(!h) - return; - - for(i = 0; i < h->slots; ++i) { - list = h->table[i]; - le = list->head; /* get first list entry */ - while(le) { - struct curl_hash_element *he = le->ptr; - lnext = le->next; - /* ask the callback function if we shall remove this entry or not */ - if(comp == NULL || comp(user, he->ptr)) { - Curl_llist_remove(list, le, (void *) h); - --h->size; /* one less entry in the hash now */ - } - le = lnext; - } - } -} - -size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num) -{ - const char* key_str = (const char *) key; - const char *end = key_str + key_length; - unsigned long h = 5381; - - while(key_str < end) { - h += h << 5; - h ^= (unsigned long) *key_str++; - } - - return (h % slots_num); -} - -size_t Curl_str_key_compare(void *k1, size_t key1_len, - void *k2, size_t key2_len) -{ - if((key1_len == key2_len) && !memcmp(k1, k2, key1_len)) - return 1; - - return 0; -} - -void Curl_hash_start_iterate(struct curl_hash *hash, - struct curl_hash_iterator *iter) -{ - iter->hash = hash; - iter->slot_index = 0; - iter->current_element = NULL; -} - -struct curl_hash_element * -Curl_hash_next_element(struct curl_hash_iterator *iter) -{ - int i; - struct curl_hash *h = iter->hash; - - /* Get the next element in the current list, if any */ - if(iter->current_element) - iter->current_element = iter->current_element->next; - - /* If we have reached the end of the list, find the next one */ - if(!iter->current_element) { - for(i = iter->slot_index;i < h->slots;i++) { - if(h->table[i]->head) { - iter->current_element = h->table[i]->head; - iter->slot_index = i+1; - break; - } - } - } - - if(iter->current_element) { - struct curl_hash_element *he = iter->current_element->ptr; - return he; - } - else { - iter->current_element = NULL; - return NULL; - } -} - -#if 0 /* useful function for debugging hashes and their contents */ -void Curl_hash_print(struct curl_hash *h, - void (*func)(void *)) -{ - struct curl_hash_iterator iter; - struct curl_hash_element *he; - int last_index = -1; - - if(!h) - return; - - fprintf(stderr, "=Hash dump=\n"); - - Curl_hash_start_iterate(h, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - if(iter.slot_index != last_index) { - fprintf(stderr, "index %d:", iter.slot_index); - if(last_index >= 0) { - fprintf(stderr, "\n"); - } - last_index = iter.slot_index; - } - - if(func) - func(he->ptr); - else - fprintf(stderr, " [%p]", (void *)he->ptr); - - he = Curl_hash_next_element(&iter); - } - fprintf(stderr, "\n"); -} -#endif diff --git a/Externals/curl/lib/hash.h b/Externals/curl/lib/hash.h deleted file mode 100644 index 57a17f02ab..0000000000 --- a/Externals/curl/lib/hash.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef HEADER_CURL_HASH_H -#define HEADER_CURL_HASH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "llist.h" - -/* Hash function prototype */ -typedef size_t (*hash_function) (void* key, - size_t key_length, - size_t slots_num); - -/* - Comparator function prototype. Compares two keys. -*/ -typedef size_t (*comp_function) (void* key1, - size_t key1_len, - void*key2, - size_t key2_len); - -typedef void (*curl_hash_dtor)(void *); - -struct curl_hash { - struct curl_llist **table; - - /* Hash function to be used for this hash table */ - hash_function hash_func; - - /* Comparator function to compare keys */ - comp_function comp_func; - curl_hash_dtor dtor; - int slots; - size_t size; -}; - -struct curl_hash_element { - void *ptr; - char *key; - size_t key_len; -}; - -struct curl_hash_iterator { - struct curl_hash *hash; - int slot_index; - struct curl_llist_element *current_element; -}; - -int Curl_hash_init(struct curl_hash *h, - int slots, - hash_function hfunc, - comp_function comparator, - curl_hash_dtor dtor); - -void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p); -int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len); -void *Curl_hash_pick(struct curl_hash *, void * key, size_t key_len); -void Curl_hash_apply(struct curl_hash *h, void *user, - void (*cb)(void *user, void *ptr)); -int Curl_hash_count(struct curl_hash *h); -void Curl_hash_destroy(struct curl_hash *h); -void Curl_hash_clean(struct curl_hash *h); -void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user, - int (*comp)(void *, void *)); -size_t Curl_hash_str(void* key, size_t key_length, size_t slots_num); -size_t Curl_str_key_compare(void*k1, size_t key1_len, void*k2, - size_t key2_len); - -void Curl_hash_start_iterate(struct curl_hash *hash, - struct curl_hash_iterator *iter); -struct curl_hash_element * -Curl_hash_next_element(struct curl_hash_iterator *iter); - -void Curl_hash_print(struct curl_hash *h, - void (*func)(void *)); - - -#endif /* HEADER_CURL_HASH_H */ diff --git a/Externals/curl/lib/hmac.c b/Externals/curl/lib/hmac.c deleted file mode 100644 index 3df4715850..0000000000 --- a/Externals/curl/lib/hmac.c +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC2104 Keyed-Hashing for Message Authentication - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_CRYPTO_AUTH - -#include - -#include "curl_hmac.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * Generic HMAC algorithm. - * - * This module computes HMAC digests based on any hash function. Parameters - * and computing procedures are set-up dynamically at HMAC computation - * context initialisation. - */ - -static const unsigned char hmac_ipad = 0x36; -static const unsigned char hmac_opad = 0x5C; - - - -HMAC_context * -Curl_HMAC_init(const HMAC_params * hashparams, - const unsigned char * key, - unsigned int keylen) -{ - size_t i; - HMAC_context * ctxt; - unsigned char * hkey; - unsigned char b; - - /* Create HMAC context. */ - i = sizeof *ctxt + 2 * hashparams->hmac_ctxtsize + - hashparams->hmac_resultlen; - ctxt = malloc(i); - - if(!ctxt) - return ctxt; - - ctxt->hmac_hash = hashparams; - ctxt->hmac_hashctxt1 = (void *) (ctxt + 1); - ctxt->hmac_hashctxt2 = (void *) ((char *) ctxt->hmac_hashctxt1 + - hashparams->hmac_ctxtsize); - - /* If the key is too long, replace it by its hash digest. */ - if(keylen > hashparams->hmac_maxkeylen) { - (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1); - (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, key, keylen); - hkey = (unsigned char *) ctxt->hmac_hashctxt2 + hashparams->hmac_ctxtsize; - (*hashparams->hmac_hfinal)(hkey, ctxt->hmac_hashctxt1); - key = hkey; - keylen = hashparams->hmac_resultlen; - } - - /* Prime the two hash contexts with the modified key. */ - (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1); - (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2); - - for(i = 0; i < keylen; i++) { - b = (unsigned char)(*key ^ hmac_ipad); - (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1); - b = (unsigned char)(*key++ ^ hmac_opad); - (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1); - } - - for(; i < hashparams->hmac_maxkeylen; i++) { - (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1); - (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1); - } - - /* Done, return pointer to HMAC context. */ - return ctxt; -} - -int Curl_HMAC_update(HMAC_context * ctxt, - const unsigned char * data, - unsigned int len) -{ - /* Update first hash calculation. */ - (*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len); - return 0; -} - - -int Curl_HMAC_final(HMAC_context * ctxt, unsigned char * result) -{ - const HMAC_params * hashparams = ctxt->hmac_hash; - - /* Do not get result if called with a null parameter: only release - storage. */ - - if(!result) - result = (unsigned char *) ctxt->hmac_hashctxt2 + - ctxt->hmac_hash->hmac_ctxtsize; - - (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt1); - (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, - result, hashparams->hmac_resultlen); - (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt2); - free((char *) ctxt); - return 0; -} - -#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/Externals/curl/lib/hostasyn.c b/Externals/curl/lib/hostasyn.c deleted file mode 100644 index c96734a5af..0000000000 --- a/Externals/curl/lib/hostasyn.c +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_PROCESS_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for builds using asynchronous name resolves - **********************************************************************/ -#ifdef CURLRES_ASYNCH - -/* - * Curl_addrinfo_callback() gets called by ares, gethostbyname_thread() - * or getaddrinfo_thread() when we got the name resolved (or not!). - * - * If the status argument is CURL_ASYNC_SUCCESS, this function takes - * ownership of the Curl_addrinfo passed, storing the resolved data - * in the DNS cache. - * - * The storage operation locks and unlocks the DNS cache. - */ -CURLcode Curl_addrinfo_callback(struct connectdata *conn, - int status, - struct Curl_addrinfo *ai) -{ - struct Curl_dns_entry *dns = NULL; - CURLcode result = CURLE_OK; - - conn->async.status = status; - - if(CURL_ASYNC_SUCCESS == status) { - if(ai) { - struct SessionHandle *data = conn->data; - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - dns = Curl_cache_addr(data, ai, - conn->async.hostname, - conn->async.port); - if(!dns) { - /* failed to store, cleanup and return error */ - Curl_freeaddrinfo(ai); - result = CURLE_OUT_OF_MEMORY; - } - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - } - else { - result = CURLE_OUT_OF_MEMORY; - } - } - - conn->async.dns = dns; - - /* Set async.done TRUE last in this function since it may be used multi- - threaded and once this is TRUE the other thread may read fields from the - async struct */ - conn->async.done = TRUE; - - /* IPv4: The input hostent struct will be freed by ares when we return from - this function */ - return result; -} - -/* Call this function after Curl_connect() has returned async=TRUE and - then a successful name resolve has been received. - - Note: this function disconnects and frees the conn data in case of - resolve failure */ -CURLcode Curl_async_resolved(struct connectdata *conn, - bool *protocol_done) -{ - CURLcode result; - - if(conn->async.dns) { - conn->dns_entry = conn->async.dns; - conn->async.dns = NULL; - } - - result = Curl_setup_conn(conn, protocol_done); - - if(result) - /* We're not allowed to return failure with memory left allocated - in the connectdata struct, free those here */ - Curl_disconnect(conn, FALSE); /* close the connection */ - - return result; -} - -/* - * Curl_getaddrinfo() is the generic low-level name resolve API within this - * source file. There are several versions of this function - for different - * name resolve layers (selected at build-time). They all take this same set - * of arguments - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) -{ - return Curl_resolver_getaddrinfo(conn, hostname, port, waitp); -} - -#endif /* CURLRES_ASYNCH */ diff --git a/Externals/curl/lib/hostcheck.c b/Externals/curl/lib/hostcheck.c deleted file mode 100644 index 4db9e6ba87..0000000000 --- a/Externals/curl/lib/hostcheck.c +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT) -/* these backends use functions from this file */ - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#include "hostcheck.h" -#include "rawstr.h" -#include "inet_pton.h" - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * Match a hostname against a wildcard pattern. - * E.g. - * "foo.host.com" matches "*.host.com". - * - * We use the matching rule described in RFC6125, section 6.4.3. - * https://tools.ietf.org/html/rfc6125#section-6.4.3 - * - * In addition: ignore trailing dots in the host names and wildcards, so that - * the names are used normalized. This is what the browsers do. - * - * Do not allow wildcard matching on IP numbers. There are apparently - * certificates being used with an IP address in the CN field, thus making no - * apparent distinction between a name and an IP. We need to detect the use of - * an IP address and not wildcard match on such names. - * - * NOTE: hostmatch() gets called with copied buffers so that it can modify the - * contents at will. - */ - -static int hostmatch(char *hostname, char *pattern) -{ - const char *pattern_label_end, *pattern_wildcard, *hostname_label_end; - int wildcard_enabled; - size_t prefixlen, suffixlen; - struct in_addr ignored; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 si6; -#endif - - /* normalize pattern and hostname by stripping off trailing dots */ - size_t len = strlen(hostname); - if(hostname[len-1]=='.') - hostname[len-1]=0; - len = strlen(pattern); - if(pattern[len-1]=='.') - pattern[len-1]=0; - - pattern_wildcard = strchr(pattern, '*'); - if(pattern_wildcard == NULL) - return Curl_raw_equal(pattern, hostname) ? - CURL_HOST_MATCH : CURL_HOST_NOMATCH; - - /* detect IP address as hostname and fail the match if so */ - if(Curl_inet_pton(AF_INET, hostname, &ignored) > 0) - return CURL_HOST_NOMATCH; -#ifdef ENABLE_IPV6 - else if(Curl_inet_pton(AF_INET6, hostname, &si6.sin6_addr) > 0) - return CURL_HOST_NOMATCH; -#endif - - /* We require at least 2 dots in pattern to avoid too wide wildcard - match. */ - wildcard_enabled = 1; - pattern_label_end = strchr(pattern, '.'); - if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL || - pattern_wildcard > pattern_label_end || - Curl_raw_nequal(pattern, "xn--", 4)) { - wildcard_enabled = 0; - } - if(!wildcard_enabled) - return Curl_raw_equal(pattern, hostname) ? - CURL_HOST_MATCH : CURL_HOST_NOMATCH; - - hostname_label_end = strchr(hostname, '.'); - if(hostname_label_end == NULL || - !Curl_raw_equal(pattern_label_end, hostname_label_end)) - return CURL_HOST_NOMATCH; - - /* The wildcard must match at least one character, so the left-most - label of the hostname is at least as large as the left-most label - of the pattern. */ - if(hostname_label_end - hostname < pattern_label_end - pattern) - return CURL_HOST_NOMATCH; - - prefixlen = pattern_wildcard - pattern; - suffixlen = pattern_label_end - (pattern_wildcard+1); - return Curl_raw_nequal(pattern, hostname, prefixlen) && - Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen, - suffixlen) ? - CURL_HOST_MATCH : CURL_HOST_NOMATCH; -} - -int Curl_cert_hostcheck(const char *match_pattern, const char *hostname) -{ - char *matchp; - char *hostp; - int res = 0; - if(!match_pattern || !*match_pattern || - !hostname || !*hostname) /* sanity check */ - ; - else { - matchp = strdup(match_pattern); - if(matchp) { - hostp = strdup(hostname); - if(hostp) { - if(hostmatch(hostp, matchp) == CURL_HOST_MATCH) - res= 1; - free(hostp); - } - free(matchp); - } - } - - return res; -} - -#endif /* OPENSSL or AXTLS or GSKIT */ diff --git a/Externals/curl/lib/hostcheck.h b/Externals/curl/lib/hostcheck.h deleted file mode 100644 index 86e3b96a97..0000000000 --- a/Externals/curl/lib/hostcheck.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef HEADER_CURL_HOSTCHECK_H -#define HEADER_CURL_HOSTCHECK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -#define CURL_HOST_NOMATCH 0 -#define CURL_HOST_MATCH 1 -int Curl_cert_hostcheck(const char *match_pattern, const char *hostname); - -#endif /* HEADER_CURL_HOSTCHECK_H */ - diff --git a/Externals/curl/lib/hostip.c b/Externals/curl/lib/hostip.c deleted file mode 100644 index ead78de729..0000000000 --- a/Externals/curl/lib/hostip.c +++ /dev/null @@ -1,881 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_SETJMP_H -#include -#endif -#ifdef HAVE_SIGNAL_H -#include -#endif - -#ifdef HAVE_PROCESS_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "inet_ntop.h" -#include "warnless.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#if defined(CURLRES_SYNCH) && \ - defined(HAVE_ALARM) && defined(SIGALRM) && defined(HAVE_SIGSETJMP) -/* alarm-based timeouts can only be used with all the dependencies satisfied */ -#define USE_ALARM_TIMEOUT -#endif - -/* - * hostip.c explained - * ================== - * - * The main COMPILE-TIME DEFINES to keep in mind when reading the host*.c - * source file are these: - * - * CURLRES_IPV6 - this host has getaddrinfo() and family, and thus we use - * that. The host may not be able to resolve IPv6, but we don't really have to - * take that into account. Hosts that aren't IPv6-enabled have CURLRES_IPV4 - * defined. - * - * CURLRES_ARES - is defined if libcurl is built to use c-ares for - * asynchronous name resolves. This can be Windows or *nix. - * - * CURLRES_THREADED - is defined if libcurl is built to run under (native) - * Windows, and then the name resolve will be done in a new thread, and the - * supported API will be the same as for ares-builds. - * - * If any of the two previous are defined, CURLRES_ASYNCH is defined too. If - * libcurl is not built to use an asynchronous resolver, CURLRES_SYNCH is - * defined. - * - * The host*.c sources files are split up like this: - * - * hostip.c - method-independent resolver functions and utility functions - * hostasyn.c - functions for asynchronous name resolves - * hostsyn.c - functions for synchronous name resolves - * hostip4.c - IPv4 specific functions - * hostip6.c - IPv6 specific functions - * - * The two asynchronous name resolver backends are implemented in: - * asyn-ares.c - functions for ares-using name resolves - * asyn-thread.c - functions for threaded name resolves - - * The hostip.h is the united header file for all this. It defines the - * CURLRES_* defines based on the config*.h and curl_setup.h defines. - */ - -/* These two symbols are for the global DNS cache */ -static struct curl_hash hostname_cache; -static int host_cache_initialized; - -static void freednsentry(void *freethis); - -/* - * Curl_global_host_cache_init() initializes and sets up a global DNS cache. - * Global DNS cache is general badness. Do not use. This will be removed in - * a future version. Use the share interface instead! - * - * Returns a struct curl_hash pointer on success, NULL on failure. - */ -struct curl_hash *Curl_global_host_cache_init(void) -{ - int rc = 0; - if(!host_cache_initialized) { - rc = Curl_hash_init(&hostname_cache, 7, Curl_hash_str, - Curl_str_key_compare, freednsentry); - if(!rc) - host_cache_initialized = 1; - } - return rc?NULL:&hostname_cache; -} - -/* - * Destroy and cleanup the global DNS cache - */ -void Curl_global_host_cache_dtor(void) -{ - if(host_cache_initialized) { - Curl_hash_destroy(&hostname_cache); - host_cache_initialized = 0; - } -} - -/* - * Return # of adresses in a Curl_addrinfo struct - */ -int Curl_num_addresses(const Curl_addrinfo *addr) -{ - int i = 0; - while(addr) { - addr = addr->ai_next; - i++; - } - return i; -} - -/* - * Curl_printable_address() returns a printable version of the 1st address - * given in the 'ai' argument. The result will be stored in the buf that is - * bufsize bytes big. - * - * If the conversion fails, it returns NULL. - */ -const char * -Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize) -{ - const struct sockaddr_in *sa4; - const struct in_addr *ipaddr4; -#ifdef ENABLE_IPV6 - const struct sockaddr_in6 *sa6; - const struct in6_addr *ipaddr6; -#endif - - switch (ai->ai_family) { - case AF_INET: - sa4 = (const void *)ai->ai_addr; - ipaddr4 = &sa4->sin_addr; - return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr4, buf, - bufsize); -#ifdef ENABLE_IPV6 - case AF_INET6: - sa6 = (const void *)ai->ai_addr; - ipaddr6 = &sa6->sin6_addr; - return Curl_inet_ntop(ai->ai_family, (const void *)ipaddr6, buf, - bufsize); -#endif - default: - break; - } - return NULL; -} - -/* - * Return a hostcache id string for the provided host + port, to be used by - * the DNS caching. - */ -static char * -create_hostcache_id(const char *name, int port) -{ - /* create and return the new allocated entry */ - char *id = aprintf("%s:%d", name, port); - char *ptr = id; - if(ptr) { - /* lower case the name part */ - while(*ptr && (*ptr != ':')) { - *ptr = (char)TOLOWER(*ptr); - ptr++; - } - } - return id; -} - -struct hostcache_prune_data { - long cache_timeout; - time_t now; -}; - -/* - * This function is set as a callback to be called for every entry in the DNS - * cache when we want to prune old unused entries. - * - * Returning non-zero means remove the entry, return 0 to keep it in the - * cache. - */ -static int -hostcache_timestamp_remove(void *datap, void *hc) -{ - struct hostcache_prune_data *data = - (struct hostcache_prune_data *) datap; - struct Curl_dns_entry *c = (struct Curl_dns_entry *) hc; - - return (0 != c->timestamp) - && (data->now - c->timestamp >= data->cache_timeout); -} - -/* - * Prune the DNS cache. This assumes that a lock has already been taken. - */ -static void -hostcache_prune(struct curl_hash *hostcache, long cache_timeout, time_t now) -{ - struct hostcache_prune_data user; - - user.cache_timeout = cache_timeout; - user.now = now; - - Curl_hash_clean_with_criterium(hostcache, - (void *) &user, - hostcache_timestamp_remove); -} - -/* - * Library-wide function for pruning the DNS cache. This function takes and - * returns the appropriate locks. - */ -void Curl_hostcache_prune(struct SessionHandle *data) -{ - time_t now; - - if((data->set.dns_cache_timeout == -1) || !data->dns.hostcache) - /* cache forever means never prune, and NULL hostcache means - we can't do it */ - return; - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - time(&now); - - /* Remove outdated and unused entries from the hostcache */ - hostcache_prune(data->dns.hostcache, - data->set.dns_cache_timeout, - now); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); -} - -#ifdef HAVE_SIGSETJMP -/* Beware this is a global and unique instance. This is used to store the - return address that we can jump back to from inside a signal handler. This - is not thread-safe stuff. */ -sigjmp_buf curl_jmpenv; -#endif - -/* lookup address, returns entry if found and not stale */ -static struct Curl_dns_entry * -fetch_addr(struct connectdata *conn, - const char *hostname, - int port) -{ - char *entry_id = NULL; - struct Curl_dns_entry *dns = NULL; - size_t entry_len; - struct SessionHandle *data = conn->data; - - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) - return dns; - - entry_len = strlen(entry_id); - - /* See if its already in our dns cache */ - dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1); - - if(dns && (data->set.dns_cache_timeout != -1)) { - /* See whether the returned entry is stale. Done before we release lock */ - struct hostcache_prune_data user; - - time(&user.now); - user.cache_timeout = data->set.dns_cache_timeout; - - if(hostcache_timestamp_remove(&user, dns)) { - infof(data, "Hostname in DNS cache was stale, zapped\n"); - dns = NULL; /* the memory deallocation is being handled by the hash */ - Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1); - } - } - - /* free the allocated entry_id again */ - free(entry_id); - - return dns; -} - -/* - * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache. - * - * Curl_resolv() checks initially and multi_runsingle() checks each time - * it discovers the handle in the state WAITRESOLVE whether the hostname - * has already been resolved and the address has already been stored in - * the DNS cache. This short circuits waiting for a lot of pending - * lookups for the same hostname requested by different handles. - * - * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. - * - * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after - * use, or we'll leak memory! - */ -struct Curl_dns_entry * -Curl_fetch_addr(struct connectdata *conn, - const char *hostname, - int port) -{ - struct SessionHandle *data = conn->data; - struct Curl_dns_entry *dns = NULL; - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - dns = fetch_addr(conn, hostname, port); - - if(dns) - dns->inuse++; /* we use it! */ - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - return dns; -} - -/* - * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. - * - * When calling Curl_resolv() has resulted in a response with a returned - * address, we call this function to store the information in the dns - * cache etc - * - * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. - */ -struct Curl_dns_entry * -Curl_cache_addr(struct SessionHandle *data, - Curl_addrinfo *addr, - const char *hostname, - int port) -{ - char *entry_id; - size_t entry_len; - struct Curl_dns_entry *dns; - struct Curl_dns_entry *dns2; - - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) - return NULL; - entry_len = strlen(entry_id); - - /* Create a new cache entry */ - dns = calloc(1, sizeof(struct Curl_dns_entry)); - if(!dns) { - free(entry_id); - return NULL; - } - - dns->inuse = 1; /* the cache has the first reference */ - dns->addr = addr; /* this is the address(es) */ - time(&dns->timestamp); - if(dns->timestamp == 0) - dns->timestamp = 1; /* zero indicates CURLOPT_RESOLVE entry */ - - /* Store the resolved data in our DNS cache. */ - dns2 = Curl_hash_add(data->dns.hostcache, entry_id, entry_len+1, - (void *)dns); - if(!dns2) { - free(dns); - free(entry_id); - return NULL; - } - - dns = dns2; - dns->inuse++; /* mark entry as in-use */ - - /* free the allocated entry_id */ - free(entry_id); - - return dns; -} - -/* - * Curl_resolv() is the main name resolve function within libcurl. It resolves - * a name and returns a pointer to the entry in the 'entry' argument (if one - * is provided). This function might return immediately if we're using asynch - * resolves. See the return codes. - * - * The cache entry we return will get its 'inuse' counter increased when this - * function is used. You MUST call Curl_resolv_unlock() later (when you're - * done using this struct) to decrease the counter again. - * - * In debug mode, we specifically test for an interface name "LocalHost" - * and resolve "localhost" instead as a means to permit test cases - * to connect to a local test server with any host name. - * - * Return codes: - * - * CURLRESOLV_ERROR (-1) = error, no pointer - * CURLRESOLV_RESOLVED (0) = OK, pointer provided - * CURLRESOLV_PENDING (1) = waiting for response, no pointer - */ - -int Curl_resolv(struct connectdata *conn, - const char *hostname, - int port, - struct Curl_dns_entry **entry) -{ - struct Curl_dns_entry *dns = NULL; - struct SessionHandle *data = conn->data; - CURLcode result; - int rc = CURLRESOLV_ERROR; /* default to failure */ - - *entry = NULL; - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - dns = fetch_addr(conn, hostname, port); - - if(dns) { - infof(data, "Hostname %s was found in DNS cache\n", hostname); - dns->inuse++; /* we use it! */ - rc = CURLRESOLV_RESOLVED; - } - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - if(!dns) { - /* The entry was not in the cache. Resolve it to IP address */ - - Curl_addrinfo *addr; - int respwait; - - /* Check what IP specifics the app has requested and if we can provide it. - * If not, bail out. */ - if(!Curl_ipvalid(conn)) - return CURLRESOLV_ERROR; - - /* If Curl_getaddrinfo() returns NULL, 'respwait' might be set to a - non-zero value indicating that we need to wait for the response to the - resolve call */ - addr = Curl_getaddrinfo(conn, -#ifdef DEBUGBUILD - (data->set.str[STRING_DEVICE] - && !strcmp(data->set.str[STRING_DEVICE], - "LocalHost"))?"localhost": -#endif - hostname, port, &respwait); - - if(!addr) { - if(respwait) { - /* the response to our resolve call will come asynchronously at - a later time, good or bad */ - /* First, check that we haven't received the info by now */ - result = Curl_resolver_is_resolved(conn, &dns); - if(result) /* error detected */ - return CURLRESOLV_ERROR; - if(dns) - rc = CURLRESOLV_RESOLVED; /* pointer provided */ - else - rc = CURLRESOLV_PENDING; /* no info yet */ - } - } - else { - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - /* we got a response, store it in the cache */ - dns = Curl_cache_addr(data, addr, hostname, port); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - if(!dns) - /* returned failure, bail out nicely */ - Curl_freeaddrinfo(addr); - else - rc = CURLRESOLV_RESOLVED; - } - } - - *entry = dns; - - return rc; -} - -#ifdef USE_ALARM_TIMEOUT -/* - * This signal handler jumps back into the main libcurl code and continues - * execution. This effectively causes the remainder of the application to run - * within a signal handler which is nonportable and could lead to problems. - */ -static -RETSIGTYPE alarmfunc(int sig) -{ - /* this is for "-ansi -Wall -pedantic" to stop complaining! (rabe) */ - (void)sig; - siglongjmp(curl_jmpenv, 1); - return; -} -#endif /* USE_ALARM_TIMEOUT */ - -/* - * Curl_resolv_timeout() is the same as Curl_resolv() but specifies a - * timeout. This function might return immediately if we're using asynch - * resolves. See the return codes. - * - * The cache entry we return will get its 'inuse' counter increased when this - * function is used. You MUST call Curl_resolv_unlock() later (when you're - * done using this struct) to decrease the counter again. - * - * If built with a synchronous resolver and use of signals is not - * disabled by the application, then a nonzero timeout will cause a - * timeout after the specified number of milliseconds. Otherwise, timeout - * is ignored. - * - * Return codes: - * - * CURLRESOLV_TIMEDOUT(-2) = warning, time too short or previous alarm expired - * CURLRESOLV_ERROR (-1) = error, no pointer - * CURLRESOLV_RESOLVED (0) = OK, pointer provided - * CURLRESOLV_PENDING (1) = waiting for response, no pointer - */ - -int Curl_resolv_timeout(struct connectdata *conn, - const char *hostname, - int port, - struct Curl_dns_entry **entry, - long timeoutms) -{ -#ifdef USE_ALARM_TIMEOUT -#ifdef HAVE_SIGACTION - struct sigaction keep_sigact; /* store the old struct here */ - volatile bool keep_copysig = FALSE; /* wether old sigact has been saved */ - struct sigaction sigact; -#else -#ifdef HAVE_SIGNAL - void (*keep_sigact)(int); /* store the old handler here */ -#endif /* HAVE_SIGNAL */ -#endif /* HAVE_SIGACTION */ - volatile long timeout; - volatile unsigned int prev_alarm = 0; - struct SessionHandle *data = conn->data; -#endif /* USE_ALARM_TIMEOUT */ - int rc; - - *entry = NULL; - - if(timeoutms < 0) - /* got an already expired timeout */ - return CURLRESOLV_TIMEDOUT; - -#ifdef USE_ALARM_TIMEOUT - if(data->set.no_signal) - /* Ignore the timeout when signals are disabled */ - timeout = 0; - else - timeout = timeoutms; - - if(!timeout) - /* USE_ALARM_TIMEOUT defined, but no timeout actually requested */ - return Curl_resolv(conn, hostname, port, entry); - - if(timeout < 1000) - /* The alarm() function only provides integer second resolution, so if - we want to wait less than one second we must bail out already now. */ - return CURLRESOLV_TIMEDOUT; - - /* This allows us to time-out from the name resolver, as the timeout - will generate a signal and we will siglongjmp() from that here. - This technique has problems (see alarmfunc). - This should be the last thing we do before calling Curl_resolv(), - as otherwise we'd have to worry about variables that get modified - before we invoke Curl_resolv() (and thus use "volatile"). */ - if(sigsetjmp(curl_jmpenv, 1)) { - /* this is coming from a siglongjmp() after an alarm signal */ - failf(data, "name lookup timed out"); - rc = CURLRESOLV_ERROR; - goto clean_up; - } - else { - /************************************************************* - * Set signal handler to catch SIGALRM - * Store the old value to be able to set it back later! - *************************************************************/ -#ifdef HAVE_SIGACTION - sigaction(SIGALRM, NULL, &sigact); - keep_sigact = sigact; - keep_copysig = TRUE; /* yes, we have a copy */ - sigact.sa_handler = alarmfunc; -#ifdef SA_RESTART - /* HPUX doesn't have SA_RESTART but defaults to that behaviour! */ - sigact.sa_flags &= ~SA_RESTART; -#endif - /* now set the new struct */ - sigaction(SIGALRM, &sigact, NULL); -#else /* HAVE_SIGACTION */ - /* no sigaction(), revert to the much lamer signal() */ -#ifdef HAVE_SIGNAL - keep_sigact = signal(SIGALRM, alarmfunc); -#endif -#endif /* HAVE_SIGACTION */ - - /* alarm() makes a signal get sent when the timeout fires off, and that - will abort system calls */ - prev_alarm = alarm(curlx_sltoui(timeout/1000L)); - } - -#else -#ifndef CURLRES_ASYNCH - if(timeoutms) - infof(conn->data, "timeout on name lookup is not supported\n"); -#else - (void)timeoutms; /* timeoutms not used with an async resolver */ -#endif -#endif /* USE_ALARM_TIMEOUT */ - - /* Perform the actual name resolution. This might be interrupted by an - * alarm if it takes too long. - */ - rc = Curl_resolv(conn, hostname, port, entry); - -#ifdef USE_ALARM_TIMEOUT -clean_up: - - if(!prev_alarm) - /* deactivate a possibly active alarm before uninstalling the handler */ - alarm(0); - -#ifdef HAVE_SIGACTION - if(keep_copysig) { - /* we got a struct as it looked before, now put that one back nice - and clean */ - sigaction(SIGALRM, &keep_sigact, NULL); /* put it back */ - } -#else -#ifdef HAVE_SIGNAL - /* restore the previous SIGALRM handler */ - signal(SIGALRM, keep_sigact); -#endif -#endif /* HAVE_SIGACTION */ - - /* switch back the alarm() to either zero or to what it was before minus - the time we spent until now! */ - if(prev_alarm) { - /* there was an alarm() set before us, now put it back */ - unsigned long elapsed_ms = Curl_tvdiff(Curl_tvnow(), conn->created); - - /* the alarm period is counted in even number of seconds */ - unsigned long alarm_set = prev_alarm - elapsed_ms/1000; - - if(!alarm_set || - ((alarm_set >= 0x80000000) && (prev_alarm < 0x80000000)) ) { - /* if the alarm time-left reached zero or turned "negative" (counted - with unsigned values), we should fire off a SIGALRM here, but we - won't, and zero would be to switch it off so we never set it to - less than 1! */ - alarm(1); - rc = CURLRESOLV_TIMEDOUT; - failf(data, "Previous alarm fired off!"); - } - else - alarm((unsigned int)alarm_set); - } -#endif /* USE_ALARM_TIMEOUT */ - - return rc; -} - -/* - * Curl_resolv_unlock() unlocks the given cached DNS entry. When this has been - * made, the struct may be destroyed due to pruning. It is important that only - * one unlock is made for each Curl_resolv() call. - * - * May be called with 'data' == NULL for global cache. - */ -void Curl_resolv_unlock(struct SessionHandle *data, struct Curl_dns_entry *dns) -{ - if(data && data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - freednsentry(dns); - - if(data && data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); -} - -/* - * File-internal: release cache dns entry reference, free if inuse drops to 0 - */ -static void freednsentry(void *freethis) -{ - struct Curl_dns_entry *dns = (struct Curl_dns_entry *) freethis; - DEBUGASSERT(dns && (dns->inuse>0)); - - dns->inuse--; - if(dns->inuse == 0) { - Curl_freeaddrinfo(dns->addr); - free(dns); - } -} - -/* - * Curl_mk_dnscache() inits a new DNS cache and returns success/failure. - */ -int Curl_mk_dnscache(struct curl_hash *hash) -{ - return Curl_hash_init(hash, 7, Curl_hash_str, Curl_str_key_compare, - freednsentry); -} - -/* - * Curl_hostcache_clean() - * - * This _can_ be called with 'data' == NULL but then of course no locking - * can be done! - */ - -void Curl_hostcache_clean(struct SessionHandle *data, - struct curl_hash *hash) -{ - if(data && data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - Curl_hash_clean(hash); - - if(data && data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); -} - - -CURLcode Curl_loadhostpairs(struct SessionHandle *data) -{ - struct curl_slist *hostp; - char hostname[256]; - char address[256]; - int port; - - for(hostp = data->change.resolve; hostp; hostp = hostp->next) { - if(!hostp->data) - continue; - if(hostp->data[0] == '-') { - char *entry_id; - size_t entry_len; - - if(2 != sscanf(hostp->data + 1, "%255[^:]:%d", hostname, &port)) { - infof(data, "Couldn't parse CURLOPT_RESOLVE removal entry '%s'!\n", - hostp->data); - continue; - } - - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) { - return CURLE_OUT_OF_MEMORY; - } - - entry_len = strlen(entry_id); - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - /* delete entry, ignore if it didn't exist */ - Curl_hash_delete(data->dns.hostcache, entry_id, entry_len+1); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - /* free the allocated entry_id again */ - free(entry_id); - } - else { - struct Curl_dns_entry *dns; - Curl_addrinfo *addr; - char *entry_id; - size_t entry_len; - - if(3 != sscanf(hostp->data, "%255[^:]:%d:%255s", hostname, &port, - address)) { - infof(data, "Couldn't parse CURLOPT_RESOLVE entry '%s'!\n", - hostp->data); - continue; - } - - addr = Curl_str2addr(address, port); - if(!addr) { - infof(data, "Address in '%s' found illegal!\n", hostp->data); - continue; - } - - /* Create an entry id, based upon the hostname and port */ - entry_id = create_hostcache_id(hostname, port); - /* If we can't create the entry id, fail */ - if(!entry_id) { - Curl_freeaddrinfo(addr); - return CURLE_OUT_OF_MEMORY; - } - - entry_len = strlen(entry_id); - - if(data->share) - Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE); - - /* See if its already in our dns cache */ - dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len+1); - - /* free the allocated entry_id again */ - free(entry_id); - - if(!dns) { - /* if not in the cache already, put this host in the cache */ - dns = Curl_cache_addr(data, addr, hostname, port); - if(dns) { - dns->timestamp = 0; /* mark as added by CURLOPT_RESOLVE */ - /* release the returned reference; the cache itself will keep the - * entry alive: */ - dns->inuse--; - } - } - else - /* this is a duplicate, free it again */ - Curl_freeaddrinfo(addr); - - if(data->share) - Curl_share_unlock(data, CURL_LOCK_DATA_DNS); - - if(!dns) { - Curl_freeaddrinfo(addr); - return CURLE_OUT_OF_MEMORY; - } - infof(data, "Added %s:%d:%s to DNS cache\n", - hostname, port, address); - } - } - data->change.resolve = NULL; /* dealt with now */ - - return CURLE_OK; -} diff --git a/Externals/curl/lib/hostip.h b/Externals/curl/lib/hostip.h deleted file mode 100644 index 37ccd96e11..0000000000 --- a/Externals/curl/lib/hostip.h +++ /dev/null @@ -1,250 +0,0 @@ -#ifndef HEADER_CURL_HOSTIP_H -#define HEADER_CURL_HOSTIP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" -#include "hash.h" -#include "curl_addrinfo.h" -#include "asyn.h" - -#ifdef HAVE_SETJMP_H -#include -#endif - -#ifdef NETWARE -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -/* Allocate enough memory to hold the full name information structs and - * everything. OSF1 is known to require at least 8872 bytes. The buffer - * required for storing all possible aliases and IP numbers is according to - * Stevens' Unix Network Programming 2nd edition, p. 304: 8192 bytes! - */ -#define CURL_HOSTENT_SIZE 9000 - -#define CURL_TIMEOUT_RESOLVE 300 /* when using asynch methods, we allow this - many seconds for a name resolve */ - -#define CURL_ASYNC_SUCCESS CURLE_OK - -struct addrinfo; -struct hostent; -struct SessionHandle; -struct connectdata; - -/* - * Curl_global_host_cache_init() initializes and sets up a global DNS cache. - * Global DNS cache is general badness. Do not use. This will be removed in - * a future version. Use the share interface instead! - * - * Returns a struct curl_hash pointer on success, NULL on failure. - */ -struct curl_hash *Curl_global_host_cache_init(void); -void Curl_global_host_cache_dtor(void); - -struct Curl_dns_entry { - Curl_addrinfo *addr; - /* timestamp == 0 -- CURLOPT_RESOLVE entry, doesn't timeout */ - time_t timestamp; - /* use-counter, use Curl_resolv_unlock to release reference */ - long inuse; -}; - -/* - * Curl_resolv() returns an entry with the info for the specified host - * and port. - * - * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after - * use, or we'll leak memory! - */ -/* return codes */ -#define CURLRESOLV_TIMEDOUT -2 -#define CURLRESOLV_ERROR -1 -#define CURLRESOLV_RESOLVED 0 -#define CURLRESOLV_PENDING 1 -int Curl_resolv(struct connectdata *conn, const char *hostname, - int port, struct Curl_dns_entry **dnsentry); -int Curl_resolv_timeout(struct connectdata *conn, const char *hostname, - int port, struct Curl_dns_entry **dnsentry, - long timeoutms); - -#ifdef CURLRES_IPV6 -/* - * Curl_ipv6works() returns TRUE if IPv6 seems to work. - */ -bool Curl_ipv6works(void); -#else -#define Curl_ipv6works() FALSE -#endif - -/* - * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've - * been set and returns TRUE if they are OK. - */ -bool Curl_ipvalid(struct connectdata *conn); - - -/* - * Curl_getaddrinfo() is the generic low-level name resolve API within this - * source file. There are several versions of this function - for different - * name resolve layers (selected at build-time). They all take this same set - * of arguments - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp); - - -/* unlock a previously resolved dns entry */ -void Curl_resolv_unlock(struct SessionHandle *data, - struct Curl_dns_entry *dns); - -/* for debugging purposes only: */ -void Curl_scan_cache_used(void *user, void *ptr); - -/* init a new dns cache and return success */ -int Curl_mk_dnscache(struct curl_hash *hash); - -/* prune old entries from the DNS cache */ -void Curl_hostcache_prune(struct SessionHandle *data); - -/* Return # of adresses in a Curl_addrinfo struct */ -int Curl_num_addresses (const Curl_addrinfo *addr); - -#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) -int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa, - GETNAMEINFO_TYPE_ARG2 salen, - char *host, GETNAMEINFO_TYPE_ARG46 hostlen, - char *serv, GETNAMEINFO_TYPE_ARG46 servlen, - GETNAMEINFO_TYPE_ARG7 flags, - int line, const char *source); -#endif - -/* IPv4 threadsafe resolve function used for synch and asynch builds */ -Curl_addrinfo *Curl_ipv4_resolve_r(const char * hostname, int port); - -CURLcode Curl_async_resolved(struct connectdata *conn, - bool *protocol_connect); - -#ifndef CURLRES_ASYNCH -#define Curl_async_resolved(x,y) CURLE_OK -#endif - -/* - * Curl_addrinfo_callback() is used when we build with any asynch specialty. - * Handles end of async request processing. Inserts ai into hostcache when - * status is CURL_ASYNC_SUCCESS. Twiddles fields in conn to indicate async - * request completed whether successful or failed. - */ -CURLcode Curl_addrinfo_callback(struct connectdata *conn, - int status, - Curl_addrinfo *ai); - -/* - * Curl_printable_address() returns a printable version of the 1st address - * given in the 'ip' argument. The result will be stored in the buf that is - * bufsize bytes big. - */ -const char *Curl_printable_address(const Curl_addrinfo *ip, - char *buf, size_t bufsize); - -/* - * Curl_fetch_addr() fetches a 'Curl_dns_entry' already in the DNS cache. - * - * Returns the Curl_dns_entry entry pointer or NULL if not in the cache. - * - * The returned data *MUST* be "unlocked" with Curl_resolv_unlock() after - * use, or we'll leak memory! - */ -struct Curl_dns_entry * -Curl_fetch_addr(struct connectdata *conn, - const char *hostname, - int port); -/* - * Curl_cache_addr() stores a 'Curl_addrinfo' struct in the DNS cache. - * - * Returns the Curl_dns_entry entry pointer or NULL if the storage failed. - */ -struct Curl_dns_entry * -Curl_cache_addr(struct SessionHandle *data, Curl_addrinfo *addr, - const char *hostname, int port); - -#ifndef INADDR_NONE -#define CURL_INADDR_NONE (in_addr_t) ~0 -#else -#define CURL_INADDR_NONE INADDR_NONE -#endif - -#ifdef HAVE_SIGSETJMP -/* Forward-declaration of variable defined in hostip.c. Beware this - * is a global and unique instance. This is used to store the return - * address that we can jump back to from inside a signal handler. - * This is not thread-safe stuff. - */ -extern sigjmp_buf curl_jmpenv; -#endif - -/* - * Function provided by the resolver backend to set DNS servers to use. - */ -CURLcode Curl_set_dns_servers(struct SessionHandle *data, char *servers); - -/* - * Function provided by the resolver backend to set - * outgoing interface to use for DNS requests - */ -CURLcode Curl_set_dns_interface(struct SessionHandle *data, - const char *interf); - -/* - * Function provided by the resolver backend to set - * local IPv4 address to use as source address for DNS requests - */ -CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data, - const char *local_ip4); - -/* - * Function provided by the resolver backend to set - * local IPv6 address to use as source address for DNS requests - */ -CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data, - const char *local_ip6); - -/* - * Clean off entries from the cache - */ -void Curl_hostcache_clean(struct SessionHandle *data, struct curl_hash *hash); - -/* - * Destroy the hostcache of this handle. - */ -void Curl_hostcache_destroy(struct SessionHandle *data); - -/* - * Populate the cache with specified entries from CURLOPT_RESOLVE. - */ -CURLcode Curl_loadhostpairs(struct SessionHandle *data); - -#endif /* HEADER_CURL_HOSTIP_H */ diff --git a/Externals/curl/lib/hostip4.c b/Externals/curl/lib/hostip4.c deleted file mode 100644 index 15895d7cec..0000000000 --- a/Externals/curl/lib/hostip4.c +++ /dev/null @@ -1,307 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_PROCESS_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "inet_pton.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/*********************************************************************** - * Only for plain IPv4 builds - **********************************************************************/ -#ifdef CURLRES_IPV4 /* plain IPv4 code coming up */ -/* - * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've - * been set and returns TRUE if they are OK. - */ -bool Curl_ipvalid(struct connectdata *conn) -{ - if(conn->ip_version == CURL_IPRESOLVE_V6) - /* An IPv6 address was requested and we can't get/use one */ - return FALSE; - - return TRUE; /* OK, proceed */ -} - -#ifdef CURLRES_SYNCH - -/* - * Curl_getaddrinfo() - the IPv4 synchronous version. - * - * The original code to this function was from the Dancer source code, written - * by Bjorn Reese, it has since been patched and modified considerably. - * - * gethostbyname_r() is the thread-safe version of the gethostbyname() - * function. When we build for plain IPv4, we attempt to use this - * function. There are _three_ different gethostbyname_r() versions, and we - * detect which one this platform supports in the configure script and set up - * the HAVE_GETHOSTBYNAME_R_3, HAVE_GETHOSTBYNAME_R_5 or - * HAVE_GETHOSTBYNAME_R_6 defines accordingly. Note that HAVE_GETADDRBYNAME - * has the corresponding rules. This is primarily on *nix. Note that some unix - * flavours have thread-safe versions of the plain gethostbyname() etc. - * - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) -{ - Curl_addrinfo *ai = NULL; - -#ifdef CURL_DISABLE_VERBOSE_STRINGS - (void)conn; -#endif - - *waitp = 0; /* synchronous response only */ - - ai = Curl_ipv4_resolve_r(hostname, port); - if(!ai) - infof(conn->data, "Curl_ipv4_resolve_r failed for %s\n", hostname); - - return ai; -} -#endif /* CURLRES_SYNCH */ -#endif /* CURLRES_IPV4 */ - -#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES) - -/* - * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function. - * - * This is used for both synchronous and asynchronous resolver builds, - * implying that only threadsafe code and function calls may be used. - * - */ -Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, - int port) -{ -#if !defined(HAVE_GETADDRINFO_THREADSAFE) && defined(HAVE_GETHOSTBYNAME_R_3) - int res; -#endif - Curl_addrinfo *ai = NULL; - struct hostent *h = NULL; - struct in_addr in; - struct hostent *buf = NULL; - - if(Curl_inet_pton(AF_INET, hostname, &in) > 0) - /* This is a dotted IP address 123.123.123.123-style */ - return Curl_ip2addr(AF_INET, &in, hostname, port); - -#if defined(HAVE_GETADDRINFO_THREADSAFE) - else { - struct addrinfo hints; - char sbuf[12]; - char *sbufptr = NULL; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_INET; - hints.ai_socktype = SOCK_STREAM; - if(port) { - snprintf(sbuf, sizeof(sbuf), "%d", port); - sbufptr = sbuf; - } - - (void)Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &ai); - -#elif defined(HAVE_GETHOSTBYNAME_R) - /* - * gethostbyname_r() is the preferred resolve function for many platforms. - * Since there are three different versions of it, the following code is - * somewhat #ifdef-ridden. - */ - else { - int h_errnop; - - buf = calloc(1, CURL_HOSTENT_SIZE); - if(!buf) - return NULL; /* major failure */ - /* - * The clearing of the buffer is a workaround for a gethostbyname_r bug in - * qnx nto and it is also _required_ for some of these functions on some - * platforms. - */ - -#if defined(HAVE_GETHOSTBYNAME_R_5) - /* Solaris, IRIX and more */ - h = gethostbyname_r(hostname, - (struct hostent *)buf, - (char *)buf + sizeof(struct hostent), - CURL_HOSTENT_SIZE - sizeof(struct hostent), - &h_errnop); - - /* If the buffer is too small, it returns NULL and sets errno to - * ERANGE. The errno is thread safe if this is compiled with - * -D_REENTRANT as then the 'errno' variable is a macro defined to get - * used properly for threads. - */ - - if(h) { - ; - } - else -#elif defined(HAVE_GETHOSTBYNAME_R_6) - /* Linux */ - - (void)gethostbyname_r(hostname, - (struct hostent *)buf, - (char *)buf + sizeof(struct hostent), - CURL_HOSTENT_SIZE - sizeof(struct hostent), - &h, /* DIFFERENCE */ - &h_errnop); - /* Redhat 8, using glibc 2.2.93 changed the behavior. Now all of a - * sudden this function returns EAGAIN if the given buffer size is too - * small. Previous versions are known to return ERANGE for the same - * problem. - * - * This wouldn't be such a big problem if older versions wouldn't - * sometimes return EAGAIN on a common failure case. Alas, we can't - * assume that EAGAIN *or* ERANGE means ERANGE for any given version of - * glibc. - * - * For now, we do that and thus we may call the function repeatedly and - * fail for older glibc versions that return EAGAIN, until we run out of - * buffer size (step_size grows beyond CURL_HOSTENT_SIZE). - * - * If anyone has a better fix, please tell us! - * - * ------------------------------------------------------------------- - * - * On October 23rd 2003, Dan C dug up more details on the mysteries of - * gethostbyname_r() in glibc: - * - * In glibc 2.2.5 the interface is different (this has also been - * discovered in glibc 2.1.1-6 as shipped by Redhat 6). What I can't - * explain, is that tests performed on glibc 2.2.4-34 and 2.2.4-32 - * (shipped/upgraded by Redhat 7.2) don't show this behavior! - * - * In this "buggy" version, the return code is -1 on error and 'errno' - * is set to the ERANGE or EAGAIN code. Note that 'errno' is not a - * thread-safe variable. - */ - - if(!h) /* failure */ -#elif defined(HAVE_GETHOSTBYNAME_R_3) - /* AIX, Digital Unix/Tru64, HPUX 10, more? */ - - /* For AIX 4.3 or later, we don't use gethostbyname_r() at all, because of - * the plain fact that it does not return unique full buffers on each - * call, but instead several of the pointers in the hostent structs will - * point to the same actual data! This have the unfortunate down-side that - * our caching system breaks down horribly. Luckily for us though, AIX 4.3 - * and more recent versions have a "completely thread-safe"[*] libc where - * all the data is stored in thread-specific memory areas making calls to - * the plain old gethostbyname() work fine even for multi-threaded - * programs. - * - * This AIX 4.3 or later detection is all made in the configure script. - * - * Troels Walsted Hansen helped us work this out on March 3rd, 2003. - * - * [*] = much later we've found out that it isn't at all "completely - * thread-safe", but at least the gethostbyname() function is. - */ - - if(CURL_HOSTENT_SIZE >= - (sizeof(struct hostent)+sizeof(struct hostent_data))) { - - /* August 22nd, 2000: Albert Chin-A-Young brought an updated version - * that should work! September 20: Richard Prescott worked on the buffer - * size dilemma. - */ - - res = gethostbyname_r(hostname, - (struct hostent *)buf, - (struct hostent_data *)((char *)buf + - sizeof(struct hostent))); - h_errnop = SOCKERRNO; /* we don't deal with this, but set it anyway */ - } - else - res = -1; /* failure, too smallish buffer size */ - - if(!res) { /* success */ - - h = buf; /* result expected in h */ - - /* This is the worst kind of the different gethostbyname_r() interfaces. - * Since we don't know how big buffer this particular lookup required, - * we can't realloc down the huge alloc without doing closer analysis of - * the returned data. Thus, we always use CURL_HOSTENT_SIZE for every - * name lookup. Fixing this would require an extra malloc() and then - * calling Curl_addrinfo_copy() that subsequent realloc()s down the new - * memory area to the actually used amount. - */ - } - else -#endif /* HAVE_...BYNAME_R_5 || HAVE_...BYNAME_R_6 || HAVE_...BYNAME_R_3 */ - { - h = NULL; /* set return code to NULL */ - free(buf); - } -#else /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */ - /* - * Here is code for platforms that don't have a thread safe - * getaddrinfo() nor gethostbyname_r() function or for which - * gethostbyname() is the preferred one. - */ - else { - h = gethostbyname((void*)hostname); -#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */ - } - - if(h) { - ai = Curl_he2ai(h, port); - - if(buf) /* used a *_r() function */ - free(buf); - } - - return ai; -} -#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */ diff --git a/Externals/curl/lib/hostip6.c b/Externals/curl/lib/hostip6.c deleted file mode 100644 index 59bc4e4ac5..0000000000 --- a/Externals/curl/lib/hostip6.c +++ /dev/null @@ -1,222 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_PROCESS_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "inet_pton.h" -#include "connect.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/*********************************************************************** - * Only for IPv6-enabled builds - **********************************************************************/ -#ifdef CURLRES_IPV6 - -#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) -/* These are strictly for memory tracing and are using the same style as the - * family otherwise present in memdebug.c. I put these ones here since they - * require a bunch of structs I didn't want to include in memdebug.c - */ - -/* - * For CURLRES_ARS, this should be written using ares_gethostbyaddr() - * (ignoring the fact c-ares doesn't return 'serv'). - */ - -int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa, - GETNAMEINFO_TYPE_ARG2 salen, - char *host, GETNAMEINFO_TYPE_ARG46 hostlen, - char *serv, GETNAMEINFO_TYPE_ARG46 servlen, - GETNAMEINFO_TYPE_ARG7 flags, - int line, const char *source) -{ - int res = (getnameinfo)(sa, salen, - host, hostlen, - serv, servlen, - flags); - if(0 == res) - /* success */ - curl_memlog("GETNAME %s:%d getnameinfo()\n", - source, line); - else - curl_memlog("GETNAME %s:%d getnameinfo() failed = %d\n", - source, line, res); - return res; -} -#endif /* defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO) */ - -/* - * Curl_ipv6works() returns TRUE if IPv6 seems to work. - */ -bool Curl_ipv6works(void) -{ - /* the nature of most system is that IPv6 status doesn't come and go - during a program's lifetime so we only probe the first time and then we - have the info kept for fast re-use */ - static int ipv6_works = -1; - if(-1 == ipv6_works) { - /* probe to see if we have a working IPv6 stack */ - curl_socket_t s = socket(PF_INET6, SOCK_DGRAM, 0); - if(s == CURL_SOCKET_BAD) - /* an IPv6 address was requested but we can't get/use one */ - ipv6_works = 0; - else { - ipv6_works = 1; - Curl_closesocket(NULL, s); - } - } - return (ipv6_works>0)?TRUE:FALSE; -} - -/* - * Curl_ipvalid() checks what CURL_IPRESOLVE_* requirements that might've - * been set and returns TRUE if they are OK. - */ -bool Curl_ipvalid(struct connectdata *conn) -{ - if(conn->ip_version == CURL_IPRESOLVE_V6) - return Curl_ipv6works(); - - return TRUE; -} - -#if defined(CURLRES_SYNCH) - -#ifdef DEBUG_ADDRINFO -static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai) -{ - printf("dump_addrinfo:\n"); - for(; ai; ai = ai->ai_next) { - char buf[INET6_ADDRSTRLEN]; - - printf(" fam %2d, CNAME %s, ", - ai->ai_family, ai->ai_canonname ? ai->ai_canonname : ""); - if(Curl_printable_address(ai, buf, sizeof(buf))) - printf("%s\n", buf); - else - printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO)); - } -} -#else -#define dump_addrinfo(x,y) Curl_nop_stmt -#endif - -/* - * Curl_getaddrinfo() when built IPv6-enabled (non-threading and - * non-ares version). - * - * Returns name information about the given hostname and port number. If - * successful, the 'addrinfo' is returned and the forth argument will point to - * memory we need to free after use. That memory *MUST* be freed with - * Curl_freeaddrinfo(), nothing else. - */ -Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn, - const char *hostname, - int port, - int *waitp) -{ - struct addrinfo hints; - Curl_addrinfo *res; - int error; - char sbuf[12]; - char *sbufptr = NULL; - char addrbuf[128]; - int pf; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) - struct SessionHandle *data = conn->data; -#endif - - *waitp = 0; /* synchronous response only */ - - /* Check if a limited name resolve has been requested */ - switch(conn->ip_version) { - case CURL_IPRESOLVE_V4: - pf = PF_INET; - break; - case CURL_IPRESOLVE_V6: - pf = PF_INET6; - break; - default: - pf = PF_UNSPEC; - break; - } - - if((pf != PF_INET) && !Curl_ipv6works()) - /* The stack seems to be a non-IPv6 one */ - pf = PF_INET; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = pf; - hints.ai_socktype = conn->socktype; - - if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) || - (1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) { - /* the given address is numerical only, prevent a reverse lookup */ - hints.ai_flags = AI_NUMERICHOST; - } - - if(port) { - snprintf(sbuf, sizeof(sbuf), "%d", port); - sbufptr=sbuf; - } - - error = Curl_getaddrinfo_ex(hostname, sbufptr, &hints, &res); - if(error) { - infof(data, "getaddrinfo(3) failed for %s:%d\n", hostname, port); - return NULL; - } - - dump_addrinfo(conn, res); - - return res; -} -#endif /* CURLRES_SYNCH */ - -#endif /* CURLRES_IPV6 */ diff --git a/Externals/curl/lib/hostsyn.c b/Externals/curl/lib/hostsyn.c deleted file mode 100644 index db4c82fcc2..0000000000 --- a/Externals/curl/lib/hostsyn.c +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_PROCESS_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "hash.h" -#include "share.h" -#include "strerror.h" -#include "url.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/*********************************************************************** - * Only for builds using synchronous name resolves - **********************************************************************/ -#ifdef CURLRES_SYNCH - -/* - * Function provided by the resolver backend to set DNS servers to use. - */ -CURLcode Curl_set_dns_servers(struct SessionHandle *data, - char *servers) -{ - (void)data; - (void)servers; - return CURLE_NOT_BUILT_IN; - -} - -/* - * Function provided by the resolver backend to set - * outgoing interface to use for DNS requests - */ -CURLcode Curl_set_dns_interface(struct SessionHandle *data, - const char *interf) -{ - (void)data; - (void)interf; - return CURLE_NOT_BUILT_IN; -} - -/* - * Function provided by the resolver backend to set - * local IPv4 address to use as source address for DNS requests - */ -CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data, - const char *local_ip4) -{ - (void)data; - (void)local_ip4; - return CURLE_NOT_BUILT_IN; -} - -/* - * Function provided by the resolver backend to set - * local IPv6 address to use as source address for DNS requests - */ -CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data, - const char *local_ip6) -{ - (void)data; - (void)local_ip6; - return CURLE_NOT_BUILT_IN; -} - -#endif /* truly sync */ diff --git a/Externals/curl/lib/http.c b/Externals/curl/lib/http.c deleted file mode 100644 index 6a76b88ed1..0000000000 --- a/Externals/curl/lib/http.c +++ /dev/null @@ -1,3766 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "urldata.h" -#include -#include "transfer.h" -#include "sendf.h" -#include "formdata.h" -#include "progress.h" -#include "curl_base64.h" -#include "cookie.h" -#include "strequal.h" -#include "vauth/vauth.h" -#include "vtls/vtls.h" -#include "http_digest.h" -#include "http_ntlm.h" -#include "curl_ntlm_wb.h" -#include "http_negotiate.h" -#include "url.h" -#include "share.h" -#include "hostip.h" -#include "http.h" -#include "select.h" -#include "parsedate.h" /* for the week day and month names */ -#include "strtoofft.h" -#include "multiif.h" -#include "rawstr.h" -#include "content_encoding.h" -#include "http_proxy.h" -#include "warnless.h" -#include "non-ascii.h" -#include "conncache.h" -#include "pipeline.h" -#include "http2.h" -#include "connect.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Forward declarations. - */ - -static int http_getsock_do(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); -static int http_should_fail(struct connectdata *conn); - -#ifdef USE_SSL -static CURLcode https_connecting(struct connectdata *conn, bool *done); -static int https_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); -#else -#define https_connecting(x,y) CURLE_COULDNT_CONNECT -#endif - -/* - * HTTP handler interface. - */ -const struct Curl_handler Curl_handler_http = { - "HTTP", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - Curl_http_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - http_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_HTTP, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_CREDSPERREQUEST /* flags */ -}; - -#ifdef USE_SSL -/* - * HTTPS handler interface. - */ -const struct Curl_handler Curl_handler_https = { - "HTTPS", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - Curl_http_connect, /* connect_it */ - https_connecting, /* connecting */ - ZERO_NULL, /* doing */ - https_getsock, /* proto_getsock */ - http_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_HTTPS, /* defport */ - CURLPROTO_HTTPS, /* protocol */ - PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */ -}; -#endif - -CURLcode Curl_http_setup_conn(struct connectdata *conn) -{ - /* allocate the HTTP-specific struct for the SessionHandle, only to survive - during this request */ - struct HTTP *http; - DEBUGASSERT(conn->data->req.protop == NULL); - - http = calloc(1, sizeof(struct HTTP)); - if(!http) - return CURLE_OUT_OF_MEMORY; - - conn->data->req.protop = http; - - Curl_http2_setup_conn(conn); - Curl_http2_setup_req(conn->data); - - return CURLE_OK; -} - -/* - * checkheaders() checks the linked list of custom HTTP headers for a - * particular header (prefix). - * - * Returns a pointer to the first matching header or NULL if none matched. - */ -char *Curl_checkheaders(const struct connectdata *conn, - const char *thisheader) -{ - struct curl_slist *head; - size_t thislen = strlen(thisheader); - struct SessionHandle *data = conn->data; - - for(head = data->set.headers;head; head=head->next) { - if(Curl_raw_nequal(head->data, thisheader, thislen)) - return head->data; - } - - return NULL; -} - -/* - * checkProxyHeaders() checks the linked list of custom proxy headers - * if proxy headers are not available, then it will lookup into http header - * link list - * - * It takes a connectdata struct as input instead of the SessionHandle simply - * to know if this is a proxy request or not, as it then might check a - * different header list. - */ -char *Curl_checkProxyheaders(const struct connectdata *conn, - const char *thisheader) -{ - struct curl_slist *head; - size_t thislen = strlen(thisheader); - struct SessionHandle *data = conn->data; - - for(head = (conn->bits.proxy && data->set.sep_headers) ? - data->set.proxyheaders : data->set.headers; - head; head=head->next) { - if(Curl_raw_nequal(head->data, thisheader, thislen)) - return head->data; - } - - return NULL; -} - -/* - * Strip off leading and trailing whitespace from the value in the - * given HTTP header line and return a strdupped copy. Returns NULL in - * case of allocation failure. Returns an empty string if the header value - * consists entirely of whitespace. - */ -char *Curl_copy_header_value(const char *header) -{ - const char *start; - const char *end; - char *value; - size_t len; - - DEBUGASSERT(header); - - /* Find the end of the header name */ - while(*header && (*header != ':')) - ++header; - - if(*header) - /* Skip over colon */ - ++header; - - /* Find the first non-space letter */ - start = header; - while(*start && ISSPACE(*start)) - start++; - - /* data is in the host encoding so - use '\r' and '\n' instead of 0x0d and 0x0a */ - end = strchr(start, '\r'); - if(!end) - end = strchr(start, '\n'); - if(!end) - end = strchr(start, '\0'); - if(!end) - return NULL; - - /* skip all trailing space letters */ - while((end > start) && ISSPACE(*end)) - end--; - - /* get length of the type */ - len = end - start + 1; - - value = malloc(len + 1); - if(!value) - return NULL; - - memcpy(value, start, len); - value[len] = 0; /* zero terminate */ - - return value; -} - -/* - * http_output_basic() sets up an Authorization: header (or the proxy version) - * for HTTP Basic authentication. - * - * Returns CURLcode. - */ -static CURLcode http_output_basic(struct connectdata *conn, bool proxy) -{ - size_t size = 0; - char *authorization = NULL; - struct SessionHandle *data = conn->data; - char **userp; - const char *user; - const char *pwd; - CURLcode result; - - if(proxy) { - userp = &conn->allocptr.proxyuserpwd; - user = conn->proxyuser; - pwd = conn->proxypasswd; - } - else { - userp = &conn->allocptr.userpwd; - user = conn->user; - pwd = conn->passwd; - } - - snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd); - - result = Curl_base64_encode(data, - data->state.buffer, strlen(data->state.buffer), - &authorization, &size); - if(result) - return result; - - if(!authorization) - return CURLE_REMOTE_ACCESS_DENIED; - - free(*userp); - *userp = aprintf("%sAuthorization: Basic %s\r\n", - proxy ? "Proxy-" : "", - authorization); - free(authorization); - if(!*userp) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -/* pickoneauth() selects the most favourable authentication method from the - * ones available and the ones we want. - * - * return TRUE if one was picked - */ -static bool pickoneauth(struct auth *pick) -{ - bool picked; - /* only deal with authentication we want */ - unsigned long avail = pick->avail & pick->want; - picked = TRUE; - - /* The order of these checks is highly relevant, as this will be the order - of preference in case of the existence of multiple accepted types. */ - if(avail & CURLAUTH_NEGOTIATE) - pick->picked = CURLAUTH_NEGOTIATE; - else if(avail & CURLAUTH_DIGEST) - pick->picked = CURLAUTH_DIGEST; - else if(avail & CURLAUTH_NTLM) - pick->picked = CURLAUTH_NTLM; - else if(avail & CURLAUTH_NTLM_WB) - pick->picked = CURLAUTH_NTLM_WB; - else if(avail & CURLAUTH_BASIC) - pick->picked = CURLAUTH_BASIC; - else { - pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */ - picked = FALSE; - } - pick->avail = CURLAUTH_NONE; /* clear it here */ - - return picked; -} - -/* - * Curl_http_perhapsrewind() - * - * If we are doing POST or PUT { - * If we have more data to send { - * If we are doing NTLM { - * Keep sending since we must not disconnect - * } - * else { - * If there is more than just a little data left to send, close - * the current connection by force. - * } - * } - * If we have sent any data { - * If we don't have track of all the data { - * call app to tell it to rewind - * } - * else { - * rewind internally so that the operation can restart fine - * } - * } - * } - */ -static CURLcode http_perhapsrewind(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - struct HTTP *http = data->req.protop; - curl_off_t bytessent; - curl_off_t expectsend = -1; /* default is unknown */ - - if(!http) - /* If this is still NULL, we have not reach very far and we can safely - skip this rewinding stuff */ - return CURLE_OK; - - switch(data->set.httpreq) { - case HTTPREQ_GET: - case HTTPREQ_HEAD: - return CURLE_OK; - default: - break; - } - - bytessent = http->writebytecount; - - if(conn->bits.authneg) { - /* This is a state where we are known to be negotiating and we don't send - any data then. */ - expectsend = 0; - } - else if(!conn->bits.protoconnstart) { - /* HTTP CONNECT in progress: there is no body */ - expectsend = 0; - } - else { - /* figure out how much data we are expected to send */ - switch(data->set.httpreq) { - case HTTPREQ_POST: - if(data->state.infilesize != -1) - expectsend = data->state.infilesize; - else if(data->set.postfields) - expectsend = (curl_off_t)strlen(data->set.postfields); - break; - case HTTPREQ_PUT: - if(data->state.infilesize != -1) - expectsend = data->state.infilesize; - break; - case HTTPREQ_POST_FORM: - expectsend = http->postsize; - break; - default: - break; - } - } - - conn->bits.rewindaftersend = FALSE; /* default */ - - if((expectsend == -1) || (expectsend > bytessent)) { -#if defined(USE_NTLM) - /* There is still data left to send */ - if((data->state.authproxy.picked == CURLAUTH_NTLM) || - (data->state.authhost.picked == CURLAUTH_NTLM) || - (data->state.authproxy.picked == CURLAUTH_NTLM_WB) || - (data->state.authhost.picked == CURLAUTH_NTLM_WB)) { - if(((expectsend - bytessent) < 2000) || - (conn->ntlm.state != NTLMSTATE_NONE) || - (conn->proxyntlm.state != NTLMSTATE_NONE)) { - /* The NTLM-negotiation has started *OR* there is just a little (<2K) - data left to send, keep on sending. */ - - /* rewind data when completely done sending! */ - if(!conn->bits.authneg) { - conn->bits.rewindaftersend = TRUE; - infof(data, "Rewind stream after send\n"); - } - - return CURLE_OK; - } - - if(conn->bits.close) - /* this is already marked to get closed */ - return CURLE_OK; - - infof(data, "NTLM send, close instead of sending %" - CURL_FORMAT_CURL_OFF_T " bytes\n", - (curl_off_t)(expectsend - bytessent)); - } -#endif - - /* This is not NTLM or many bytes left to send: close */ - connclose(conn, "Mid-auth HTTP and much data left to send"); - data->req.size = 0; /* don't download any more than 0 bytes */ - - /* There still is data left to send, but this connection is marked for - closure so we can safely do the rewind right now */ - } - - if(bytessent) - /* we rewind now at once since if we already sent something */ - return Curl_readrewind(conn); - - return CURLE_OK; -} - -/* - * Curl_http_auth_act() gets called when all HTTP headers have been received - * and it checks what authentication methods that are available and decides - * which one (if any) to use. It will set 'newurl' if an auth method was - * picked. - */ - -CURLcode Curl_http_auth_act(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - bool pickhost = FALSE; - bool pickproxy = FALSE; - CURLcode result = CURLE_OK; - - if(100 <= data->req.httpcode && 199 >= data->req.httpcode) - /* this is a transient response code, ignore */ - return CURLE_OK; - - if(data->state.authproblem) - return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK; - - if(conn->bits.user_passwd && - ((data->req.httpcode == 401) || - (conn->bits.authneg && data->req.httpcode < 300))) { - pickhost = pickoneauth(&data->state.authhost); - if(!pickhost) - data->state.authproblem = TRUE; - } - if(conn->bits.proxy_user_passwd && - ((data->req.httpcode == 407) || - (conn->bits.authneg && data->req.httpcode < 300))) { - pickproxy = pickoneauth(&data->state.authproxy); - if(!pickproxy) - data->state.authproblem = TRUE; - } - - if(pickhost || pickproxy) { - /* In case this is GSS auth, the newurl field is already allocated so - we must make sure to free it before allocating a new one. As figured - out in bug #2284386 */ - Curl_safefree(data->req.newurl); - data->req.newurl = strdup(data->change.url); /* clone URL */ - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - - if((data->set.httpreq != HTTPREQ_GET) && - (data->set.httpreq != HTTPREQ_HEAD) && - !conn->bits.rewindaftersend) { - result = http_perhapsrewind(conn); - if(result) - return result; - } - } - else if((data->req.httpcode < 300) && - (!data->state.authhost.done) && - conn->bits.authneg) { - /* no (known) authentication available, - authentication is not "done" yet and - no authentication seems to be required and - we didn't try HEAD or GET */ - if((data->set.httpreq != HTTPREQ_GET) && - (data->set.httpreq != HTTPREQ_HEAD)) { - data->req.newurl = strdup(data->change.url); /* clone URL */ - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - data->state.authhost.done = TRUE; - } - } - if(http_should_fail(conn)) { - failf (data, "The requested URL returned error: %d", - data->req.httpcode); - result = CURLE_HTTP_RETURNED_ERROR; - } - - return result; -} - -/* - * Output the correct authentication header depending on the auth type - * and whether or not it is to a proxy. - */ -static CURLcode -output_auth_headers(struct connectdata *conn, - struct auth *authstatus, - const char *request, - const char *path, - bool proxy) -{ - const char *auth = NULL; - CURLcode result = CURLE_OK; -#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO) - struct SessionHandle *data = conn->data; -#endif -#ifdef USE_SPNEGO - struct negotiatedata *negdata = proxy ? - &data->state.proxyneg : &data->state.negotiate; -#endif - -#ifdef CURL_DISABLE_CRYPTO_AUTH - (void)request; - (void)path; -#endif - -#ifdef USE_SPNEGO - negdata->state = GSS_AUTHNONE; - if((authstatus->picked == CURLAUTH_NEGOTIATE) && - negdata->context && !GSS_ERROR(negdata->status)) { - auth = "Negotiate"; - result = Curl_output_negotiate(conn, proxy); - if(result) - return result; - authstatus->done = TRUE; - negdata->state = GSS_AUTHSENT; - } - else -#endif -#ifdef USE_NTLM - if(authstatus->picked == CURLAUTH_NTLM) { - auth = "NTLM"; - result = Curl_output_ntlm(conn, proxy); - if(result) - return result; - } - else -#endif -#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED) - if(authstatus->picked == CURLAUTH_NTLM_WB) { - auth="NTLM_WB"; - result = Curl_output_ntlm_wb(conn, proxy); - if(result) - return result; - } - else -#endif -#ifndef CURL_DISABLE_CRYPTO_AUTH - if(authstatus->picked == CURLAUTH_DIGEST) { - auth = "Digest"; - result = Curl_output_digest(conn, - proxy, - (const unsigned char *)request, - (const unsigned char *)path); - if(result) - return result; - } - else -#endif - if(authstatus->picked == CURLAUTH_BASIC) { - /* Basic */ - if((proxy && conn->bits.proxy_user_passwd && - !Curl_checkProxyheaders(conn, "Proxy-authorization:")) || - (!proxy && conn->bits.user_passwd && - !Curl_checkheaders(conn, "Authorization:"))) { - auth = "Basic"; - result = http_output_basic(conn, proxy); - if(result) - return result; - } - - /* NOTE: this function should set 'done' TRUE, as the other auth - functions work that way */ - authstatus->done = TRUE; - } - - if(auth) { - infof(data, "%s auth using %s with user '%s'\n", - proxy ? "Proxy" : "Server", auth, - proxy ? (conn->proxyuser ? conn->proxyuser : "") : - (conn->user ? conn->user : "")); - authstatus->multi = (!authstatus->done) ? TRUE : FALSE; - } - else - authstatus->multi = FALSE; - - return CURLE_OK; -} - -/** - * Curl_http_output_auth() setups the authentication headers for the - * host/proxy and the correct authentication - * method. conn->data->state.authdone is set to TRUE when authentication is - * done. - * - * @param conn all information about the current connection - * @param request pointer to the request keyword - * @param path pointer to the requested path - * @param proxytunnel boolean if this is the request setting up a "proxy - * tunnel" - * - * @returns CURLcode - */ -CURLcode -Curl_http_output_auth(struct connectdata *conn, - const char *request, - const char *path, - bool proxytunnel) /* TRUE if this is the request setting - up the proxy tunnel */ -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct auth *authhost; - struct auth *authproxy; - - DEBUGASSERT(data); - - authhost = &data->state.authhost; - authproxy = &data->state.authproxy; - - if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) || - conn->bits.user_passwd) - /* continue please */; - else { - authhost->done = TRUE; - authproxy->done = TRUE; - return CURLE_OK; /* no authentication with no user or password */ - } - - if(authhost->want && !authhost->picked) - /* The app has selected one or more methods, but none has been picked - so far by a server round-trip. Then we set the picked one to the - want one, and if this is one single bit it'll be used instantly. */ - authhost->picked = authhost->want; - - if(authproxy->want && !authproxy->picked) - /* The app has selected one or more methods, but none has been picked so - far by a proxy round-trip. Then we set the picked one to the want one, - and if this is one single bit it'll be used instantly. */ - authproxy->picked = authproxy->want; - -#ifndef CURL_DISABLE_PROXY - /* Send proxy authentication header if needed */ - if(conn->bits.httpproxy && - (conn->bits.tunnel_proxy == proxytunnel)) { - result = output_auth_headers(conn, authproxy, request, path, TRUE); - if(result) - return result; - } - else -#else - (void)proxytunnel; -#endif /* CURL_DISABLE_PROXY */ - /* we have no proxy so let's pretend we're done authenticating - with it */ - authproxy->done = TRUE; - - /* To prevent the user+password to get sent to other than the original - host due to a location-follow, we do some weirdo checks here */ - if(!data->state.this_is_a_follow || - conn->bits.netrc || - !data->state.first_host || - data->set.http_disable_hostname_check_before_authentication || - Curl_raw_equal(data->state.first_host, conn->host.name)) { - result = output_auth_headers(conn, authhost, request, path, FALSE); - } - else - authhost->done = TRUE; - - return result; -} - -/* - * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: - * headers. They are dealt with both in the transfer.c main loop and in the - * proxy CONNECT loop. - */ - -CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, - const char *auth) /* the first non-space */ -{ - /* - * This resource requires authentication - */ - struct SessionHandle *data = conn->data; - -#ifdef USE_SPNEGO - struct negotiatedata *negdata = proxy? - &data->state.proxyneg:&data->state.negotiate; -#endif - unsigned long *availp; - struct auth *authp; - - if(proxy) { - availp = &data->info.proxyauthavail; - authp = &data->state.authproxy; - } - else { - availp = &data->info.httpauthavail; - authp = &data->state.authhost; - } - - /* - * Here we check if we want the specific single authentication (using ==) and - * if we do, we initiate usage of it. - * - * If the provided authentication is wanted as one out of several accepted - * types (using &), we OR this authentication type to the authavail - * variable. - * - * Note: - * - * ->picked is first set to the 'want' value (one or more bits) before the - * request is sent, and then it is again set _after_ all response 401/407 - * headers have been received but then only to a single preferred method - * (bit). - */ - - while(*auth) { -#ifdef USE_SPNEGO - if(checkprefix("Negotiate", auth)) { - *availp |= CURLAUTH_NEGOTIATE; - authp->avail |= CURLAUTH_NEGOTIATE; - - if(authp->picked == CURLAUTH_NEGOTIATE) { - if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) { - CURLcode result = Curl_input_negotiate(conn, proxy, auth); - if(!result) { - DEBUGASSERT(!data->req.newurl); - data->req.newurl = strdup(data->change.url); - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - data->state.authproblem = FALSE; - /* we received a GSS auth token and we dealt with it fine */ - negdata->state = GSS_AUTHRECV; - } - else - data->state.authproblem = TRUE; - } - } - } - else -#endif -#ifdef USE_NTLM - /* NTLM support requires the SSL crypto libs */ - if(checkprefix("NTLM", auth)) { - *availp |= CURLAUTH_NTLM; - authp->avail |= CURLAUTH_NTLM; - if(authp->picked == CURLAUTH_NTLM || - authp->picked == CURLAUTH_NTLM_WB) { - /* NTLM authentication is picked and activated */ - CURLcode result = Curl_input_ntlm(conn, proxy, auth); - if(!result) { - data->state.authproblem = FALSE; -#ifdef NTLM_WB_ENABLED - if(authp->picked == CURLAUTH_NTLM_WB) { - *availp &= ~CURLAUTH_NTLM; - authp->avail &= ~CURLAUTH_NTLM; - *availp |= CURLAUTH_NTLM_WB; - authp->avail |= CURLAUTH_NTLM_WB; - - /* Get the challenge-message which will be passed to - * ntlm_auth for generating the type 3 message later */ - while(*auth && ISSPACE(*auth)) - auth++; - if(checkprefix("NTLM", auth)) { - auth += strlen("NTLM"); - while(*auth && ISSPACE(*auth)) - auth++; - if(*auth) - if((conn->challenge_header = strdup(auth)) == NULL) - return CURLE_OUT_OF_MEMORY; - } - } -#endif - } - else { - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; - } - } - } - else -#endif -#ifndef CURL_DISABLE_CRYPTO_AUTH - if(checkprefix("Digest", auth)) { - if((authp->avail & CURLAUTH_DIGEST) != 0) { - infof(data, "Ignoring duplicate digest auth header.\n"); - } - else { - CURLcode result; - *availp |= CURLAUTH_DIGEST; - authp->avail |= CURLAUTH_DIGEST; - - /* We call this function on input Digest headers even if Digest - * authentication isn't activated yet, as we need to store the - * incoming data from this header in case we are gonna use - * Digest. */ - result = Curl_input_digest(conn, proxy, auth); - if(result) { - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; - } - } - } - else -#endif - if(checkprefix("Basic", auth)) { - *availp |= CURLAUTH_BASIC; - authp->avail |= CURLAUTH_BASIC; - if(authp->picked == CURLAUTH_BASIC) { - /* We asked for Basic authentication but got a 40X back - anyway, which basically means our name+password isn't - valid. */ - authp->avail = CURLAUTH_NONE; - infof(data, "Authentication problem. Ignoring this.\n"); - data->state.authproblem = TRUE; - } - } - - /* there may be multiple methods on one line, so keep reading */ - while(*auth && *auth != ',') /* read up to the next comma */ - auth++; - if(*auth == ',') /* if we're on a comma, skip it */ - auth++; - while(*auth && ISSPACE(*auth)) - auth++; - } - - return CURLE_OK; -} - -/** - * http_should_fail() determines whether an HTTP response has gotten us - * into an error state or not. - * - * @param conn all information about the current connection - * - * @retval 0 communications should continue - * - * @retval 1 communications should not continue - */ -static int http_should_fail(struct connectdata *conn) -{ - struct SessionHandle *data; - int httpcode; - - DEBUGASSERT(conn); - data = conn->data; - DEBUGASSERT(data); - - httpcode = data->req.httpcode; - - /* - ** If we haven't been asked to fail on error, - ** don't fail. - */ - if(!data->set.http_fail_on_error) - return 0; - - /* - ** Any code < 400 is never terminal. - */ - if(httpcode < 400) - return 0; - - /* - ** Any code >= 400 that's not 401 or 407 is always - ** a terminal error - */ - if((httpcode != 401) && (httpcode != 407)) - return 1; - - /* - ** All we have left to deal with is 401 and 407 - */ - DEBUGASSERT((httpcode == 401) || (httpcode == 407)); - - /* - ** Examine the current authentication state to see if this - ** is an error. The idea is for this function to get - ** called after processing all the headers in a response - ** message. So, if we've been to asked to authenticate a - ** particular stage, and we've done it, we're OK. But, if - ** we're already completely authenticated, it's not OK to - ** get another 401 or 407. - ** - ** It is possible for authentication to go stale such that - ** the client needs to reauthenticate. Once that info is - ** available, use it here. - */ - - /* - ** Either we're not authenticating, or we're supposed to - ** be authenticating something else. This is an error. - */ - if((httpcode == 401) && !conn->bits.user_passwd) - return TRUE; - if((httpcode == 407) && !conn->bits.proxy_user_passwd) - return TRUE; - - return data->state.authproblem; -} - -/* - * readmoredata() is a "fread() emulation" to provide POST and/or request - * data. It is used when a huge POST is to be made and the entire chunk wasn't - * sent in the first send(). This function will then be called from the - * transfer.c loop when more data is to be sent to the peer. - * - * Returns the amount of bytes it filled the buffer with. - */ -static size_t readmoredata(char *buffer, - size_t size, - size_t nitems, - void *userp) -{ - struct connectdata *conn = (struct connectdata *)userp; - struct HTTP *http = conn->data->req.protop; - size_t fullsize = size * nitems; - - if(!http->postsize) - /* nothing to return */ - return 0; - - /* make sure that a HTTP request is never sent away chunked! */ - conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE; - - if(http->postsize <= (curl_off_t)fullsize) { - memcpy(buffer, http->postdata, (size_t)http->postsize); - fullsize = (size_t)http->postsize; - - if(http->backup.postsize) { - /* move backup data into focus and continue on that */ - http->postdata = http->backup.postdata; - http->postsize = http->backup.postsize; - conn->data->state.fread_func = http->backup.fread_func; - conn->data->state.in = http->backup.fread_in; - - http->sending++; /* move one step up */ - - http->backup.postsize=0; - } - else - http->postsize = 0; - - return fullsize; - } - - memcpy(buffer, http->postdata, fullsize); - http->postdata += fullsize; - http->postsize -= fullsize; - - return fullsize; -} - -/* ------------------------------------------------------------------------- */ -/* add_buffer functions */ - -/* - * Curl_add_buffer_init() sets up and returns a fine buffer struct - */ -Curl_send_buffer *Curl_add_buffer_init(void) -{ - return calloc(1, sizeof(Curl_send_buffer)); -} - -/* - * Curl_add_buffer_free() frees all associated resources. - */ -void Curl_add_buffer_free(Curl_send_buffer *buff) -{ - if(buff) /* deal with NULL input */ - free(buff->buffer); - free(buff); -} - -/* - * Curl_add_buffer_send() sends a header buffer and frees all associated - * memory. Body data may be appended to the header data if desired. - * - * Returns CURLcode - */ -CURLcode Curl_add_buffer_send(Curl_send_buffer *in, - struct connectdata *conn, - - /* add the number of sent bytes to this - counter */ - long *bytes_written, - - /* how much of the buffer contains body data */ - size_t included_body_bytes, - int socketindex) - -{ - ssize_t amount; - CURLcode result; - char *ptr; - size_t size; - struct HTTP *http = conn->data->req.protop; - size_t sendsize; - curl_socket_t sockfd; - size_t headersize; - - DEBUGASSERT(socketindex <= SECONDARYSOCKET); - - sockfd = conn->sock[socketindex]; - - /* The looping below is required since we use non-blocking sockets, but due - to the circumstances we will just loop and try again and again etc */ - - ptr = in->buffer; - size = in->size_used; - - headersize = size - included_body_bytes; /* the initial part that isn't body - is header */ - - DEBUGASSERT(size > included_body_bytes); - - result = Curl_convert_to_network(conn->data, ptr, headersize); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) { - /* conversion failed, free memory and return to the caller */ - Curl_add_buffer_free(in); - return result; - } - - if((conn->handler->flags & PROTOPT_SSL) && conn->httpversion != 20) { - /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk - when we speak HTTPS, as if only a fraction of it is sent now, this data - needs to fit into the normal read-callback buffer later on and that - buffer is using this size. - */ - - sendsize = (size > CURL_MAX_WRITE_SIZE) ? CURL_MAX_WRITE_SIZE : size; - - /* OpenSSL is very picky and we must send the SAME buffer pointer to the - library when we attempt to re-send this buffer. Sending the same data - is not enough, we must use the exact same address. For this reason, we - must copy the data to the uploadbuffer first, since that is the buffer - we will be using if this send is retried later. - */ - memcpy(conn->data->state.uploadbuffer, ptr, sendsize); - ptr = conn->data->state.uploadbuffer; - } - else - sendsize = size; - - result = Curl_write(conn, sockfd, ptr, sendsize, &amount); - - if(!result) { - /* - * Note that we may not send the entire chunk at once, and we have a set - * number of data bytes at the end of the big buffer (out of which we may - * only send away a part). - */ - /* how much of the header that was sent */ - size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount; - size_t bodylen = amount - headlen; - - if(conn->data->set.verbose) { - /* this data _may_ contain binary stuff */ - Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn); - if(bodylen) { - /* there was body data sent beyond the initial header part, pass that - on to the debug callback too */ - Curl_debug(conn->data, CURLINFO_DATA_OUT, - ptr+headlen, bodylen, conn); - } - } - - /* 'amount' can never be a very large value here so typecasting it so a - signed 31 bit value should not cause problems even if ssize_t is - 64bit */ - *bytes_written += (long)amount; - - if(http) { - /* if we sent a piece of the body here, up the byte counter for it - accordingly */ - http->writebytecount += bodylen; - - if((size_t)amount != size) { - /* The whole request could not be sent in one system call. We must - queue it up and send it later when we get the chance. We must not - loop here and wait until it might work again. */ - - size -= amount; - - ptr = in->buffer + amount; - - /* backup the currently set pointers */ - http->backup.fread_func = conn->data->state.fread_func; - http->backup.fread_in = conn->data->state.in; - http->backup.postdata = http->postdata; - http->backup.postsize = http->postsize; - - /* set the new pointers for the request-sending */ - conn->data->state.fread_func = (curl_read_callback)readmoredata; - conn->data->state.in = (void *)conn; - http->postdata = ptr; - http->postsize = (curl_off_t)size; - - http->send_buffer = in; - http->sending = HTTPSEND_REQUEST; - - return CURLE_OK; - } - http->sending = HTTPSEND_BODY; - /* the full buffer was sent, clean up and return */ - } - else { - if((size_t)amount != size) - /* We have no continue-send mechanism now, fail. This can only happen - when this function is used from the CONNECT sending function. We - currently (stupidly) assume that the whole request is always sent - away in the first single chunk. - - This needs FIXing. - */ - return CURLE_SEND_ERROR; - else - Curl_pipeline_leave_write(conn); - } - } - Curl_add_buffer_free(in); - - return result; -} - - -/* - * add_bufferf() add the formatted input to the buffer. - */ -CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...) -{ - char *s; - va_list ap; - va_start(ap, fmt); - s = vaprintf(fmt, ap); /* this allocs a new string to append */ - va_end(ap); - - if(s) { - CURLcode result = Curl_add_buffer(in, s, strlen(s)); - free(s); - return result; - } - /* If we failed, we cleanup the whole buffer and return error */ - free(in->buffer); - free(in); - return CURLE_OUT_OF_MEMORY; -} - -/* - * add_buffer() appends a memory chunk to the existing buffer - */ -CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) -{ - char *new_rb; - size_t new_size; - - if(~size < in->size_used) { - /* If resulting used size of send buffer would wrap size_t, cleanup - the whole buffer and return error. Otherwise the required buffer - size will fit into a single allocatable memory chunk */ - Curl_safefree(in->buffer); - free(in); - return CURLE_OUT_OF_MEMORY; - } - - if(!in->buffer || - ((in->size_used + size) > (in->size_max - 1))) { - - /* If current buffer size isn't enough to hold the result, use a - buffer size that doubles the required size. If this new size - would wrap size_t, then just use the largest possible one */ - - if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) || - (~(size * 2) < (in->size_used * 2))) - new_size = (size_t)-1; - else - new_size = (in->size_used+size) * 2; - - if(in->buffer) - /* we have a buffer, enlarge the existing one */ - new_rb = realloc(in->buffer, new_size); - else - /* create a new buffer */ - new_rb = malloc(new_size); - - if(!new_rb) { - /* If we failed, we cleanup the whole buffer and return error */ - Curl_safefree(in->buffer); - free(in); - return CURLE_OUT_OF_MEMORY; - } - - in->buffer = new_rb; - in->size_max = new_size; - } - memcpy(&in->buffer[in->size_used], inptr, size); - - in->size_used += size; - - return CURLE_OK; -} - -/* end of the add_buffer functions */ -/* ------------------------------------------------------------------------- */ - - - -/* - * Curl_compareheader() - * - * Returns TRUE if 'headerline' contains the 'header' with given 'content'. - * Pass headers WITH the colon. - */ -bool -Curl_compareheader(const char *headerline, /* line to check */ - const char *header, /* header keyword _with_ colon */ - const char *content) /* content string to find */ -{ - /* RFC2616, section 4.2 says: "Each header field consists of a name followed - * by a colon (":") and the field value. Field names are case-insensitive. - * The field value MAY be preceded by any amount of LWS, though a single SP - * is preferred." */ - - size_t hlen = strlen(header); - size_t clen; - size_t len; - const char *start; - const char *end; - - if(!Curl_raw_nequal(headerline, header, hlen)) - return FALSE; /* doesn't start with header */ - - /* pass the header */ - start = &headerline[hlen]; - - /* pass all white spaces */ - while(*start && ISSPACE(*start)) - start++; - - /* find the end of the header line */ - end = strchr(start, '\r'); /* lines end with CRLF */ - if(!end) { - /* in case there's a non-standard compliant line here */ - end = strchr(start, '\n'); - - if(!end) - /* hm, there's no line ending here, use the zero byte! */ - end = strchr(start, '\0'); - } - - len = end-start; /* length of the content part of the input line */ - clen = strlen(content); /* length of the word to find */ - - /* find the content string in the rest of the line */ - for(;len>=clen;len--, start++) { - if(Curl_raw_nequal(start, content, clen)) - return TRUE; /* match! */ - } - - return FALSE; /* no match */ -} - -/* - * Curl_http_connect() performs HTTP stuff to do at connect-time, called from - * the generic Curl_connect(). - */ -CURLcode Curl_http_connect(struct connectdata *conn, bool *done) -{ - CURLcode result; - - /* We default to persistent connections. We set this already in this connect - function to make the re-use checks properly be able to check this bit. */ - connkeep(conn, "HTTP default"); - - /* the CONNECT procedure might not have been completed */ - result = Curl_proxy_connect(conn); - if(result) - return result; - - if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) - /* nothing else to do except wait right now - we're not done here. */ - return CURLE_OK; - - if(conn->given->flags & PROTOPT_SSL) { - /* perform SSL initialization */ - result = https_connecting(conn, done); - if(result) - return result; - } - else - *done = TRUE; - - return CURLE_OK; -} - -/* this returns the socket to wait for in the DO and DOING state for the multi - interface and then we're always _sending_ a request and thus we wait for - the single socket to become writable only */ -static int http_getsock_do(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - /* write mode */ - (void)numsocks; /* unused, we trust it to be at least 1 */ - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_WRITESOCK(0); -} - -#ifdef USE_SSL -static CURLcode https_connecting(struct connectdata *conn, bool *done) -{ - CURLcode result; - DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL)); - - /* perform SSL initialization for this socket */ - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done); - if(result) - connclose(conn, "Failed HTTPS connection"); - - return result; -} -#endif - -#if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \ - defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \ - defined(USE_MBEDTLS) -/* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only. - It should be made to query the generic SSL layer instead. */ -static int https_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - if(conn->handler->flags & PROTOPT_SSL) { - struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; - - if(!numsocks) - return GETSOCK_BLANK; - - if(connssl->connecting_state == ssl_connect_2_writing) { - /* write mode */ - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_WRITESOCK(0); - } - else if(connssl->connecting_state == ssl_connect_2_reading) { - /* read mode */ - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_READSOCK(0); - } - } - - return CURLE_OK; -} -#else -#ifdef USE_SSL -static int https_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - (void)conn; - (void)socks; - (void)numsocks; - return GETSOCK_BLANK; -} -#endif /* USE_SSL */ -#endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */ - -/* - * Curl_http_done() gets called after a single HTTP request has been - * performed. - */ - -CURLcode Curl_http_done(struct connectdata *conn, - CURLcode status, bool premature) -{ - struct SessionHandle *data = conn->data; - struct HTTP *http = data->req.protop; -#ifdef USE_NGHTTP2 - struct http_conn *httpc = &conn->proto.httpc; -#endif - - Curl_unencode_cleanup(conn); - -#ifdef USE_SPNEGO - if(data->state.proxyneg.state == GSS_AUTHSENT || - data->state.negotiate.state == GSS_AUTHSENT) { - /* add forbid re-use if http-code != 401/407 as a WA only needed for - * 401/407 that signal auth failure (empty) otherwise state will be RECV - * with current code. - * Do not close CONNECT_ONLY connections. */ - if((data->req.httpcode != 401) && (data->req.httpcode != 407) && - !data->set.connect_only) - connclose(conn, "Negotiate transfer completed"); - Curl_cleanup_negotiate(data); - } -#endif - - /* set the proper values (possibly modified on POST) */ - conn->seek_func = data->set.seek_func; /* restore */ - conn->seek_client = data->set.seek_client; /* restore */ - - if(!http) - return CURLE_OK; - - if(http->send_buffer) { - Curl_add_buffer_free(http->send_buffer); - http->send_buffer = NULL; /* clear the pointer */ - } - -#ifdef USE_NGHTTP2 - if(http->header_recvbuf) { - DEBUGF(infof(data, "free header_recvbuf!!\n")); - Curl_add_buffer_free(http->header_recvbuf); - http->header_recvbuf = NULL; /* clear the pointer */ - Curl_add_buffer_free(http->trailer_recvbuf); - http->trailer_recvbuf = NULL; /* clear the pointer */ - if(http->push_headers) { - /* if they weren't used and then freed before */ - for(; http->push_headers_used > 0; --http->push_headers_used) { - free(http->push_headers[http->push_headers_used - 1]); - } - free(http->push_headers); - http->push_headers = NULL; - } - } - if(http->stream_id) { - nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0); - http->stream_id = 0; - } -#endif - - if(HTTPREQ_POST_FORM == data->set.httpreq) { - data->req.bytecount = http->readbytecount + http->writebytecount; - - Curl_formclean(&http->sendit); /* Now free that whole lot */ - if(http->form.fp) { - /* a file being uploaded was left opened, close it! */ - fclose(http->form.fp); - http->form.fp = NULL; - } - } - else if(HTTPREQ_PUT == data->set.httpreq) - data->req.bytecount = http->readbytecount + http->writebytecount; - - if(status) - return status; - - if(!premature && /* this check is pointless when DONE is called before the - entire operation is complete */ - !conn->bits.retry && - !data->set.connect_only && - (http->readbytecount + - data->req.headerbytecount - - data->req.deductheadercount) <= 0) { - /* If this connection isn't simply closed to be retried, AND nothing was - read from the HTTP server (that counts), this can't be right so we - return an error here */ - failf(data, "Empty reply from server"); - return CURLE_GOT_NOTHING; - } - - return CURLE_OK; -} - -/* - * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons - * to avoid it include: - * - * - if the user specifically requested HTTP 1.0 - * - if the server we are connected to only supports 1.0 - * - if any server previously contacted to handle this request only supports - * 1.0. - */ -static bool use_http_1_1plus(const struct SessionHandle *data, - const struct connectdata *conn) -{ - if((data->state.httpversion == 10) || (conn->httpversion == 10)) - return FALSE; - if((data->set.httpversion == CURL_HTTP_VERSION_1_0) && - (conn->httpversion <= 10)) - return FALSE; - return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) || - (data->set.httpversion >= CURL_HTTP_VERSION_1_1)); -} - -/* check and possibly add an Expect: header */ -static CURLcode expect100(struct SessionHandle *data, - struct connectdata *conn, - Curl_send_buffer *req_buffer) -{ - CURLcode result = CURLE_OK; - const char *ptr; - data->state.expect100header = FALSE; /* default to false unless it is set - to TRUE below */ - if(use_http_1_1plus(data, conn) && - (conn->httpversion != 20)) { - /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an - Expect: 100-continue to the headers which actually speeds up post - operations (as there is one packet coming back from the web server) */ - ptr = Curl_checkheaders(conn, "Expect:"); - if(ptr) { - data->state.expect100header = - Curl_compareheader(ptr, "Expect:", "100-continue"); - } - else { - result = Curl_add_bufferf(req_buffer, - "Expect: 100-continue\r\n"); - if(!result) - data->state.expect100header = TRUE; - } - } - - return result; -} - -enum proxy_use { - HEADER_SERVER, /* direct to server */ - HEADER_PROXY, /* regular request to proxy */ - HEADER_CONNECT /* sending CONNECT to a proxy */ -}; - -CURLcode Curl_add_custom_headers(struct connectdata *conn, - bool is_connect, - Curl_send_buffer *req_buffer) -{ - char *ptr; - struct curl_slist *h[2]; - struct curl_slist *headers; - int numlists=1; /* by default */ - struct SessionHandle *data = conn->data; - int i; - - enum proxy_use proxy; - - if(is_connect) - proxy = HEADER_CONNECT; - else - proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy? - HEADER_PROXY:HEADER_SERVER; - - switch(proxy) { - case HEADER_SERVER: - h[0] = data->set.headers; - break; - case HEADER_PROXY: - h[0] = data->set.headers; - if(data->set.sep_headers) { - h[1] = data->set.proxyheaders; - numlists++; - } - break; - case HEADER_CONNECT: - if(data->set.sep_headers) - h[0] = data->set.proxyheaders; - else - h[0] = data->set.headers; - break; - } - - /* loop through one or two lists */ - for(i=0; i < numlists; i++) { - headers = h[i]; - - while(headers) { - ptr = strchr(headers->data, ':'); - if(ptr) { - /* we require a colon for this to be a true header */ - - ptr++; /* pass the colon */ - while(*ptr && ISSPACE(*ptr)) - ptr++; - - if(*ptr) { - /* only send this if the contents was non-blank */ - - if(conn->allocptr.host && - /* a Host: header was sent already, don't pass on any custom Host: - header as that will produce *two* in the same request! */ - checkprefix("Host:", headers->data)) - ; - else if(data->set.httpreq == HTTPREQ_POST_FORM && - /* this header (extended by formdata.c) is sent later */ - checkprefix("Content-Type:", headers->data)) - ; - else if(conn->bits.authneg && - /* while doing auth neg, don't allow the custom length since - we will force length zero then */ - checkprefix("Content-Length", headers->data)) - ; - else if(conn->allocptr.te && - /* when asking for Transfer-Encoding, don't pass on a custom - Connection: */ - checkprefix("Connection", headers->data)) - ; - else { - CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n", - headers->data); - if(result) - return result; - } - } - } - else { - ptr = strchr(headers->data, ';'); - if(ptr) { - - ptr++; /* pass the semicolon */ - while(*ptr && ISSPACE(*ptr)) - ptr++; - - if(*ptr) { - /* this may be used for something else in the future */ - } - else { - if(*(--ptr) == ';') { - CURLcode result; - - /* send no-value custom header if terminated by semicolon */ - *ptr = ':'; - result = Curl_add_bufferf(req_buffer, "%s\r\n", - headers->data); - if(result) - return result; - } - } - } - } - headers = headers->next; - } - } - - return CURLE_OK; -} - -CURLcode Curl_add_timecondition(struct SessionHandle *data, - Curl_send_buffer *req_buffer) -{ - const struct tm *tm; - char *buf = data->state.buffer; - struct tm keeptime; - CURLcode result; - - if(data->set.timecondition == CURL_TIMECOND_NONE) - /* no condition was asked for */ - return CURLE_OK; - - result = Curl_gmtime(data->set.timevalue, &keeptime); - if(result) { - failf(data, "Invalid TIMEVALUE"); - return result; - } - tm = &keeptime; - - /* The If-Modified-Since header family should have their times set in - * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be - * represented in Greenwich Mean Time (GMT), without exception. For the - * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal - * Time)." (see page 20 of RFC2616). - */ - - /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ - snprintf(buf, BUFSIZE-1, - "%s, %02d %s %4d %02d:%02d:%02d GMT", - Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - - switch(data->set.timecondition) { - default: - break; - case CURL_TIMECOND_IFMODSINCE: - result = Curl_add_bufferf(req_buffer, - "If-Modified-Since: %s\r\n", buf); - break; - case CURL_TIMECOND_IFUNMODSINCE: - result = Curl_add_bufferf(req_buffer, - "If-Unmodified-Since: %s\r\n", buf); - break; - case CURL_TIMECOND_LASTMOD: - result = Curl_add_bufferf(req_buffer, - "Last-Modified: %s\r\n", buf); - break; - } - - return result; -} - -/* - * Curl_http() gets called from the generic Curl_do() function when a HTTP - * request is to be performed. This creates and sends a properly constructed - * HTTP request. - */ -CURLcode Curl_http(struct connectdata *conn, bool *done) -{ - struct SessionHandle *data = conn->data; - CURLcode result = CURLE_OK; - struct HTTP *http; - const char *ppath = data->state.path; - bool paste_ftp_userpwd = FALSE; - char ftp_typecode[sizeof("/;type=?")] = ""; - const char *host = conn->host.name; - const char *te = ""; /* transfer-encoding */ - const char *ptr; - const char *request; - Curl_HttpReq httpreq = data->set.httpreq; -#if !defined(CURL_DISABLE_COOKIES) - char *addcookies = NULL; -#endif - curl_off_t included_body = 0; - const char *httpstring; - Curl_send_buffer *req_buffer; - curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */ - int seekerr = CURL_SEEKFUNC_OK; - - /* Always consider the DO phase done after this function call, even if there - may be parts of the request that is not yet sent, since we can deal with - the rest of the request in the PERFORM phase. */ - *done = TRUE; - - if(conn->httpversion < 20) { /* unless the connection is re-used and already - http2 */ - switch(conn->negnpn) { - case CURL_HTTP_VERSION_2: - conn->httpversion = 20; /* we know we're on HTTP/2 now */ - - result = Curl_http2_switched(conn, NULL, 0); - if(result) - return result; - break; - case CURL_HTTP_VERSION_1_1: - /* continue with HTTP/1.1 when explicitly requested */ - break; - default: - /* Check if user wants to use HTTP/2 with clear TCP*/ -#ifdef USE_NGHTTP2 - if(conn->data->set.httpversion == - CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) { - DEBUGF(infof(data, "HTTP/2 over clean TCP\n")); - conn->httpversion = 20; - - result = Curl_http2_switched(conn, NULL, 0); - if(result) - return result; - } -#endif - break; - } - } - else { - /* prepare for a http2 request */ - result = Curl_http2_setup(conn); - if(result) - return result; - } - - http = data->req.protop; - - if(!data->state.this_is_a_follow) { - /* Free to avoid leaking memory on multiple requests*/ - free(data->state.first_host); - - data->state.first_host = strdup(conn->host.name); - if(!data->state.first_host) - return CURLE_OUT_OF_MEMORY; - - data->state.first_remote_port = conn->remote_port; - } - http->writebytecount = http->readbytecount = 0; - - if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && - data->set.upload) { - httpreq = HTTPREQ_PUT; - } - - /* Now set the 'request' pointer to the proper request string */ - if(data->set.str[STRING_CUSTOMREQUEST]) - request = data->set.str[STRING_CUSTOMREQUEST]; - else { - if(data->set.opt_no_body) - request = "HEAD"; - else { - DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST)); - switch(httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - request = "POST"; - break; - case HTTPREQ_PUT: - request = "PUT"; - break; - default: /* this should never happen */ - case HTTPREQ_GET: - request = "GET"; - break; - case HTTPREQ_HEAD: - request = "HEAD"; - break; - } - } - } - - /* The User-Agent string might have been allocated in url.c already, because - it might have been used in the proxy connect, but if we have got a header - with the user-agent string specified, we erase the previously made string - here. */ - if(Curl_checkheaders(conn, "User-Agent:")) { - free(conn->allocptr.uagent); - conn->allocptr.uagent=NULL; - } - - /* setup the authentication headers */ - result = Curl_http_output_auth(conn, request, ppath, FALSE); - if(result) - return result; - - if((data->state.authhost.multi || data->state.authproxy.multi) && - (httpreq != HTTPREQ_GET) && - (httpreq != HTTPREQ_HEAD)) { - /* Auth is required and we are not authenticated yet. Make a PUT or POST - with content-length zero as a "probe". */ - conn->bits.authneg = TRUE; - } - else - conn->bits.authneg = FALSE; - - Curl_safefree(conn->allocptr.ref); - if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) { - conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer); - if(!conn->allocptr.ref) - return CURLE_OUT_OF_MEMORY; - } - else - conn->allocptr.ref = NULL; - -#if !defined(CURL_DISABLE_COOKIES) - if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:")) - addcookies = data->set.str[STRING_COOKIE]; -#endif - - if(!Curl_checkheaders(conn, "Accept-Encoding:") && - data->set.str[STRING_ENCODING]) { - Curl_safefree(conn->allocptr.accept_encoding); - conn->allocptr.accept_encoding = - aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]); - if(!conn->allocptr.accept_encoding) - return CURLE_OUT_OF_MEMORY; - } - else { - Curl_safefree(conn->allocptr.accept_encoding); - conn->allocptr.accept_encoding = NULL; - } - -#ifdef HAVE_LIBZ - /* we only consider transfer-encoding magic if libz support is built-in */ - - if(!Curl_checkheaders(conn, "TE:") && - data->set.http_transfer_encoding) { - /* When we are to insert a TE: header in the request, we must also insert - TE in a Connection: header, so we need to merge the custom provided - Connection: header and prevent the original to get sent. Note that if - the user has inserted his/hers own TE: header we don't do this magic - but then assume that the user will handle it all! */ - char *cptr = Curl_checkheaders(conn, "Connection:"); -#define TE_HEADER "TE: gzip\r\n" - - Curl_safefree(conn->allocptr.te); - - /* Create the (updated) Connection: header */ - conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr): - strdup("Connection: TE\r\n" TE_HEADER); - - if(!conn->allocptr.te) - return CURLE_OUT_OF_MEMORY; - } -#endif - - if(conn->httpversion == 20) - /* In HTTP2 forbids Transfer-Encoding: chunked */ - ptr = NULL; - else { - ptr = Curl_checkheaders(conn, "Transfer-Encoding:"); - if(ptr) { - /* Some kind of TE is requested, check if 'chunked' is chosen */ - data->req.upload_chunky = - Curl_compareheader(ptr, "Transfer-Encoding:", "chunked"); - } - else { - if((conn->handler->protocol&PROTO_FAMILY_HTTP) && - data->set.upload && - (data->state.infilesize == -1)) { - if(conn->bits.authneg) - /* don't enable chunked during auth neg */ - ; - else if(use_http_1_1plus(data, conn)) { - /* HTTP, upload, unknown file size and not HTTP 1.0 */ - data->req.upload_chunky = TRUE; - } - else { - failf(data, "Chunky upload is not supported by HTTP 1.0"); - return CURLE_UPLOAD_FAILED; - } - } - else { - /* else, no chunky upload */ - data->req.upload_chunky = FALSE; - } - - if(data->req.upload_chunky) - te = "Transfer-Encoding: chunked\r\n"; - } - } - - Curl_safefree(conn->allocptr.host); - - ptr = Curl_checkheaders(conn, "Host:"); - if(ptr && (!data->state.this_is_a_follow || - Curl_raw_equal(data->state.first_host, conn->host.name))) { -#if !defined(CURL_DISABLE_COOKIES) - /* If we have a given custom Host: header, we extract the host name in - order to possibly use it for cookie reasons later on. We only allow the - custom Host: header if this is NOT a redirect, as setting Host: in the - redirected request is being out on thin ice. Except if the host name - is the same as the first one! */ - char *cookiehost = Curl_copy_header_value(ptr); - if(!cookiehost) - return CURLE_OUT_OF_MEMORY; - if(!*cookiehost) - /* ignore empty data */ - free(cookiehost); - else { - /* If the host begins with '[', we start searching for the port after - the bracket has been closed */ - int startsearch = 0; - if(*cookiehost == '[') { - char *closingbracket; - /* since the 'cookiehost' is an allocated memory area that will be - freed later we cannot simply increment the pointer */ - memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1); - closingbracket = strchr(cookiehost, ']'); - if(closingbracket) - *closingbracket = 0; - } - else { - char *colon = strchr(cookiehost + startsearch, ':'); - if(colon) - *colon = 0; /* The host must not include an embedded port number */ - } - Curl_safefree(conn->allocptr.cookiehost); - conn->allocptr.cookiehost = cookiehost; - } -#endif - - if(strcmp("Host:", ptr)) { - conn->allocptr.host = aprintf("%s\r\n", ptr); - if(!conn->allocptr.host) - return CURLE_OUT_OF_MEMORY; - } - else - /* when clearing the header */ - conn->allocptr.host = NULL; - } - else { - /* When building Host: headers, we must put the host name within - [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ - - if(((conn->given->protocol&CURLPROTO_HTTPS) && - (conn->remote_port == PORT_HTTPS)) || - ((conn->given->protocol&CURLPROTO_HTTP) && - (conn->remote_port == PORT_HTTP)) ) - /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include - the port number in the host string */ - conn->allocptr.host = aprintf("Host: %s%s%s\r\n", - conn->bits.ipv6_ip?"[":"", - host, - conn->bits.ipv6_ip?"]":""); - else - conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n", - conn->bits.ipv6_ip?"[":"", - host, - conn->bits.ipv6_ip?"]":"", - conn->remote_port); - - if(!conn->allocptr.host) - /* without Host: we can't make a nice request */ - return CURLE_OUT_OF_MEMORY; - } - -#ifndef CURL_DISABLE_PROXY - if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { - /* Using a proxy but does not tunnel through it */ - - /* The path sent to the proxy is in fact the entire URL. But if the remote - host is a IDN-name, we must make sure that the request we produce only - uses the encoded host name! */ - if(conn->host.dispname != conn->host.name) { - char *url = data->change.url; - ptr = strstr(url, conn->host.dispname); - if(ptr) { - /* This is where the display name starts in the URL, now replace this - part with the encoded name. TODO: This method of replacing the host - name is rather crude as I believe there's a slight risk that the - user has entered a user name or password that contain the host name - string. */ - size_t currlen = strlen(conn->host.dispname); - size_t newlen = strlen(conn->host.name); - size_t urllen = strlen(url); - - char *newurl; - - newurl = malloc(urllen + newlen - currlen + 1); - if(newurl) { - /* copy the part before the host name */ - memcpy(newurl, url, ptr - url); - /* append the new host name instead of the old */ - memcpy(newurl + (ptr - url), conn->host.name, newlen); - /* append the piece after the host name */ - memcpy(newurl + newlen + (ptr - url), - ptr + currlen, /* copy the trailing zero byte too */ - urllen - (ptr-url) - currlen + 1); - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - data->change.url = newurl; - data->change.url_alloc = TRUE; - } - else - return CURLE_OUT_OF_MEMORY; - } - } - ppath = data->change.url; - if(checkprefix("ftp://", ppath)) { - if(data->set.proxy_transfer_mode) { - /* when doing ftp, append ;type= if not present */ - char *type = strstr(ppath, ";type="); - if(type && type[6] && type[7] == 0) { - switch (Curl_raw_toupper(type[6])) { - case 'A': - case 'D': - case 'I': - break; - default: - type = NULL; - } - } - if(!type) { - char *p = ftp_typecode; - /* avoid sending invalid URLs like ftp://example.com;type=i if the - * user specified ftp://example.com without the slash */ - if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') { - *p++ = '/'; - } - snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c", - data->set.prefer_ascii ? 'a' : 'i'); - } - } - if(conn->bits.user_passwd && !conn->bits.userpwd_in_url) - paste_ftp_userpwd = TRUE; - } - } -#endif /* CURL_DISABLE_PROXY */ - - if(HTTPREQ_POST_FORM == httpreq) { - /* we must build the whole post sequence first, so that we have a size of - the whole transfer before we start to send it */ - result = Curl_getformdata(data, &http->sendit, data->set.httppost, - Curl_checkheaders(conn, "Content-Type:"), - &http->postsize); - if(result) - return result; - } - - http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n"; - - if(( (HTTPREQ_POST == httpreq) || - (HTTPREQ_POST_FORM == httpreq) || - (HTTPREQ_PUT == httpreq) ) && - data->state.resume_from) { - /********************************************************************** - * Resuming upload in HTTP means that we PUT or POST and that we have - * got a resume_from value set. The resume value has already created - * a Range: header that will be passed along. We need to "fast forward" - * the file the given number of bytes and decrease the assume upload - * file size before we continue this venture in the dark lands of HTTP. - *********************************************************************/ - - if(data->state.resume_from < 0) { - /* - * This is meant to get the size of the present remote-file by itself. - * We don't support this now. Bail out! - */ - data->state.resume_from = 0; - } - - if(data->state.resume_from && !data->state.this_is_a_follow) { - /* do we still game? */ - - /* Now, let's read off the proper amount of bytes from the - input. */ - if(conn->seek_func) { - seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, - SEEK_SET); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_READ_ERROR; - } - /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ - else { - curl_off_t passed=0; - do { - size_t readthisamountnow = - (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? - BUFSIZE : curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread = - data->state.fread_func(data->state.buffer, 1, readthisamountnow, - data->state.in); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T - " bytes from the input", passed); - return CURLE_READ_ERROR; - } - } while(passed < data->state.resume_from); - } - } - - /* now, decrease the size of the read */ - if(data->state.infilesize>0) { - data->state.infilesize -= data->state.resume_from; - - if(data->state.infilesize <= 0) { - failf(data, "File already completely uploaded"); - return CURLE_PARTIAL_FILE; - } - } - /* we've passed, proceed as normal */ - } - } - if(data->state.use_range) { - /* - * A range is selected. We use different headers whether we're downloading - * or uploading and we always let customized headers override our internal - * ones if any such are specified. - */ - if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) && - !Curl_checkheaders(conn, "Range:")) { - /* if a line like this was already allocated, free the previous one */ - free(conn->allocptr.rangeline); - conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", - data->state.range); - } - else if((httpreq != HTTPREQ_GET) && - !Curl_checkheaders(conn, "Content-Range:")) { - - /* if a line like this was already allocated, free the previous one */ - free(conn->allocptr.rangeline); - - if(data->set.set_resume_from < 0) { - /* Upload resume was asked for, but we don't know the size of the - remote part so we tell the server (and act accordingly) that we - upload the whole file (again) */ - conn->allocptr.rangeline = - aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T - "/%" CURL_FORMAT_CURL_OFF_T "\r\n", - data->state.infilesize - 1, data->state.infilesize); - - } - else if(data->state.resume_from) { - /* This is because "resume" was selected */ - curl_off_t total_expected_size= - data->state.resume_from + data->state.infilesize; - conn->allocptr.rangeline = - aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T - "/%" CURL_FORMAT_CURL_OFF_T "\r\n", - data->state.range, total_expected_size-1, - total_expected_size); - } - else { - /* Range was selected and then we just pass the incoming range and - append total size */ - conn->allocptr.rangeline = - aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n", - data->state.range, data->state.infilesize); - } - if(!conn->allocptr.rangeline) - return CURLE_OUT_OF_MEMORY; - } - } - - /* Use 1.1 unless the user specifically asked for 1.0 or the server only - supports 1.0 */ - httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0"; - - /* initialize a dynamic send-buffer */ - req_buffer = Curl_add_buffer_init(); - - if(!req_buffer) - return CURLE_OUT_OF_MEMORY; - - /* add the main request stuff */ - /* GET/HEAD/POST/PUT */ - result = Curl_add_bufferf(req_buffer, "%s ", request); - if(result) - return result; - - /* url */ - if(paste_ftp_userpwd) - result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s", - conn->user, conn->passwd, - ppath + sizeof("ftp://") - 1); - else - result = Curl_add_buffer(req_buffer, ppath, strlen(ppath)); - if(result) - return result; - - result = - Curl_add_bufferf(req_buffer, - "%s" /* ftp typecode (;type=x) */ - " HTTP/%s\r\n" /* HTTP version */ - "%s" /* host */ - "%s" /* proxyuserpwd */ - "%s" /* userpwd */ - "%s" /* range */ - "%s" /* user agent */ - "%s" /* accept */ - "%s" /* TE: */ - "%s" /* accept-encoding */ - "%s" /* referer */ - "%s",/* transfer-encoding */ - - ftp_typecode, - httpstring, - (conn->allocptr.host?conn->allocptr.host:""), - conn->allocptr.proxyuserpwd? - conn->allocptr.proxyuserpwd:"", - conn->allocptr.userpwd?conn->allocptr.userpwd:"", - (data->state.use_range && conn->allocptr.rangeline)? - conn->allocptr.rangeline:"", - (data->set.str[STRING_USERAGENT] && - *data->set.str[STRING_USERAGENT] && - conn->allocptr.uagent)? - conn->allocptr.uagent:"", - http->p_accept?http->p_accept:"", - conn->allocptr.te?conn->allocptr.te:"", - (data->set.str[STRING_ENCODING] && - *data->set.str[STRING_ENCODING] && - conn->allocptr.accept_encoding)? - conn->allocptr.accept_encoding:"", - (data->change.referer && conn->allocptr.ref)? - conn->allocptr.ref:"" /* Referer: */, - te - ); - - /* clear userpwd to avoid re-using credentials from re-used connections */ - Curl_safefree(conn->allocptr.userpwd); - - /* - * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated - * with the connection and shouldn't be repeated over it either. - */ - switch (data->state.authproxy.picked) { - case CURLAUTH_NEGOTIATE: - case CURLAUTH_NTLM: - case CURLAUTH_NTLM_WB: - Curl_safefree(conn->allocptr.proxyuserpwd); - break; - } - - if(result) - return result; - - if(!(conn->handler->flags&PROTOPT_SSL) && - conn->httpversion != 20 && - (data->set.httpversion == CURL_HTTP_VERSION_2)) { - /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done - over SSL */ - result = Curl_http2_request_upgrade(req_buffer, conn); - if(result) - return result; - } - -#if !defined(CURL_DISABLE_COOKIES) - if(data->cookies || addcookies) { - struct Cookie *co=NULL; /* no cookies from start */ - int count=0; - - if(data->cookies) { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - co = Curl_cookie_getlist(data->cookies, - conn->allocptr.cookiehost? - conn->allocptr.cookiehost:host, - data->state.path, - (conn->handler->protocol&CURLPROTO_HTTPS)? - TRUE:FALSE); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - if(co) { - struct Cookie *store=co; - /* now loop through all cookies that matched */ - while(co) { - if(co->value) { - if(0 == count) { - result = Curl_add_bufferf(req_buffer, "Cookie: "); - if(result) - break; - } - result = Curl_add_bufferf(req_buffer, - "%s%s=%s", count?"; ":"", - co->name, co->value); - if(result) - break; - count++; - } - co = co->next; /* next cookie please */ - } - Curl_cookie_freelist(store, FALSE); /* free the cookie list */ - } - if(addcookies && !result) { - if(!count) - result = Curl_add_bufferf(req_buffer, "Cookie: "); - if(!result) { - result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"", - addcookies); - count++; - } - } - if(count && !result) - result = Curl_add_buffer(req_buffer, "\r\n", 2); - - if(result) - return result; - } -#endif - - result = Curl_add_timecondition(data, req_buffer); - if(result) - return result; - - result = Curl_add_custom_headers(conn, FALSE, req_buffer); - if(result) - return result; - - http->postdata = NULL; /* nothing to post at this point */ - Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */ - - /* If 'authdone' is FALSE, we must not set the write socket index to the - Curl_transfer() call below, as we're not ready to actually upload any - data yet. */ - - switch(httpreq) { - - case HTTPREQ_POST_FORM: - if(!http->sendit || conn->bits.authneg) { - /* nothing to post! */ - result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n"); - if(result) - return result; - - result = Curl_add_buffer_send(req_buffer, conn, - &data->info.request_size, 0, FIRSTSOCKET); - if(result) - failf(data, "Failed sending POST request"); - else - /* setup variables for the upcoming transfer */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, - -1, NULL); - break; - } - - if(Curl_FormInit(&http->form, http->sendit)) { - failf(data, "Internal HTTP POST error!"); - return CURLE_HTTP_POST_ERROR; - } - - /* Get the currently set callback function pointer and store that in the - form struct since we might want the actual user-provided callback later - on. The data->set.fread_func pointer itself will be changed for the - multipart case to the function that returns a multipart formatted - stream. */ - http->form.fread_func = data->state.fread_func; - - /* Set the read function to read from the generated form data */ - data->state.fread_func = (curl_read_callback)Curl_FormReader; - data->state.in = &http->form; - - http->sending = HTTPSEND_BODY; - - if(!data->req.upload_chunky && - !Curl_checkheaders(conn, "Content-Length:")) { - /* only add Content-Length if not uploading chunked */ - result = Curl_add_bufferf(req_buffer, - "Content-Length: %" CURL_FORMAT_CURL_OFF_T - "\r\n", http->postsize); - if(result) - return result; - } - - result = expect100(data, conn, req_buffer); - if(result) - return result; - - { - - /* Get Content-Type: line from Curl_formpostheader. - */ - char *contentType; - size_t linelength=0; - contentType = Curl_formpostheader((void *)&http->form, - &linelength); - if(!contentType) { - failf(data, "Could not get Content-Type header line!"); - return CURLE_HTTP_POST_ERROR; - } - - result = Curl_add_buffer(req_buffer, contentType, linelength); - if(result) - return result; - } - - /* make the request end in a true CRLF */ - result = Curl_add_buffer(req_buffer, "\r\n", 2); - if(result) - return result; - - /* set upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, http->postsize); - - /* fire away the whole request to the server */ - result = Curl_add_buffer_send(req_buffer, conn, - &data->info.request_size, 0, FIRSTSOCKET); - if(result) - failf(data, "Failed sending POST request"); - else - /* setup variables for the upcoming transfer */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, FIRSTSOCKET, - &http->writebytecount); - - if(result) { - Curl_formclean(&http->sendit); /* free that whole lot */ - return result; - } - - /* convert the form data */ - result = Curl_convert_form(data, http->sendit); - if(result) { - Curl_formclean(&http->sendit); /* free that whole lot */ - return result; - } - - break; - - case HTTPREQ_PUT: /* Let's PUT the data to the server! */ - - if(conn->bits.authneg) - postsize = 0; - else - postsize = data->state.infilesize; - - if((postsize != -1) && !data->req.upload_chunky && - !Curl_checkheaders(conn, "Content-Length:")) { - /* only add Content-Length if not uploading chunked */ - result = Curl_add_bufferf(req_buffer, - "Content-Length: %" CURL_FORMAT_CURL_OFF_T - "\r\n", postsize); - if(result) - return result; - } - - if(postsize != 0) { - result = expect100(data, conn, req_buffer); - if(result) - return result; - } - - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */ - if(result) - return result; - - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, postsize); - - /* this sends the buffer and frees all the buffer resources */ - result = Curl_add_buffer_send(req_buffer, conn, - &data->info.request_size, 0, FIRSTSOCKET); - if(result) - failf(data, "Failed sending PUT request"); - else - /* prepare for transfer */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, postsize?FIRSTSOCKET:-1, - postsize?&http->writebytecount:NULL); - if(result) - return result; - break; - - case HTTPREQ_POST: - /* this is the simple POST, using x-www-form-urlencoded style */ - - if(conn->bits.authneg) - postsize = 0; - else { - /* figure out the size of the postfields */ - postsize = (data->state.infilesize != -1)? - data->state.infilesize: - (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1); - } - - /* We only set Content-Length and allow a custom Content-Length if - we don't upload data chunked, as RFC2616 forbids us to set both - kinds of headers (Transfer-Encoding: chunked and Content-Length) */ - if((postsize != -1) && !data->req.upload_chunky && - !Curl_checkheaders(conn, "Content-Length:")) { - /* we allow replacing this header if not during auth negotiation, - although it isn't very wise to actually set your own */ - result = Curl_add_bufferf(req_buffer, - "Content-Length: %" CURL_FORMAT_CURL_OFF_T - "\r\n", postsize); - if(result) - return result; - } - - if(!Curl_checkheaders(conn, "Content-Type:")) { - result = Curl_add_bufferf(req_buffer, - "Content-Type: application/" - "x-www-form-urlencoded\r\n"); - if(result) - return result; - } - - /* For really small posts we don't use Expect: headers at all, and for - the somewhat bigger ones we allow the app to disable it. Just make - sure that the expect100header is always set to the preferred value - here. */ - ptr = Curl_checkheaders(conn, "Expect:"); - if(ptr) { - data->state.expect100header = - Curl_compareheader(ptr, "Expect:", "100-continue"); - } - else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) { - result = expect100(data, conn, req_buffer); - if(result) - return result; - } - else - data->state.expect100header = FALSE; - - if(data->set.postfields) { - - /* In HTTP2, we send request body in DATA frame regardless of - its size. */ - if(conn->httpversion != 20 && - !data->state.expect100header && - (postsize < MAX_INITIAL_POST_SIZE)) { - /* if we don't use expect: 100 AND - postsize is less than MAX_INITIAL_POST_SIZE - - then append the post data to the HTTP request header. This limit - is no magic limit but only set to prevent really huge POSTs to - get the data duplicated with malloc() and family. */ - - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ - if(result) - return result; - - if(!data->req.upload_chunky) { - /* We're not sending it 'chunked', append it to the request - already now to reduce the number if send() calls */ - result = Curl_add_buffer(req_buffer, data->set.postfields, - (size_t)postsize); - included_body = postsize; - } - else { - if(postsize) { - /* Append the POST data chunky-style */ - result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize); - if(!result) { - result = Curl_add_buffer(req_buffer, data->set.postfields, - (size_t)postsize); - if(!result) - result = Curl_add_buffer(req_buffer, "\r\n", 2); - included_body = postsize + 2; - } - } - if(!result) - result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); - /* 0 CR LF CR LF */ - included_body += 5; - } - if(result) - return result; - /* Make sure the progress information is accurate */ - Curl_pgrsSetUploadSize(data, postsize); - } - else { - /* A huge POST coming up, do data separate from the request */ - http->postsize = postsize; - http->postdata = data->set.postfields; - - http->sending = HTTPSEND_BODY; - - data->state.fread_func = (curl_read_callback)readmoredata; - data->state.in = (void *)conn; - - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, http->postsize); - - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ - if(result) - return result; - } - } - else { - result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ - if(result) - return result; - - if(data->req.upload_chunky && conn->bits.authneg) { - /* Chunky upload is selected and we're negotiating auth still, send - end-of-data only */ - result = Curl_add_buffer(req_buffer, - "\x30\x0d\x0a\x0d\x0a", 5); - /* 0 CR LF CR LF */ - if(result) - return result; - } - - else if(data->state.infilesize) { - /* set the upload size to the progress meter */ - Curl_pgrsSetUploadSize(data, postsize?postsize:-1); - - /* set the pointer to mark that we will send the post body using the - read callback, but only if we're not in authenticate - negotiation */ - if(!conn->bits.authneg) { - http->postdata = (char *)&http->postdata; - http->postsize = postsize; - } - } - } - /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size, - (size_t)included_body, FIRSTSOCKET); - - if(result) - failf(data, "Failed sending HTTP POST request"); - else - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, http->postdata?FIRSTSOCKET:-1, - http->postdata?&http->writebytecount:NULL); - break; - - default: - result = Curl_add_buffer(req_buffer, "\r\n", 2); - if(result) - return result; - - /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, - &data->info.request_size, 0, FIRSTSOCKET); - - if(result) - failf(data, "Failed sending HTTP request"); - else - /* HTTP GET/HEAD download: */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, - http->postdata?FIRSTSOCKET:-1, - http->postdata?&http->writebytecount:NULL); - } - if(result) - return result; - - if(http->writebytecount) { - /* if a request-body has been sent off, we make sure this progress is noted - properly */ - Curl_pgrsSetUploadCounter(data, http->writebytecount); - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - - if(http->writebytecount >= postsize) { - /* already sent the entire request body, mark the "upload" as - complete */ - infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T - " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n", - http->writebytecount, postsize); - data->req.upload_done = TRUE; - data->req.keepon &= ~KEEP_SEND; /* we're done writing */ - data->req.exp100 = EXP100_SEND_DATA; /* already sent */ - } - } - - return result; -} - -/* - * checkhttpprefix() - * - * Returns TRUE if member of the list matches prefix of string - */ -static bool -checkhttpprefix(struct SessionHandle *data, - const char *s) -{ - struct curl_slist *head = data->set.http200aliases; - bool rc = FALSE; -#ifdef CURL_DOES_CONVERSIONS - /* convert from the network encoding using a scratch area */ - char *scratch = strdup(s); - if(NULL == scratch) { - failf (data, "Failed to allocate memory for conversion!"); - return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */ - } - if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) { - /* Curl_convert_from_network calls failf if unsuccessful */ - free(scratch); - return FALSE; /* can't return CURLE_foobar so return FALSE */ - } - s = scratch; -#endif /* CURL_DOES_CONVERSIONS */ - - while(head) { - if(checkprefix(head->data, s)) { - rc = TRUE; - break; - } - head = head->next; - } - - if(!rc && (checkprefix("HTTP/", s))) - rc = TRUE; - -#ifdef CURL_DOES_CONVERSIONS - free(scratch); -#endif /* CURL_DOES_CONVERSIONS */ - return rc; -} - -#ifndef CURL_DISABLE_RTSP -static bool -checkrtspprefix(struct SessionHandle *data, - const char *s) -{ - -#ifdef CURL_DOES_CONVERSIONS - /* convert from the network encoding using a scratch area */ - char *scratch = strdup(s); - if(NULL == scratch) { - failf (data, "Failed to allocate memory for conversion!"); - return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */ - } - if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) { - /* Curl_convert_from_network calls failf if unsuccessful */ - free(scratch); - return FALSE; /* can't return CURLE_foobar so return FALSE */ - } - s = scratch; -#else - (void)data; /* unused */ -#endif /* CURL_DOES_CONVERSIONS */ - if(checkprefix("RTSP/", s)) - return TRUE; - else - return FALSE; -} -#endif /* CURL_DISABLE_RTSP */ - -static bool -checkprotoprefix(struct SessionHandle *data, struct connectdata *conn, - const char *s) -{ -#ifndef CURL_DISABLE_RTSP - if(conn->handler->protocol & CURLPROTO_RTSP) - return checkrtspprefix(data, s); -#else - (void)conn; -#endif /* CURL_DISABLE_RTSP */ - - return checkhttpprefix(data, s); -} - -/* - * header_append() copies a chunk of data to the end of the already received - * header. We make sure that the full string fit in the allocated header - * buffer, or else we enlarge it. - */ -static CURLcode header_append(struct SessionHandle *data, - struct SingleRequest *k, - size_t length) -{ - if(k->hbuflen + length >= data->state.headersize) { - /* We enlarge the header buffer as it is too small */ - char *newbuff; - size_t hbufp_index; - size_t newsize; - - if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) { - /* The reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause - reallocs infinitely */ - failf (data, "Avoided giant realloc for header (max is %d)!", - CURL_MAX_HTTP_HEADER); - return CURLE_OUT_OF_MEMORY; - } - - newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2); - hbufp_index = k->hbufp - data->state.headerbuff; - newbuff = realloc(data->state.headerbuff, newsize); - if(!newbuff) { - failf (data, "Failed to alloc memory for big header!"); - return CURLE_OUT_OF_MEMORY; - } - data->state.headersize=newsize; - data->state.headerbuff = newbuff; - k->hbufp = data->state.headerbuff + hbufp_index; - } - memcpy(k->hbufp, k->str_start, length); - k->hbufp += length; - k->hbuflen += length; - *k->hbufp = 0; - - return CURLE_OK; -} - -static void print_http_error(struct SessionHandle *data) -{ - struct SingleRequest *k = &data->req; - char *beg = k->p; - - /* make sure that data->req.p points to the HTTP status line */ - if(!strncmp(beg, "HTTP", 4)) { - - /* skip to HTTP status code */ - beg = strchr(beg, ' '); - if(beg && *++beg) { - - /* find trailing CR */ - char end_char = '\r'; - char *end = strchr(beg, end_char); - if(!end) { - /* try to find LF (workaround for non-compliant HTTP servers) */ - end_char = '\n'; - end = strchr(beg, end_char); - } - - if(end) { - /* temporarily replace CR or LF by NUL and print the error message */ - *end = '\0'; - failf(data, "The requested URL returned error: %s", beg); - - /* restore the previously replaced CR or LF */ - *end = end_char; - return; - } - } - } - - /* fall-back to printing the HTTP status code only */ - failf(data, "The requested URL returned error: %d", k->httpcode); -} - -/* - * Read any HTTP header lines from the server and pass them to the client app. - */ -CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, - struct connectdata *conn, - ssize_t *nread, - bool *stop_reading) -{ - CURLcode result; - struct SingleRequest *k = &data->req; - - /* header line within buffer loop */ - do { - size_t rest_length; - size_t full_length; - int writetype; - - /* str_start is start of line within buf */ - k->str_start = k->str; - - /* data is in network encoding so use 0x0a instead of '\n' */ - k->end_ptr = memchr(k->str_start, 0x0a, *nread); - - if(!k->end_ptr) { - /* Not a complete header line within buffer, append the data to - the end of the headerbuff. */ - result = header_append(data, k, *nread); - if(result) - return result; - - if(!k->headerline && (k->hbuflen>5)) { - /* make a first check that this looks like a protocol header */ - if(!checkprotoprefix(data, conn, data->state.headerbuff)) { - /* this is not the beginning of a protocol first header line */ - k->header = FALSE; - k->badheader = HEADER_ALLBAD; - break; - } - } - - break; /* read more and try again */ - } - - /* decrease the size of the remaining (supposed) header line */ - rest_length = (k->end_ptr - k->str)+1; - *nread -= (ssize_t)rest_length; - - k->str = k->end_ptr + 1; /* move past new line */ - - full_length = k->str - k->str_start; - - result = header_append(data, k, full_length); - if(result) - return result; - - k->end_ptr = k->hbufp; - k->p = data->state.headerbuff; - - /**** - * We now have a FULL header line that p points to - *****/ - - if(!k->headerline) { - /* the first read header */ - if((k->hbuflen>5) && - !checkprotoprefix(data, conn, data->state.headerbuff)) { - /* this is not the beginning of a protocol first header line */ - k->header = FALSE; - if(*nread) - /* since there's more, this is a partial bad header */ - k->badheader = HEADER_PARTHEADER; - else { - /* this was all we read so it's all a bad header */ - k->badheader = HEADER_ALLBAD; - *nread = (ssize_t)rest_length; - } - break; - } - } - - /* headers are in network encoding so - use 0x0a and 0x0d instead of '\n' and '\r' */ - if((0x0a == *k->p) || (0x0d == *k->p)) { - size_t headerlen; - /* Zero-length header line means end of headers! */ - -#ifdef CURL_DOES_CONVERSIONS - if(0x0d == *k->p) { - *k->p = '\r'; /* replace with CR in host encoding */ - k->p++; /* pass the CR byte */ - } - if(0x0a == *k->p) { - *k->p = '\n'; /* replace with LF in host encoding */ - k->p++; /* pass the LF byte */ - } -#else - if('\r' == *k->p) - k->p++; /* pass the \r byte */ - if('\n' == *k->p) - k->p++; /* pass the \n byte */ -#endif /* CURL_DOES_CONVERSIONS */ - - if(100 <= k->httpcode && 199 >= k->httpcode) { - /* - * We have made a HTTP PUT or POST and this is 1.1-lingo - * that tells us that the server is OK with this and ready - * to receive the data. - * However, we'll get more headers now so we must get - * back into the header-parsing state! - */ - k->header = TRUE; - k->headerline = 0; /* restart the header line counter */ - - /* "A user agent MAY ignore unexpected 1xx status responses." */ - switch(k->httpcode) { - case 100: - /* if we did wait for this do enable write now! */ - if(k->exp100) { - k->exp100 = EXP100_SEND_DATA; - k->keepon |= KEEP_SEND; - } - break; - case 101: - /* Switching Protocols */ - if(k->upgr101 == UPGR101_REQUESTED) { - infof(data, "Received 101\n"); - k->upgr101 = UPGR101_RECEIVED; - - /* switch to http2 now. The bytes after response headers - are also processed here, otherwise they are lost. */ - result = Curl_http2_switched(conn, k->str, *nread); - if(result) - return result; - *nread = 0; - } - break; - default: - break; - } - } - else { - k->header = FALSE; /* no more header to parse! */ - - if((k->size == -1) && !k->chunk && !conn->bits.close && - (conn->httpversion == 11) && - !(conn->handler->protocol & CURLPROTO_RTSP) && - data->set.httpreq != HTTPREQ_HEAD) { - /* On HTTP 1.1, when connection is not to get closed, but no - Content-Length nor Content-Encoding chunked have been - received, according to RFC2616 section 4.4 point 5, we - assume that the server will close the connection to - signal the end of the document. */ - infof(data, "no chunk, no close, no size. Assume close to " - "signal end\n"); - connclose(conn, "HTTP: No end-of-message indicator"); - } - } - - /* At this point we have some idea about the fate of the connection. - If we are closing the connection it may result auth failure. */ -#if defined(USE_NTLM) - if(conn->bits.close && - (((data->req.httpcode == 401) && - (conn->ntlm.state == NTLMSTATE_TYPE2)) || - ((data->req.httpcode == 407) && - (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) { - infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); - data->state.authproblem = TRUE; - } -#endif - - /* - * When all the headers have been parsed, see if we should give - * up and return an error. - */ - if(http_should_fail(conn)) { - failf (data, "The requested URL returned error: %d", - k->httpcode); - return CURLE_HTTP_RETURNED_ERROR; - } - - /* now, only output this if the header AND body are requested: - */ - writetype = CLIENTWRITE_HEADER; - if(data->set.include_header) - writetype |= CLIENTWRITE_BODY; - - headerlen = k->p - data->state.headerbuff; - - result = Curl_client_write(conn, writetype, - data->state.headerbuff, - headerlen); - if(result) - return result; - - data->info.header_size += (long)headerlen; - data->req.headerbytecount += (long)headerlen; - - data->req.deductheadercount = - (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0; - - if(!*stop_reading) { - /* Curl_http_auth_act() checks what authentication methods - * that are available and decides which one (if any) to - * use. It will set 'newurl' if an auth method was picked. */ - result = Curl_http_auth_act(conn); - - if(result) - return result; - - if(k->httpcode >= 300) { - if((!conn->bits.authneg) && !conn->bits.close && - !conn->bits.rewindaftersend) { - /* - * General treatment of errors when about to send data. Including : - * "417 Expectation Failed", while waiting for 100-continue. - * - * The check for close above is done simply because of something - * else has already deemed the connection to get closed then - * something else should've considered the big picture and we - * avoid this check. - * - * rewindaftersend indicates that something has told libcurl to - * continue sending even if it gets discarded - */ - - switch(data->set.httpreq) { - case HTTPREQ_PUT: - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - /* We got an error response. If this happened before the whole - * request body has been sent we stop sending and mark the - * connection for closure after we've read the entire response. - */ - if(!k->upload_done) { - infof(data, "HTTP error before end of send, stop sending\n"); - connclose(conn, "Stop sending data before everything sent"); - k->upload_done = TRUE; - k->keepon &= ~KEEP_SEND; /* don't send */ - if(data->state.expect100header) - k->exp100 = EXP100_FAILED; - } - break; - - default: /* default label present to avoid compiler warnings */ - break; - } - } - } - - if(conn->bits.rewindaftersend) { - /* We rewind after a complete send, so thus we continue - sending now */ - infof(data, "Keep sending data to get tossed away!\n"); - k->keepon |= KEEP_SEND; - } - } - - if(!k->header) { - /* - * really end-of-headers. - * - * If we requested a "no body", this is a good time to get - * out and return home. - */ - if(data->set.opt_no_body) - *stop_reading = TRUE; -#ifndef CURL_DISABLE_RTSP - else if((conn->handler->protocol & CURLPROTO_RTSP) && - (data->set.rtspreq == RTSPREQ_DESCRIBE) && - (k->size <= -1)) - /* Respect section 4.4 of rfc2326: If the Content-Length header is - absent, a length 0 must be assumed. It will prevent libcurl from - hanging on DECRIBE request that got refused for whatever - reason */ - *stop_reading = TRUE; -#endif - else { - /* If we know the expected size of this document, we set the - maximum download size to the size of the expected - document or else, we won't know when to stop reading! - - Note that we set the download maximum even if we read a - "Connection: close" header, to make sure that - "Content-Length: 0" still prevents us from attempting to - read the (missing) response-body. - */ - /* According to RFC2616 section 4.4, we MUST ignore - Content-Length: headers if we are now receiving data - using chunked Transfer-Encoding. - */ - if(k->chunk) - k->maxdownload = k->size = -1; - } - if(-1 != k->size) { - /* We do this operation even if no_body is true, since this - data might be retrieved later with curl_easy_getinfo() - and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */ - - Curl_pgrsSetDownloadSize(data, k->size); - k->maxdownload = k->size; - } - - /* If max download size is *zero* (nothing) we already - have nothing and can safely return ok now! */ - if(0 == k->maxdownload) - *stop_reading = TRUE; - - if(*stop_reading) { - /* we make sure that this socket isn't read more now */ - k->keepon &= ~KEEP_RECV; - } - - if(data->set.verbose) - Curl_debug(data, CURLINFO_HEADER_IN, - k->str_start, headerlen, conn); - break; /* exit header line loop */ - } - - /* We continue reading headers, so reset the line-based - header parsing variables hbufp && hbuflen */ - k->hbufp = data->state.headerbuff; - k->hbuflen = 0; - continue; - } - - /* - * Checks for special headers coming up. - */ - - if(!k->headerline++) { - /* This is the first header, it MUST be the error code line - or else we consider this to be the body right away! */ - int httpversion_major; - int rtspversion_major; - int nc = 0; -#ifdef CURL_DOES_CONVERSIONS -#define HEADER1 scratch -#define SCRATCHSIZE 21 - CURLcode res; - char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */ - /* We can't really convert this yet because we - don't know if it's the 1st header line or the body. - So we do a partial conversion into a scratch area, - leaving the data at k->p as-is. - */ - strncpy(&scratch[0], k->p, SCRATCHSIZE); - scratch[SCRATCHSIZE] = 0; /* null terminate */ - res = Curl_convert_from_network(data, - &scratch[0], - SCRATCHSIZE); - if(res) - /* Curl_convert_from_network calls failf if unsuccessful */ - return res; -#else -#define HEADER1 k->p /* no conversion needed, just use k->p */ -#endif /* CURL_DOES_CONVERSIONS */ - - if(conn->handler->protocol & PROTO_FAMILY_HTTP) { - /* - * https://tools.ietf.org/html/rfc7230#section-3.1.2 - * - * The reponse code is always a three-digit number in HTTP as the spec - * says. We try to allow any number here, but we cannot make - * guarantees on future behaviors since it isn't within the protocol. - */ - nc = sscanf(HEADER1, - " HTTP/%d.%d %d", - &httpversion_major, - &conn->httpversion, - &k->httpcode); - if(nc==3) { - conn->httpversion += 10 * httpversion_major; - - if(k->upgr101 == UPGR101_RECEIVED) { - /* supposedly upgraded to http2 now */ - if(conn->httpversion != 20) - infof(data, "Lying server, not serving HTTP/2\n"); - } - } - else { - /* this is the real world, not a Nirvana - NCSA 1.5.x returns this crap when asked for HTTP/1.1 - */ - nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode); - conn->httpversion = 10; - - /* If user has set option HTTP200ALIASES, - compare header line against list of aliases - */ - if(!nc) { - if(checkhttpprefix(data, k->p)) { - nc = 1; - k->httpcode = 200; - conn->httpversion = 10; - } - } - } - } - else if(conn->handler->protocol & CURLPROTO_RTSP) { - nc = sscanf(HEADER1, - " RTSP/%d.%d %3d", - &rtspversion_major, - &conn->rtspversion, - &k->httpcode); - if(nc==3) { - conn->rtspversion += 10 * rtspversion_major; - conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */ - } - else { - /* TODO: do we care about the other cases here? */ - nc = 0; - } - } - - if(nc) { - data->info.httpcode = k->httpcode; - - data->info.httpversion = conn->httpversion; - if(!data->state.httpversion || - data->state.httpversion > conn->httpversion) - /* store the lowest server version we encounter */ - data->state.httpversion = conn->httpversion; - - /* - * This code executes as part of processing the header. As a - * result, it's not totally clear how to interpret the - * response code yet as that depends on what other headers may - * be present. 401 and 407 may be errors, but may be OK - * depending on how authentication is working. Other codes - * are definitely errors, so give up here. - */ - if(data->set.http_fail_on_error && (k->httpcode >= 400) && - ((k->httpcode != 401) || !conn->bits.user_passwd) && - ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) { - - if(data->state.resume_from && - (data->set.httpreq==HTTPREQ_GET) && - (k->httpcode == 416)) { - /* "Requested Range Not Satisfiable", just proceed and - pretend this is no error */ - } - else { - /* serious error, go home! */ - print_http_error(data); - return CURLE_HTTP_RETURNED_ERROR; - } - } - - if(conn->httpversion == 10) { - /* Default action for HTTP/1.0 must be to close, unless - we get one of those fancy headers that tell us the - server keeps it open for us! */ - infof(data, "HTTP 1.0, assume close after body\n"); - connclose(conn, "HTTP/1.0 close after body"); - } - else if(conn->httpversion == 20 || - (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) { - DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n")); - - /* HTTP/2 cannot blacklist multiplexing since it is a core - functionality of the protocol */ - conn->bundle->multiuse = BUNDLE_MULTIPLEX; - } - else if(conn->httpversion >= 11 && - !conn->bits.close) { - /* If HTTP version is >= 1.1 and connection is persistent - server supports pipelining. */ - DEBUGF(infof(data, - "HTTP 1.1 or later with persistent connection, " - "pipelining supported\n")); - /* Activate pipelining if needed */ - if(conn->bundle) { - if(!Curl_pipeline_site_blacklisted(data, conn)) - conn->bundle->multiuse = BUNDLE_PIPELINING; - } - } - - switch(k->httpcode) { - case 204: - /* (quote from RFC2616, section 10.2.5): The server has - * fulfilled the request but does not need to return an - * entity-body ... The 204 response MUST NOT include a - * message-body, and thus is always terminated by the first - * empty line after the header fields. */ - /* FALLTHROUGH */ - case 304: - /* (quote from RFC2616, section 10.3.5): The 304 response - * MUST NOT contain a message-body, and thus is always - * terminated by the first empty line after the header - * fields. */ - if(data->set.timecondition) - data->info.timecond = TRUE; - k->size=0; - k->maxdownload=0; - k->ignorecl = TRUE; /* ignore Content-Length headers */ - break; - default: - /* nothing */ - break; - } - } - else { - k->header = FALSE; /* this is not a header line */ - break; - } - } - - result = Curl_convert_from_network(data, k->p, strlen(k->p)); - /* Curl_convert_from_network calls failf if unsuccessful */ - if(result) - return result; - - /* Check for Content-Length: header lines to get size */ - if(!k->ignorecl && !data->set.ignorecl && - checkprefix("Content-Length:", k->p)) { - curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10); - if(data->set.max_filesize && - contentlength > data->set.max_filesize) { - failf(data, "Maximum file size exceeded"); - return CURLE_FILESIZE_EXCEEDED; - } - if(contentlength >= 0) { - k->size = contentlength; - k->maxdownload = k->size; - /* we set the progress download size already at this point - just to make it easier for apps/callbacks to extract this - info as soon as possible */ - Curl_pgrsSetDownloadSize(data, k->size); - } - else { - /* Negative Content-Length is really odd, and we know it - happens for example when older Apache servers send large - files */ - connclose(conn, "negative content-length"); - infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T - ", closing after transfer\n", contentlength); - } - } - /* check for Content-Type: header lines to get the MIME-type */ - else if(checkprefix("Content-Type:", k->p)) { - char *contenttype = Curl_copy_header_value(k->p); - if(!contenttype) - return CURLE_OUT_OF_MEMORY; - if(!*contenttype) - /* ignore empty data */ - free(contenttype); - else { - Curl_safefree(data->info.contenttype); - data->info.contenttype = contenttype; - } - } - else if(checkprefix("Server:", k->p)) { - if(conn->httpversion < 20) { - /* only do this for non-h2 servers */ - char *server_name = Curl_copy_header_value(k->p); - - /* Turn off pipelining if the server version is blacklisted */ - if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) { - if(Curl_pipeline_server_blacklisted(data, server_name)) - conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; - } - free(server_name); - } - } - else if((conn->httpversion == 10) && - conn->bits.httpproxy && - Curl_compareheader(k->p, - "Proxy-Connection:", "keep-alive")) { - /* - * When a HTTP/1.0 reply comes when using a proxy, the - * 'Proxy-Connection: keep-alive' line tells us the - * connection will be kept alive for our pleasure. - * Default action for 1.0 is to close. - */ - connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */ - infof(data, "HTTP/1.0 proxy connection set to keep alive!\n"); - } - else if((conn->httpversion == 11) && - conn->bits.httpproxy && - Curl_compareheader(k->p, - "Proxy-Connection:", "close")) { - /* - * We get a HTTP/1.1 response from a proxy and it says it'll - * close down after this transfer. - */ - connclose(conn, "Proxy-Connection: asked to close after done"); - infof(data, "HTTP/1.1 proxy connection set close!\n"); - } - else if((conn->httpversion == 10) && - Curl_compareheader(k->p, "Connection:", "keep-alive")) { - /* - * A HTTP/1.0 reply with the 'Connection: keep-alive' line - * tells us the connection will be kept alive for our - * pleasure. Default action for 1.0 is to close. - * - * [RFC2068, section 19.7.1] */ - connkeep(conn, "Connection keep-alive"); - infof(data, "HTTP/1.0 connection set to keep alive!\n"); - } - else if(Curl_compareheader(k->p, "Connection:", "close")) { - /* - * [RFC 2616, section 8.1.2.1] - * "Connection: close" is HTTP/1.1 language and means that - * the connection will close when this request has been - * served. - */ - connclose(conn, "Connection: close used"); - } - else if(checkprefix("Transfer-Encoding:", k->p)) { - /* One or more encodings. We check for chunked and/or a compression - algorithm. */ - /* - * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding - * means that the server will send a series of "chunks". Each - * chunk starts with line with info (including size of the - * coming block) (terminated with CRLF), then a block of data - * with the previously mentioned size. There can be any amount - * of chunks, and a chunk-data set to zero signals the - * end-of-chunks. */ - - char *start; - - /* Find the first non-space letter */ - start = k->p + 18; - - for(;;) { - /* skip whitespaces and commas */ - while(*start && (ISSPACE(*start) || (*start == ','))) - start++; - - if(checkprefix("chunked", start)) { - k->chunk = TRUE; /* chunks coming our way */ - - /* init our chunky engine */ - Curl_httpchunk_init(conn); - - start += 7; - } - - if(k->auto_decoding) - /* TODO: we only support the first mentioned compression for now */ - break; - - if(checkprefix("identity", start)) { - k->auto_decoding = IDENTITY; - start += 8; - } - else if(checkprefix("deflate", start)) { - k->auto_decoding = DEFLATE; - start += 7; - } - else if(checkprefix("gzip", start)) { - k->auto_decoding = GZIP; - start += 4; - } - else if(checkprefix("x-gzip", start)) { - k->auto_decoding = GZIP; - start += 6; - } - else - /* unknown! */ - break; - - } - - } - else if(checkprefix("Content-Encoding:", k->p) && - data->set.str[STRING_ENCODING]) { - /* - * Process Content-Encoding. Look for the values: identity, - * gzip, deflate, compress, x-gzip and x-compress. x-gzip and - * x-compress are the same as gzip and compress. (Sec 3.5 RFC - * 2616). zlib cannot handle compress. However, errors are - * handled further down when the response body is processed - */ - char *start; - - /* Find the first non-space letter */ - start = k->p + 17; - while(*start && ISSPACE(*start)) - start++; - - /* Record the content-encoding for later use */ - if(checkprefix("identity", start)) - k->auto_decoding = IDENTITY; - else if(checkprefix("deflate", start)) - k->auto_decoding = DEFLATE; - else if(checkprefix("gzip", start) - || checkprefix("x-gzip", start)) - k->auto_decoding = GZIP; - } - else if(checkprefix("Content-Range:", k->p)) { - /* Content-Range: bytes [num]- - Content-Range: bytes: [num]- - Content-Range: [num]- - Content-Range: [asterisk]/[total] - - The second format was added since Sun's webserver - JavaWebServer/1.1.1 obviously sends the header this way! - The third added since some servers use that! - The forth means the requested range was unsatisfied. - */ - - char *ptr = k->p + 14; - - /* Move forward until first digit or asterisk */ - while(*ptr && !ISDIGIT(*ptr) && *ptr != '*') - ptr++; - - /* if it truly stopped on a digit */ - if(ISDIGIT(*ptr)) { - k->offset = curlx_strtoofft(ptr, NULL, 10); - - if(data->state.resume_from == k->offset) - /* we asked for a resume and we got it */ - k->content_range = TRUE; - } - else - data->state.resume_from = 0; /* get everything */ - } -#if !defined(CURL_DISABLE_COOKIES) - else if(data->cookies && - checkprefix("Set-Cookie:", k->p)) { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, - CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_add(data, - data->cookies, TRUE, k->p+11, - /* If there is a custom-set Host: name, use it - here, or else use real peer host name. */ - conn->allocptr.cookiehost? - conn->allocptr.cookiehost:conn->host.name, - data->state.path); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } -#endif - else if(checkprefix("Last-Modified:", k->p) && - (data->set.timecondition || data->set.get_filetime) ) { - time_t secs=time(NULL); - k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"), - &secs); - if(data->set.get_filetime) - data->info.filetime = (long)k->timeofdoc; - } - else if((checkprefix("WWW-Authenticate:", k->p) && - (401 == k->httpcode)) || - (checkprefix("Proxy-authenticate:", k->p) && - (407 == k->httpcode))) { - - bool proxy = (k->httpcode == 407) ? TRUE : FALSE; - char *auth = Curl_copy_header_value(k->p); - if(!auth) - return CURLE_OUT_OF_MEMORY; - - result = Curl_http_input_auth(conn, proxy, auth); - - free(auth); - - if(result) - return result; - } - else if((k->httpcode >= 300 && k->httpcode < 400) && - checkprefix("Location:", k->p) && - !data->req.location) { - /* this is the URL that the server advises us to use instead */ - char *location = Curl_copy_header_value(k->p); - if(!location) - return CURLE_OUT_OF_MEMORY; - if(!*location) - /* ignore empty data */ - free(location); - else { - data->req.location = location; - - if(data->set.http_follow_location) { - DEBUGASSERT(!data->req.newurl); - data->req.newurl = strdup(data->req.location); /* clone */ - if(!data->req.newurl) - return CURLE_OUT_OF_MEMORY; - - /* some cases of POST and PUT etc needs to rewind the data - stream at this point */ - result = http_perhapsrewind(conn); - if(result) - return result; - } - } - } - else if(conn->handler->protocol & CURLPROTO_RTSP) { - result = Curl_rtsp_parseheader(conn, k->p); - if(result) - return result; - } - - /* - * End of header-checks. Write them to the client. - */ - - writetype = CLIENTWRITE_HEADER; - if(data->set.include_header) - writetype |= CLIENTWRITE_BODY; - - if(data->set.verbose) - Curl_debug(data, CURLINFO_HEADER_IN, - k->p, (size_t)k->hbuflen, conn); - - result = Curl_client_write(conn, writetype, k->p, k->hbuflen); - if(result) - return result; - - data->info.header_size += (long)k->hbuflen; - data->req.headerbytecount += (long)k->hbuflen; - - /* reset hbufp pointer && hbuflen */ - k->hbufp = data->state.headerbuff; - k->hbuflen = 0; - } - while(!*stop_reading && *k->str); /* header line within buffer */ - - /* We might have reached the end of the header part here, but - there might be a non-header part left in the end of the read - buffer. */ - - return CURLE_OK; -} - -#endif /* CURL_DISABLE_HTTP */ diff --git a/Externals/curl/lib/http.h b/Externals/curl/lib/http.h deleted file mode 100644 index 981472e073..0000000000 --- a/Externals/curl/lib/http.h +++ /dev/null @@ -1,253 +0,0 @@ -#ifndef HEADER_CURL_HTTP_H -#define HEADER_CURL_HTTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -#ifdef USE_NGHTTP2 -#include -#endif - -extern const struct Curl_handler Curl_handler_http; - -#ifdef USE_SSL -extern const struct Curl_handler Curl_handler_https; -#endif - -/* Header specific functions */ -bool Curl_compareheader(const char *headerline, /* line to check */ - const char *header, /* header keyword _with_ colon */ - const char *content); /* content string to find */ - -char *Curl_checkheaders(const struct connectdata *conn, - const char *thisheader); -char *Curl_copy_header_value(const char *header); - -char *Curl_checkProxyheaders(const struct connectdata *conn, - const char *thisheader); -/* ------------------------------------------------------------------------- */ -/* - * The add_buffer series of functions are used to build one large memory chunk - * from repeated function invokes. Used so that the entire HTTP request can - * be sent in one go. - */ -struct Curl_send_buffer { - char *buffer; - size_t size_max; - size_t size_used; -}; -typedef struct Curl_send_buffer Curl_send_buffer; - -Curl_send_buffer *Curl_add_buffer_init(void); -void Curl_add_buffer_free(Curl_send_buffer *buff); -CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...); -CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size); -CURLcode Curl_add_buffer_send(Curl_send_buffer *in, - struct connectdata *conn, - long *bytes_written, - size_t included_body_bytes, - int socketindex); - -CURLcode Curl_add_timecondition(struct SessionHandle *data, - Curl_send_buffer *buf); -CURLcode Curl_add_custom_headers(struct connectdata *conn, - bool is_connect, - Curl_send_buffer *req_buffer); - -/* protocol-specific functions set up to be called by the main engine */ -CURLcode Curl_http(struct connectdata *conn, bool *done); -CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature); -CURLcode Curl_http_connect(struct connectdata *conn, bool *done); -CURLcode Curl_http_setup_conn(struct connectdata *conn); - -/* The following functions are defined in http_chunks.c */ -void Curl_httpchunk_init(struct connectdata *conn); -CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap, - ssize_t length, ssize_t *wrote); - -/* These functions are in http.c */ -void Curl_http_auth_stage(struct SessionHandle *data, int stage); -CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, - const char *auth); -CURLcode Curl_http_auth_act(struct connectdata *conn); -CURLcode Curl_http_perhapsrewind(struct connectdata *conn); - -/* If only the PICKNONE bit is set, there has been a round-trip and we - selected to use no auth at all. Ie, we actively select no auth, as opposed - to not having one selected. The other CURLAUTH_* defines are present in the - public curl/curl.h header. */ -#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */ - -/* MAX_INITIAL_POST_SIZE indicates the number of bytes that will make the POST - data get included in the initial data chunk sent to the server. If the - data is larger than this, it will automatically get split up in multiple - system calls. - - This value used to be fairly big (100K), but we must take into account that - if the server rejects the POST due for authentication reasons, this data - will always be uncondtionally sent and thus it may not be larger than can - always be afforded to send twice. - - It must not be greater than 64K to work on VMS. -*/ -#ifndef MAX_INITIAL_POST_SIZE -#define MAX_INITIAL_POST_SIZE (64*1024) -#endif - -#ifndef TINY_INITIAL_POST_SIZE -#define TINY_INITIAL_POST_SIZE 1024 -#endif - -#endif /* CURL_DISABLE_HTTP */ - -/**************************************************************************** - * HTTP unique setup - ***************************************************************************/ -struct HTTP { - struct FormData *sendit; - curl_off_t postsize; /* off_t to handle large file sizes */ - const char *postdata; - - const char *p_pragma; /* Pragma: string */ - const char *p_accept; /* Accept: string */ - curl_off_t readbytecount; - curl_off_t writebytecount; - - /* For FORM posting */ - struct Form form; - - struct back { - curl_read_callback fread_func; /* backup storage for fread pointer */ - void *fread_in; /* backup storage for fread_in pointer */ - const char *postdata; - curl_off_t postsize; - } backup; - - enum { - HTTPSEND_NADA, /* init */ - HTTPSEND_REQUEST, /* sending a request */ - HTTPSEND_BODY, /* sending body */ - HTTPSEND_LAST /* never use this */ - } sending; - - void *send_buffer; /* used if the request couldn't be sent in one chunk, - points to an allocated send_buffer struct */ - -#ifdef USE_NGHTTP2 - /*********** for HTTP/2 we store stream-local data here *************/ - int32_t stream_id; /* stream we are interested in */ - - bool bodystarted; - /* We store non-final and final response headers here, per-stream */ - Curl_send_buffer *header_recvbuf; - size_t nread_header_recvbuf; /* number of bytes in header_recvbuf fed into - upper layer */ - Curl_send_buffer *trailer_recvbuf; - int status_code; /* HTTP status code */ - const uint8_t *pausedata; /* pointer to data received in on_data_chunk */ - size_t pauselen; /* the number of bytes left in data */ - bool closed; /* TRUE on HTTP2 stream close */ - uint32_t error_code; /* HTTP/2 error code */ - - char *mem; /* points to a buffer in memory to store received data */ - size_t len; /* size of the buffer 'mem' points to */ - size_t memlen; /* size of data copied to mem */ - - const uint8_t *upload_mem; /* points to a buffer to read from */ - size_t upload_len; /* size of the buffer 'upload_mem' points to */ - curl_off_t upload_left; /* number of bytes left to upload */ - - char **push_headers; /* allocated array */ - size_t push_headers_used; /* number of entries filled in */ - size_t push_headers_alloc; /* number of entries allocated */ -#endif -}; - -typedef int (*sending)(void); /* Curl_send */ -typedef int (*recving)(void); /* Curl_recv */ - -#ifdef USE_NGHTTP2 -/* h2 settings for this connection */ -struct h2settings { - uint32_t max_concurrent_streams; - bool enable_push; -}; -#endif - - -struct http_conn { -#ifdef USE_NGHTTP2 -#define H2_BINSETTINGS_LEN 80 - nghttp2_session *h2; - uint8_t binsettings[H2_BINSETTINGS_LEN]; - size_t binlen; /* length of the binsettings data */ - sending send_underlying; /* underlying send Curl_send callback */ - recving recv_underlying; /* underlying recv Curl_recv callback */ - char *inbuf; /* buffer to receive data from underlying socket */ - size_t inbuflen; /* number of bytes filled in inbuf */ - size_t nread_inbuf; /* number of bytes read from in inbuf */ - /* We need separate buffer for transmission and reception because we - may call nghttp2_session_send() after the - nghttp2_session_mem_recv() but mem buffer is still not full. In - this case, we wrongly sends the content of mem buffer if we share - them for both cases. */ - int32_t pause_stream_id; /* stream ID which paused - nghttp2_session_mem_recv */ - size_t drain_total; /* sum of all stream's UrlState.drain */ - - /* this is a hash of all individual streams (SessionHandle structs) */ - struct h2settings settings; -#else - int unused; /* prevent a compiler warning */ -#endif -}; - -CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, - struct connectdata *conn, - ssize_t *nread, - bool *stop_reading); - -/** - * Curl_http_output_auth() setups the authentication headers for the - * host/proxy and the correct authentication - * method. conn->data->state.authdone is set to TRUE when authentication is - * done. - * - * @param conn all information about the current connection - * @param request pointer to the request keyword - * @param path pointer to the requested path - * @param proxytunnel boolean if this is the request setting up a "proxy - * tunnel" - * - * @returns CURLcode - */ -CURLcode -Curl_http_output_auth(struct connectdata *conn, - const char *request, - const char *path, - bool proxytunnel); /* TRUE if this is the request setting - up the proxy tunnel */ - -#endif /* HEADER_CURL_HTTP_H */ - diff --git a/Externals/curl/lib/http2.c b/Externals/curl/lib/http2.c deleted file mode 100644 index 3fe02a57ac..0000000000 --- a/Externals/curl/lib/http2.c +++ /dev/null @@ -1,1982 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_NGHTTP2 -#include -#include "urldata.h" -#include "http2.h" -#include "http.h" -#include "sendf.h" -#include "curl_base64.h" -#include "rawstr.h" -#include "multiif.h" -#include "conncache.h" -#include "url.h" -#include "connect.h" -#include "strtoofft.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#define MIN(x,y) ((x)<(y)?(x):(y)) - -#if (NGHTTP2_VERSION_NUM < 0x010000) -#error too old nghttp2 version, upgrade! -#endif - -#if (NGHTTP2_VERSION_NUM > 0x010800) -#define NGHTTP2_HAS_HTTP2_STRERROR 1 -#endif - -#if (NGHTTP2_VERSION_NUM >= 0x010900) -/* nghttp2_session_callbacks_set_error_callback is present in nghttp2 1.9.0 or - later */ -#define NGHTTP2_HAS_ERROR_CALLBACK 1 -#else -#define nghttp2_session_callbacks_set_error_callback(x,y) -#endif - -/* - * Curl_http2_init_state() is called when the easy handle is created and - * allows for HTTP/2 specific init of state. - */ -void Curl_http2_init_state(struct UrlState *state) -{ - state->stream_weight = NGHTTP2_DEFAULT_WEIGHT; -} - -/* - * Curl_http2_init_userset() is called when the easy handle is created and - * allows for HTTP/2 specific user-set fields. - */ -void Curl_http2_init_userset(struct UserDefined *set) -{ - set->stream_weight = NGHTTP2_DEFAULT_WEIGHT; -} - -static int http2_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock, /* points to - numsocks - number of - sockets */ - int numsocks) -{ - const struct http_conn *c = &conn->proto.httpc; - int bitmap = GETSOCK_BLANK; - (void)numsocks; - - /* TODO We should check underlying socket state if it is SSL socket - because of renegotiation. */ - sock[0] = conn->sock[FIRSTSOCKET]; - - if(nghttp2_session_want_read(c->h2)) - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - if(nghttp2_session_want_write(c->h2)) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; -} - -static int http2_getsock(struct connectdata *conn, - curl_socket_t *sock, /* points to numsocks - number of sockets */ - int numsocks) -{ - return http2_perform_getsock(conn, sock, numsocks); -} - -static CURLcode http2_disconnect(struct connectdata *conn, - bool dead_connection) -{ - struct HTTP *http = conn->data->req.protop; - struct http_conn *c = &conn->proto.httpc; - (void)dead_connection; - - DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT starts now\n")); - - nghttp2_session_del(c->h2); - Curl_safefree(c->inbuf); - - if(http) { - Curl_add_buffer_free(http->header_recvbuf); - http->header_recvbuf = NULL; /* clear the pointer */ - Curl_add_buffer_free(http->trailer_recvbuf); - http->trailer_recvbuf = NULL; /* clear the pointer */ - for(; http->push_headers_used > 0; --http->push_headers_used) { - free(http->push_headers[http->push_headers_used - 1]); - } - free(http->push_headers); - http->push_headers = NULL; - } - - DEBUGF(infof(conn->data, "HTTP/2 DISCONNECT done\n")); - - return CURLE_OK; -} - -/* called from Curl_http_setup_conn */ -void Curl_http2_setup_req(struct SessionHandle *data) -{ - struct HTTP *http = data->req.protop; - - http->nread_header_recvbuf = 0; - http->bodystarted = FALSE; - http->status_code = -1; - http->pausedata = NULL; - http->pauselen = 0; - http->error_code = NGHTTP2_NO_ERROR; - http->closed = FALSE; - http->mem = data->state.buffer; - http->len = BUFSIZE; - http->memlen = 0; -} - -/* called from Curl_http_setup_conn */ -void Curl_http2_setup_conn(struct connectdata *conn) -{ - conn->proto.httpc.settings.max_concurrent_streams = - DEFAULT_MAX_CONCURRENT_STREAMS; -} - -/* - * HTTP2 handler interface. This isn't added to the general list of protocols - * but will be used at run-time when the protocol is dynamically switched from - * HTTP to HTTP2. - */ -const struct Curl_handler Curl_handler_http2 = { - "HTTP", /* scheme */ - ZERO_NULL, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - http2_getsock, /* proto_getsock */ - http2_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - http2_perform_getsock, /* perform_getsock */ - http2_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_HTTP, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -const struct Curl_handler Curl_handler_http2_ssl = { - "HTTPS", /* scheme */ - ZERO_NULL, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - http2_getsock, /* proto_getsock */ - http2_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - http2_perform_getsock, /* perform_getsock */ - http2_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_HTTP, /* defport */ - CURLPROTO_HTTPS, /* protocol */ - PROTOPT_SSL /* flags */ -}; - -/* - * Store nghttp2 version info in this buffer, Prefix with a space. Return - * total length written. - */ -int Curl_http2_ver(char *p, size_t len) -{ - nghttp2_info *h2 = nghttp2_version(0); - return snprintf(p, len, " nghttp2/%s", h2->version_str); -} - -/* HTTP/2 error code to name based on the Error Code Registry. -https://tools.ietf.org/html/rfc7540#page-77 -nghttp2_error_code enums are identical. -*/ -const char *Curl_http2_strerror(uint32_t err) { -#ifndef NGHTTP2_HAS_HTTP2_STRERROR - const char *str[] = { - "NO_ERROR", /* 0x0 */ - "PROTOCOL_ERROR", /* 0x1 */ - "INTERNAL_ERROR", /* 0x2 */ - "FLOW_CONTROL_ERROR", /* 0x3 */ - "SETTINGS_TIMEOUT", /* 0x4 */ - "STREAM_CLOSED", /* 0x5 */ - "FRAME_SIZE_ERROR", /* 0x6 */ - "REFUSED_STREAM", /* 0x7 */ - "CANCEL", /* 0x8 */ - "COMPRESSION_ERROR", /* 0x9 */ - "CONNECT_ERROR", /* 0xA */ - "ENHANCE_YOUR_CALM", /* 0xB */ - "INADEQUATE_SECURITY", /* 0xC */ - "HTTP_1_1_REQUIRED" /* 0xD */ - }; - return (err < sizeof str / sizeof str[0]) ? str[err] : "unknown"; -#else - return nghttp2_http2_strerror(err); -#endif -} - -/* - * The implementation of nghttp2_send_callback type. Here we write |data| with - * size |length| to the network and return the number of bytes actually - * written. See the documentation of nghttp2_send_callback for the details. - */ -static ssize_t send_callback(nghttp2_session *h2, - const uint8_t *data, size_t length, int flags, - void *userp) -{ - struct connectdata *conn = (struct connectdata *)userp; - struct http_conn *c = &conn->proto.httpc; - ssize_t written; - CURLcode result = CURLE_OK; - - (void)h2; - (void)flags; - - written = ((Curl_send*)c->send_underlying)(conn, FIRSTSOCKET, - data, length, &result); - - if(result == CURLE_AGAIN) { - return NGHTTP2_ERR_WOULDBLOCK; - } - - if(written == -1) { - failf(conn->data, "Failed sending HTTP2 data"); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - if(!written) - return NGHTTP2_ERR_WOULDBLOCK; - - return written; -} - - -/* We pass a pointer to this struct in the push callback, but the contents of - the struct are hidden from the user. */ -struct curl_pushheaders { - struct SessionHandle *data; - const nghttp2_push_promise *frame; -}; - -/* - * push header access function. Only to be used from within the push callback - */ -char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) -{ - /* Verify that we got a good easy handle in the push header struct, mostly to - detect rubbish input fast(er). */ - if(!h || !GOOD_EASY_HANDLE(h->data)) - return NULL; - else { - struct HTTP *stream = h->data->req.protop; - if(num < stream->push_headers_used) - return stream->push_headers[num]; - } - return NULL; -} - -/* - * push header access function. Only to be used from within the push callback - */ -char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header) -{ - /* Verify that we got a good easy handle in the push header struct, - mostly to detect rubbish input fast(er). Also empty header name - is just a rubbish too. We have to allow ":" at the beginning of - the header, but header == ":" must be rejected. If we have ':' in - the middle of header, it could be matched in middle of the value, - this is because we do prefix match.*/ - if(!h || !GOOD_EASY_HANDLE(h->data) || !header || !header[0] || - Curl_raw_equal(header, ":") || strchr(header + 1, ':')) - return NULL; - else { - struct HTTP *stream = h->data->req.protop; - size_t len = strlen(header); - size_t i; - for(i=0; ipush_headers_used; i++) { - if(!strncmp(header, stream->push_headers[i], len)) { - /* sub-match, make sure that it is followed by a colon */ - if(stream->push_headers[i][len] != ':') - continue; - return &stream->push_headers[i][len+1]; - } - } - } - return NULL; -} - -static CURL *duphandle(struct SessionHandle *data) -{ - struct SessionHandle *second = curl_easy_duphandle(data); - if(second) { - /* setup the request struct */ - struct HTTP *http = calloc(1, sizeof(struct HTTP)); - if(!http) { - (void)Curl_close(second); - second = NULL; - } - else { - second->req.protop = http; - http->header_recvbuf = Curl_add_buffer_init(); - if(!http->header_recvbuf) { - free(http); - (void)Curl_close(second); - second = NULL; - } - else { - Curl_http2_setup_req(second); - second->state.stream_weight = data->state.stream_weight; - } - } - } - return second; -} - - -static int push_promise(struct SessionHandle *data, - struct connectdata *conn, - const nghttp2_push_promise *frame) -{ - int rv; - DEBUGF(infof(data, "PUSH_PROMISE received, stream %u!\n", - frame->promised_stream_id)); - if(data->multi->push_cb) { - struct HTTP *stream; - struct HTTP *newstream; - struct curl_pushheaders heads; - CURLMcode rc; - struct http_conn *httpc; - size_t i; - /* clone the parent */ - struct SessionHandle *newhandle = duphandle(data); - if(!newhandle) { - infof(data, "failed to duplicate handle\n"); - rv = 1; /* FAIL HARD */ - goto fail; - } - - heads.data = data; - heads.frame = frame; - /* ask the application */ - DEBUGF(infof(data, "Got PUSH_PROMISE, ask application!\n")); - - stream = data->req.protop; - if(!stream) { - failf(data, "Internal NULL stream!\n"); - rv = 1; - goto fail; - } - - rv = data->multi->push_cb(data, newhandle, - stream->push_headers_used, &heads, - data->multi->push_userp); - - /* free the headers again */ - for(i=0; ipush_headers_used; i++) - free(stream->push_headers[i]); - free(stream->push_headers); - stream->push_headers = NULL; - - if(rv) { - /* denied, kill off the new handle again */ - (void)Curl_close(newhandle); - goto fail; - } - - newstream = newhandle->req.protop; - newstream->stream_id = frame->promised_stream_id; - newhandle->req.maxdownload = -1; - newhandle->req.size = -1; - - /* approved, add to the multi handle and immediately switch to PERFORM - state with the given connection !*/ - rc = Curl_multi_add_perform(data->multi, newhandle, conn); - if(rc) { - infof(data, "failed to add handle to multi\n"); - Curl_close(newhandle); - rv = 1; - goto fail; - } - - httpc = &conn->proto.httpc; - nghttp2_session_set_stream_user_data(httpc->h2, - frame->promised_stream_id, newhandle); - } - else { - DEBUGF(infof(data, "Got PUSH_PROMISE, ignore it!\n")); - rv = 1; - } - fail: - return rv; -} - -static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame, - void *userp) -{ - struct connectdata *conn = (struct connectdata *)userp; - struct http_conn *httpc = &conn->proto.httpc; - struct SessionHandle *data_s = NULL; - struct HTTP *stream = NULL; - static int lastStream = -1; - int rv; - size_t left, ncopy; - int32_t stream_id = frame->hd.stream_id; - - if(!stream_id) { - /* stream ID zero is for connection-oriented stuff */ - if(frame->hd.type == NGHTTP2_SETTINGS) { - uint32_t max_conn = httpc->settings.max_concurrent_streams; - DEBUGF(infof(conn->data, "Got SETTINGS\n")); - httpc->settings.max_concurrent_streams = - nghttp2_session_get_remote_settings( - session, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS); - httpc->settings.enable_push = - nghttp2_session_get_remote_settings( - session, NGHTTP2_SETTINGS_ENABLE_PUSH); - DEBUGF(infof(conn->data, "MAX_CONCURRENT_STREAMS == %d\n", - httpc->settings.max_concurrent_streams)); - DEBUGF(infof(conn->data, "ENABLE_PUSH == %s\n", - httpc->settings.enable_push?"TRUE":"false")); - if(max_conn != httpc->settings.max_concurrent_streams) { - /* only signal change if the value actually changed */ - infof(conn->data, - "Connection state changed (MAX_CONCURRENT_STREAMS updated)!\n"); - Curl_multi_connchanged(conn->data->multi); - } - } - return 0; - } - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(lastStream != stream_id) { - lastStream = stream_id; - } - if(!data_s) { - DEBUGF(infof(conn->data, - "No SessionHandle associated with stream: %x\n", - stream_id)); - return 0; - } - - stream = data_s->req.protop; - if(!stream) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - DEBUGF(infof(data_s, "on_frame_recv() header %x stream %x\n", - frame->hd.type, stream_id)); - - switch(frame->hd.type) { - case NGHTTP2_DATA: - /* If body started on this stream, then receiving DATA is illegal. */ - if(!stream->bodystarted) { - rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, - stream_id, NGHTTP2_PROTOCOL_ERROR); - - if(nghttp2_is_fatal(rv)) { - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - } - break; - case NGHTTP2_HEADERS: - if(stream->bodystarted) { - /* Only valid HEADERS after body started is trailer HEADERS. We - buffer them in on_header callback. */ - break; - } - - /* nghttp2 guarantees that :status is received, and we store it to - stream->status_code */ - DEBUGASSERT(stream->status_code != -1); - - /* Only final status code signals the end of header */ - if(stream->status_code / 100 != 1) { - stream->bodystarted = TRUE; - stream->status_code = -1; - } - - Curl_add_buffer(stream->header_recvbuf, "\r\n", 2); - - left = stream->header_recvbuf->size_used - stream->nread_header_recvbuf; - ncopy = MIN(stream->len, left); - - memcpy(&stream->mem[stream->memlen], - stream->header_recvbuf->buffer + stream->nread_header_recvbuf, - ncopy); - stream->nread_header_recvbuf += ncopy; - - DEBUGF(infof(data_s, "Store %zu bytes headers from stream %u at %p\n", - ncopy, stream_id, stream->mem)); - - stream->len -= ncopy; - stream->memlen += ncopy; - - data_s->state.drain++; - httpc->drain_total++; - { - /* get the pointer from userp again since it was re-assigned above */ - struct connectdata *conn_s = (struct connectdata *)userp; - - /* if we receive data for another handle, wake that up */ - if(conn_s->data != data_s) - Curl_expire(data_s, 1); - } - break; - case NGHTTP2_PUSH_PROMISE: - rv = push_promise(data_s, conn, &frame->push_promise); - if(rv) { /* deny! */ - rv = nghttp2_submit_rst_stream(session, NGHTTP2_FLAG_NONE, - frame->push_promise.promised_stream_id, - NGHTTP2_CANCEL); - if(nghttp2_is_fatal(rv)) { - return rv; - } - } - break; - default: - DEBUGF(infof(conn->data, "Got frame type %x for stream %u!\n", - frame->hd.type, stream_id)); - break; - } - return 0; -} - -static int on_invalid_frame_recv(nghttp2_session *session, - const nghttp2_frame *frame, - int lib_error_code, void *userp) -{ - struct SessionHandle *data_s = NULL; - (void)userp; - - data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); - if(data_s) { - DEBUGF(infof(data_s, - "on_invalid_frame_recv() was called, error=%d:%s\n", - lib_error_code, nghttp2_strerror(lib_error_code))); - } - return 0; -} - -static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags, - int32_t stream_id, - const uint8_t *data, size_t len, void *userp) -{ - struct HTTP *stream; - struct SessionHandle *data_s; - size_t nread; - struct connectdata *conn = (struct connectdata *)userp; - (void)session; - (void)flags; - (void)data; - - DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ - - /* get the stream from the hash based on Stream ID */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) - /* Receiving a Stream ID not in the hash should not happen, this is an - internal error more than anything else! */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - - stream = data_s->req.protop; - if(!stream) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - nread = MIN(stream->len, len); - memcpy(&stream->mem[stream->memlen], data, nread); - - stream->len -= nread; - stream->memlen += nread; - - data_s->state.drain++; - conn->proto.httpc.drain_total++; - - /* if we receive data for another handle, wake that up */ - if(conn->data != data_s) - Curl_expire(data_s, 1); /* TODO: fix so that this can be set to 0 for - immediately? */ - - DEBUGF(infof(data_s, "%zu data received for stream %u " - "(%zu left in buffer %p, total %zu)\n", - nread, stream_id, - stream->len, stream->mem, - stream->memlen)); - - if(nread < len) { - stream->pausedata = data + nread; - stream->pauselen = len - nread; - DEBUGF(infof(data_s, "NGHTTP2_ERR_PAUSE - %zu bytes out of buffer" - ", stream %u\n", - len - nread, stream_id)); - data_s->easy_conn->proto.httpc.pause_stream_id = stream_id; - - return NGHTTP2_ERR_PAUSE; - } - - /* pause execution of nghttp2 if we received data for another handle - in order to process them first. */ - if(conn->data != data_s) { - data_s->easy_conn->proto.httpc.pause_stream_id = stream_id; - - return NGHTTP2_ERR_PAUSE; - } - - return 0; -} - -static int before_frame_send(nghttp2_session *session, - const nghttp2_frame *frame, - void *userp) -{ - struct SessionHandle *data_s; - (void)userp; - - data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); - if(data_s) { - DEBUGF(infof(data_s, "before_frame_send() was called\n")); - } - - return 0; -} -static int on_frame_send(nghttp2_session *session, - const nghttp2_frame *frame, - void *userp) -{ - struct SessionHandle *data_s; - (void)userp; - - data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); - if(data_s) { - DEBUGF(infof(data_s, "on_frame_send() was called, length = %zd\n", - frame->hd.length)); - } - return 0; -} -static int on_frame_not_send(nghttp2_session *session, - const nghttp2_frame *frame, - int lib_error_code, void *userp) -{ - struct SessionHandle *data_s; - (void)userp; - - data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); - if(data_s) { - DEBUGF(infof(data_s, - "on_frame_not_send() was called, lib_error_code = %d\n", - lib_error_code)); - } - return 0; -} -static int on_stream_close(nghttp2_session *session, int32_t stream_id, - uint32_t error_code, void *userp) -{ - struct SessionHandle *data_s; - struct HTTP *stream; - struct connectdata *conn = (struct connectdata *)userp; - (void)session; - (void)stream_id; - - if(stream_id) { - /* get the stream from the hash based on Stream ID, stream ID zero is for - connection-oriented stuff */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) { - /* We could get stream ID not in the hash. For example, if we - decided to reject stream (e.g., PUSH_PROMISE). */ - return 0; - } - DEBUGF(infof(data_s, "on_stream_close(), %s (err %d), stream %u\n", - Curl_http2_strerror(error_code), error_code, stream_id)); - stream = data_s->req.protop; - if(!stream) - return NGHTTP2_ERR_CALLBACK_FAILURE; - - stream->error_code = error_code; - stream->closed = TRUE; - data_s->state.drain++; - conn->proto.httpc.drain_total++; - - /* remove the entry from the hash as the stream is now gone */ - nghttp2_session_set_stream_user_data(session, stream_id, 0); - DEBUGF(infof(data_s, "Removed stream %u hash!\n", stream_id)); - } - return 0; -} - -static int on_begin_headers(nghttp2_session *session, - const nghttp2_frame *frame, void *userp) -{ - struct HTTP *stream; - struct SessionHandle *data_s = NULL; - (void)userp; - - data_s = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); - if(!data_s) { - return 0; - } - - DEBUGF(infof(data_s, "on_begin_headers() was called\n")); - - if(frame->hd.type != NGHTTP2_HEADERS) { - return 0; - } - - stream = data_s->req.protop; - if(!stream || !stream->bodystarted) { - return 0; - } - - /* This is trailer HEADERS started. Allocate buffer for them. */ - DEBUGF(infof(data_s, "trailer field started\n")); - - assert(stream->trailer_recvbuf == NULL); - - stream->trailer_recvbuf = Curl_add_buffer_init(); - if(!stream->trailer_recvbuf) { - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } - - return 0; -} - -/* Decode HTTP status code. Returns -1 if no valid status code was - decoded. */ -static int decode_status_code(const uint8_t *value, size_t len) -{ - int i; - int res; - - if(len != 3) { - return -1; - } - - res = 0; - - for(i = 0; i < 3; ++i) { - char c = value[i]; - - if(c < '0' || c > '9') { - return -1; - } - - res *= 10; - res += c - '0'; - } - - return res; -} - -/* frame->hd.type is either NGHTTP2_HEADERS or NGHTTP2_PUSH_PROMISE */ -static int on_header(nghttp2_session *session, const nghttp2_frame *frame, - const uint8_t *name, size_t namelen, - const uint8_t *value, size_t valuelen, - uint8_t flags, - void *userp) -{ - struct HTTP *stream; - struct SessionHandle *data_s; - int32_t stream_id = frame->hd.stream_id; - struct connectdata *conn = (struct connectdata *)userp; - (void)flags; - - DEBUGASSERT(stream_id); /* should never be a zero stream ID here */ - - /* get the stream from the hash based on Stream ID */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) - /* Receiving a Stream ID not in the hash should not happen, this is an - internal error more than anything else! */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - - stream = data_s->req.protop; - if(!stream) { - failf(data_s, "Internal NULL stream! 5\n"); - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - - /* Store received PUSH_PROMISE headers to be used when the subsequent - PUSH_PROMISE callback comes */ - if(frame->hd.type == NGHTTP2_PUSH_PROMISE) { - char *h; - - if(!stream->push_headers) { - stream->push_headers_alloc = 10; - stream->push_headers = malloc(stream->push_headers_alloc * - sizeof(char *)); - stream->push_headers_used = 0; - } - else if(stream->push_headers_used == - stream->push_headers_alloc) { - char **headp; - stream->push_headers_alloc *= 2; - headp = realloc(stream->push_headers, - stream->push_headers_alloc * sizeof(char *)); - if(!headp) { - free(stream->push_headers); - stream->push_headers = NULL; - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - } - stream->push_headers = headp; - } - h = aprintf("%s:%s", name, value); - if(h) - stream->push_headers[stream->push_headers_used++] = h; - return 0; - } - - if(stream->bodystarted) { - /* This is trailer fields. */ - /* 3 is for ":" and "\r\n". */ - uint32_t n = (uint32_t)(namelen + valuelen + 3); - - DEBUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen, - value)); - - Curl_add_buffer(stream->trailer_recvbuf, &n, sizeof(n)); - Curl_add_buffer(stream->trailer_recvbuf, name, namelen); - Curl_add_buffer(stream->trailer_recvbuf, ": ", 2); - Curl_add_buffer(stream->trailer_recvbuf, value, valuelen); - Curl_add_buffer(stream->trailer_recvbuf, "\r\n\0", 3); - - return 0; - } - - if(namelen == sizeof(":status") - 1 && - memcmp(":status", name, namelen) == 0) { - /* nghttp2 guarantees :status is received first and only once, and - value is 3 digits status code, and decode_status_code always - succeeds. */ - stream->status_code = decode_status_code(value, valuelen); - DEBUGASSERT(stream->status_code != -1); - - Curl_add_buffer(stream->header_recvbuf, "HTTP/2 ", 7); - Curl_add_buffer(stream->header_recvbuf, value, valuelen); - /* the space character after the status code is mandatory */ - Curl_add_buffer(stream->header_recvbuf, " \r\n", 3); - /* if we receive data for another handle, wake that up */ - if(conn->data != data_s) - Curl_expire(data_s, 1); - - DEBUGF(infof(data_s, "h2 status: HTTP/2 %03d (easy %p)\n", - stream->status_code, data_s)); - return 0; - } - - /* nghttp2 guarantees that namelen > 0, and :status was already - received, and this is not pseudo-header field . */ - /* convert to a HTTP1-style header */ - Curl_add_buffer(stream->header_recvbuf, name, namelen); - Curl_add_buffer(stream->header_recvbuf, ": ", 2); - Curl_add_buffer(stream->header_recvbuf, value, valuelen); - Curl_add_buffer(stream->header_recvbuf, "\r\n", 2); - /* if we receive data for another handle, wake that up */ - if(conn->data != data_s) - Curl_expire(data_s, 1); - - DEBUGF(infof(data_s, "h2 header: %.*s: %.*s\n", namelen, name, valuelen, - value)); - - return 0; /* 0 is successful */ -} - -static ssize_t data_source_read_callback(nghttp2_session *session, - int32_t stream_id, - uint8_t *buf, size_t length, - uint32_t *data_flags, - nghttp2_data_source *source, - void *userp) -{ - struct SessionHandle *data_s; - struct HTTP *stream = NULL; - size_t nread; - (void)source; - (void)userp; - - if(stream_id) { - /* get the stream from the hash based on Stream ID, stream ID zero is for - connection-oriented stuff */ - data_s = nghttp2_session_get_stream_user_data(session, stream_id); - if(!data_s) - /* Receiving a Stream ID not in the hash should not happen, this is an - internal error more than anything else! */ - return NGHTTP2_ERR_CALLBACK_FAILURE; - - stream = data_s->req.protop; - if(!stream) - return NGHTTP2_ERR_CALLBACK_FAILURE; - } - else - return NGHTTP2_ERR_INVALID_ARGUMENT; - - nread = MIN(stream->upload_len, length); - if(nread > 0) { - memcpy(buf, stream->upload_mem, nread); - stream->upload_mem += nread; - stream->upload_len -= nread; - stream->upload_left -= nread; - } - - if(stream->upload_left == 0) - *data_flags = 1; - else if(nread == 0) - return NGHTTP2_ERR_DEFERRED; - - DEBUGF(infof(data_s, "data_source_read_callback: " - "returns %zu bytes stream %u\n", - nread, stream_id)); - - return nread; -} - -/* - * The HTTP2 settings we send in the Upgrade request - */ -static nghttp2_settings_entry settings[] = { - { NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100 }, - { NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, NGHTTP2_INITIAL_WINDOW_SIZE }, -}; - -#define H2_BUFSIZE 32768 - -#ifdef NGHTTP2_HAS_ERROR_CALLBACK -static int error_callback(nghttp2_session *session, - const char *msg, - size_t len, - void *userp) -{ - struct connectdata *conn = (struct connectdata *)userp; - (void)session; - infof(conn->data, "http2 error: %.*s\n", len, msg); - return 0; -} -#endif - -/* - * Initialize nghttp2 for a Curl connection - */ -CURLcode Curl_http2_init(struct connectdata *conn) -{ - if(!conn->proto.httpc.h2) { - int rc; - nghttp2_session_callbacks *callbacks; - - conn->proto.httpc.inbuf = malloc(H2_BUFSIZE); - if(conn->proto.httpc.inbuf == NULL) - return CURLE_OUT_OF_MEMORY; - - rc = nghttp2_session_callbacks_new(&callbacks); - - if(rc) { - failf(conn->data, "Couldn't initialize nghttp2 callbacks!"); - return CURLE_OUT_OF_MEMORY; /* most likely at least */ - } - - /* nghttp2_send_callback */ - nghttp2_session_callbacks_set_send_callback(callbacks, send_callback); - /* nghttp2_on_frame_recv_callback */ - nghttp2_session_callbacks_set_on_frame_recv_callback - (callbacks, on_frame_recv); - /* nghttp2_on_invalid_frame_recv_callback */ - nghttp2_session_callbacks_set_on_invalid_frame_recv_callback - (callbacks, on_invalid_frame_recv); - /* nghttp2_on_data_chunk_recv_callback */ - nghttp2_session_callbacks_set_on_data_chunk_recv_callback - (callbacks, on_data_chunk_recv); - /* nghttp2_before_frame_send_callback */ - nghttp2_session_callbacks_set_before_frame_send_callback - (callbacks, before_frame_send); - /* nghttp2_on_frame_send_callback */ - nghttp2_session_callbacks_set_on_frame_send_callback - (callbacks, on_frame_send); - /* nghttp2_on_frame_not_send_callback */ - nghttp2_session_callbacks_set_on_frame_not_send_callback - (callbacks, on_frame_not_send); - /* nghttp2_on_stream_close_callback */ - nghttp2_session_callbacks_set_on_stream_close_callback - (callbacks, on_stream_close); - /* nghttp2_on_begin_headers_callback */ - nghttp2_session_callbacks_set_on_begin_headers_callback - (callbacks, on_begin_headers); - /* nghttp2_on_header_callback */ - nghttp2_session_callbacks_set_on_header_callback(callbacks, on_header); - - nghttp2_session_callbacks_set_error_callback(callbacks, error_callback); - - /* The nghttp2 session is not yet setup, do it */ - rc = nghttp2_session_client_new(&conn->proto.httpc.h2, callbacks, conn); - - nghttp2_session_callbacks_del(callbacks); - - if(rc) { - failf(conn->data, "Couldn't initialize nghttp2!"); - return CURLE_OUT_OF_MEMORY; /* most likely at least */ - } - } - return CURLE_OK; -} - -/* - * Append headers to ask for a HTTP1.1 to HTTP2 upgrade. - */ -CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, - struct connectdata *conn) -{ - CURLcode result; - ssize_t binlen; - char *base64; - size_t blen; - struct SingleRequest *k = &conn->data->req; - uint8_t *binsettings = conn->proto.httpc.binsettings; - - /* As long as we have a fixed set of settings, we don't have to dynamically - * figure out the base64 strings since it'll always be the same. However, - * the settings will likely not be fixed every time in the future. - */ - - /* this returns number of bytes it wrote */ - binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN, - settings, - sizeof(settings)/sizeof(settings[0])); - if(!binlen) { - failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload"); - return CURLE_FAILED_INIT; - } - conn->proto.httpc.binlen = binlen; - - result = Curl_base64url_encode(conn->data, (const char *)binsettings, binlen, - &base64, &blen); - if(result) - return result; - - result = Curl_add_bufferf(req, - "Connection: Upgrade, HTTP2-Settings\r\n" - "Upgrade: %s\r\n" - "HTTP2-Settings: %s\r\n", - NGHTTP2_CLEARTEXT_PROTO_VERSION_ID, base64); - free(base64); - - k->upgr101 = UPGR101_REQUESTED; - - return result; -} - -/* - * Returns nonzero if current HTTP/2 session should be closed. - */ -static int should_close_session(struct http_conn *httpc) { - return httpc->drain_total == 0 && !nghttp2_session_want_read(httpc->h2) && - !nghttp2_session_want_write(httpc->h2); -} - -static int h2_session_send(struct SessionHandle *data, - nghttp2_session *h2); - -/* - * h2_process_pending_input() processes pending input left in - * httpc->inbuf. Then, call h2_session_send() to send pending data. - * This function returns 0 if it succeeds, or -1 and error code will - * be assigned to *err. - */ -static int h2_process_pending_input(struct SessionHandle *data, - struct http_conn *httpc, - CURLcode *err) { - ssize_t nread; - char *inbuf; - ssize_t rv; - - nread = httpc->inbuflen - httpc->nread_inbuf; - inbuf = httpc->inbuf + httpc->nread_inbuf; - - rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); - if(rv < 0) { - failf(data, - "h2_process_pending_input: nghttp2_session_mem_recv() returned " - "%d:%s\n", rv, nghttp2_strerror((int)rv)); - *err = CURLE_RECV_ERROR; - return -1; - } - - if(nread == rv) { - DEBUGF(infof(data, - "h2_process_pending_input: All data in connection buffer " - "processed\n")); - httpc->inbuflen = 0; - httpc->nread_inbuf = 0; - } - else { - httpc->nread_inbuf += rv; - DEBUGF(infof(data, - "h2_process_pending_input: %zu bytes left in connection " - "buffer\n", - httpc->inbuflen - httpc->nread_inbuf)); - } - - rv = h2_session_send(data, httpc->h2); - if(rv != 0) { - *err = CURLE_SEND_ERROR; - return -1; - } - - if(should_close_session(httpc)) { - DEBUGF(infof(data, - "h2_process_pending_input: nothing to do in this session\n")); - *err = CURLE_HTTP2; - return -1; - } - - return 0; -} - -static ssize_t http2_handle_stream_close(struct connectdata *conn, - struct SessionHandle *data, - struct HTTP *stream, CURLcode *err) { - char *trailer_pos, *trailer_end; - CURLcode result; - struct http_conn *httpc = &conn->proto.httpc; - - if(httpc->pause_stream_id == stream->stream_id) { - httpc->pause_stream_id = 0; - } - - DEBUGASSERT(httpc->drain_total >= data->state.drain); - httpc->drain_total -= data->state.drain; - data->state.drain = 0; - - if(httpc->pause_stream_id == 0) { - if(h2_process_pending_input(data, httpc, err) != 0) { - return -1; - } - } - - DEBUGASSERT(data->state.drain == 0); - - /* Reset to FALSE to prevent infinite loop in readwrite_data - function. */ - stream->closed = FALSE; - if(stream->error_code != NGHTTP2_NO_ERROR) { - failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)", - stream->stream_id, Curl_http2_strerror(stream->error_code), - stream->error_code); - *err = CURLE_HTTP2_STREAM; - return -1; - } - - if(!stream->bodystarted) { - failf(data, "HTTP/2 stream %u was closed cleanly, but before getting " - " all response header fields, teated as error", - stream->stream_id); - *err = CURLE_HTTP2_STREAM; - return -1; - } - - if(stream->trailer_recvbuf && stream->trailer_recvbuf->buffer) { - trailer_pos = stream->trailer_recvbuf->buffer; - trailer_end = trailer_pos + stream->trailer_recvbuf->size_used; - - for(; trailer_pos < trailer_end;) { - uint32_t n; - memcpy(&n, trailer_pos, sizeof(n)); - trailer_pos += sizeof(n); - - result = Curl_client_write(conn, CLIENTWRITE_HEADER, trailer_pos, n); - if(result) { - *err = result; - return -1; - } - - trailer_pos += n + 1; - } - } - - DEBUGF(infof(data, "http2_recv returns 0, http2_handle_stream_close\n")); - return 0; -} - -/* - * h2_pri_spec() fills in the pri_spec struct, used by nghttp2 to send weight - * and dependency to the peer. It also stores the updated values in the state - * struct. - */ - -static void h2_pri_spec(struct SessionHandle *data, - nghttp2_priority_spec *pri_spec) -{ - struct HTTP *depstream = (data->set.stream_depends_on? - data->set.stream_depends_on->req.protop:NULL); - int32_t depstream_id = depstream? depstream->stream_id:0; - nghttp2_priority_spec_init(pri_spec, depstream_id, data->set.stream_weight, - data->set.stream_depends_e); - data->state.stream_weight = data->set.stream_weight; - data->state.stream_depends_e = data->set.stream_depends_e; - data->state.stream_depends_on = data->set.stream_depends_on; -} - -/* - * h2_session_send() checks if there's been an update in the priority / - * dependency settings and if so it submits a PRIORITY frame with the updated - * info. - */ -static int h2_session_send(struct SessionHandle *data, - nghttp2_session *h2) -{ - struct HTTP *stream = data->req.protop; - if((data->set.stream_weight != data->state.stream_weight) || - (data->set.stream_depends_e != data->state.stream_depends_e) || - (data->set.stream_depends_on != data->state.stream_depends_on) ) { - /* send new weight and/or dependency */ - nghttp2_priority_spec pri_spec; - int rv; - - h2_pri_spec(data, &pri_spec); - - DEBUGF(infof(data, "Queuing PRIORITY on stream %u (easy %p)\n", - stream->stream_id, data)); - rv = nghttp2_submit_priority(h2, NGHTTP2_FLAG_NONE, stream->stream_id, - &pri_spec); - if(rv) - return rv; - } - - return nghttp2_session_send(h2); -} - -/* - * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return - * a regular CURLcode value. - */ -static ssize_t http2_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - CURLcode result = CURLE_OK; - ssize_t rv; - ssize_t nread; - struct http_conn *httpc = &conn->proto.httpc; - struct SessionHandle *data = conn->data; - struct HTTP *stream = data->req.protop; - - (void)sockindex; /* we always do HTTP2 on sockindex 0 */ - - if(should_close_session(httpc)) { - DEBUGF(infof(data, - "http2_recv: nothing to do in this session\n")); - *err = CURLE_HTTP2; - return -1; - } - - /* Nullify here because we call nghttp2_session_send() and they - might refer to the old buffer. */ - stream->upload_mem = NULL; - stream->upload_len = 0; - - /* - * At this point 'stream' is just in the SessionHandle the connection - * identifies as its owner at this time. - */ - - if(stream->bodystarted && - stream->nread_header_recvbuf < stream->header_recvbuf->size_used) { - /* If there is body data pending for this stream to return, do that */ - size_t left = - stream->header_recvbuf->size_used - stream->nread_header_recvbuf; - size_t ncopy = MIN(len, left); - memcpy(mem, stream->header_recvbuf->buffer + stream->nread_header_recvbuf, - ncopy); - stream->nread_header_recvbuf += ncopy; - - DEBUGF(infof(data, "http2_recv: Got %d bytes from header_recvbuf\n", - (int)ncopy)); - return ncopy; - } - - DEBUGF(infof(data, "http2_recv: easy %p (stream %u)\n", - data, stream->stream_id)); - - if((data->state.drain) && stream->memlen) { - DEBUGF(infof(data, "http2_recv: DRAIN %zu bytes stream %u!! (%p => %p)\n", - stream->memlen, stream->stream_id, - stream->mem, mem)); - if(mem != stream->mem) { - /* if we didn't get the same buffer this time, we must move the data to - the beginning */ - memmove(mem, stream->mem, stream->memlen); - stream->len = len - stream->memlen; - stream->mem = mem; - } - if(httpc->pause_stream_id == stream->stream_id && !stream->pausedata) { - /* We have paused nghttp2, but we have no pause data (see - on_data_chunk_recv). */ - httpc->pause_stream_id = 0; - if(h2_process_pending_input(data, httpc, &result) != 0) { - *err = result; - return -1; - } - } - } - else if(stream->pausedata) { - DEBUGASSERT(httpc->pause_stream_id == stream->stream_id); - nread = MIN(len, stream->pauselen); - memcpy(mem, stream->pausedata, nread); - - stream->pausedata += nread; - stream->pauselen -= nread; - - infof(data, "%zu data bytes written\n", nread); - if(stream->pauselen == 0) { - DEBUGF(infof(data, "Unpaused by stream %u\n", stream->stream_id)); - assert(httpc->pause_stream_id == stream->stream_id); - httpc->pause_stream_id = 0; - - stream->pausedata = NULL; - stream->pauselen = 0; - - /* When NGHTTP2_ERR_PAUSE is returned from - data_source_read_callback, we might not process DATA frame - fully. Calling nghttp2_session_mem_recv() again will - continue to process DATA frame, but if there is no incoming - frames, then we have to call it again with 0-length data. - Without this, on_stream_close callback will not be called, - and stream could be hanged. */ - if(h2_process_pending_input(data, httpc, &result) != 0) { - *err = result; - return -1; - } - } - DEBUGF(infof(data, "http2_recv: returns unpaused %zd bytes on stream %u\n", - nread, stream->stream_id)); - return nread; - } - else if(httpc->pause_stream_id) { - /* If a stream paused nghttp2_session_mem_recv previously, and has - not processed all data, it still refers to the buffer in - nghttp2_session. If we call nghttp2_session_mem_recv(), we may - overwrite that buffer. To avoid that situation, just return - here with CURLE_AGAIN. This could be busy loop since data in - socket is not read. But it seems that usually streams are - notified with its drain property, and socket is read again - quickly. */ - *err = CURLE_AGAIN; - return -1; - } - else { - char *inbuf; - /* remember where to store incoming data for this stream and how big the - buffer is */ - stream->mem = mem; - stream->len = len; - stream->memlen = 0; - - if(httpc->inbuflen == 0) { - nread = ((Curl_recv *)httpc->recv_underlying)( - conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result); - - if(nread == -1) { - if(result != CURLE_AGAIN) - failf(data, "Failed receiving HTTP2 data"); - else if(stream->closed) - /* received when the stream was already closed! */ - return http2_handle_stream_close(conn, data, stream, err); - - *err = result; - return -1; - } - - if(nread == 0) { - failf(data, "Unexpected EOF"); - *err = CURLE_RECV_ERROR; - return -1; - } - - DEBUGF(infof(data, "nread=%zd\n", nread)); - - httpc->inbuflen = nread; - inbuf = httpc->inbuf; - } - else { - nread = httpc->inbuflen - httpc->nread_inbuf; - inbuf = httpc->inbuf + httpc->nread_inbuf; - - DEBUGF(infof(data, "Use data left in connection buffer, nread=%zd\n", - nread)); - } - rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread); - - if(nghttp2_is_fatal((int)rv)) { - failf(data, "nghttp2_session_mem_recv() returned %d:%s\n", - rv, nghttp2_strerror((int)rv)); - *err = CURLE_RECV_ERROR; - return 0; - } - DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv)); - if(nread == rv) { - DEBUGF(infof(data, "All data in connection buffer processed\n")); - httpc->inbuflen = 0; - httpc->nread_inbuf = 0; - } - else { - httpc->nread_inbuf += rv; - DEBUGF(infof(data, "%zu bytes left in connection buffer\n", - httpc->inbuflen - httpc->nread_inbuf)); - } - /* Always send pending frames in nghttp2 session, because - nghttp2_session_mem_recv() may queue new frame */ - rv = h2_session_send(data, httpc->h2); - if(rv != 0) { - *err = CURLE_SEND_ERROR; - return 0; - } - - if(should_close_session(httpc)) { - DEBUGF(infof(data, "http2_recv: nothing to do in this session\n")); - *err = CURLE_HTTP2; - return -1; - } - } - if(stream->memlen) { - ssize_t retlen = stream->memlen; - DEBUGF(infof(data, "http2_recv: returns %zd for stream %u\n", - retlen, stream->stream_id)); - stream->memlen = 0; - - if(httpc->pause_stream_id == stream->stream_id) { - /* data for this stream is returned now, but this stream caused a pause - already so we need it called again asap */ - DEBUGF(infof(data, "Data returned for PAUSED stream %u\n", - stream->stream_id)); - } - else if(!stream->closed) { - DEBUGASSERT(httpc->drain_total >= data->state.drain); - httpc->drain_total -= data->state.drain; - data->state.drain = 0; /* this stream is hereby drained */ - } - - return retlen; - } - /* If stream is closed, return 0 to signal the http routine to close - the connection */ - if(stream->closed) { - return http2_handle_stream_close(conn, data, stream, err); - } - *err = CURLE_AGAIN; - DEBUGF(infof(data, "http2_recv returns AGAIN for stream %u\n", - stream->stream_id)); - return -1; -} - -/* Index where :authority header field will appear in request header - field list. */ -#define AUTHORITY_DST_IDX 3 - -#define HEADER_OVERFLOW(x) \ - (x.namelen > (uint16_t)-1 || x.valuelen > (uint16_t)-1 - x.namelen) - -/* return number of received (decrypted) bytes */ -static ssize_t http2_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *err) -{ - /* - * BIG TODO: Currently, we send request in this function, but this - * function is also used to send request body. It would be nice to - * add dedicated function for request. - */ - int rv; - struct http_conn *httpc = &conn->proto.httpc; - struct HTTP *stream = conn->data->req.protop; - nghttp2_nv *nva = NULL; - size_t nheader; - size_t i; - size_t authority_idx; - char *hdbuf = (char*)mem; - char *end, *line_end; - nghttp2_data_provider data_prd; - int32_t stream_id; - nghttp2_session *h2 = httpc->h2; - nghttp2_priority_spec pri_spec; - - (void)sockindex; - - DEBUGF(infof(conn->data, "http2_send len=%zu\n", len)); - - if(stream->stream_id != -1) { - /* If stream_id != -1, we have dispatched request HEADERS, and now - are going to send or sending request body in DATA frame */ - stream->upload_mem = mem; - stream->upload_len = len; - nghttp2_session_resume_data(h2, stream->stream_id); - rv = h2_session_send(conn->data, h2); - if(nghttp2_is_fatal(rv)) { - *err = CURLE_SEND_ERROR; - return -1; - } - len -= stream->upload_len; - - /* Nullify here because we call nghttp2_session_send() and they - might refer to the old buffer. */ - stream->upload_mem = NULL; - stream->upload_len = 0; - - if(should_close_session(httpc)) { - DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); - *err = CURLE_HTTP2; - return -1; - } - - if(stream->upload_left) { - /* we are sure that we have more data to send here. Calling the - following API will make nghttp2_session_want_write() return - nonzero if remote window allows it, which then libcurl checks - socket is writable or not. See http2_perform_getsock(). */ - nghttp2_session_resume_data(h2, stream->stream_id); - } - - DEBUGF(infof(conn->data, "http2_send returns %zu for stream %u\n", len, - stream->stream_id)); - return len; - } - - /* Calculate number of headers contained in [mem, mem + len) */ - /* Here, we assume the curl http code generate *correct* HTTP header - field block */ - nheader = 0; - for(i = 1; i < len; ++i) { - if(hdbuf[i] == '\n' && hdbuf[i - 1] == '\r') { - ++nheader; - ++i; - } - } - if(nheader < 2) - goto fail; - - /* We counted additional 2 \r\n in the first and last line. We need 3 - new headers: :method, :path and :scheme. Therefore we need one - more space. */ - nheader += 1; - nva = malloc(sizeof(nghttp2_nv) * nheader); - if(nva == NULL) { - *err = CURLE_OUT_OF_MEMORY; - return -1; - } - - /* Extract :method, :path from request line */ - line_end = strstr(hdbuf, "\r\n"); - - /* Method does not contain spaces */ - end = memchr(hdbuf, ' ', line_end - hdbuf); - if(!end || end == hdbuf) - goto fail; - nva[0].name = (unsigned char *)":method"; - nva[0].namelen = strlen((char *)nva[0].name); - nva[0].value = (unsigned char *)hdbuf; - nva[0].valuelen = (size_t)(end - hdbuf); - nva[0].flags = NGHTTP2_NV_FLAG_NONE; - if(HEADER_OVERFLOW(nva[0])) { - failf(conn->data, "Failed sending HTTP request: Header overflow"); - goto fail; - } - - hdbuf = end + 1; - - /* Path may contain spaces so scan backwards */ - end = NULL; - for(i = (size_t)(line_end - hdbuf); i; --i) { - if(hdbuf[i - 1] == ' ') { - end = &hdbuf[i - 1]; - break; - } - } - if(!end || end == hdbuf) - goto fail; - nva[1].name = (unsigned char *)":path"; - nva[1].namelen = strlen((char *)nva[1].name); - nva[1].value = (unsigned char *)hdbuf; - nva[1].valuelen = (size_t)(end - hdbuf); - nva[1].flags = NGHTTP2_NV_FLAG_NONE; - if(HEADER_OVERFLOW(nva[1])) { - failf(conn->data, "Failed sending HTTP request: Header overflow"); - goto fail; - } - - hdbuf = end + 1; - - end = line_end; - nva[2].name = (unsigned char *)":scheme"; - nva[2].namelen = strlen((char *)nva[2].name); - if(conn->handler->flags & PROTOPT_SSL) - nva[2].value = (unsigned char *)"https"; - else - nva[2].value = (unsigned char *)"http"; - nva[2].valuelen = strlen((char *)nva[2].value); - nva[2].flags = NGHTTP2_NV_FLAG_NONE; - if(HEADER_OVERFLOW(nva[2])) { - failf(conn->data, "Failed sending HTTP request: Header overflow"); - goto fail; - } - - authority_idx = 0; - i = 3; - while(i < nheader) { - size_t hlen; - int skip = 0; - - hdbuf = line_end + 2; - - line_end = strstr(hdbuf, "\r\n"); - if(line_end == hdbuf) - goto fail; - - /* header continuation lines are not supported */ - if(*hdbuf == ' ' || *hdbuf == '\t') - goto fail; - - for(end = hdbuf; end < line_end && *end != ':'; ++end) - ; - if(end == hdbuf || end == line_end) - goto fail; - hlen = end - hdbuf; - - if(hlen == 10 && Curl_raw_nequal("connection", hdbuf, 10)) { - /* skip Connection: headers! */ - skip = 1; - --nheader; - } - else if(hlen == 4 && Curl_raw_nequal("host", hdbuf, 4)) { - authority_idx = i; - nva[i].name = (unsigned char *)":authority"; - nva[i].namelen = strlen((char *)nva[i].name); - } - else { - nva[i].name = (unsigned char *)hdbuf; - nva[i].namelen = (size_t)(end - hdbuf); - } - hdbuf = end + 1; - while(*hdbuf == ' ' || *hdbuf == '\t') - ++hdbuf; - end = line_end; - if(!skip) { - nva[i].value = (unsigned char *)hdbuf; - nva[i].valuelen = (size_t)(end - hdbuf); - nva[i].flags = NGHTTP2_NV_FLAG_NONE; - if(HEADER_OVERFLOW(nva[i])) { - failf(conn->data, "Failed sending HTTP request: Header overflow"); - goto fail; - } - /* Inspect Content-Length header field and retrieve the request - entity length so that we can set END_STREAM to the last DATA - frame. */ - if(nva[i].namelen == 14 && - Curl_raw_nequal("content-length", (char*)nva[i].name, 14)) { - size_t j; - stream->upload_left = 0; - if(!nva[i].valuelen) - goto fail; - for(j = 0; j < nva[i].valuelen; ++j) { - if(nva[i].value[j] < '0' || nva[i].value[j] > '9') - goto fail; - if(stream->upload_left >= CURL_OFF_T_MAX / 10) - goto fail; - stream->upload_left *= 10; - stream->upload_left += nva[i].value[j] - '0'; - } - DEBUGF(infof(conn->data, - "request content-length=%" - CURL_FORMAT_CURL_OFF_T - "\n", stream->upload_left)); - } - ++i; - } - } - - /* :authority must come before non-pseudo header fields */ - if(authority_idx != 0 && authority_idx != AUTHORITY_DST_IDX) { - nghttp2_nv authority = nva[authority_idx]; - for(i = authority_idx; i > AUTHORITY_DST_IDX; --i) { - nva[i] = nva[i - 1]; - } - nva[i] = authority; - } - - /* Warn stream may be rejected if cumulative length of headers is too large. - It appears nghttp2 will not send a header frame larger than 64KB. */ - { - size_t acc = 0; - const size_t max_acc = 60000; /* <64KB to account for some overhead */ - - for(i = 0; i < nheader; ++i) { - if(nva[i].namelen > max_acc - acc) - break; - acc += nva[i].namelen; - - if(nva[i].valuelen > max_acc - acc) - break; - acc += nva[i].valuelen; - } - - if(i != nheader) { - infof(conn->data, "http2_send: Warning: The cumulative length of all " - "headers exceeds %zu bytes and that could cause the " - "stream to be rejected.\n", max_acc); - } - } - - h2_pri_spec(conn->data, &pri_spec); - - switch(conn->data->set.httpreq) { - case HTTPREQ_POST: - case HTTPREQ_POST_FORM: - case HTTPREQ_PUT: - data_prd.read_callback = data_source_read_callback; - data_prd.source.ptr = NULL; - stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader, - &data_prd, conn->data); - break; - default: - stream_id = nghttp2_submit_request(h2, &pri_spec, nva, nheader, - NULL, conn->data); - } - - Curl_safefree(nva); - - if(stream_id < 0) { - DEBUGF(infof(conn->data, "http2_send() send error\n")); - *err = CURLE_SEND_ERROR; - return -1; - } - - infof(conn->data, "Using Stream ID: %x (easy handle %p)\n", - stream_id, conn->data); - stream->stream_id = stream_id; - - /* this does not call h2_session_send() since there can not have been any - * priority upodate since the nghttp2_submit_request() call above */ - rv = nghttp2_session_send(h2); - - if(rv != 0) { - *err = CURLE_SEND_ERROR; - return -1; - } - - if(should_close_session(httpc)) { - DEBUGF(infof(conn->data, "http2_send: nothing to do in this session\n")); - *err = CURLE_HTTP2; - return -1; - } - - if(stream->stream_id != -1) { - /* If whole HEADERS frame was sent off to the underlying socket, - the nghttp2 library calls data_source_read_callback. But only - it found that no data available, so it deferred the DATA - transmission. Which means that nghttp2_session_want_write() - returns 0 on http2_perform_getsock(), which results that no - writable socket check is performed. To workaround this, we - issue nghttp2_session_resume_data() here to bring back DATA - transmission from deferred state. */ - nghttp2_session_resume_data(h2, stream->stream_id); - } - - return len; - -fail: - free(nva); - *err = CURLE_SEND_ERROR; - return -1; -} - -CURLcode Curl_http2_setup(struct connectdata *conn) -{ - CURLcode result; - struct http_conn *httpc = &conn->proto.httpc; - struct HTTP *stream = conn->data->req.protop; - - stream->stream_id = -1; - - if(!stream->header_recvbuf) - stream->header_recvbuf = Curl_add_buffer_init(); - - if((conn->handler == &Curl_handler_http2_ssl) || - (conn->handler == &Curl_handler_http2)) - return CURLE_OK; /* already done */ - - if(conn->handler->flags & PROTOPT_SSL) - conn->handler = &Curl_handler_http2_ssl; - else - conn->handler = &Curl_handler_http2; - - result = Curl_http2_init(conn); - if(result) - return result; - - infof(conn->data, "Using HTTP2, server supports multi-use\n"); - stream->upload_left = 0; - stream->upload_mem = NULL; - stream->upload_len = 0; - - httpc->inbuflen = 0; - httpc->nread_inbuf = 0; - - httpc->pause_stream_id = 0; - httpc->drain_total = 0; - - conn->bits.multiplex = TRUE; /* at least potentially multiplexed */ - conn->httpversion = 20; - conn->bundle->multiuse = BUNDLE_MULTIPLEX; - - infof(conn->data, "Connection state changed (HTTP/2 confirmed)\n"); - Curl_multi_connchanged(conn->data->multi); - - /* switch on TCP_NODELAY as we need to send off packets without delay for - maximum throughput */ - Curl_tcpnodelay(conn, conn->sock[FIRSTSOCKET]); - - return CURLE_OK; -} - -CURLcode Curl_http2_switched(struct connectdata *conn, - const char *mem, size_t nread) -{ - CURLcode result; - struct http_conn *httpc = &conn->proto.httpc; - int rv; - ssize_t nproc; - struct SessionHandle *data = conn->data; - struct HTTP *stream = conn->data->req.protop; - - result = Curl_http2_setup(conn); - if(result) - return result; - - httpc->recv_underlying = (recving)conn->recv[FIRSTSOCKET]; - httpc->send_underlying = (sending)conn->send[FIRSTSOCKET]; - conn->recv[FIRSTSOCKET] = http2_recv; - conn->send[FIRSTSOCKET] = http2_send; - - if(conn->data->req.upgr101 == UPGR101_RECEIVED) { - /* stream 1 is opened implicitly on upgrade */ - stream->stream_id = 1; - /* queue SETTINGS frame (again) */ - rv = nghttp2_session_upgrade(httpc->h2, httpc->binsettings, - httpc->binlen, NULL); - if(rv != 0) { - failf(data, "nghttp2_session_upgrade() failed: %s(%d)", - nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } - - nghttp2_session_set_stream_user_data(httpc->h2, - stream->stream_id, - conn->data); - } - else { - /* stream ID is unknown at this point */ - stream->stream_id = -1; - rv = nghttp2_submit_settings(httpc->h2, NGHTTP2_FLAG_NONE, NULL, 0); - if(rv != 0) { - failf(data, "nghttp2_submit_settings() failed: %s(%d)", - nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } - } - - /* we are going to copy mem to httpc->inbuf. This is required since - mem is part of buffer pointed by stream->mem, and callbacks - called by nghttp2_session_mem_recv() will write stream specific - data into stream->mem, overwriting data already there. */ - if(H2_BUFSIZE < nread) { - failf(data, "connection buffer size is too small to store data following " - "HTTP Upgrade response header: buflen=%zu, datalen=%zu", - H2_BUFSIZE, nread); - return CURLE_HTTP2; - } - - infof(conn->data, "Copying HTTP/2 data in stream buffer to connection buffer" - " after upgrade: len=%zu\n", - nread); - - memcpy(httpc->inbuf, mem, nread); - httpc->inbuflen = nread; - - nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf, - httpc->inbuflen); - - if(nghttp2_is_fatal((int)nproc)) { - failf(data, "nghttp2_session_mem_recv() failed: %s(%d)", - nghttp2_strerror((int)nproc), (int)nproc); - return CURLE_HTTP2; - } - - DEBUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc)); - - if((ssize_t)nread == nproc) { - httpc->inbuflen = 0; - httpc->nread_inbuf = 0; - } - else { - httpc->nread_inbuf += nproc; - } - - /* Try to send some frames since we may read SETTINGS already. */ - rv = h2_session_send(data, httpc->h2); - - if(rv != 0) { - failf(data, "nghttp2_session_send() failed: %s(%d)", - nghttp2_strerror(rv), rv); - return CURLE_HTTP2; - } - - if(should_close_session(httpc)) { - DEBUGF(infof(data, - "nghttp2_session_send(): nothing to do in this session\n")); - return CURLE_HTTP2; - } - - return CURLE_OK; -} - -#else /* !USE_NGHTTP2 */ - -/* Satisfy external references even if http2 is not compiled in. */ - -#define CURL_DISABLE_TYPECHECK -#include - -char *curl_pushheader_bynum(struct curl_pushheaders *h, size_t num) -{ - (void) h; - (void) num; - return NULL; -} - -char *curl_pushheader_byname(struct curl_pushheaders *h, const char *header) -{ - (void) h; - (void) header; - return NULL; -} - -#endif /* USE_NGHTTP2 */ diff --git a/Externals/curl/lib/http2.h b/Externals/curl/lib/http2.h deleted file mode 100644 index 1aec304036..0000000000 --- a/Externals/curl/lib/http2.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef HEADER_CURL_HTTP2_H -#define HEADER_CURL_HTTP2_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_NGHTTP2 -#include "http.h" - -/* value for MAX_CONCURRENT_STREAMS we use until we get an updated setting - from the peer */ -#define DEFAULT_MAX_CONCURRENT_STREAMS 13 - -/* - * Store nghttp2 version info in this buffer, Prefix with a space. Return - * total length written. - */ -int Curl_http2_ver(char *p, size_t len); - -const char *Curl_http2_strerror(uint32_t err); - -CURLcode Curl_http2_init(struct connectdata *conn); -void Curl_http2_init_state(struct UrlState *state); -void Curl_http2_init_userset(struct UserDefined *set); -CURLcode Curl_http2_send_request(struct connectdata *conn); -CURLcode Curl_http2_request_upgrade(Curl_send_buffer *req, - struct connectdata *conn); -CURLcode Curl_http2_setup(struct connectdata *conn); -CURLcode Curl_http2_switched(struct connectdata *conn, - const char *data, size_t nread); -/* called from Curl_http_setup_conn */ -void Curl_http2_setup_conn(struct connectdata *conn); -void Curl_http2_setup_req(struct SessionHandle *data); -#else /* USE_NGHTTP2 */ -#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL -#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL -#define Curl_http2_request_upgrade(x,y) CURLE_UNSUPPORTED_PROTOCOL -#define Curl_http2_setup(x) CURLE_UNSUPPORTED_PROTOCOL -#define Curl_http2_switched(x,y,z) CURLE_UNSUPPORTED_PROTOCOL -#define Curl_http2_setup_conn(x) -#define Curl_http2_setup_req(x) -#define Curl_http2_init_state(x) -#define Curl_http2_init_userset(x) -#endif - -#endif /* HEADER_CURL_HTTP2_H */ - diff --git a/Externals/curl/lib/http_chunks.c b/Externals/curl/lib/http_chunks.c deleted file mode 100644 index 433f76e1c3..0000000000 --- a/Externals/curl/lib/http_chunks.c +++ /dev/null @@ -1,381 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_HTTP - -#include "urldata.h" /* it includes http_chunks.h */ -#include "sendf.h" /* for the client write stuff */ - -#include "content_encoding.h" -#include "http.h" -#include "non-ascii.h" /* for Curl_convert_to_network prototype */ -#include "strtoofft.h" -#include "warnless.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Chunk format (simplified): - * - * [ chunk extension ] CRLF - * CRLF - * - * Highlights from RFC2616 section 3.6 say: - - The chunked encoding modifies the body of a message in order to - transfer it as a series of chunks, each with its own size indicator, - followed by an OPTIONAL trailer containing entity-header fields. This - allows dynamically produced content to be transferred along with the - information necessary for the recipient to verify that it has - received the full message. - - Chunked-Body = *chunk - last-chunk - trailer - CRLF - - chunk = chunk-size [ chunk-extension ] CRLF - chunk-data CRLF - chunk-size = 1*HEX - last-chunk = 1*("0") [ chunk-extension ] CRLF - - chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) - chunk-ext-name = token - chunk-ext-val = token | quoted-string - chunk-data = chunk-size(OCTET) - trailer = *(entity-header CRLF) - - The chunk-size field is a string of hex digits indicating the size of - the chunk. The chunked encoding is ended by any chunk whose size is - zero, followed by the trailer, which is terminated by an empty line. - - */ - -/* Check for an ASCII hex digit. - We avoid the use of isxdigit to accommodate non-ASCII hosts. */ -static bool Curl_isxdigit(char digit) -{ - return ( (digit >= 0x30 && digit <= 0x39) /* 0-9 */ - || (digit >= 0x41 && digit <= 0x46) /* A-F */ - || (digit >= 0x61 && digit <= 0x66) /* a-f */) ? TRUE : FALSE; -} - -void Curl_httpchunk_init(struct connectdata *conn) -{ - struct Curl_chunker *chunk = &conn->chunk; - chunk->hexindex=0; /* start at 0 */ - chunk->dataleft=0; /* no data left yet! */ - chunk->state = CHUNK_HEX; /* we get hex first! */ -} - -/* - * chunk_read() returns a OK for normal operations, or a positive return code - * for errors. STOP means this sequence of chunks is complete. The 'wrote' - * argument is set to tell the caller how many bytes we actually passed to the - * client (for byte-counting and whatever). - * - * The states and the state-machine is further explained in the header file. - * - * This function always uses ASCII hex values to accommodate non-ASCII hosts. - * For example, 0x0d and 0x0a are used instead of '\r' and '\n'. - */ -CHUNKcode Curl_httpchunk_read(struct connectdata *conn, - char *datap, - ssize_t datalen, - ssize_t *wrotep) -{ - CURLcode result=CURLE_OK; - struct SessionHandle *data = conn->data; - struct Curl_chunker *ch = &conn->chunk; - struct SingleRequest *k = &data->req; - size_t piece; - curl_off_t length = (curl_off_t)datalen; - size_t *wrote = (size_t *)wrotep; - - *wrote = 0; /* nothing's written yet */ - - /* the original data is written to the client, but we go on with the - chunk read process, to properly calculate the content length*/ - if(data->set.http_te_skip && !k->ignorebody) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, datalen); - if(result) - return CHUNKE_WRITE_ERROR; - } - - while(length) { - switch(ch->state) { - case CHUNK_HEX: - if(Curl_isxdigit(*datap)) { - if(ch->hexindex < MAXNUM_SIZE) { - ch->hexbuffer[ch->hexindex] = *datap; - datap++; - length--; - ch->hexindex++; - } - else { - return CHUNKE_TOO_LONG_HEX; /* longer hex than we support */ - } - } - else { - char *endptr; - if(0 == ch->hexindex) - /* This is illegal data, we received junk where we expected - a hexadecimal digit. */ - return CHUNKE_ILLEGAL_HEX; - - /* length and datap are unmodified */ - ch->hexbuffer[ch->hexindex]=0; - - /* convert to host encoding before calling strtoul */ - result = Curl_convert_from_network(conn->data, ch->hexbuffer, - ch->hexindex); - if(result) { - /* Curl_convert_from_network calls failf if unsuccessful */ - /* Treat it as a bad hex character */ - return CHUNKE_ILLEGAL_HEX; - } - - ch->datasize=curlx_strtoofft(ch->hexbuffer, &endptr, 16); - if((ch->datasize == CURL_OFF_T_MAX) && (errno == ERANGE)) - /* overflow is an error */ - return CHUNKE_ILLEGAL_HEX; - ch->state = CHUNK_LF; /* now wait for the CRLF */ - } - break; - - case CHUNK_LF: - /* waiting for the LF after a chunk size */ - if(*datap == 0x0a) { - /* we're now expecting data to come, unless size was zero! */ - if(0 == ch->datasize) { - ch->state = CHUNK_TRAILER; /* now check for trailers */ - conn->trlPos=0; - } - else - ch->state = CHUNK_DATA; - } - - datap++; - length--; - break; - - case CHUNK_DATA: - /* We expect 'datasize' of data. We have 'length' right now, it can be - more or less than 'datasize'. Get the smallest piece. - */ - piece = curlx_sotouz((ch->datasize >= length)?length:ch->datasize); - - /* Write the data portion available */ -#ifdef HAVE_LIBZ - switch (conn->data->set.http_ce_skip? - IDENTITY : data->req.auto_decoding) { - case IDENTITY: -#endif - if(!k->ignorebody) { - if(!data->set.http_te_skip) - result = Curl_client_write(conn, CLIENTWRITE_BODY, datap, - piece); - else - result = CURLE_OK; - } -#ifdef HAVE_LIBZ - break; - - case DEFLATE: - /* update data->req.keep.str to point to the chunk data. */ - data->req.str = datap; - result = Curl_unencode_deflate_write(conn, &data->req, - (ssize_t)piece); - break; - - case GZIP: - /* update data->req.keep.str to point to the chunk data. */ - data->req.str = datap; - result = Curl_unencode_gzip_write(conn, &data->req, - (ssize_t)piece); - break; - - default: - failf (conn->data, - "Unrecognized content encoding type. " - "libcurl understands `identity', `deflate' and `gzip' " - "content encodings."); - return CHUNKE_BAD_ENCODING; - } -#endif - - if(result) - return CHUNKE_WRITE_ERROR; - - *wrote += piece; - - ch->datasize -= piece; /* decrease amount left to expect */ - datap += piece; /* move read pointer forward */ - length -= piece; /* decrease space left in this round */ - - if(0 == ch->datasize) - /* end of data this round, we now expect a trailing CRLF */ - ch->state = CHUNK_POSTLF; - break; - - case CHUNK_POSTLF: - if(*datap == 0x0a) { - /* The last one before we go back to hex state and start all over. */ - Curl_httpchunk_init(conn); /* sets state back to CHUNK_HEX */ - } - else if(*datap != 0x0d) - return CHUNKE_BAD_CHUNK; - datap++; - length--; - break; - - case CHUNK_TRAILER: - if((*datap == 0x0d) || (*datap == 0x0a)) { - /* this is the end of a trailer, but if the trailer was zero bytes - there was no trailer and we move on */ - - if(conn->trlPos) { - /* we allocate trailer with 3 bytes extra room to fit this */ - conn->trailer[conn->trlPos++]=0x0d; - conn->trailer[conn->trlPos++]=0x0a; - conn->trailer[conn->trlPos]=0; - - /* Convert to host encoding before calling Curl_client_write */ - result = Curl_convert_from_network(conn->data, conn->trailer, - conn->trlPos); - if(result) - /* Curl_convert_from_network calls failf if unsuccessful */ - /* Treat it as a bad chunk */ - return CHUNKE_BAD_CHUNK; - - if(!data->set.http_te_skip) { - result = Curl_client_write(conn, CLIENTWRITE_HEADER, - conn->trailer, conn->trlPos); - if(result) - return CHUNKE_WRITE_ERROR; - } - conn->trlPos=0; - ch->state = CHUNK_TRAILER_CR; - if(*datap == 0x0a) - /* already on the LF */ - break; - } - else { - /* no trailer, we're on the final CRLF pair */ - ch->state = CHUNK_TRAILER_POSTCR; - break; /* don't advance the pointer */ - } - } - else { - /* conn->trailer is assumed to be freed in url.c on a - connection basis */ - if(conn->trlPos >= conn->trlMax) { - /* we always allocate three extra bytes, just because when the full - header has been received we append CRLF\0 */ - char *ptr; - if(conn->trlMax) { - conn->trlMax *= 2; - ptr = realloc(conn->trailer, conn->trlMax + 3); - } - else { - conn->trlMax=128; - ptr = malloc(conn->trlMax + 3); - } - if(!ptr) - return CHUNKE_OUT_OF_MEMORY; - conn->trailer = ptr; - } - conn->trailer[conn->trlPos++]=*datap; - } - datap++; - length--; - break; - - case CHUNK_TRAILER_CR: - if(*datap == 0x0a) { - ch->state = CHUNK_TRAILER_POSTCR; - datap++; - length--; - } - else - return CHUNKE_BAD_CHUNK; - break; - - case CHUNK_TRAILER_POSTCR: - /* We enter this state when a CR should arrive so we expect to - have to first pass a CR before we wait for LF */ - if((*datap != 0x0d) && (*datap != 0x0a)) { - /* not a CR then it must be another header in the trailer */ - ch->state = CHUNK_TRAILER; - break; - } - if(*datap == 0x0d) { - /* skip if CR */ - datap++; - length--; - } - /* now wait for the final LF */ - ch->state = CHUNK_STOP; - break; - - case CHUNK_STOP: - if(*datap == 0x0a) { - length--; - - /* Record the length of any data left in the end of the buffer - even if there's no more chunks to read */ - ch->dataleft = curlx_sotouz(length); - - return CHUNKE_STOP; /* return stop */ - } - else - return CHUNKE_BAD_CHUNK; - } - } - return CHUNKE_OK; -} - -const char *Curl_chunked_strerror(CHUNKcode code) -{ - switch (code) { - default: - return "OK"; - case CHUNKE_TOO_LONG_HEX: - return "Too long hexadecimal number"; - case CHUNKE_ILLEGAL_HEX: - return "Illegal or missing hexadecimal sequence"; - case CHUNKE_BAD_CHUNK: - return "Malformed encoding found"; - case CHUNKE_WRITE_ERROR: - return "Write error"; - case CHUNKE_BAD_ENCODING: - return "Bad content-encoding found"; - case CHUNKE_OUT_OF_MEMORY: - return "Out of memory"; - } -} - -#endif /* CURL_DISABLE_HTTP */ diff --git a/Externals/curl/lib/http_chunks.h b/Externals/curl/lib/http_chunks.h deleted file mode 100644 index 3a8b4ddf37..0000000000 --- a/Externals/curl/lib/http_chunks.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef HEADER_CURL_HTTP_CHUNKS_H -#define HEADER_CURL_HTTP_CHUNKS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* - * The longest possible hexadecimal number we support in a chunked transfer. - * Weird enough, RFC2616 doesn't set a maximum size! Since we use strtoul() - * to convert it, we "only" support 2^32 bytes chunk data. - */ -#define MAXNUM_SIZE 16 - -typedef enum { - /* await and buffer all hexadecimal digits until we get one that isn't a - hexadecimal digit. When done, we go CHUNK_LF */ - CHUNK_HEX, - - /* wait for LF, ignore all else */ - CHUNK_LF, - - /* We eat the amount of data specified. When done, we move on to the - POST_CR state. */ - CHUNK_DATA, - - /* POSTLF should get a CR and then a LF and nothing else, then move back to - HEX as the CRLF combination marks the end of a chunk. A missing CR is no - big deal. */ - CHUNK_POSTLF, - - /* Used to mark that we're out of the game. NOTE: that there's a 'dataleft' - field in the struct that will tell how many bytes that were not passed to - the client in the end of the last buffer! */ - CHUNK_STOP, - - /* At this point optional trailer headers can be found, unless the next line - is CRLF */ - CHUNK_TRAILER, - - /* A trailer CR has been found - next state is CHUNK_TRAILER_POSTCR. - Next char must be a LF */ - CHUNK_TRAILER_CR, - - /* A trailer LF must be found now, otherwise CHUNKE_BAD_CHUNK will be - signalled If this is an empty trailer CHUNKE_STOP will be signalled. - Otherwise the trailer will be broadcasted via Curl_client_write() and the - next state will be CHUNK_TRAILER */ - CHUNK_TRAILER_POSTCR -} ChunkyState; - -typedef enum { - CHUNKE_STOP = -1, - CHUNKE_OK = 0, - CHUNKE_TOO_LONG_HEX = 1, - CHUNKE_ILLEGAL_HEX, - CHUNKE_BAD_CHUNK, - CHUNKE_WRITE_ERROR, - CHUNKE_BAD_ENCODING, - CHUNKE_OUT_OF_MEMORY, - CHUNKE_LAST -} CHUNKcode; - -const char *Curl_chunked_strerror(CHUNKcode code); - -struct Curl_chunker { - char hexbuffer[ MAXNUM_SIZE + 1]; - int hexindex; - ChunkyState state; - curl_off_t datasize; - size_t dataleft; /* untouched data amount at the end of the last buffer */ -}; - -#endif /* HEADER_CURL_HTTP_CHUNKS_H */ - diff --git a/Externals/curl/lib/http_digest.c b/Externals/curl/lib/http_digest.c deleted file mode 100644 index a1768b863c..0000000000 --- a/Externals/curl/lib/http_digest.c +++ /dev/null @@ -1,178 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) - -#include "urldata.h" -#include "rawstr.h" -#include "vauth/vauth.h" -#include "http_digest.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Test example headers: - -WWW-Authenticate: Digest realm="testrealm", nonce="1053604598" -Proxy-Authenticate: Digest realm="testrealm", nonce="1053604598" - -*/ - -CURLcode Curl_input_digest(struct connectdata *conn, - bool proxy, - const char *header) /* rest of the *-authenticate: - header */ -{ - struct SessionHandle *data = conn->data; - - /* Point to the correct struct with this */ - struct digestdata *digest; - - if(proxy) { - digest = &data->state.proxydigest; - } - else { - digest = &data->state.digest; - } - - if(!checkprefix("Digest", header)) - return CURLE_BAD_CONTENT_ENCODING; - - header += strlen("Digest"); - while(*header && ISSPACE(*header)) - header++; - - return Curl_auth_decode_digest_http_message(header, digest); -} - -CURLcode Curl_output_digest(struct connectdata *conn, - bool proxy, - const unsigned char *request, - const unsigned char *uripath) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - unsigned char *path; - char *tmp; - char *response; - size_t len; - bool have_chlg; - - /* Point to the address of the pointer that holds the string to send to the - server, which is for a plain host or for a HTTP proxy */ - char **allocuserpwd; - - /* Point to the name and password for this */ - const char *userp; - const char *passwdp; - - /* Point to the correct struct with this */ - struct digestdata *digest; - struct auth *authp; - - if(proxy) { - digest = &data->state.proxydigest; - allocuserpwd = &conn->allocptr.proxyuserpwd; - userp = conn->proxyuser; - passwdp = conn->proxypasswd; - authp = &data->state.authproxy; - } - else { - digest = &data->state.digest; - allocuserpwd = &conn->allocptr.userpwd; - userp = conn->user; - passwdp = conn->passwd; - authp = &data->state.authhost; - } - - Curl_safefree(*allocuserpwd); - - /* not set means empty */ - if(!userp) - userp = ""; - - if(!passwdp) - passwdp = ""; - -#if defined(USE_WINDOWS_SSPI) - have_chlg = digest->input_token ? TRUE : FALSE; -#else - have_chlg = digest->nonce ? TRUE : FALSE; -#endif - - if(!have_chlg) { - authp->done = FALSE; - return CURLE_OK; - } - - /* So IE browsers < v7 cut off the URI part at the query part when they - evaluate the MD5 and some (IIS?) servers work with them so we may need to - do the Digest IE-style. Note that the different ways cause different MD5 - sums to get sent. - - Apache servers can be set to do the Digest IE-style automatically using - the BrowserMatch feature: - https://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie - - Further details on Digest implementation differences: - http://www.fngtps.com/2006/09/http-authentication - */ - - if(authp->iestyle && ((tmp = strchr((char *)uripath, '?')) != NULL)) { - size_t urilen = tmp - (char *)uripath; - - path = (unsigned char *) aprintf("%.*s", urilen, uripath); - } - else - path = (unsigned char *) strdup((char *) uripath); - - if(!path) - return CURLE_OUT_OF_MEMORY; - - result = Curl_auth_create_digest_http_message(data, userp, passwdp, request, - path, digest, &response, &len); - free(path); - if(result) - return result; - - *allocuserpwd = aprintf("%sAuthorization: Digest %s\r\n", - proxy ? "Proxy-" : "", - response); - free(response); - if(!*allocuserpwd) - return CURLE_OUT_OF_MEMORY; - - authp->done = TRUE; - - return CURLE_OK; -} - -void Curl_digest_cleanup(struct SessionHandle *data) -{ - Curl_auth_digest_cleanup(&data->state.digest); - Curl_auth_digest_cleanup(&data->state.proxydigest); -} - -#endif diff --git a/Externals/curl/lib/http_digest.h b/Externals/curl/lib/http_digest.h deleted file mode 100644 index 49aad897c2..0000000000 --- a/Externals/curl/lib/http_digest.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef HEADER_CURL_HTTP_DIGEST_H -#define HEADER_CURL_HTTP_DIGEST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -/* this is for digest header input */ -CURLcode Curl_input_digest(struct connectdata *conn, - bool proxy, const char *header); - -/* this is for creating digest header output */ -CURLcode Curl_output_digest(struct connectdata *conn, - bool proxy, - const unsigned char *request, - const unsigned char *uripath); - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH) -void Curl_digest_cleanup(struct SessionHandle *data); -#else -#define Curl_digest_cleanup(x) Curl_nop_stmt -#endif - -#endif /* HEADER_CURL_HTTP_DIGEST_H */ diff --git a/Externals/curl/lib/http_negotiate.c b/Externals/curl/lib/http_negotiate.c deleted file mode 100644 index 999bc0c528..0000000000 --- a/Externals/curl/lib/http_negotiate.c +++ /dev/null @@ -1,133 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) - -#include "urldata.h" -#include "sendf.h" -#include "rawstr.h" -#include "http_negotiate.h" -#include "vauth/vauth.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, - const char *header) -{ - struct SessionHandle *data = conn->data; - size_t len; - - /* Point to the username, password, service and host */ - const char *userp; - const char *passwdp; - const char *service; - const char *host; - - /* Point to the correct struct with this */ - struct negotiatedata *neg_ctx; - - if(proxy) { - userp = conn->proxyuser; - passwdp = conn->proxypasswd; - service = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP"; - host = conn->proxy.name; - neg_ctx = &data->state.proxyneg; - } - else { - userp = conn->user; - passwdp = conn->passwd; - service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : "HTTP"; - host = conn->host.name; - neg_ctx = &data->state.negotiate; - } - - /* Not set means empty */ - if(!userp) - userp = ""; - - if(!passwdp) - passwdp = ""; - - /* Obtain the input token, if any */ - header += strlen("Negotiate"); - while(*header && ISSPACE(*header)) - header++; - - len = strlen(header); - if(!len) { - /* Is this the first call in a new negotiation? */ - if(neg_ctx->context) { - /* The server rejected our authentication and hasn't suppled any more - negotiation mechanisms */ - return CURLE_LOGIN_DENIED; - } - } - - /* Initilise the security context and decode our challenge */ - return Curl_auth_decode_spnego_message(data, userp, passwdp, service, host, - header, neg_ctx); -} - -CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy) -{ - struct negotiatedata *neg_ctx = proxy ? &conn->data->state.proxyneg : - &conn->data->state.negotiate; - char *base64 = NULL; - size_t len = 0; - char *userp; - CURLcode result; - - result = Curl_auth_create_spnego_message(conn->data, neg_ctx, &base64, &len); - if(result) - return result; - - userp = aprintf("%sAuthorization: Negotiate %s\r\n", proxy ? "Proxy-" : "", - base64); - - if(proxy) { - Curl_safefree(conn->allocptr.proxyuserpwd); - conn->allocptr.proxyuserpwd = userp; - } - else { - Curl_safefree(conn->allocptr.userpwd); - conn->allocptr.userpwd = userp; - } - - free(base64); - - return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK; -} - -void Curl_cleanup_negotiate(struct SessionHandle *data) -{ - Curl_auth_spnego_cleanup(&data->state.negotiate); - Curl_auth_spnego_cleanup(&data->state.proxyneg); -} - -#endif /* !CURL_DISABLE_HTTP && USE_SPNEGO */ diff --git a/Externals/curl/lib/http_negotiate.h b/Externals/curl/lib/http_negotiate.h deleted file mode 100644 index 21b7f8834e..0000000000 --- a/Externals/curl/lib/http_negotiate.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef HEADER_CURL_HTTP_NEGOTIATE_H -#define HEADER_CURL_HTTP_NEGOTIATE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifdef USE_SPNEGO - -/* this is for Negotiate header input */ -CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy, - const char *header); - -/* this is for creating Negotiate header output */ -CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy); - -void Curl_cleanup_negotiate(struct SessionHandle *data); - -#endif /* USE_SPNEGO */ - -#endif /* HEADER_CURL_HTTP_NEGOTIATE_H */ diff --git a/Externals/curl/lib/http_ntlm.c b/Externals/curl/lib/http_ntlm.c deleted file mode 100644 index 935df25dbe..0000000000 --- a/Externals/curl/lib/http_ntlm.c +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) - -/* - * NTLM details: - * - * http://davenport.sourceforge.net/ntlm.html - * https://www.innovation.ch/java/ntlm.html - */ - -#define DEBUG_ME 0 - -#include "urldata.h" -#include "sendf.h" -#include "rawstr.h" -#include "http_ntlm.h" -#include "curl_ntlm_wb.h" -#include "vauth/vauth.h" -#include "url.h" - -#if defined(USE_NSS) -#include "vtls/nssg.h" -#elif defined(USE_WINDOWS_SSPI) -#include "curl_sspi.h" -#endif - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#if DEBUG_ME -# define DEBUG_OUT(x) x -#else -# define DEBUG_OUT(x) Curl_nop_stmt -#endif - -CURLcode Curl_input_ntlm(struct connectdata *conn, - bool proxy, /* if proxy or not */ - const char *header) /* rest of the www-authenticate: - header */ -{ - /* point to the correct struct with this */ - struct ntlmdata *ntlm; - CURLcode result = CURLE_OK; - - ntlm = proxy ? &conn->proxyntlm : &conn->ntlm; - - if(checkprefix("NTLM", header)) { - header += strlen("NTLM"); - - while(*header && ISSPACE(*header)) - header++; - - if(*header) { - result = Curl_auth_decode_ntlm_type2_message(conn->data, header, ntlm); - if(result) - return result; - - ntlm->state = NTLMSTATE_TYPE2; /* We got a type-2 message */ - } - else { - if(ntlm->state == NTLMSTATE_LAST) { - infof(conn->data, "NTLM auth restarted\n"); - Curl_http_ntlm_cleanup(conn); - } - else if(ntlm->state == NTLMSTATE_TYPE3) { - infof(conn->data, "NTLM handshake rejected\n"); - Curl_http_ntlm_cleanup(conn); - ntlm->state = NTLMSTATE_NONE; - return CURLE_REMOTE_ACCESS_DENIED; - } - else if(ntlm->state >= NTLMSTATE_TYPE1) { - infof(conn->data, "NTLM handshake failure (internal error)\n"); - return CURLE_REMOTE_ACCESS_DENIED; - } - - ntlm->state = NTLMSTATE_TYPE1; /* We should send away a type-1 */ - } - } - - return result; -} - -/* - * This is for creating ntlm header output - */ -CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy) -{ - char *base64 = NULL; - size_t len = 0; - CURLcode result; - - /* point to the address of the pointer that holds the string to send to the - server, which is for a plain host or for a HTTP proxy */ - char **allocuserpwd; - - /* point to the name and password for this */ - const char *userp; - const char *passwdp; - - /* point to the correct struct with this */ - struct ntlmdata *ntlm; - struct auth *authp; - - DEBUGASSERT(conn); - DEBUGASSERT(conn->data); - -#ifdef USE_NSS - if(CURLE_OK != Curl_nss_force_init(conn->data)) - return CURLE_OUT_OF_MEMORY; -#endif - - if(proxy) { - allocuserpwd = &conn->allocptr.proxyuserpwd; - userp = conn->proxyuser; - passwdp = conn->proxypasswd; - ntlm = &conn->proxyntlm; - authp = &conn->data->state.authproxy; - } - else { - allocuserpwd = &conn->allocptr.userpwd; - userp = conn->user; - passwdp = conn->passwd; - ntlm = &conn->ntlm; - authp = &conn->data->state.authhost; - } - authp->done = FALSE; - - /* not set means empty */ - if(!userp) - userp = ""; - - if(!passwdp) - passwdp = ""; - -#ifdef USE_WINDOWS_SSPI - if(s_hSecDll == NULL) { - /* not thread safe and leaks - use curl_global_init() to avoid */ - CURLcode err = Curl_sspi_global_init(); - if(s_hSecDll == NULL) - return err; - } -#endif - - switch(ntlm->state) { - case NTLMSTATE_TYPE1: - default: /* for the weird cases we (re)start here */ - /* Create a type-1 message */ - result = Curl_auth_create_ntlm_type1_message(userp, passwdp, ntlm, &base64, - &len); - if(result) - return result; - - if(base64) { - free(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", - base64); - free(base64); - if(!*allocuserpwd) - return CURLE_OUT_OF_MEMORY; - - DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); - } - break; - - case NTLMSTATE_TYPE2: - /* We already received the type-2 message, create a type-3 message */ - result = Curl_auth_create_ntlm_type3_message(conn->data, userp, passwdp, - ntlm, &base64, &len); - if(result) - return result; - - if(base64) { - free(*allocuserpwd); - *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy ? "Proxy-" : "", - base64); - free(base64); - if(!*allocuserpwd) - return CURLE_OUT_OF_MEMORY; - - DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd)); - - ntlm->state = NTLMSTATE_TYPE3; /* we send a type-3 */ - authp->done = TRUE; - } - break; - - case NTLMSTATE_TYPE3: - /* connection is already authenticated, - * don't send a header in future requests */ - ntlm->state = NTLMSTATE_LAST; - /* fall-through */ - case NTLMSTATE_LAST: - Curl_safefree(*allocuserpwd); - authp->done = TRUE; - break; - } - - return CURLE_OK; -} - -void Curl_http_ntlm_cleanup(struct connectdata *conn) -{ - Curl_auth_ntlm_cleanup(&conn->ntlm); - Curl_auth_ntlm_cleanup(&conn->proxyntlm); - -#if defined(NTLM_WB_ENABLED) - Curl_ntlm_wb_cleanup(conn); -#endif -} - -#endif /* !CURL_DISABLE_HTTP && USE_NTLM */ diff --git a/Externals/curl/lib/http_ntlm.h b/Externals/curl/lib/http_ntlm.h deleted file mode 100644 index d186bbe370..0000000000 --- a/Externals/curl/lib/http_ntlm.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_NTLM_H -#define HEADER_CURL_NTLM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) - -/* this is for ntlm header input */ -CURLcode Curl_input_ntlm(struct connectdata *conn, bool proxy, - const char *header); - -/* this is for creating ntlm header output */ -CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy); - -void Curl_http_ntlm_cleanup(struct connectdata *conn); - -#endif /* !CURL_DISABLE_HTTP && USE_NTLM */ - -#endif /* HEADER_CURL_NTLM_H */ diff --git a/Externals/curl/lib/http_proxy.c b/Externals/curl/lib/http_proxy.c deleted file mode 100644 index 814c572f6f..0000000000 --- a/Externals/curl/lib/http_proxy.c +++ /dev/null @@ -1,605 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP) - -#include "urldata.h" -#include -#include "http_proxy.h" -#include "sendf.h" -#include "http.h" -#include "url.h" -#include "select.h" -#include "rawstr.h" -#include "progress.h" -#include "non-ascii.h" -#include "connect.h" -#include "curlx.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -CURLcode Curl_proxy_connect(struct connectdata *conn) -{ - if(conn->bits.tunnel_proxy && conn->bits.httpproxy) { -#ifndef CURL_DISABLE_PROXY - /* for [protocol] tunneled through HTTP proxy */ - struct HTTP http_proxy; - void *prot_save; - const char *hostname; - int remote_port; - CURLcode result; - - /* BLOCKING */ - /* We want "seamless" operations through HTTP proxy tunnel */ - - /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the - * member conn->proto.http; we want [protocol] through HTTP and we have - * to change the member temporarily for connecting to the HTTP - * proxy. After Curl_proxyCONNECT we have to set back the member to the - * original pointer - * - * This function might be called several times in the multi interface case - * if the proxy's CONNTECT response is not instant. - */ - prot_save = conn->data->req.protop; - memset(&http_proxy, 0, sizeof(http_proxy)); - conn->data->req.protop = &http_proxy; - connkeep(conn, "HTTP proxy CONNECT"); - if(conn->bits.conn_to_host) - hostname = conn->conn_to_host.name; - else - hostname = conn->host.name; - if(conn->bits.conn_to_port) - remote_port = conn->conn_to_port; - else - remote_port = conn->remote_port; - result = Curl_proxyCONNECT(conn, FIRSTSOCKET, hostname, - remote_port, FALSE); - conn->data->req.protop = prot_save; - if(CURLE_OK != result) - return result; - Curl_safefree(conn->allocptr.proxyuserpwd); -#else - return CURLE_NOT_BUILT_IN; -#endif - } - /* no HTTP tunnel proxy, just return */ - return CURLE_OK; -} - -/* - * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This - * function will issue the necessary commands to get a seamless tunnel through - * this proxy. After that, the socket can be used just as a normal socket. - * - * 'blocking' set to TRUE means that this function will do the entire CONNECT - * + response in a blocking fashion. Should be avoided! - */ - -CURLcode Curl_proxyCONNECT(struct connectdata *conn, - int sockindex, - const char *hostname, - int remote_port, - bool blocking) -{ - int subversion=0; - struct SessionHandle *data=conn->data; - struct SingleRequest *k = &data->req; - CURLcode result; - curl_socket_t tunnelsocket = conn->sock[sockindex]; - curl_off_t cl=0; - bool closeConnection = FALSE; - bool chunked_encoding = FALSE; - long check; - -#define SELECT_OK 0 -#define SELECT_ERROR 1 -#define SELECT_TIMEOUT 2 - int error = SELECT_OK; - - if(conn->tunnel_state[sockindex] == TUNNEL_COMPLETE) - return CURLE_OK; /* CONNECT is already completed */ - - conn->bits.proxy_connect_closed = FALSE; - - do { - if(TUNNEL_INIT == conn->tunnel_state[sockindex]) { - /* BEGIN CONNECT PHASE */ - char *host_port; - Curl_send_buffer *req_buffer; - - infof(data, "Establish HTTP proxy tunnel to %s:%hu\n", - hostname, remote_port); - - /* This only happens if we've looped here due to authentication - reasons, and we don't really use the newly cloned URL here - then. Just free() it. */ - free(data->req.newurl); - data->req.newurl = NULL; - - /* initialize a dynamic send-buffer */ - req_buffer = Curl_add_buffer_init(); - - if(!req_buffer) - return CURLE_OUT_OF_MEMORY; - - host_port = aprintf("%s:%hu", hostname, remote_port); - if(!host_port) { - Curl_add_buffer_free(req_buffer); - return CURLE_OUT_OF_MEMORY; - } - - /* Setup the proxy-authorization header, if any */ - result = Curl_http_output_auth(conn, "CONNECT", host_port, TRUE); - - free(host_port); - - if(!result) { - char *host=(char *)""; - const char *useragent=""; - const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ? - "1.0" : "1.1"; - bool ipv6_ip = conn->bits.ipv6_ip; - char *hostheader; - - /* the hostname may be different */ - if(hostname != conn->host.name) - ipv6_ip = (strchr(hostname, ':') != NULL); - hostheader= /* host:port with IPv6 support */ - aprintf("%s%s%s:%hu", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"", - remote_port); - if(!hostheader) { - Curl_add_buffer_free(req_buffer); - return CURLE_OUT_OF_MEMORY; - } - - if(!Curl_checkProxyheaders(conn, "Host:")) { - host = aprintf("Host: %s\r\n", hostheader); - if(!host) { - free(hostheader); - Curl_add_buffer_free(req_buffer); - return CURLE_OUT_OF_MEMORY; - } - } - if(!Curl_checkProxyheaders(conn, "User-Agent:") && - data->set.str[STRING_USERAGENT]) - useragent = conn->allocptr.uagent; - - result = - Curl_add_bufferf(req_buffer, - "CONNECT %s HTTP/%s\r\n" - "%s" /* Host: */ - "%s" /* Proxy-Authorization */ - "%s", /* User-Agent */ - hostheader, - http, - host, - conn->allocptr.proxyuserpwd? - conn->allocptr.proxyuserpwd:"", - useragent); - - if(host && *host) - free(host); - free(hostheader); - - if(!result) - result = Curl_add_custom_headers(conn, TRUE, req_buffer); - - if(!result) - /* CRLF terminate the request */ - result = Curl_add_bufferf(req_buffer, "\r\n"); - - if(!result) { - /* Send the connect request to the proxy */ - /* BLOCKING */ - result = - Curl_add_buffer_send(req_buffer, conn, - &data->info.request_size, 0, sockindex); - } - req_buffer = NULL; - if(result) - failf(data, "Failed sending CONNECT to proxy"); - } - - Curl_add_buffer_free(req_buffer); - if(result) - return result; - - conn->tunnel_state[sockindex] = TUNNEL_CONNECT; - } /* END CONNECT PHASE */ - - check = Curl_timeleft(data, NULL, TRUE); - if(check <= 0) { - failf(data, "Proxy CONNECT aborted due to timeout"); - return CURLE_RECV_ERROR; - } - - if(!blocking) { - if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0)) - /* return so we'll be called again polling-style */ - return CURLE_OK; - else { - DEBUGF(infof(data, - "Read response immediately from proxy CONNECT\n")); - } - } - - /* at this point, the tunnel_connecting phase is over. */ - - { /* READING RESPONSE PHASE */ - size_t nread; /* total size read */ - int perline; /* count bytes per line */ - int keepon=TRUE; - ssize_t gotbytes; - char *ptr; - char *line_start; - - ptr=data->state.buffer; - line_start = ptr; - - nread=0; - perline=0; - - while((nreadstate.buffer+BUFSIZE+1); - result = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, - &gotbytes); - if(result==CURLE_AGAIN) - continue; /* go loop yourself */ - else if(result) - keepon = FALSE; - else if(gotbytes <= 0) { - keepon = FALSE; - if(data->set.proxyauth && data->state.authproxy.avail) { - /* proxy auth was requested and there was proxy auth available, - then deem this as "mere" proxy disconnect */ - conn->bits.proxy_connect_closed = TRUE; - infof(data, "Proxy CONNECT connection closed\n"); - } - else { - error = SELECT_ERROR; - failf(data, "Proxy CONNECT aborted"); - } - } - else { - /* - * We got a whole chunk of data, which can be anything from one - * byte to a set of lines and possibly just a piece of the last - * line. - */ - int i; - - nread += gotbytes; - - if(keepon > TRUE) { - /* This means we are currently ignoring a response-body */ - - nread = 0; /* make next read start over in the read buffer */ - ptr=data->state.buffer; - if(cl) { - /* A Content-Length based body: simply count down the counter - and make sure to break out of the loop when we're done! */ - cl -= gotbytes; - if(cl<=0) { - keepon = FALSE; - break; - } - } - else { - /* chunked-encoded body, so we need to do the chunked dance - properly to know when the end of the body is reached */ - CHUNKcode r; - ssize_t tookcareof=0; - - /* now parse the chunked piece of data so that we can - properly tell when the stream ends */ - r = Curl_httpchunk_read(conn, ptr, gotbytes, &tookcareof); - if(r == CHUNKE_STOP) { - /* we're done reading chunks! */ - infof(data, "chunk reading DONE\n"); - keepon = FALSE; - /* we did the full CONNECT treatment, go COMPLETE */ - conn->tunnel_state[sockindex] = TUNNEL_COMPLETE; - } - else - infof(data, "Read %zd bytes of chunk, continue\n", - tookcareof); - } - } - else - for(i = 0; i < gotbytes; ptr++, i++) { - perline++; /* amount of bytes in this line so far */ - if(*ptr == 0x0a) { - char letter; - int writetype; - - /* convert from the network encoding */ - result = Curl_convert_from_network(data, line_start, - perline); - /* Curl_convert_from_network calls failf if unsuccessful */ - if(result) - return result; - - /* output debug if that is requested */ - if(data->set.verbose) - Curl_debug(data, CURLINFO_HEADER_IN, - line_start, (size_t)perline, conn); - - /* send the header to the callback */ - writetype = CLIENTWRITE_HEADER; - if(data->set.include_header) - writetype |= CLIENTWRITE_BODY; - - result = Curl_client_write(conn, writetype, line_start, - perline); - - data->info.header_size += (long)perline; - data->req.headerbytecount += (long)perline; - - if(result) - return result; - - /* Newlines are CRLF, so the CR is ignored as the line isn't - really terminated until the LF comes. Treat a following CR - as end-of-headers as well.*/ - - if(('\r' == line_start[0]) || - ('\n' == line_start[0])) { - /* end of response-headers from the proxy */ - nread = 0; /* make next read start over in the read - buffer */ - ptr=data->state.buffer; - if((407 == k->httpcode) && !data->state.authproblem) { - /* If we get a 407 response code with content length - when we have no auth problem, we must ignore the - whole response-body */ - keepon = 2; - - if(cl) { - infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T - " bytes of response-body\n", cl); - - /* remove the remaining chunk of what we already - read */ - cl -= (gotbytes - i); - - if(cl<=0) - /* if the whole thing was already read, we are done! - */ - keepon=FALSE; - } - else if(chunked_encoding) { - CHUNKcode r; - /* We set ignorebody true here since the chunked - decoder function will acknowledge that. Pay - attention so that this is cleared again when this - function returns! */ - k->ignorebody = TRUE; - infof(data, "%zd bytes of chunk left\n", gotbytes-i); - - if(line_start[1] == '\n') { - /* this can only be a LF if the letter at index 0 - was a CR */ - line_start++; - i++; - } - - /* now parse the chunked piece of data so that we can - properly tell when the stream ends */ - r = Curl_httpchunk_read(conn, line_start+1, - gotbytes -i, &gotbytes); - if(r == CHUNKE_STOP) { - /* we're done reading chunks! */ - infof(data, "chunk reading DONE\n"); - keepon = FALSE; - /* we did the full CONNECT treatment, go to - COMPLETE */ - conn->tunnel_state[sockindex] = TUNNEL_COMPLETE; - } - else - infof(data, "Read %zd bytes of chunk, continue\n", - gotbytes); - } - else { - /* without content-length or chunked encoding, we - can't keep the connection alive since the close is - the end signal so we bail out at once instead */ - keepon=FALSE; - } - } - else { - keepon = FALSE; - if(200 == data->info.httpproxycode) { - if(gotbytes - (i+1)) - failf(data, "Proxy CONNECT followed by %zd bytes " - "of opaque data. Data ignored (known bug #39)", - gotbytes - (i+1)); - } - } - /* we did the full CONNECT treatment, go to COMPLETE */ - conn->tunnel_state[sockindex] = TUNNEL_COMPLETE; - break; /* breaks out of for-loop, not switch() */ - } - - /* keep a backup of the position we are about to blank */ - letter = line_start[perline]; - line_start[perline]=0; /* zero terminate the buffer */ - if((checkprefix("WWW-Authenticate:", line_start) && - (401 == k->httpcode)) || - (checkprefix("Proxy-authenticate:", line_start) && - (407 == k->httpcode))) { - - bool proxy = (k->httpcode == 407) ? TRUE : FALSE; - char *auth = Curl_copy_header_value(line_start); - if(!auth) - return CURLE_OUT_OF_MEMORY; - - result = Curl_http_input_auth(conn, proxy, auth); - - free(auth); - - if(result) - return result; - } - else if(checkprefix("Content-Length:", line_start)) { - cl = curlx_strtoofft(line_start + - strlen("Content-Length:"), NULL, 10); - } - else if(Curl_compareheader(line_start, - "Connection:", "close")) - closeConnection = TRUE; - else if(Curl_compareheader(line_start, - "Transfer-Encoding:", - "chunked")) { - infof(data, "CONNECT responded chunked\n"); - chunked_encoding = TRUE; - /* init our chunky engine */ - Curl_httpchunk_init(conn); - } - else if(Curl_compareheader(line_start, - "Proxy-Connection:", "close")) - closeConnection = TRUE; - else if(2 == sscanf(line_start, "HTTP/1.%d %d", - &subversion, - &k->httpcode)) { - /* store the HTTP code from the proxy */ - data->info.httpproxycode = k->httpcode; - } - /* put back the letter we blanked out before */ - line_start[perline]= letter; - - perline=0; /* line starts over here */ - line_start = ptr+1; /* this skips the zero byte we wrote */ - } - } - } - break; - } /* switch */ - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; - } /* while there's buffer left and loop is requested */ - - if(error) - return CURLE_RECV_ERROR; - - if(data->info.httpproxycode != 200) { - /* Deal with the possibly already received authenticate - headers. 'newurl' is set to a new URL if we must loop. */ - result = Curl_http_auth_act(conn); - if(result) - return result; - - if(conn->bits.close) - /* the connection has been marked for closure, most likely in the - Curl_http_auth_act() function and thus we can kill it at once - below - */ - closeConnection = TRUE; - } - - if(closeConnection && data->req.newurl) { - /* Connection closed by server. Don't use it anymore */ - Curl_closesocket(conn, conn->sock[sockindex]); - conn->sock[sockindex] = CURL_SOCKET_BAD; - break; - } - } /* END READING RESPONSE PHASE */ - - /* If we are supposed to continue and request a new URL, which basically - * means the HTTP authentication is still going on so if the tunnel - * is complete we start over in INIT state */ - if(data->req.newurl && - (TUNNEL_COMPLETE == conn->tunnel_state[sockindex])) { - conn->tunnel_state[sockindex] = TUNNEL_INIT; - infof(data, "TUNNEL_STATE switched to: %d\n", - conn->tunnel_state[sockindex]); - } - - } while(data->req.newurl); - - if(200 != data->req.httpcode) { - if(closeConnection && data->req.newurl) { - conn->bits.proxy_connect_closed = TRUE; - infof(data, "Connect me again please\n"); - } - else { - free(data->req.newurl); - data->req.newurl = NULL; - /* failure, close this connection to avoid re-use */ - connclose(conn, "proxy CONNECT failure"); - Curl_closesocket(conn, conn->sock[sockindex]); - conn->sock[sockindex] = CURL_SOCKET_BAD; - } - - /* to back to init state */ - conn->tunnel_state[sockindex] = TUNNEL_INIT; - - if(conn->bits.proxy_connect_closed) - /* this is not an error, just part of the connection negotiation */ - return CURLE_OK; - else { - failf(data, "Received HTTP code %d from proxy after CONNECT", - data->req.httpcode); - return CURLE_RECV_ERROR; - } - } - - conn->tunnel_state[sockindex] = TUNNEL_COMPLETE; - - /* If a proxy-authorization header was used for the proxy, then we should - make sure that it isn't accidentally used for the document request - after we've connected. So let's free and clear it here. */ - Curl_safefree(conn->allocptr.proxyuserpwd); - conn->allocptr.proxyuserpwd = NULL; - - data->state.authproxy.done = TRUE; - - infof (data, "Proxy replied OK to CONNECT request\n"); - data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */ - conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the - document request */ - return CURLE_OK; -} -#endif /* CURL_DISABLE_PROXY */ diff --git a/Externals/curl/lib/http_proxy.h b/Externals/curl/lib/http_proxy.h deleted file mode 100644 index fd04330333..0000000000 --- a/Externals/curl/lib/http_proxy.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef HEADER_CURL_HTTP_PROXY_H -#define HEADER_CURL_HTTP_PROXY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP) -/* ftp can use this as well */ -CURLcode Curl_proxyCONNECT(struct connectdata *conn, - int tunnelsocket, - const char *hostname, int remote_port, - bool blocking); - -/* Default proxy timeout in milliseconds */ -#define PROXY_TIMEOUT (3600*1000) - -CURLcode Curl_proxy_connect(struct connectdata *conn); - -#else -#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN -#define Curl_proxy_connect(x) CURLE_OK -#endif - -#endif /* HEADER_CURL_HTTP_PROXY_H */ diff --git a/Externals/curl/lib/idn_win32.c b/Externals/curl/lib/idn_win32.c deleted file mode 100644 index 8dc300b36d..0000000000 --- a/Externals/curl/lib/idn_win32.c +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - - /* - * IDN conversions using Windows kernel32 and normaliz libraries. - */ - -#include "curl_setup.h" - -#ifdef USE_WIN32_IDN - -#include "curl_multibyte.h" -#include "curl_memory.h" -#include "warnless.h" - - /* The last #include file should be: */ -#include "memdebug.h" - -#ifdef WANT_IDN_PROTOTYPES -# if defined(_SAL_VERSION) -WINNORMALIZEAPI int WINAPI -IdnToAscii(_In_ DWORD dwFlags, - _In_reads_(cchUnicodeChar) LPCWSTR lpUnicodeCharStr, - _In_ int cchUnicodeChar, - _Out_writes_opt_(cchASCIIChar) LPWSTR lpASCIICharStr, - _In_ int cchASCIIChar); -WINNORMALIZEAPI int WINAPI -IdnToUnicode(_In_ DWORD dwFlags, - _In_reads_(cchASCIIChar) LPCWSTR lpASCIICharStr, - _In_ int cchASCIIChar, - _Out_writes_opt_(cchUnicodeChar) LPWSTR lpUnicodeCharStr, - _In_ int cchUnicodeChar); -# else -WINBASEAPI int WINAPI IdnToAscii(DWORD dwFlags, - const WCHAR *lpUnicodeCharStr, - int cchUnicodeChar, - WCHAR *lpASCIICharStr, - int cchASCIIChar); -WINBASEAPI int WINAPI IdnToUnicode(DWORD dwFlags, - const WCHAR *lpASCIICharStr, - int cchASCIIChar, - WCHAR *lpUnicodeCharStr, - int cchUnicodeChar); -# endif -#endif - -#define IDN_MAX_LENGTH 255 - -bool curl_win32_idn_to_ascii(const char *in, char **out); -bool curl_win32_ascii_to_idn(const char *in, char **out); - -bool curl_win32_idn_to_ascii(const char *in, char **out) -{ - bool success = FALSE; - - wchar_t *in_w = Curl_convert_UTF8_to_wchar(in); - if(in_w) { - wchar_t punycode[IDN_MAX_LENGTH]; - int chars = IdnToAscii(0, in_w, -1, punycode, IDN_MAX_LENGTH); - free(in_w); - if(chars) { - *out = Curl_convert_wchar_to_UTF8(punycode); - if(*out) - success = TRUE; - } - } - - return success; -} - -bool curl_win32_ascii_to_idn(const char *in, char **out) -{ - bool success = FALSE; - - wchar_t *in_w = Curl_convert_UTF8_to_wchar(in); - if(in_w) { - size_t in_len = wcslen(in_w) + 1; - wchar_t unicode[IDN_MAX_LENGTH]; - int chars = IdnToUnicode(0, in_w, curlx_uztosi(in_len), - unicode, IDN_MAX_LENGTH); - free(in_w); - if(chars) { - *out = Curl_convert_wchar_to_UTF8(unicode); - if(*out) - success = TRUE; - } - } - - return success; -} - -#endif /* USE_WIN32_IDN */ diff --git a/Externals/curl/lib/if2ip.c b/Externals/curl/lib/if2ip.c deleted file mode 100644 index 2f92b2def5..0000000000 --- a/Externals/curl/lib/if2ip.c +++ /dev/null @@ -1,272 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_NET_IF_H -# include -#endif -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_SYS_SOCKIO_H -# include -#endif -#ifdef HAVE_IFADDRS_H -# include -#endif -#ifdef HAVE_STROPTS_H -# include -#endif -#ifdef __VMS -# include -#endif - -#include "inet_ntop.h" -#include "strequal.h" -#include "if2ip.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* ------------------------------------------------------------------ */ - -/* Return the scope of the given address. */ -unsigned int Curl_ipv6_scope(const struct sockaddr *sa) -{ -#ifndef ENABLE_IPV6 - (void) sa; -#else - if(sa->sa_family == AF_INET6) { - const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa; - const unsigned char * b = sa6->sin6_addr.s6_addr; - unsigned short w = (unsigned short) ((b[0] << 8) | b[1]); - - switch(w & 0xFFC0) { - case 0xFE80: - return IPV6_SCOPE_LINKLOCAL; - case 0xFEC0: - return IPV6_SCOPE_SITELOCAL; - case 0x0000: - w = b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | b[7] | b[8] | b[9] | - b[10] | b[11] | b[12] | b[13] | b[14]; - if(w || b[15] != 0x01) - break; - return IPV6_SCOPE_NODELOCAL; - default: - break; - } - } -#endif - - return IPV6_SCOPE_GLOBAL; -} - - -#if defined(HAVE_GETIFADDRS) - -bool Curl_if_is_interface_name(const char *interf) -{ - bool result = FALSE; - - struct ifaddrs *iface, *head; - - if(getifaddrs(&head) >= 0) { - for(iface=head; iface != NULL; iface=iface->ifa_next) { - if(curl_strequal(iface->ifa_name, interf)) { - result = TRUE; - break; - } - } - freeifaddrs(head); - } - return result; -} - -if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int remote_scope_id, const char *interf, - char *buf, int buf_size) -{ - struct ifaddrs *iface, *head; - if2ip_result_t res = IF2IP_NOT_FOUND; - -#ifndef ENABLE_IPV6 - (void) remote_scope; - -#ifndef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - (void) remote_scope_id; -#endif - -#endif - - if(getifaddrs(&head) >= 0) { - for(iface = head; iface != NULL; iface=iface->ifa_next) { - if(iface->ifa_addr != NULL) { - if(iface->ifa_addr->sa_family == af) { - if(curl_strequal(iface->ifa_name, interf)) { - void *addr; - char *ip; - char scope[12] = ""; - char ipstr[64]; -#ifdef ENABLE_IPV6 - if(af == AF_INET6) { - unsigned int scopeid = 0; - unsigned int ifscope = Curl_ipv6_scope(iface->ifa_addr); - - if(ifscope != remote_scope) { - /* We are interested only in interface addresses whose - scope matches the remote address we want to - connect to: global for global, link-local for - link-local, etc... */ - if(res == IF2IP_NOT_FOUND) res = IF2IP_AF_NOT_SUPPORTED; - continue; - } - - addr = - &((struct sockaddr_in6 *)(void *)iface->ifa_addr)->sin6_addr; -#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID - /* Include the scope of this interface as part of the address */ - scopeid = ((struct sockaddr_in6 *)(void *)iface->ifa_addr) - ->sin6_scope_id; - - /* If given, scope id should match. */ - if(remote_scope_id && scopeid != remote_scope_id) { - if(res == IF2IP_NOT_FOUND) - res = IF2IP_AF_NOT_SUPPORTED; - - continue; - } -#endif - if(scopeid) - snprintf(scope, sizeof(scope), "%%%u", scopeid); - } - else -#endif - addr = - &((struct sockaddr_in *)(void *)iface->ifa_addr)->sin_addr; - res = IF2IP_FOUND; - ip = (char *) Curl_inet_ntop(af, addr, ipstr, sizeof(ipstr)); - snprintf(buf, buf_size, "%s%s", ip, scope); - break; - } - } - else if((res == IF2IP_NOT_FOUND) && - curl_strequal(iface->ifa_name, interf)) { - res = IF2IP_AF_NOT_SUPPORTED; - } - } - } - - freeifaddrs(head); - } - - return res; -} - -#elif defined(HAVE_IOCTL_SIOCGIFADDR) - -bool Curl_if_is_interface_name(const char *interf) -{ - /* This is here just to support the old interfaces */ - char buf[256]; - - return (Curl_if2ip(AF_INET, 0 /* unused */, 0, interf, buf, sizeof(buf)) == - IF2IP_NOT_FOUND) ? FALSE : TRUE; -} - -if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int remote_scope_id, const char *interf, - char *buf, int buf_size) -{ - struct ifreq req; - struct in_addr in; - struct sockaddr_in *s; - curl_socket_t dummy; - size_t len; - - (void)remote_scope; - (void)remote_scope_id; - - if(!interf || (af != AF_INET)) - return IF2IP_NOT_FOUND; - - len = strlen(interf); - if(len >= sizeof(req.ifr_name)) - return IF2IP_NOT_FOUND; - - dummy = socket(AF_INET, SOCK_STREAM, 0); - if(CURL_SOCKET_BAD == dummy) - return IF2IP_NOT_FOUND; - - memset(&req, 0, sizeof(req)); - memcpy(req.ifr_name, interf, len+1); - req.ifr_addr.sa_family = AF_INET; - - if(ioctl(dummy, SIOCGIFADDR, &req) < 0) { - sclose(dummy); - /* With SIOCGIFADDR, we cannot tell the difference between an interface - that does not exist and an interface that has no address of the - correct family. Assume the interface does not exist */ - return IF2IP_NOT_FOUND; - } - - s = (struct sockaddr_in *)&req.ifr_addr; - memcpy(&in, &s->sin_addr, sizeof(in)); - Curl_inet_ntop(s->sin_family, &in, buf, buf_size); - - sclose(dummy); - return IF2IP_FOUND; -} - -#else - -bool Curl_if_is_interface_name(const char *interf) -{ - (void) interf; - - return FALSE; -} - -if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int remote_scope_id, const char *interf, - char *buf, int buf_size) -{ - (void) af; - (void) remote_scope; - (void) remote_scope_id; - (void) interf; - (void) buf; - (void) buf_size; - return IF2IP_NOT_FOUND; -} - -#endif diff --git a/Externals/curl/lib/if2ip.h b/Externals/curl/lib/if2ip.h deleted file mode 100644 index f3a7ff0b2f..0000000000 --- a/Externals/curl/lib/if2ip.h +++ /dev/null @@ -1,83 +0,0 @@ -#ifndef HEADER_CURL_IF2IP_H -#define HEADER_CURL_IF2IP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -/* IPv6 address scopes. */ -#define IPV6_SCOPE_GLOBAL 0 /* Global scope. */ -#define IPV6_SCOPE_LINKLOCAL 1 /* Link-local scope. */ -#define IPV6_SCOPE_SITELOCAL 2 /* Site-local scope (deprecated). */ -#define IPV6_SCOPE_NODELOCAL 3 /* Loopback. */ - -unsigned int Curl_ipv6_scope(const struct sockaddr *sa); - -bool Curl_if_is_interface_name(const char *interf); - -typedef enum { - IF2IP_NOT_FOUND = 0, /* Interface not found */ - IF2IP_AF_NOT_SUPPORTED = 1, /* Int. exists but has no address for this af */ - IF2IP_FOUND = 2 /* The address has been stored in "buf" */ -} if2ip_result_t; - -if2ip_result_t Curl_if2ip(int af, unsigned int remote_scope, - unsigned int remote_scope_id, const char *interf, - char *buf, int buf_size); - -#ifdef __INTERIX - -/* Nedelcho Stanev's work-around for SFU 3.0 */ -struct ifreq { -#define IFNAMSIZ 16 -#define IFHWADDRLEN 6 - union { - char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ - } ifr_ifrn; - - union { - struct sockaddr ifru_addr; - struct sockaddr ifru_broadaddr; - struct sockaddr ifru_netmask; - struct sockaddr ifru_hwaddr; - short ifru_flags; - int ifru_metric; - int ifru_mtu; - } ifr_ifru; -}; - -/* This define was added by Daniel to avoid an extra #ifdef INTERIX in the - C code. */ - -#define ifr_name ifr_ifrn.ifrn_name /* interface name */ -#define ifr_addr ifr_ifru.ifru_addr /* address */ -#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ -#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ -#define ifr_flags ifr_ifru.ifru_flags /* flags */ -#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ -#define ifr_metric ifr_ifru.ifru_metric /* metric */ -#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ - -#define SIOCGIFADDR _IOW('s', 102, struct ifreq) /* Get if addr */ - -#endif /* __INTERIX */ - -#endif /* HEADER_CURL_IF2IP_H */ diff --git a/Externals/curl/lib/imap.c b/Externals/curl/lib/imap.c deleted file mode 100644 index 16ba402ca7..0000000000 --- a/Externals/curl/lib/imap.c +++ /dev/null @@ -1,2132 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC2195 CRAM-MD5 authentication - * RFC2595 Using TLS with IMAP, POP3 and ACAP - * RFC2831 DIGEST-MD5 authentication - * RFC3501 IMAPv4 protocol - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * RFC4959 IMAP Extension for SASL Initial Client Response - * RFC5092 IMAP URL Scheme - * RFC6749 OAuth 2.0 Authorization Framework - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_IMAP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_UTSNAME_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "socks.h" -#include "imap.h" - -#include "strtoofft.h" -#include "strequal.h" -#include "vtls/vtls.h" -#include "connect.h" -#include "strerror.h" -#include "select.h" -#include "multiif.h" -#include "url.h" -#include "rawstr.h" -#include "curl_sasl.h" -#include "warnless.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Local API functions */ -static CURLcode imap_regular_transfer(struct connectdata *conn, bool *done); -static CURLcode imap_do(struct connectdata *conn, bool *done); -static CURLcode imap_done(struct connectdata *conn, CURLcode status, - bool premature); -static CURLcode imap_connect(struct connectdata *conn, bool *done); -static CURLcode imap_disconnect(struct connectdata *conn, bool dead); -static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done); -static int imap_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks); -static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done); -static CURLcode imap_setup_connection(struct connectdata *conn); -static char *imap_atom(const char *str, bool escape_only); -static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...); -static CURLcode imap_parse_url_options(struct connectdata *conn); -static CURLcode imap_parse_url_path(struct connectdata *conn); -static CURLcode imap_parse_custom_request(struct connectdata *conn); -static CURLcode imap_perform_authenticate(struct connectdata *conn, - const char *mech, - const char *initresp); -static CURLcode imap_continue_authenticate(struct connectdata *conn, - const char *resp); -static void imap_get_message(char *buffer, char** outptr); - -/* - * IMAP protocol handler. - */ - -const struct Curl_handler Curl_handler_imap = { - "IMAP", /* scheme */ - imap_setup_connection, /* setup_connection */ - imap_do, /* do_it */ - imap_done, /* done */ - ZERO_NULL, /* do_more */ - imap_connect, /* connect_it */ - imap_multi_statemach, /* connecting */ - imap_doing, /* doing */ - imap_getsock, /* proto_getsock */ - imap_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - imap_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_IMAP, /* defport */ - CURLPROTO_IMAP, /* protocol */ - PROTOPT_CLOSEACTION /* flags */ -}; - -#ifdef USE_SSL -/* - * IMAPS protocol handler. - */ - -const struct Curl_handler Curl_handler_imaps = { - "IMAPS", /* scheme */ - imap_setup_connection, /* setup_connection */ - imap_do, /* do_it */ - imap_done, /* done */ - ZERO_NULL, /* do_more */ - imap_connect, /* connect_it */ - imap_multi_statemach, /* connecting */ - imap_doing, /* doing */ - imap_getsock, /* proto_getsock */ - imap_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - imap_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_IMAPS, /* defport */ - CURLPROTO_IMAPS, /* protocol */ - PROTOPT_CLOSEACTION | PROTOPT_SSL /* flags */ -}; -#endif - -#ifndef CURL_DISABLE_HTTP -/* - * HTTP-proxyed IMAP protocol handler. - */ - -static const struct Curl_handler Curl_handler_imap_proxy = { - "IMAP", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_IMAP, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -#ifdef USE_SSL -/* - * HTTP-proxyed IMAPS protocol handler. - */ - -static const struct Curl_handler Curl_handler_imaps_proxy = { - "IMAPS", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_IMAPS, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; -#endif -#endif - -/* SASL parameters for the imap protocol */ -static const struct SASLproto saslimap = { - "imap", /* The service name */ - '+', /* Code received when continuation is expected */ - 'O', /* Code to receive upon authentication success */ - 0, /* Maximum initial response length (no max) */ - imap_perform_authenticate, /* Send authentication command */ - imap_continue_authenticate, /* Send authentication continuation */ - imap_get_message /* Get SASL response message */ -}; - - -#ifdef USE_SSL -static void imap_to_imaps(struct connectdata *conn) -{ - /* Change the connection handler */ - conn->handler = &Curl_handler_imaps; - - /* Set the connection's upgraded to TLS flag */ - conn->tls_upgraded = TRUE; -} -#else -#define imap_to_imaps(x) Curl_nop_stmt -#endif - -/*********************************************************************** - * - * imap_matchresp() - * - * Determines whether the untagged response is related to the specified - * command by checking if it is in format "* ..." or - * "* ...". - * - * The "* " marker is assumed to have already been checked by the caller. - */ -static bool imap_matchresp(const char *line, size_t len, const char *cmd) -{ - const char *end = line + len; - size_t cmd_len = strlen(cmd); - - /* Skip the untagged response marker */ - line += 2; - - /* Do we have a number after the marker? */ - if(line < end && ISDIGIT(*line)) { - /* Skip the number */ - do - line++; - while(line < end && ISDIGIT(*line)); - - /* Do we have the space character? */ - if(line == end || *line != ' ') - return FALSE; - - line++; - } - - /* Does the command name match and is it followed by a space character or at - the end of line? */ - if(line + cmd_len <= end && Curl_raw_nequal(line, cmd, cmd_len) && - (line[cmd_len] == ' ' || line + cmd_len + 2 == end)) - return TRUE; - - return FALSE; -} - -/*********************************************************************** - * - * imap_endofresp() - * - * Checks whether the given string is a valid tagged, untagged or continuation - * response which can be processed by the response handler. - */ -static bool imap_endofresp(struct connectdata *conn, char *line, size_t len, - int *resp) -{ - struct IMAP *imap = conn->data->req.protop; - struct imap_conn *imapc = &conn->proto.imapc; - const char *id = imapc->resptag; - size_t id_len = strlen(id); - - /* Do we have a tagged command response? */ - if(len >= id_len + 1 && !memcmp(id, line, id_len) && line[id_len] == ' ') { - line += id_len + 1; - len -= id_len + 1; - - if(len >= 2 && !memcmp(line, "OK", 2)) - *resp = 'O'; - else if(len >= 2 && !memcmp(line, "NO", 2)) - *resp = 'N'; - else if(len >= 3 && !memcmp(line, "BAD", 3)) - *resp = 'B'; - else { - failf(conn->data, "Bad tagged response"); - *resp = -1; - } - - return TRUE; - } - - /* Do we have an untagged command response? */ - if(len >= 2 && !memcmp("* ", line, 2)) { - switch(imapc->state) { - /* States which are interested in untagged responses */ - case IMAP_CAPABILITY: - if(!imap_matchresp(line, len, "CAPABILITY")) - return FALSE; - break; - - case IMAP_LIST: - if((!imap->custom && !imap_matchresp(line, len, "LIST")) || - (imap->custom && !imap_matchresp(line, len, imap->custom) && - (strcmp(imap->custom, "STORE") || - !imap_matchresp(line, len, "FETCH")) && - strcmp(imap->custom, "SELECT") && - strcmp(imap->custom, "EXAMINE") && - strcmp(imap->custom, "SEARCH") && - strcmp(imap->custom, "EXPUNGE") && - strcmp(imap->custom, "LSUB") && - strcmp(imap->custom, "UID") && - strcmp(imap->custom, "NOOP"))) - return FALSE; - break; - - case IMAP_SELECT: - /* SELECT is special in that its untagged responses do not have a - common prefix so accept anything! */ - break; - - case IMAP_FETCH: - if(!imap_matchresp(line, len, "FETCH")) - return FALSE; - break; - - case IMAP_SEARCH: - if(!imap_matchresp(line, len, "SEARCH")) - return FALSE; - break; - - /* Ignore other untagged responses */ - default: - return FALSE; - } - - *resp = '*'; - return TRUE; - } - - /* Do we have a continuation response? This should be a + symbol followed by - a space and optionally some text as per RFC-3501 for the AUTHENTICATE and - APPEND commands and as outlined in Section 4. Examples of RFC-4959 but - some e-mail servers ignore this and only send a single + instead. */ - if(imap && !imap->custom && ((len == 3 && !memcmp("+", line, 1)) || - (len >= 2 && !memcmp("+ ", line, 2)))) { - switch(imapc->state) { - /* States which are interested in continuation responses */ - case IMAP_AUTHENTICATE: - case IMAP_APPEND: - *resp = '+'; - break; - - default: - failf(conn->data, "Unexpected continuation response"); - *resp = -1; - break; - } - - return TRUE; - } - - return FALSE; /* Nothing for us */ -} - -/*********************************************************************** - * - * imap_get_message() - * - * Gets the authentication message from the response buffer. - */ -static void imap_get_message(char *buffer, char** outptr) -{ - size_t len = 0; - char* message = NULL; - - /* Find the start of the message */ - for(message = buffer + 2; *message == ' ' || *message == '\t'; message++) - ; - - /* Find the end of the message */ - for(len = strlen(message); len--;) - if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && - message[len] != '\t') - break; - - /* Terminate the message */ - if(++len) { - message[len] = '\0'; - } - - *outptr = message; -} - -/*********************************************************************** - * - * state() - * - * This is the ONLY way to change IMAP state! - */ -static void state(struct connectdata *conn, imapstate newstate) -{ - struct imap_conn *imapc = &conn->proto.imapc; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char * const names[]={ - "STOP", - "SERVERGREET", - "CAPABILITY", - "STARTTLS", - "UPGRADETLS", - "AUTHENTICATE", - "LOGIN", - "LIST", - "SELECT", - "FETCH", - "FETCH_FINAL", - "APPEND", - "APPEND_FINAL", - "SEARCH", - "LOGOUT", - /* LAST */ - }; - - if(imapc->state != newstate) - infof(conn->data, "IMAP %p state change from %s to %s\n", - (void *)imapc, names[imapc->state], names[newstate]); -#endif - - imapc->state = newstate; -} - -/*********************************************************************** - * - * imap_perform_capability() - * - * Sends the CAPABILITY command in order to obtain a list of server side - * supported capabilities. - */ -static CURLcode imap_perform_capability(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - - imapc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */ - imapc->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */ - imapc->tls_supported = FALSE; /* Clear the TLS capability */ - - /* Send the CAPABILITY command */ - result = imap_sendf(conn, "CAPABILITY"); - - if(!result) - state(conn, IMAP_CAPABILITY); - - return result; -} - -/*********************************************************************** - * - * imap_perform_starttls() - * - * Sends the STARTTLS command to start the upgrade to TLS. - */ -static CURLcode imap_perform_starttls(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* Send the STARTTLS command */ - result = imap_sendf(conn, "STARTTLS"); - - if(!result) - state(conn, IMAP_STARTTLS); - - return result; -} - -/*********************************************************************** - * - * imap_perform_upgrade_tls() - * - * Performs the upgrade to TLS. - */ -static CURLcode imap_perform_upgrade_tls(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - - /* Start the SSL connection */ - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone); - - if(!result) { - if(imapc->state != IMAP_UPGRADETLS) - state(conn, IMAP_UPGRADETLS); - - if(imapc->ssldone) { - imap_to_imaps(conn); - result = imap_perform_capability(conn); - } - } - - return result; -} - -/*********************************************************************** - * - * imap_perform_login() - * - * Sends a clear text LOGIN command to authenticate with. - */ -static CURLcode imap_perform_login(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - char *user; - char *passwd; - - /* Check we have a username and password to authenticate with and end the - connect phase if we don't */ - if(!conn->bits.user_passwd) { - state(conn, IMAP_STOP); - - return result; - } - - /* Make sure the username and password are in the correct atom format */ - user = imap_atom(conn->user, false); - passwd = imap_atom(conn->passwd, false); - - /* Send the LOGIN command */ - result = imap_sendf(conn, "LOGIN %s %s", user ? user : "", - passwd ? passwd : ""); - - free(user); - free(passwd); - - if(!result) - state(conn, IMAP_LOGIN); - - return result; -} - -/*********************************************************************** - * - * imap_perform_authenticate() - * - * Sends an AUTHENTICATE command allowing the client to login with the given - * SASL authentication mechanism. - */ -static CURLcode imap_perform_authenticate(struct connectdata *conn, - const char *mech, - const char *initresp) -{ - CURLcode result = CURLE_OK; - - if(initresp) { - /* Send the AUTHENTICATE command with the initial response */ - result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp); - } - else { - /* Send the AUTHENTICATE command */ - result = imap_sendf(conn, "AUTHENTICATE %s", mech); - } - - return result; -} - -/*********************************************************************** - * - * imap_continue_authenticate() - * - * Sends SASL continuation data or cancellation. - */ -static CURLcode imap_continue_authenticate(struct connectdata *conn, - const char *resp) -{ - struct imap_conn *imapc = &conn->proto.imapc; - - return Curl_pp_sendf(&imapc->pp, "%s", resp); -} - -/*********************************************************************** - * - * imap_perform_authentication() - * - * Initiates the authentication sequence, with the appropriate SASL - * authentication mechanism, falling back to clear text should a common - * mechanism not be available between the client and server. - */ -static CURLcode imap_perform_authentication(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - saslprogress progress; - - /* Check we have enough data to authenticate with and end the - connect phase if we don't */ - if(!Curl_sasl_can_authenticate(&imapc->sasl, conn)) { - state(conn, IMAP_STOP); - return result; - } - - /* Calculate the SASL login details */ - result = Curl_sasl_start(&imapc->sasl, conn, imapc->ir_supported, &progress); - - if(!result) { - if(progress == SASL_INPROGRESS) - state(conn, IMAP_AUTHENTICATE); - else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) - /* Perform clear text authentication */ - result = imap_perform_login(conn); - else { - /* Other mechanisms not supported */ - infof(conn->data, "No known authentication mechanisms supported!\n"); - result = CURLE_LOGIN_DENIED; - } - } - - return result; -} - -/*********************************************************************** - * - * imap_perform_list() - * - * Sends a LIST command or an alternative custom request. - */ -static CURLcode imap_perform_list(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap = data->req.protop; - char *mailbox; - - if(imap->custom) - /* Send the custom request */ - result = imap_sendf(conn, "%s%s", imap->custom, - imap->custom_params ? imap->custom_params : ""); - else { - /* Make sure the mailbox is in the correct atom format if necessary */ - mailbox = imap->mailbox ? imap_atom(imap->mailbox, true) : strdup(""); - if(!mailbox) - return CURLE_OUT_OF_MEMORY; - - /* Send the LIST command */ - result = imap_sendf(conn, "LIST \"%s\" *", mailbox); - - free(mailbox); - } - - if(!result) - state(conn, IMAP_LIST); - - return result; -} - -/*********************************************************************** - * - * imap_perform_select() - * - * Sends a SELECT command to ask the server to change the selected mailbox. - */ -static CURLcode imap_perform_select(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap = data->req.protop; - struct imap_conn *imapc = &conn->proto.imapc; - char *mailbox; - - /* Invalidate old information as we are switching mailboxes */ - Curl_safefree(imapc->mailbox); - Curl_safefree(imapc->mailbox_uidvalidity); - - /* Check we have a mailbox */ - if(!imap->mailbox) { - failf(conn->data, "Cannot SELECT without a mailbox."); - return CURLE_URL_MALFORMAT; - } - - /* Make sure the mailbox is in the correct atom format */ - mailbox = imap_atom(imap->mailbox, false); - if(!mailbox) - return CURLE_OUT_OF_MEMORY; - - /* Send the SELECT command */ - result = imap_sendf(conn, "SELECT %s", mailbox); - - free(mailbox); - - if(!result) - state(conn, IMAP_SELECT); - - return result; -} - -/*********************************************************************** - * - * imap_perform_fetch() - * - * Sends a FETCH command to initiate the download of a message. - */ -static CURLcode imap_perform_fetch(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct IMAP *imap = conn->data->req.protop; - - /* Check we have a UID */ - if(!imap->uid) { - failf(conn->data, "Cannot FETCH without a UID."); - return CURLE_URL_MALFORMAT; - } - - /* Send the FETCH command */ - if(imap->partial) - result = imap_sendf(conn, "FETCH %s BODY[%s]<%s>", - imap->uid, - imap->section ? imap->section : "", - imap->partial); - else - result = imap_sendf(conn, "FETCH %s BODY[%s]", - imap->uid, - imap->section ? imap->section : ""); - - if(!result) - state(conn, IMAP_FETCH); - - return result; -} - -/*********************************************************************** - * - * imap_perform_append() - * - * Sends an APPEND command to initiate the upload of a message. - */ -static CURLcode imap_perform_append(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct IMAP *imap = conn->data->req.protop; - char *mailbox; - - /* Check we have a mailbox */ - if(!imap->mailbox) { - failf(conn->data, "Cannot APPEND without a mailbox."); - return CURLE_URL_MALFORMAT; - } - - /* Check we know the size of the upload */ - if(conn->data->state.infilesize < 0) { - failf(conn->data, "Cannot APPEND with unknown input file size\n"); - return CURLE_UPLOAD_FAILED; - } - - /* Make sure the mailbox is in the correct atom format */ - mailbox = imap_atom(imap->mailbox, false); - if(!mailbox) - return CURLE_OUT_OF_MEMORY; - - /* Send the APPEND command */ - result = imap_sendf(conn, "APPEND %s (\\Seen) {%" CURL_FORMAT_CURL_OFF_T "}", - mailbox, conn->data->state.infilesize); - - free(mailbox); - - if(!result) - state(conn, IMAP_APPEND); - - return result; -} - -/*********************************************************************** - * - * imap_perform_search() - * - * Sends a SEARCH command. - */ -static CURLcode imap_perform_search(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct IMAP *imap = conn->data->req.protop; - - /* Check we have a query string */ - if(!imap->query) { - failf(conn->data, "Cannot SEARCH without a query string."); - return CURLE_URL_MALFORMAT; - } - - /* Send the SEARCH command */ - result = imap_sendf(conn, "SEARCH %s", imap->query); - - if(!result) - state(conn, IMAP_SEARCH); - - return result; -} - -/*********************************************************************** - * - * imap_perform_logout() - * - * Performs the logout action prior to sclose() being called. - */ -static CURLcode imap_perform_logout(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* Send the LOGOUT command */ - result = imap_sendf(conn, "LOGOUT"); - - if(!result) - state(conn, IMAP_LOGOUT); - - return result; -} - -/* For the initial server greeting */ -static CURLcode imap_state_servergreet_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(imapcode != 'O') { - failf(data, "Got unexpected imap-server response"); - result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */ - } - else - result = imap_perform_capability(conn); - - return result; -} - -/* For CAPABILITY responses */ -static CURLcode imap_state_capability_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct imap_conn *imapc = &conn->proto.imapc; - const char *line = data->state.buffer; - size_t wordlen; - - (void)instate; /* no use for this yet */ - - /* Do we have a untagged response? */ - if(imapcode == '*') { - line += 2; - - /* Loop through the data line */ - for(;;) { - while(*line && - (*line == ' ' || *line == '\t' || - *line == '\r' || *line == '\n')) { - - line++; - } - - if(!*line) - break; - - /* Extract the word */ - for(wordlen = 0; line[wordlen] && line[wordlen] != ' ' && - line[wordlen] != '\t' && line[wordlen] != '\r' && - line[wordlen] != '\n';) - wordlen++; - - /* Does the server support the STARTTLS capability? */ - if(wordlen == 8 && !memcmp(line, "STARTTLS", 8)) - imapc->tls_supported = TRUE; - - /* Has the server explicitly disabled clear text authentication? */ - else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13)) - imapc->login_disabled = TRUE; - - /* Does the server support the SASL-IR capability? */ - else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7)) - imapc->ir_supported = TRUE; - - /* Do we have a SASL based authentication mechanism? */ - else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) { - size_t llen; - unsigned int mechbit; - - line += 5; - wordlen -= 5; - - /* Test the word for a matching authentication mechanism */ - mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); - if(mechbit && llen == wordlen) - imapc->sasl.authmechs |= mechbit; - } - - line += wordlen; - } - } - else if(imapcode == 'O') { - if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { - /* We don't have a SSL/TLS connection yet, but SSL is requested */ - if(imapc->tls_supported) - /* Switch to TLS connection now */ - result = imap_perform_starttls(conn); - else if(data->set.use_ssl == CURLUSESSL_TRY) - /* Fallback and carry on with authentication */ - result = imap_perform_authentication(conn); - else { - failf(data, "STARTTLS not supported."); - result = CURLE_USE_SSL_FAILED; - } - } - else - result = imap_perform_authentication(conn); - } - else - result = imap_perform_authentication(conn); - - return result; -} - -/* For STARTTLS responses */ -static CURLcode imap_state_starttls_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(imapcode != 'O') { - if(data->set.use_ssl != CURLUSESSL_TRY) { - failf(data, "STARTTLS denied. %c", imapcode); - result = CURLE_USE_SSL_FAILED; - } - else - result = imap_perform_authentication(conn); - } - else - result = imap_perform_upgrade_tls(conn); - - return result; -} - -/* For SASL authentication responses */ -static CURLcode imap_state_auth_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct imap_conn *imapc = &conn->proto.imapc; - saslprogress progress; - - (void)instate; /* no use for this yet */ - - result = Curl_sasl_continue(&imapc->sasl, conn, imapcode, &progress); - if(!result) - switch(progress) { - case SASL_DONE: - state(conn, IMAP_STOP); /* Authenticated */ - break; - case SASL_IDLE: /* No mechanism left after cancellation */ - if((!imapc->login_disabled) && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) - /* Perform clear text authentication */ - result = imap_perform_login(conn); - else { - failf(data, "Authentication cancelled"); - result = CURLE_LOGIN_DENIED; - } - break; - default: - break; - } - - return result; -} - -/* For LOGIN responses */ -static CURLcode imap_state_login_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(imapcode != 'O') { - failf(data, "Access denied. %c", imapcode); - result = CURLE_LOGIN_DENIED; - } - else - /* End of connect phase */ - state(conn, IMAP_STOP); - - return result; -} - -/* For LIST and SEARCH responses */ -static CURLcode imap_state_listsearch_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - char *line = conn->data->state.buffer; - size_t len = strlen(line); - - (void)instate; /* No use for this yet */ - - if(imapcode == '*') { - /* Temporarily add the LF character back and send as body to the client */ - line[len] = '\n'; - result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1); - line[len] = '\0'; - } - else if(imapcode != 'O') - result = CURLE_QUOTE_ERROR; /* TODO: Fix error code */ - else - /* End of DO phase */ - state(conn, IMAP_STOP); - - return result; -} - -/* For SELECT responses */ -static CURLcode imap_state_select_resp(struct connectdata *conn, int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap = conn->data->req.protop; - struct imap_conn *imapc = &conn->proto.imapc; - const char *line = data->state.buffer; - char tmp[20]; - - (void)instate; /* no use for this yet */ - - if(imapcode == '*') { - /* See if this is an UIDVALIDITY response */ - if(sscanf(line + 2, "OK [UIDVALIDITY %19[0123456789]]", tmp) == 1) { - Curl_safefree(imapc->mailbox_uidvalidity); - imapc->mailbox_uidvalidity = strdup(tmp); - } - } - else if(imapcode == 'O') { - /* Check if the UIDVALIDITY has been specified and matches */ - if(imap->uidvalidity && imapc->mailbox_uidvalidity && - strcmp(imap->uidvalidity, imapc->mailbox_uidvalidity)) { - failf(conn->data, "Mailbox UIDVALIDITY has changed"); - result = CURLE_REMOTE_FILE_NOT_FOUND; - } - else { - /* Note the currently opened mailbox on this connection */ - imapc->mailbox = strdup(imap->mailbox); - - if(imap->custom) - result = imap_perform_list(conn); - else if(imap->query) - result = imap_perform_search(conn); - else - result = imap_perform_fetch(conn); - } - } - else { - failf(data, "Select failed"); - result = CURLE_LOGIN_DENIED; - } - - return result; -} - -/* For the (first line of the) FETCH responses */ -static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct imap_conn *imapc = &conn->proto.imapc; - struct pingpong *pp = &imapc->pp; - const char *ptr = data->state.buffer; - bool parsed = FALSE; - curl_off_t size = 0; - - (void)instate; /* no use for this yet */ - - if(imapcode != '*') { - Curl_pgrsSetDownloadSize(data, -1); - state(conn, IMAP_STOP); - return CURLE_REMOTE_FILE_NOT_FOUND; /* TODO: Fix error code */ - } - - /* Something like this is received "* 1 FETCH (BODY[TEXT] {2021}\r" so parse - the continuation data contained within the curly brackets */ - while(*ptr && (*ptr != '{')) - ptr++; - - if(*ptr == '{') { - char *endptr; - size = curlx_strtoofft(ptr + 1, &endptr, 10); - if(endptr - ptr > 1 && endptr[0] == '}' && - endptr[1] == '\r' && endptr[2] == '\0') - parsed = TRUE; - } - - if(parsed) { - infof(data, "Found %" CURL_FORMAT_CURL_OFF_TU " bytes to download\n", - size); - Curl_pgrsSetDownloadSize(data, size); - - if(pp->cache) { - /* At this point there is a bunch of data in the header "cache" that is - actually body content, send it as body and then skip it. Do note - that there may even be additional "headers" after the body. */ - size_t chunk = pp->cache_size; - - if(chunk > (size_t)size) - /* The conversion from curl_off_t to size_t is always fine here */ - chunk = (size_t)size; - - result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk); - if(result) - return result; - - data->req.bytecount += chunk; - - infof(data, "Written %" CURL_FORMAT_CURL_OFF_TU - " bytes, %" CURL_FORMAT_CURL_OFF_TU - " bytes are left for transfer\n", (curl_off_t)chunk, - size - chunk); - - /* Have we used the entire cache or just part of it?*/ - if(pp->cache_size > chunk) { - /* Only part of it so shrink the cache to fit the trailing data */ - memmove(pp->cache, pp->cache + chunk, pp->cache_size - chunk); - pp->cache_size -= chunk; - } - else { - /* Free the cache */ - Curl_safefree(pp->cache); - - /* Reset the cache size */ - pp->cache_size = 0; - } - } - - if(data->req.bytecount == size) - /* The entire data is already transferred! */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - else { - /* IMAP download */ - data->req.maxdownload = size; - Curl_setup_transfer(conn, FIRSTSOCKET, size, FALSE, NULL, -1, NULL); - } - } - else { - /* We don't know how to parse this line */ - failf(pp->conn->data, "Failed to parse FETCH response."); - result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: fix this code */ - } - - /* End of DO phase */ - state(conn, IMAP_STOP); - - return result; -} - -/* For final FETCH responses performed after the download */ -static CURLcode imap_state_fetch_final_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - - (void)instate; /* No use for this yet */ - - if(imapcode != 'O') - result = CURLE_FTP_WEIRD_SERVER_REPLY; /* TODO: Fix error code */ - else - /* End of DONE phase */ - state(conn, IMAP_STOP); - - return result; -} - -/* For APPEND responses */ -static CURLcode imap_state_append_resp(struct connectdata *conn, int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* No use for this yet */ - - if(imapcode != '+') { - result = CURLE_UPLOAD_FAILED; - } - else { - /* Set the progress upload size */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* IMAP upload */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); - - /* End of DO phase */ - state(conn, IMAP_STOP); - } - - return result; -} - -/* For final APPEND responses performed after the upload */ -static CURLcode imap_state_append_final_resp(struct connectdata *conn, - int imapcode, - imapstate instate) -{ - CURLcode result = CURLE_OK; - - (void)instate; /* No use for this yet */ - - if(imapcode != 'O') - result = CURLE_UPLOAD_FAILED; - else - /* End of DONE phase */ - state(conn, IMAP_STOP); - - return result; -} - -static CURLcode imap_statemach_act(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int imapcode; - struct imap_conn *imapc = &conn->proto.imapc; - struct pingpong *pp = &imapc->pp; - size_t nread = 0; - - /* Busy upgrading the connection; right now all I/O is SSL/TLS, not IMAP */ - if(imapc->state == IMAP_UPGRADETLS) - return imap_perform_upgrade_tls(conn); - - /* Flush any data that needs to be sent */ - if(pp->sendleft) - return Curl_pp_flushsend(pp); - - do { - /* Read the response from the server */ - result = Curl_pp_readresp(sock, pp, &imapcode, &nread); - if(result) - return result; - - /* Was there an error parsing the response line? */ - if(imapcode == -1) - return CURLE_FTP_WEIRD_SERVER_REPLY; - - if(!imapcode) - break; - - /* We have now received a full IMAP server response */ - switch(imapc->state) { - case IMAP_SERVERGREET: - result = imap_state_servergreet_resp(conn, imapcode, imapc->state); - break; - - case IMAP_CAPABILITY: - result = imap_state_capability_resp(conn, imapcode, imapc->state); - break; - - case IMAP_STARTTLS: - result = imap_state_starttls_resp(conn, imapcode, imapc->state); - break; - - case IMAP_AUTHENTICATE: - result = imap_state_auth_resp(conn, imapcode, imapc->state); - break; - - case IMAP_LOGIN: - result = imap_state_login_resp(conn, imapcode, imapc->state); - break; - - case IMAP_LIST: - result = imap_state_listsearch_resp(conn, imapcode, imapc->state); - break; - - case IMAP_SELECT: - result = imap_state_select_resp(conn, imapcode, imapc->state); - break; - - case IMAP_FETCH: - result = imap_state_fetch_resp(conn, imapcode, imapc->state); - break; - - case IMAP_FETCH_FINAL: - result = imap_state_fetch_final_resp(conn, imapcode, imapc->state); - break; - - case IMAP_APPEND: - result = imap_state_append_resp(conn, imapcode, imapc->state); - break; - - case IMAP_APPEND_FINAL: - result = imap_state_append_final_resp(conn, imapcode, imapc->state); - break; - - case IMAP_SEARCH: - result = imap_state_listsearch_resp(conn, imapcode, imapc->state); - break; - - case IMAP_LOGOUT: - /* fallthrough, just stop! */ - default: - /* internal error */ - state(conn, IMAP_STOP); - break; - } - } while(!result && imapc->state != IMAP_STOP && Curl_pp_moredata(pp)); - - return result; -} - -/* Called repeatedly until done from multi.c */ -static CURLcode imap_multi_statemach(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - - if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) { - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &imapc->ssldone); - if(result || !imapc->ssldone) - return result; - } - - result = Curl_pp_statemach(&imapc->pp, FALSE); - *done = (imapc->state == IMAP_STOP) ? TRUE : FALSE; - - return result; -} - -static CURLcode imap_block_statemach(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - - while(imapc->state != IMAP_STOP && !result) - result = Curl_pp_statemach(&imapc->pp, TRUE); - - return result; -} - -/* Allocate and initialize the struct IMAP for the current SessionHandle if - required */ -static CURLcode imap_init(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap; - - imap = data->req.protop = calloc(sizeof(struct IMAP), 1); - if(!imap) - result = CURLE_OUT_OF_MEMORY; - - return result; -} - -/* For the IMAP "protocol connect" and "doing" phases only */ -static int imap_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks) -{ - return Curl_pp_getsock(&conn->proto.imapc.pp, socks, numsocks); -} - -/*********************************************************************** - * - * imap_connect() - * - * This function should do everything that is to be considered a part of the - * connection phase. - * - * The variable 'done' points to will be TRUE if the protocol-layer connect - * phase is done when this function returns, or FALSE if not. - */ -static CURLcode imap_connect(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - struct pingpong *pp = &imapc->pp; - - *done = FALSE; /* default to not done yet */ - - /* We always support persistent connections in IMAP */ - connkeep(conn, "IMAP default"); - - /* Set the default response time-out */ - pp->response_time = RESP_TIMEOUT; - pp->statemach_act = imap_statemach_act; - pp->endofresp = imap_endofresp; - pp->conn = conn; - - /* Set the default preferred authentication type and mechanism */ - imapc->preftype = IMAP_TYPE_ANY; - Curl_sasl_init(&imapc->sasl, &saslimap); - - /* Initialise the pingpong layer */ - Curl_pp_init(pp); - - /* Parse the URL options */ - result = imap_parse_url_options(conn); - if(result) - return result; - - /* Start off waiting for the server greeting response */ - state(conn, IMAP_SERVERGREET); - - /* Start off with an response id of '*' */ - strcpy(imapc->resptag, "*"); - - result = imap_multi_statemach(conn, done); - - return result; -} - -/*********************************************************************** - * - * imap_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode imap_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap = data->req.protop; - - (void)premature; - - if(!imap) - return CURLE_OK; - - if(status) { - connclose(conn, "IMAP done with bad status"); /* marked for closure */ - result = status; /* use the already set error code */ - } - else if(!data->set.connect_only && !imap->custom && - (imap->uid || data->set.upload)) { - /* Handle responses after FETCH or APPEND transfer has finished */ - if(!data->set.upload) - state(conn, IMAP_FETCH_FINAL); - else { - /* End the APPEND command first by sending an empty line */ - result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", ""); - if(!result) - state(conn, IMAP_APPEND_FINAL); - } - - /* Run the state-machine - - TODO: when the multi interface is used, this _really_ should be using - the imap_multi_statemach function but we have no general support for - non-blocking DONE operations! - */ - if(!result) - result = imap_block_statemach(conn); - } - - /* Cleanup our per-request based variables */ - Curl_safefree(imap->mailbox); - Curl_safefree(imap->uidvalidity); - Curl_safefree(imap->uid); - Curl_safefree(imap->section); - Curl_safefree(imap->partial); - Curl_safefree(imap->query); - Curl_safefree(imap->custom); - Curl_safefree(imap->custom_params); - - /* Clear the transfer mode for the next request */ - imap->transfer = FTPTRANSFER_BODY; - - return result; -} - -/*********************************************************************** - * - * imap_perform() - * - * This is the actual DO function for IMAP. Fetch or append a message, or do - * other things according to the options previously setup. - */ -static CURLcode imap_perform(struct connectdata *conn, bool *connected, - bool *dophase_done) -{ - /* This is IMAP and no proxy */ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap = data->req.protop; - struct imap_conn *imapc = &conn->proto.imapc; - bool selected = FALSE; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - if(conn->data->set.opt_no_body) { - /* Requested no body means no transfer */ - imap->transfer = FTPTRANSFER_INFO; - } - - *dophase_done = FALSE; /* not done yet */ - - /* Determine if the requested mailbox (with the same UIDVALIDITY if set) - has already been selected on this connection */ - if(imap->mailbox && imapc->mailbox && - !strcmp(imap->mailbox, imapc->mailbox) && - (!imap->uidvalidity || !imapc->mailbox_uidvalidity || - !strcmp(imap->uidvalidity, imapc->mailbox_uidvalidity))) - selected = TRUE; - - /* Start the first command in the DO phase */ - if(conn->data->set.upload) - /* APPEND can be executed directly */ - result = imap_perform_append(conn); - else if(imap->custom && (selected || !imap->mailbox)) - /* Custom command using the same mailbox or no mailbox */ - result = imap_perform_list(conn); - else if(!imap->custom && selected && imap->uid) - /* FETCH from the same mailbox */ - result = imap_perform_fetch(conn); - else if(!imap->custom && selected && imap->query) - /* SEARCH the current mailbox */ - result = imap_perform_search(conn); - else if(imap->mailbox && !selected && - (imap->custom || imap->uid || imap->query)) - /* SELECT the mailbox */ - result = imap_perform_select(conn); - else - /* LIST */ - result = imap_perform_list(conn); - - if(result) - return result; - - /* Run the state-machine */ - result = imap_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) - DEBUGF(infof(conn->data, "DO phase is complete\n")); - - return result; -} - -/*********************************************************************** - * - * imap_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (imap_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode imap_do(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - - *done = FALSE; /* default to false */ - - /* Parse the URL path */ - result = imap_parse_url_path(conn); - if(result) - return result; - - /* Parse the custom request */ - result = imap_parse_custom_request(conn); - if(result) - return result; - - result = imap_regular_transfer(conn, done); - - return result; -} - -/*********************************************************************** - * - * imap_disconnect() - * - * Disconnect from an IMAP server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode imap_disconnect(struct connectdata *conn, bool dead_connection) -{ - struct imap_conn *imapc = &conn->proto.imapc; - - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. */ - - /* The IMAP session may or may not have been allocated/setup at this - point! */ - if(!dead_connection && imapc->pp.conn && imapc->pp.conn->bits.protoconnstart) - if(!imap_perform_logout(conn)) - (void)imap_block_statemach(conn); /* ignore errors on LOGOUT */ - - /* Disconnect from the server */ - Curl_pp_disconnect(&imapc->pp); - - /* Cleanup the SASL module */ - Curl_sasl_cleanup(conn, imapc->sasl.authused); - - /* Cleanup our connection based variables */ - Curl_safefree(imapc->mailbox); - Curl_safefree(imapc->mailbox_uidvalidity); - - return CURLE_OK; -} - -/* Call this when the DO phase has completed */ -static CURLcode imap_dophase_done(struct connectdata *conn, bool connected) -{ - struct IMAP *imap = conn->data->req.protop; - - (void)connected; - - if(imap->transfer != FTPTRANSFER_BODY) - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - - return CURLE_OK; -} - -/* Called from multi.c while DOing */ -static CURLcode imap_doing(struct connectdata *conn, bool *dophase_done) -{ - CURLcode result = imap_multi_statemach(conn, dophase_done); - - if(result) - DEBUGF(infof(conn->data, "DO phase failed\n")); - else if(*dophase_done) { - result = imap_dophase_done(conn, FALSE /* not connected */); - - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/*********************************************************************** - * - * imap_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - */ -static CURLcode imap_regular_transfer(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - bool connected = FALSE; - struct SessionHandle *data = conn->data; - - /* Make sure size is unknown at this point */ - data->req.size = -1; - - /* Set the progress data */ - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - - /* Carry out the perform */ - result = imap_perform(conn, &connected, dophase_done); - - /* Perform post DO phase operations if necessary */ - if(!result && *dophase_done) - result = imap_dophase_done(conn, connected); - - return result; -} - -static CURLcode imap_setup_connection(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - - /* Initialise the IMAP layer */ - CURLcode result = imap_init(conn); - if(result) - return result; - - /* Clear the TLS upgraded flag */ - conn->tls_upgraded = FALSE; - - /* Set up the proxy if necessary */ - if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) { - /* Unless we have asked to tunnel IMAP operations through the proxy, we - switch and use HTTP operations only */ -#ifndef CURL_DISABLE_HTTP - if(conn->handler == &Curl_handler_imap) - conn->handler = &Curl_handler_imap_proxy; - else { -#ifdef USE_SSL - conn->handler = &Curl_handler_imaps_proxy; -#else - failf(data, "IMAPS not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - /* set it up as an HTTP connection instead */ - return conn->handler->setup_connection(conn); -#else - failf(data, "IMAP over http proxy requires HTTP support built-in!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - data->state.path++; /* don't include the initial slash */ - - return CURLE_OK; -} - -/*********************************************************************** - * - * imap_sendf() - * - * Sends the formated string as an IMAP command to the server. - * - * Designed to never block. - */ -static CURLcode imap_sendf(struct connectdata *conn, const char *fmt, ...) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - char *taggedfmt; - va_list ap; - - DEBUGASSERT(fmt); - - /* Calculate the next command ID wrapping at 3 digits */ - imapc->cmdid = (imapc->cmdid + 1) % 1000; - - /* Calculate the tag based on the connection ID and command ID */ - snprintf(imapc->resptag, sizeof(imapc->resptag), "%c%03d", - 'A' + curlx_sltosi(conn->connection_id % 26), imapc->cmdid); - - /* Prefix the format with the tag */ - taggedfmt = aprintf("%s %s", imapc->resptag, fmt); - if(!taggedfmt) - return CURLE_OUT_OF_MEMORY; - - /* Send the data with the tag */ - va_start(ap, fmt); - result = Curl_pp_vsendf(&imapc->pp, taggedfmt, ap); - va_end(ap); - - free(taggedfmt); - - return result; -} - -/*********************************************************************** - * - * imap_atom() - * - * Checks the input string for characters that need escaping and returns an - * atom ready for sending to the server. - * - * The returned string needs to be freed. - * - */ -static char *imap_atom(const char *str, bool escape_only) -{ - /* !checksrc! disable PARENBRACE 1 */ - const char atom_specials[] = "(){ %*]"; - const char *p1; - char *p2; - size_t backsp_count = 0; - size_t quote_count = 0; - bool others_exists = FALSE; - size_t newlen = 0; - char *newstr = NULL; - - if(!str) - return NULL; - - /* Look for "atom-specials", counting the backslash and quote characters as - these will need escapping */ - p1 = str; - while(*p1) { - if(*p1 == '\\') - backsp_count++; - else if(*p1 == '"') - quote_count++; - else if(!escape_only) { - const char *p3 = atom_specials; - - while(*p3 && !others_exists) { - if(*p1 == *p3) - others_exists = TRUE; - - p3++; - } - } - - p1++; - } - - /* Does the input contain any "atom-special" characters? */ - if(!backsp_count && !quote_count && !others_exists) - return strdup(str); - - /* Calculate the new string length */ - newlen = strlen(str) + backsp_count + quote_count + (others_exists ? 2 : 0); - - /* Allocate the new string */ - newstr = (char *) malloc((newlen + 1) * sizeof(char)); - if(!newstr) - return NULL; - - /* Surround the string in quotes if necessary */ - p2 = newstr; - if(others_exists) { - newstr[0] = '"'; - newstr[newlen - 1] = '"'; - p2++; - } - - /* Copy the string, escaping backslash and quote characters along the way */ - p1 = str; - while(*p1) { - if(*p1 == '\\' || *p1 == '"') { - *p2 = '\\'; - p2++; - } - - *p2 = *p1; - - p1++; - p2++; - } - - /* Terminate the string */ - newstr[newlen] = '\0'; - - return newstr; -} - -/*********************************************************************** - * - * imap_is_bchar() - * - * Portable test of whether the specified char is a "bchar" as defined in the - * grammar of RFC-5092. - */ -static bool imap_is_bchar(char ch) -{ - switch(ch) { - /* bchar */ - case ':': case '@': case '/': - /* bchar -> achar */ - case '&': case '=': - /* bchar -> achar -> uchar -> unreserved */ - case '0': case '1': case '2': case '3': case '4': case '5': case '6': - case '7': case '8': case '9': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': - case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': - case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': - case 'V': case 'W': case 'X': case 'Y': case 'Z': - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': - case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': - case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': - case 'v': case 'w': case 'x': case 'y': case 'z': - case '-': case '.': case '_': case '~': - /* bchar -> achar -> uchar -> sub-delims-sh */ - case '!': case '$': case '\'': case '(': case ')': case '*': - case '+': case ',': - /* bchar -> achar -> uchar -> pct-encoded */ - case '%': /* HEXDIG chars are already included above */ - return true; - - default: - return false; - } -} - -/*********************************************************************** - * - * imap_parse_url_options() - * - * Parse the URL login options. - */ -static CURLcode imap_parse_url_options(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct imap_conn *imapc = &conn->proto.imapc; - const char *ptr = conn->options; - - imapc->sasl.resetprefs = TRUE; - - while(!result && ptr && *ptr) { - const char *key = ptr; - const char *value; - - while(*ptr && *ptr != '=') - ptr++; - - value = ptr + 1; - - while(*ptr && *ptr != ';') - ptr++; - - if(strnequal(key, "AUTH=", 5)) - result = Curl_sasl_parse_url_auth_option(&imapc->sasl, - value, ptr - value); - else - result = CURLE_URL_MALFORMAT; - - if(*ptr == ';') - ptr++; - } - - switch(imapc->sasl.prefmech) { - case SASL_AUTH_NONE: - imapc->preftype = IMAP_TYPE_NONE; - break; - case SASL_AUTH_DEFAULT: - imapc->preftype = IMAP_TYPE_ANY; - break; - default: - imapc->preftype = IMAP_TYPE_SASL; - break; - } - - return result; -} - -/*********************************************************************** - * - * imap_parse_url_path() - * - * Parse the URL path into separate path components. - * - */ -static CURLcode imap_parse_url_path(struct connectdata *conn) -{ - /* The imap struct is already initialised in imap_connect() */ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap = data->req.protop; - const char *begin = data->state.path; - const char *ptr = begin; - - /* See how much of the URL is a valid path and decode it */ - while(imap_is_bchar(*ptr)) - ptr++; - - if(ptr != begin) { - /* Remove the trailing slash if present */ - const char *end = ptr; - if(end > begin && end[-1] == '/') - end--; - - result = Curl_urldecode(data, begin, end - begin, &imap->mailbox, NULL, - TRUE); - if(result) - return result; - } - else - imap->mailbox = NULL; - - /* There can be any number of parameters in the form ";NAME=VALUE" */ - while(*ptr == ';') { - char *name; - char *value; - size_t valuelen; - - /* Find the length of the name parameter */ - begin = ++ptr; - while(*ptr && *ptr != '=') - ptr++; - - if(!*ptr) - return CURLE_URL_MALFORMAT; - - /* Decode the name parameter */ - result = Curl_urldecode(data, begin, ptr - begin, &name, NULL, TRUE); - if(result) - return result; - - /* Find the length of the value parameter */ - begin = ++ptr; - while(imap_is_bchar(*ptr)) - ptr++; - - /* Decode the value parameter */ - result = Curl_urldecode(data, begin, ptr - begin, &value, &valuelen, TRUE); - if(result) { - free(name); - return result; - } - - DEBUGF(infof(conn->data, "IMAP URL parameter '%s' = '%s'\n", name, value)); - - /* Process the known hierarchical parameters (UIDVALIDITY, UID, SECTION and - PARTIAL) stripping of the trailing slash character if it is present. - - Note: Unknown parameters trigger a URL_MALFORMAT error. */ - if(Curl_raw_equal(name, "UIDVALIDITY") && !imap->uidvalidity) { - if(valuelen > 0 && value[valuelen - 1] == '/') - value[valuelen - 1] = '\0'; - - imap->uidvalidity = value; - value = NULL; - } - else if(Curl_raw_equal(name, "UID") && !imap->uid) { - if(valuelen > 0 && value[valuelen - 1] == '/') - value[valuelen - 1] = '\0'; - - imap->uid = value; - value = NULL; - } - else if(Curl_raw_equal(name, "SECTION") && !imap->section) { - if(valuelen > 0 && value[valuelen - 1] == '/') - value[valuelen - 1] = '\0'; - - imap->section = value; - value = NULL; - } - else if(Curl_raw_equal(name, "PARTIAL") && !imap->partial) { - if(valuelen > 0 && value[valuelen - 1] == '/') - value[valuelen - 1] = '\0'; - - imap->partial = value; - value = NULL; - } - else { - free(name); - free(value); - - return CURLE_URL_MALFORMAT; - } - - free(name); - free(value); - } - - /* Does the URL contain a query parameter? Only valid when we have a mailbox - and no UID as per RFC-5092 */ - if(imap->mailbox && !imap->uid && *ptr == '?') { - /* Find the length of the query parameter */ - begin = ++ptr; - while(imap_is_bchar(*ptr)) - ptr++; - - /* Decode the query parameter */ - result = Curl_urldecode(data, begin, ptr - begin, &imap->query, NULL, - TRUE); - if(result) - return result; - } - - /* Any extra stuff at the end of the URL is an error */ - if(*ptr) - return CURLE_URL_MALFORMAT; - - return CURLE_OK; -} - -/*********************************************************************** - * - * imap_parse_custom_request() - * - * Parse the custom request. - */ -static CURLcode imap_parse_custom_request(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct IMAP *imap = data->req.protop; - const char *custom = data->set.str[STRING_CUSTOMREQUEST]; - - if(custom) { - /* URL decode the custom request */ - result = Curl_urldecode(data, custom, 0, &imap->custom, NULL, TRUE); - - /* Extract the parameters if specified */ - if(!result) { - const char *params = imap->custom; - - while(*params && *params != ' ') - params++; - - if(*params) { - imap->custom_params = strdup(params); - imap->custom[params - imap->custom] = '\0'; - - if(!imap->custom_params) - result = CURLE_OUT_OF_MEMORY; - } - } - } - - return result; -} - -#endif /* CURL_DISABLE_IMAP */ diff --git a/Externals/curl/lib/imap.h b/Externals/curl/lib/imap.h deleted file mode 100644 index e6b9b8944e..0000000000 --- a/Externals/curl/lib/imap.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef HEADER_CURL_IMAP_H -#define HEADER_CURL_IMAP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2009 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "pingpong.h" -#include "curl_sasl.h" - -/**************************************************************************** - * IMAP unique setup - ***************************************************************************/ -typedef enum { - IMAP_STOP, /* do nothing state, stops the state machine */ - IMAP_SERVERGREET, /* waiting for the initial greeting immediately after - a connect */ - IMAP_CAPABILITY, - IMAP_STARTTLS, - IMAP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS - (multi mode only) */ - IMAP_AUTHENTICATE, - IMAP_LOGIN, - IMAP_LIST, - IMAP_SELECT, - IMAP_FETCH, - IMAP_FETCH_FINAL, - IMAP_APPEND, - IMAP_APPEND_FINAL, - IMAP_SEARCH, - IMAP_LOGOUT, - IMAP_LAST /* never used */ -} imapstate; - -/* This IMAP struct is used in the SessionHandle. All IMAP data that is - connection-oriented must be in imap_conn to properly deal with the fact that - perhaps the SessionHandle is changed between the times the connection is - used. */ -struct IMAP { - curl_pp_transfer transfer; - char *mailbox; /* Mailbox to select */ - char *uidvalidity; /* UIDVALIDITY to check in select */ - char *uid; /* Message UID to fetch */ - char *section; /* Message SECTION to fetch */ - char *partial; /* Message PARTIAL to fetch */ - char *query; /* Query to search for */ - char *custom; /* Custom request */ - char *custom_params; /* Parameters for the custom request */ -}; - -/* imap_conn is used for struct connection-oriented data in the connectdata - struct */ -struct imap_conn { - struct pingpong pp; - imapstate state; /* Always use imap.c:state() to change state! */ - bool ssldone; /* Is connect() over SSL done? */ - struct SASL sasl; /* SASL-related parameters */ - unsigned int preftype; /* Preferred authentication type */ - int cmdid; /* Last used command ID */ - char resptag[5]; /* Response tag to wait for */ - bool tls_supported; /* StartTLS capability supported by server */ - bool login_disabled; /* LOGIN command disabled by server */ - bool ir_supported; /* Initial response supported by server */ - char *mailbox; /* The last selected mailbox */ - char *mailbox_uidvalidity; /* UIDVALIDITY parsed from select response */ -}; - -extern const struct Curl_handler Curl_handler_imap; -extern const struct Curl_handler Curl_handler_imaps; - -/* Authentication type flags */ -#define IMAP_TYPE_CLEARTEXT (1 << 0) -#define IMAP_TYPE_SASL (1 << 1) - -/* Authentication type values */ -#define IMAP_TYPE_NONE 0 -#define IMAP_TYPE_ANY ~0U - -#endif /* HEADER_CURL_IMAP_H */ diff --git a/Externals/curl/lib/inet_ntop.c b/Externals/curl/lib/inet_ntop.c deleted file mode 100644 index 416005c034..0000000000 --- a/Externals/curl/lib/inet_ntop.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 1996-2001 Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM - * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL - * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/* - * Original code by Paul Vixie. "curlified" by Gisle Vanem. - */ - -#include "curl_setup.h" - -#ifndef HAVE_INET_NTOP - -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "inet_ntop.h" -#include "curl_printf.h" - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -/* - * Format an IPv4 address, more or less like inet_ntoa(). - * - * Returns `dst' (as a const) - * Note: - * - uses no statics - * - takes a unsigned char* not an in_addr as input - */ -static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size) -{ - char tmp[sizeof "255.255.255.255"]; - size_t len; - - DEBUGASSERT(size >= 16); - - tmp[0] = '\0'; - (void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d", - ((int)((unsigned char)src[0])) & 0xff, - ((int)((unsigned char)src[1])) & 0xff, - ((int)((unsigned char)src[2])) & 0xff, - ((int)((unsigned char)src[3])) & 0xff); - - len = strlen(tmp); - if(len == 0 || len >= size) { - SET_ERRNO(ENOSPC); - return (NULL); - } - strcpy(dst, tmp); - return dst; -} - -#ifdef ENABLE_IPV6 -/* - * Convert IPv6 binary address into presentation (printable) format. - */ -static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - char *tp; - struct { - long base; - long len; - } best, cur; - unsigned long words[IN6ADDRSZ / INT16SZ]; - int i; - - /* Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof(words)); - for(i = 0; i < IN6ADDRSZ; i++) - words[i/2] |= (src[i] << ((1 - (i % 2)) << 3)); - - best.base = -1; - cur.base = -1; - best.len = 0; - cur.len = 0; - - for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { - if(words[i] == 0) { - if(cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } - else if(cur.base != -1) { - if(best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - if((cur.base != -1) && (best.base == -1 || cur.len > best.len)) - best = cur; - if(best.base != -1 && best.len < 2) - best.base = -1; - /* Format the result. */ - tp = tmp; - for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { - /* Are we inside the best run of 0x00's? */ - if(best.base != -1 && i >= best.base && i < (best.base + best.len)) { - if(i == best.base) - *tp++ = ':'; - continue; - } - - /* Are we following an initial run of 0x00s or any real hex? - */ - if(i != 0) - *tp++ = ':'; - - /* Is this address an encapsulated IPv4? - */ - if(i == 6 && best.base == 0 && - (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { - if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp))) { - SET_ERRNO(ENOSPC); - return (NULL); - } - tp += strlen(tp); - break; - } - tp += snprintf(tp, 5, "%lx", words[i]); - } - - /* Was it a trailing run of 0x00's? - */ - if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) - *tp++ = ':'; - *tp++ = '\0'; - - /* Check for overflow, copy, and we're done. - */ - if((size_t)(tp - tmp) > size) { - SET_ERRNO(ENOSPC); - return (NULL); - } - strcpy(dst, tmp); - return dst; -} -#endif /* ENABLE_IPV6 */ - -/* - * Convert a network format address to presentation format. - * - * Returns pointer to presentation format address (`buf'). - * Returns NULL on error and errno set with the specific - * error, EAFNOSUPPORT or ENOSPC. - * - * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid losing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this function sets when returning NULL, not SOCKERRNO. - */ -char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size) -{ - switch (af) { - case AF_INET: - return inet_ntop4((const unsigned char*)src, buf, size); -#ifdef ENABLE_IPV6 - case AF_INET6: - return inet_ntop6((const unsigned char*)src, buf, size); -#endif - default: - SET_ERRNO(EAFNOSUPPORT); - return NULL; - } -} -#endif /* HAVE_INET_NTOP */ diff --git a/Externals/curl/lib/inet_ntop.h b/Externals/curl/lib/inet_ntop.h deleted file mode 100644 index 9f44612710..0000000000 --- a/Externals/curl/lib/inet_ntop.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef HEADER_CURL_INET_NTOP_H -#define HEADER_CURL_INET_NTOP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -char *Curl_inet_ntop(int af, const void *addr, char *buf, size_t size); - -#ifdef HAVE_INET_NTOP -#ifdef HAVE_ARPA_INET_H -#include -#endif -#define Curl_inet_ntop(af,addr,buf,size) \ - inet_ntop(af, addr, buf, (curl_socklen_t)size) -#endif - -#endif /* HEADER_CURL_INET_NTOP_H */ - diff --git a/Externals/curl/lib/inet_pton.c b/Externals/curl/lib/inet_pton.c deleted file mode 100644 index cf8b88a1d0..0000000000 --- a/Externals/curl/lib/inet_pton.c +++ /dev/null @@ -1,234 +0,0 @@ -/* This is from the BIND 4.9.4 release, modified to compile by itself */ - -/* Copyright (c) 1996 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS - * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE - * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#include "curl_setup.h" - -#ifndef HAVE_INET_PTON - -#ifdef HAVE_SYS_PARAM_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "inet_pton.h" - -#define IN6ADDRSZ 16 -#define INADDRSZ 4 -#define INT16SZ 2 - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - -static int inet_pton4(const char *src, unsigned char *dst); -#ifdef ENABLE_IPV6 -static int inet_pton6(const char *src, unsigned char *dst); -#endif - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * notice: - * On Windows we store the error in the thread errno, not - * in the winsock error code. This is to avoid losing the - * actual last winsock error. So use macro ERRNO to fetch the - * errno this function sets when returning (-1), not SOCKERRNO. - * author: - * Paul Vixie, 1996. - */ -int -Curl_inet_pton(int af, const char *src, void *dst) -{ - switch (af) { - case AF_INET: - return (inet_pton4(src, (unsigned char *)dst)); -#ifdef ENABLE_IPV6 - case AF_INET6: - return (inet_pton6(src, (unsigned char *)dst)); -#endif - default: - SET_ERRNO(EAFNOSUPPORT); - return (-1); - } - /* NOTREACHED */ -} - -/* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton4(const char *src, unsigned char *dst) -{ - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - unsigned char tmp[INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - tp = tmp; - *tp = 0; - while((ch = *src++) != '\0') { - const char *pch; - - if((pch = strchr(digits, ch)) != NULL) { - unsigned int val = *tp * 10 + (unsigned int)(pch - digits); - - if(saw_digit && *tp == 0) - return (0); - if(val > 255) - return (0); - *tp = (unsigned char)val; - if(! saw_digit) { - if(++octets > 4) - return (0); - saw_digit = 1; - } - } - else if(ch == '.' && saw_digit) { - if(octets == 4) - return (0); - *++tp = 0; - saw_digit = 0; - } - else - return (0); - } - if(octets < 4) - return (0); - memcpy(dst, tmp, INADDRSZ); - return (1); -} - -#ifdef ENABLE_IPV6 -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -static int -inet_pton6(const char *src, unsigned char *dst) -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - size_t val; - - memset((tp = tmp), 0, IN6ADDRSZ); - endp = tp + IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if(*src == ':') - if(*++src != ':') - return (0); - curtok = src; - saw_xdigit = 0; - val = 0; - while((ch = *src++) != '\0') { - const char *pch; - - if((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if(pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if(++saw_xdigit > 4) - return (0); - continue; - } - if(ch == ':') { - curtok = src; - if(!saw_xdigit) { - if(colonp) - return (0); - colonp = tp; - continue; - } - if(tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) ((val >> 8) & 0xff); - *tp++ = (unsigned char) (val & 0xff); - saw_xdigit = 0; - val = 0; - continue; - } - if(ch == '.' && ((tp + INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if(saw_xdigit) { - if(tp + INT16SZ > endp) - return (0); - *tp++ = (unsigned char) ((val >> 8) & 0xff); - *tp++ = (unsigned char) (val & 0xff); - } - if(colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const ssize_t n = tp - colonp; - ssize_t i; - - if(tp == endp) - return (0); - for(i = 1; i <= n; i++) { - *(endp - i) = *(colonp + n - i); - *(colonp + n - i) = 0; - } - tp = endp; - } - if(tp != endp) - return (0); - memcpy(dst, tmp, IN6ADDRSZ); - return (1); -} -#endif /* ENABLE_IPV6 */ - -#endif /* HAVE_INET_PTON */ diff --git a/Externals/curl/lib/inet_pton.h b/Externals/curl/lib/inet_pton.h deleted file mode 100644 index 9188d9598f..0000000000 --- a/Externals/curl/lib/inet_pton.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADER_CURL_INET_PTON_H -#define HEADER_CURL_INET_PTON_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -int Curl_inet_pton(int, const char *, void *); - -#ifdef HAVE_INET_PTON -#ifdef HAVE_ARPA_INET_H -#include -#endif -#define Curl_inet_pton(x,y,z) inet_pton(x,y,z) -#endif - -#endif /* HEADER_CURL_INET_PTON_H */ - diff --git a/Externals/curl/lib/krb5.c b/Externals/curl/lib/krb5.c deleted file mode 100644 index 0b146e06bb..0000000000 --- a/Externals/curl/lib/krb5.c +++ /dev/null @@ -1,332 +0,0 @@ -/* GSSAPI/krb5 support for FTP - loosely based on old krb4.c - * - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Hgskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * Copyright (c) 2004 - 2016 Daniel Stenberg - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ - -#include "curl_setup.h" - -#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_FTP) - -#ifdef HAVE_NETDB_H -#include -#endif - -#include "urldata.h" -#include "curl_base64.h" -#include "ftp.h" -#include "curl_gssapi.h" -#include "sendf.h" -#include "curl_sec.h" -#include "warnless.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -static int -krb5_init(void *app_data) -{ - gss_ctx_id_t *context = app_data; - /* Make sure our context is initialized for krb5_end. */ - *context = GSS_C_NO_CONTEXT; - return 0; -} - -static int -krb5_check_prot(void *app_data, int level) -{ - (void)app_data; /* unused */ - if(level == PROT_CONFIDENTIAL) - return -1; - return 0; -} - -static int -krb5_decode(void *app_data, void *buf, int len, - int level UNUSED_PARAM, - struct connectdata *conn UNUSED_PARAM) -{ - gss_ctx_id_t *context = app_data; - OM_uint32 maj, min; - gss_buffer_desc enc, dec; - - (void)level; - (void)conn; - - enc.value = buf; - enc.length = len; - maj = gss_unseal(&min, *context, &enc, &dec, NULL, NULL); - if(maj != GSS_S_COMPLETE) { - if(len >= 4) - strcpy(buf, "599 "); - return -1; - } - - memcpy(buf, dec.value, dec.length); - len = curlx_uztosi(dec.length); - gss_release_buffer(&min, &dec); - - return len; -} - -static int -krb5_overhead(void *app_data, int level, int len) -{ - /* no arguments are used */ - (void)app_data; - (void)level; - (void)len; - return 0; -} - -static int -krb5_encode(void *app_data, const void *from, int length, int level, void **to) -{ - gss_ctx_id_t *context = app_data; - gss_buffer_desc dec, enc; - OM_uint32 maj, min; - int state; - int len; - - /* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal - * libraries modify the input buffer in gss_seal() - */ - dec.value = (void*)from; - dec.length = length; - maj = gss_seal(&min, *context, - level == PROT_PRIVATE, - GSS_C_QOP_DEFAULT, - &dec, &state, &enc); - - if(maj != GSS_S_COMPLETE) - return -1; - - /* malloc a new buffer, in case gss_release_buffer doesn't work as - expected */ - *to = malloc(enc.length); - if(!*to) - return -1; - memcpy(*to, enc.value, enc.length); - len = curlx_uztosi(enc.length); - gss_release_buffer(&min, &enc); - return len; -} - -static int -krb5_auth(void *app_data, struct connectdata *conn) -{ - int ret = AUTH_OK; - char *p; - const char *host = conn->host.name; - ssize_t nread; - curl_socklen_t l = sizeof(conn->local_addr); - struct SessionHandle *data = conn->data; - CURLcode result; - const char *service = data->set.str[STRING_SERVICE_NAME] ? - data->set.str[STRING_SERVICE_NAME] : - "ftp"; - const char *srv_host = "host"; - gss_buffer_desc input_buffer, output_buffer, _gssresp, *gssresp; - OM_uint32 maj, min; - gss_name_t gssname; - gss_ctx_id_t *context = app_data; - struct gss_channel_bindings_struct chan; - size_t base64_sz = 0; - struct sockaddr_in **remote_addr = - (struct sockaddr_in **)&conn->ip_addr->ai_addr; - - if(getsockname(conn->sock[FIRSTSOCKET], - (struct sockaddr *)&conn->local_addr, &l) < 0) - perror("getsockname()"); - - chan.initiator_addrtype = GSS_C_AF_INET; - chan.initiator_address.length = l - 4; - chan.initiator_address.value = &conn->local_addr.sin_addr.s_addr; - chan.acceptor_addrtype = GSS_C_AF_INET; - chan.acceptor_address.length = l - 4; - chan.acceptor_address.value = &(*remote_addr)->sin_addr.s_addr; - chan.application_data.length = 0; - chan.application_data.value = NULL; - - /* this loop will execute twice (once for service, once for host) */ - for(;;) { - /* this really shouldn't be repeated here, but can't help it */ - if(service == srv_host) { - result = Curl_ftpsendf(conn, "AUTH GSSAPI"); - if(result) - return -2; - - if(Curl_GetFTPResponse(&nread, conn, NULL)) - return -1; - - if(data->state.buffer[0] != '3') - return -1; - } - - input_buffer.value = data->state.buffer; - input_buffer.length = snprintf(input_buffer.value, BUFSIZE, "%s@%s", - service, host); - maj = gss_import_name(&min, &input_buffer, GSS_C_NT_HOSTBASED_SERVICE, - &gssname); - if(maj != GSS_S_COMPLETE) { - gss_release_name(&min, &gssname); - if(service == srv_host) { - Curl_failf(data, "Error importing service name %s", - input_buffer.value); - return AUTH_ERROR; - } - service = srv_host; - continue; - } - /* We pass NULL as |output_name_type| to avoid a leak. */ - gss_display_name(&min, gssname, &output_buffer, NULL); - Curl_infof(data, "Trying against %s\n", output_buffer.value); - gssresp = GSS_C_NO_BUFFER; - *context = GSS_C_NO_CONTEXT; - - do { - /* Release the buffer at each iteration to avoid leaking: the first time - we are releasing the memory from gss_display_name. The last item is - taken care by a final gss_release_buffer. */ - gss_release_buffer(&min, &output_buffer); - ret = AUTH_OK; - maj = Curl_gss_init_sec_context(data, - &min, - context, - gssname, - &Curl_krb5_mech_oid, - &chan, - gssresp, - &output_buffer, - TRUE, - NULL); - - if(gssresp) { - free(_gssresp.value); - gssresp = NULL; - } - - if(GSS_ERROR(maj)) { - Curl_infof(data, "Error creating security context\n"); - ret = AUTH_ERROR; - break; - } - - if(output_buffer.length != 0) { - result = Curl_base64_encode(data, (char *)output_buffer.value, - output_buffer.length, &p, &base64_sz); - if(result) { - Curl_infof(data, "base64-encoding: %s\n", - curl_easy_strerror(result)); - ret = AUTH_CONTINUE; - break; - } - - result = Curl_ftpsendf(conn, "ADAT %s", p); - - free(p); - - if(result) { - ret = -2; - break; - } - - if(Curl_GetFTPResponse(&nread, conn, NULL)) { - ret = -1; - break; - } - - if(data->state.buffer[0] != '2' && data->state.buffer[0] != '3') { - Curl_infof(data, "Server didn't accept auth data\n"); - ret = AUTH_ERROR; - break; - } - - p = data->state.buffer + 4; - p = strstr(p, "ADAT="); - if(p) { - result = Curl_base64_decode(p + 5, - (unsigned char **)&_gssresp.value, - &_gssresp.length); - if(result) { - Curl_failf(data, "base64-decoding: %s", - curl_easy_strerror(result)); - ret = AUTH_CONTINUE; - break; - } - } - - gssresp = &_gssresp; - } - } while(maj == GSS_S_CONTINUE_NEEDED); - - gss_release_name(&min, &gssname); - gss_release_buffer(&min, &output_buffer); - - if(gssresp) - free(_gssresp.value); - - if(ret == AUTH_OK || service == srv_host) - return ret; - - service = srv_host; - } - return ret; -} - -static void krb5_end(void *app_data) -{ - OM_uint32 min; - gss_ctx_id_t *context = app_data; - if(*context != GSS_C_NO_CONTEXT) { -#ifdef DEBUGBUILD - OM_uint32 maj = -#endif - gss_delete_sec_context(&min, context, GSS_C_NO_BUFFER); - DEBUGASSERT(maj == GSS_S_COMPLETE); - } -} - -struct Curl_sec_client_mech Curl_krb5_client_mech = { - "GSSAPI", - sizeof(gss_ctx_id_t), - krb5_init, - krb5_auth, - krb5_end, - krb5_check_prot, - krb5_overhead, - krb5_encode, - krb5_decode -}; - -#endif /* HAVE_GSSAPI && !CURL_DISABLE_FTP */ diff --git a/Externals/curl/lib/ldap.c b/Externals/curl/lib/ldap.c deleted file mode 100644 index 1f1f72fba4..0000000000 --- a/Externals/curl/lib/ldap.c +++ /dev/null @@ -1,1012 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP) - -/* - * Notice that USE_OPENLDAP is only a source code selection switch. When - * libcurl is built with USE_OPENLDAP defined the libcurl source code that - * gets compiled is the code from openldap.c, otherwise the code that gets - * compiled is the code from ldap.c. - * - * When USE_OPENLDAP is defined a recent version of the OpenLDAP library - * might be required for compilation and runtime. In order to use ancient - * OpenLDAP library versions, USE_OPENLDAP shall not be defined. - */ - -#ifdef USE_WIN32_LDAP /* Use Windows LDAP implementation. */ -# include -# ifndef LDAP_VENDOR_NAME -# error Your Platform SDK is NOT sufficient for LDAP support! \ - Update your Platform SDK, or disable LDAP support! -# else -# include -# endif -#else -# define LDAP_DEPRECATED 1 /* Be sure ldap_init() is defined. */ -# ifdef HAVE_LBER_H -# include -# endif -# include -# if (defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H)) -# include -# endif /* HAVE_LDAP_SSL && HAVE_LDAP_SSL_H */ -#endif - -/* These are macros in both (in above ) and typedefs - * in BoringSSL's - */ -#ifdef HAVE_BORINGSSL -# undef X509_NAME -# undef X509_CERT_PAIR -# undef X509_EXTENSIONS -#endif - -#include "urldata.h" -#include -#include "sendf.h" -#include "escape.h" -#include "progress.h" -#include "transfer.h" -#include "strequal.h" -#include "strtok.h" -#include "curl_ldap.h" -#include "curl_multibyte.h" -#include "curl_base64.h" -#include "rawstr.h" -#include "connect.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifndef HAVE_LDAP_URL_PARSE - -/* Use our own implementation. */ - -typedef struct { - char *lud_host; - int lud_port; -#if defined(USE_WIN32_LDAP) - TCHAR *lud_dn; - TCHAR **lud_attrs; -#else - char *lud_dn; - char **lud_attrs; -#endif - int lud_scope; -#if defined(USE_WIN32_LDAP) - TCHAR *lud_filter; -#else - char *lud_filter; -#endif - char **lud_exts; - size_t lud_attrs_dups; /* how many were dup'ed, this field is not in the - "real" struct so can only be used in code - without HAVE_LDAP_URL_PARSE defined */ -} CURL_LDAPURLDesc; - -#undef LDAPURLDesc -#define LDAPURLDesc CURL_LDAPURLDesc - -static int _ldap_url_parse (const struct connectdata *conn, - LDAPURLDesc **ludp); -static void _ldap_free_urldesc (LDAPURLDesc *ludp); - -#undef ldap_free_urldesc -#define ldap_free_urldesc _ldap_free_urldesc -#endif - -#ifdef DEBUG_LDAP - #define LDAP_TRACE(x) do { \ - _ldap_trace ("%u: ", __LINE__); \ - _ldap_trace x; \ - } WHILE_FALSE - - static void _ldap_trace (const char *fmt, ...); -#else - #define LDAP_TRACE(x) Curl_nop_stmt -#endif - - -static CURLcode Curl_ldap(struct connectdata *conn, bool *done); - -/* - * LDAP protocol handler. - */ - -const struct Curl_handler Curl_handler_ldap = { - "LDAP", /* scheme */ - ZERO_NULL, /* setup_connection */ - Curl_ldap, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_LDAP, /* defport */ - CURLPROTO_LDAP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -#ifdef HAVE_LDAP_SSL -/* - * LDAPS protocol handler. - */ - -const struct Curl_handler Curl_handler_ldaps = { - "LDAPS", /* scheme */ - ZERO_NULL, /* setup_connection */ - Curl_ldap, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_LDAPS, /* defport */ - CURLPROTO_LDAPS, /* protocol */ - PROTOPT_SSL /* flags */ -}; -#endif - - -static CURLcode Curl_ldap(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - int rc = 0; - LDAP *server = NULL; - LDAPURLDesc *ludp = NULL; - LDAPMessage *ldapmsg = NULL; - LDAPMessage *entryIterator; - int num = 0; - struct SessionHandle *data=conn->data; - int ldap_proto = LDAP_VERSION3; - int ldap_ssl = 0; - char *val_b64 = NULL; - size_t val_b64_sz = 0; - curl_off_t dlsize = 0; -#ifdef LDAP_OPT_NETWORK_TIMEOUT - struct timeval ldap_timeout = {10, 0}; /* 10 sec connection/search timeout */ -#endif -#if defined(USE_WIN32_LDAP) - TCHAR *host = NULL; - TCHAR *user = NULL; - TCHAR *passwd = NULL; -#else - char *host = NULL; - char *user = NULL; - char *passwd = NULL; -#endif - - *done = TRUE; /* unconditionally */ - infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n", - LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION); - infof(data, "LDAP local: %s\n", data->change.url); - -#ifdef HAVE_LDAP_URL_PARSE - rc = ldap_url_parse(data->change.url, &ludp); -#else - rc = _ldap_url_parse(conn, &ludp); -#endif - if(rc != 0) { - failf(data, "LDAP local: %s", ldap_err2string(rc)); - result = CURLE_LDAP_INVALID_URL; - goto quit; - } - - /* Get the URL scheme (either ldap or ldaps) */ - if(conn->given->flags & PROTOPT_SSL) - ldap_ssl = 1; - infof(data, "LDAP local: trying to establish %s connection\n", - ldap_ssl ? "encrypted" : "cleartext"); - -#if defined(USE_WIN32_LDAP) - host = Curl_convert_UTF8_to_tchar(conn->host.name); - if(!host) { - result = CURLE_OUT_OF_MEMORY; - - goto quit; - } - - if(conn->bits.user_passwd) { - user = Curl_convert_UTF8_to_tchar(conn->user); - passwd = Curl_convert_UTF8_to_tchar(conn->passwd); - if(!user || !passwd) { - result = CURLE_OUT_OF_MEMORY; - - goto quit; - } - } -#else - host = conn->host.name; - - if(conn->bits.user_passwd) { - user = conn->user; - passwd = conn->passwd; - } -#endif - -#ifdef LDAP_OPT_NETWORK_TIMEOUT - ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout); -#endif - ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); - - if(ldap_ssl) { -#ifdef HAVE_LDAP_SSL -#ifdef USE_WIN32_LDAP - /* Win32 LDAP SDK doesn't support insecure mode without CA! */ - server = ldap_sslinit(host, (int)conn->port, 1); - ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON); -#else - int ldap_option; - char* ldap_ca = data->set.str[STRING_SSL_CAFILE]; -#if defined(CURL_HAS_NOVELL_LDAPSDK) - rc = ldapssl_client_init(NULL, NULL); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - if(data->set.ssl.verifypeer) { - /* Novell SDK supports DER or BASE64 files. */ - int cert_type = LDAPSSL_CERT_FILETYPE_B64; - if((data->set.str[STRING_CERT_TYPE]) && - (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER"))) - cert_type = LDAPSSL_CERT_FILETYPE_DER; - if(!ldap_ca) { - failf(data, "LDAP local: ERROR %s CA cert not set!", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM")); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - infof(data, "LDAP local: using %s CA cert '%s'\n", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), - ldap_ca); - rc = ldapssl_add_trusted_cert(ldap_ca, cert_type); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting %s CA cert: %s", - (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"), - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - ldap_option = LDAPSSL_VERIFY_SERVER; - } - else - ldap_option = LDAPSSL_VERIFY_NONE; - rc = ldapssl_set_verify_mode(ldap_option); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting cert verify mode: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - server = ldapssl_init(host, (int)conn->port, 1); - if(server == NULL) { - failf(data, "LDAP local: Cannot connect to %s:%ld", - conn->host.dispname, conn->port); - result = CURLE_COULDNT_CONNECT; - goto quit; - } -#elif defined(LDAP_OPT_X_TLS) - if(data->set.ssl.verifypeer) { - /* OpenLDAP SDK supports BASE64 files. */ - if((data->set.str[STRING_CERT_TYPE]) && - (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) { - failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!"); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - if(!ldap_ca) { - failf(data, "LDAP local: ERROR PEM CA cert not set!"); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca); - rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting PEM CA cert: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - ldap_option = LDAP_OPT_X_TLS_DEMAND; - } - else - ldap_option = LDAP_OPT_X_TLS_NEVER; - - rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting cert verify mode: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } - server = ldap_init(host, (int)conn->port); - if(server == NULL) { - failf(data, "LDAP local: Cannot connect to %s:%ld", - conn->host.dispname, conn->port); - result = CURLE_COULDNT_CONNECT; - goto quit; - } - ldap_option = LDAP_OPT_X_TLS_HARD; - rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } -/* - rc = ldap_start_tls_s(server, NULL, NULL); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s", - ldap_err2string(rc)); - result = CURLE_SSL_CERTPROBLEM; - goto quit; - } -*/ -#else - /* we should probably never come up to here since configure - should check in first place if we can support LDAP SSL/TLS */ - failf(data, "LDAP local: SSL/TLS not supported with this version " - "of the OpenLDAP toolkit\n"); - result = CURLE_SSL_CERTPROBLEM; - goto quit; -#endif -#endif -#endif /* CURL_LDAP_USE_SSL */ - } - else { - server = ldap_init(host, (int)conn->port); - if(server == NULL) { - failf(data, "LDAP local: Cannot connect to %s:%ld", - conn->host.dispname, conn->port); - result = CURLE_COULDNT_CONNECT; - goto quit; - } - } -#ifdef USE_WIN32_LDAP - ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); -#endif - - rc = ldap_simple_bind_s(server, user, passwd); - if(!ldap_ssl && rc != 0) { - ldap_proto = LDAP_VERSION2; - ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto); - rc = ldap_simple_bind_s(server, user, passwd); - } - if(rc != 0) { - failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc)); - result = CURLE_LDAP_CANNOT_BIND; - goto quit; - } - - rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope, - ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg); - - if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) { - failf(data, "LDAP remote: %s", ldap_err2string(rc)); - result = CURLE_LDAP_SEARCH_FAILED; - goto quit; - } - - for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg); - entryIterator; - entryIterator = ldap_next_entry(server, entryIterator), num++) { - BerElement *ber = NULL; -#if defined(USE_WIN32_LDAP) - TCHAR *attribute; -#else - char *attribute; /*! suspicious that this isn't 'const' */ -#endif - int i; - - /* Get the DN and write it to the client */ - { - char *name; - size_t name_len; -#if defined(USE_WIN32_LDAP) - TCHAR *dn = ldap_get_dn(server, entryIterator); - name = Curl_convert_tchar_to_UTF8(dn); - if(!name) { - ldap_memfree(dn); - - result = CURLE_OUT_OF_MEMORY; - - goto quit; - } -#else - char *dn = name = ldap_get_dn(server, entryIterator); -#endif - name_len = strlen(name); - - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); - if(result) { -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(name); -#endif - ldap_memfree(dn); - - goto quit; - } - - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *) name, - name_len); - if(result) { -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(name); -#endif - ldap_memfree(dn); - - goto quit; - } - - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); - if(result) { -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(name); -#endif - ldap_memfree(dn); - - goto quit; - } - - dlsize += name_len + 5; - -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(name); -#endif - ldap_memfree(dn); - } - - /* Get the attributes and write them to the client */ - for(attribute = ldap_first_attribute(server, entryIterator, &ber); - attribute; - attribute = ldap_next_attribute(server, entryIterator, ber)) { - BerValue **vals; - size_t attr_len; -#if defined(USE_WIN32_LDAP) - char *attr = Curl_convert_tchar_to_UTF8(attribute); - if(!attr) { - if(ber) - ber_free(ber, 0); - - result = CURLE_OUT_OF_MEMORY; - - goto quit; - } -#else - char *attr = attribute; -#endif - attr_len = strlen(attr); - - vals = ldap_get_values_len(server, entryIterator, attribute); - if(vals != NULL) { - for(i = 0; (vals[i] != NULL); i++) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); - if(result) { - ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - result = Curl_client_write(conn, CLIENTWRITE_BODY, - (char *) attr, attr_len); - if(result) { - ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2); - if(result) { - ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - dlsize += attr_len + 3; - - if((attr_len > 7) && - (strcmp(";binary", (char *) attr + (attr_len - 7)) == 0)) { - /* Binary attribute, encode to base64. */ - result = Curl_base64_encode(data, - vals[i]->bv_val, - vals[i]->bv_len, - &val_b64, - &val_b64_sz); - if(result) { - ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - if(val_b64_sz > 0) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, - val_b64_sz); - free(val_b64); - if(result) { - ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - dlsize += val_b64_sz; - } - } - else { - result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val, - vals[i]->bv_len); - if(result) { - ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - dlsize += vals[i]->bv_len; - } - - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); - if(result) { - ldap_value_free_len(vals); -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - if(ber) - ber_free(ber, 0); - - goto quit; - } - - dlsize++; - } - - /* Free memory used to store values */ - ldap_value_free_len(vals); - } - - /* Free the attribute as we are done with it */ -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(attr); -#endif - ldap_memfree(attribute); - - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); - if(result) - goto quit; - dlsize++; - Curl_pgrsSetDownloadCounter(data, dlsize); - } - - if(ber) - ber_free(ber, 0); - } - -quit: - if(ldapmsg) { - ldap_msgfree(ldapmsg); - LDAP_TRACE (("Received %d entries\n", num)); - } - if(rc == LDAP_SIZELIMIT_EXCEEDED) - infof(data, "There are more than %d entries\n", num); - if(ludp) - ldap_free_urldesc(ludp); - if(server) - ldap_unbind_s(server); -#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK) - if(ldap_ssl) - ldapssl_client_deinit(); -#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */ - -#if defined(USE_WIN32_LDAP) - Curl_unicodefree(passwd); - Curl_unicodefree(user); - Curl_unicodefree(host); -#endif - - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - connclose(conn, "LDAP connection always disable re-use"); - - return result; -} - -#ifdef DEBUG_LDAP -static void _ldap_trace (const char *fmt, ...) -{ - static int do_trace = -1; - va_list args; - - if(do_trace == -1) { - const char *env = getenv("CURL_TRACE"); - do_trace = (env && strtol(env, NULL, 10) > 0); - } - if(!do_trace) - return; - - va_start (args, fmt); - vfprintf (stderr, fmt, args); - va_end (args); -} -#endif - -#ifndef HAVE_LDAP_URL_PARSE - -/* - * Return scope-value for a scope-string. - */ -static int str2scope (const char *p) -{ - if(strequal(p, "one")) - return LDAP_SCOPE_ONELEVEL; - if(strequal(p, "onetree")) - return LDAP_SCOPE_ONELEVEL; - if(strequal(p, "base")) - return LDAP_SCOPE_BASE; - if(strequal(p, "sub")) - return LDAP_SCOPE_SUBTREE; - if(strequal(p, "subtree")) - return LDAP_SCOPE_SUBTREE; - return (-1); -} - -/* - * Split 'str' into strings separated by commas. - * Note: out[] points into 'str'. - */ -static bool split_str(char *str, char ***out, size_t *count) -{ - char **res; - char *lasts; - char *s; - size_t i; - size_t items = 1; - - s = strchr(str, ','); - while(s) { - items++; - s = strchr(++s, ','); - } - - res = calloc(items, sizeof(char *)); - if(!res) - return FALSE; - - for(i = 0, s = strtok_r(str, ",", &lasts); s && i < items; - s = strtok_r(NULL, ",", &lasts), i++) - res[i] = s; - - *out = res; - *count = items; - - return TRUE; -} - -/* - * Break apart the pieces of an LDAP URL. - * Syntax: - * ldap://:/???? - * - * already known from 'conn->host.name'. - * already known from 'conn->remote_port'. - * extract the rest from 'conn->data->state.path+1'. All fields are optional. - * e.g. - * ldap://:/??? - * yields ludp->lud_dn = "". - * - * Defined in RFC4516 section 2. - */ -static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp) -{ - int rc = LDAP_SUCCESS; - char *path; - char *p; - char *q; - size_t i; - - if(!conn->data || - !conn->data->state.path || - conn->data->state.path[0] != '/' || - !checkprefix("LDAP", conn->data->change.url)) - return LDAP_INVALID_SYNTAX; - - ludp->lud_scope = LDAP_SCOPE_BASE; - ludp->lud_port = conn->remote_port; - ludp->lud_host = conn->host.name; - - /* Duplicate the path */ - p = path = strdup(conn->data->state.path + 1); - if(!path) - return LDAP_NO_MEMORY; - - /* Parse the DN (Distinguished Name) */ - q = strchr(p, '?'); - if(q) - *q++ = '\0'; - - if(*p) { - char *dn = p; - char *unescaped; - - LDAP_TRACE (("DN '%s'\n", dn)); - - /* Unescape the DN */ - unescaped = curl_easy_unescape(conn->data, dn, 0, NULL); - if(!unescaped) { - rc = LDAP_NO_MEMORY; - - goto quit; - } - -#if defined(USE_WIN32_LDAP) - /* Convert the unescaped string to a tchar */ - ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped); - - /* Free the unescaped string as we are done with it */ - Curl_unicodefree(unescaped); - - if(!ludp->lud_dn) { - rc = LDAP_NO_MEMORY; - - goto quit; - } -#else - ludp->lud_dn = unescaped; -#endif - } - - p = q; - if(!p) - goto quit; - - /* Parse the attributes. skip "??" */ - q = strchr(p, '?'); - if(q) - *q++ = '\0'; - - if(*p) { - char **attributes; - size_t count = 0; - - /* Split the string into an array of attributes */ - if(!split_str(p, &attributes, &count)) { - rc = LDAP_NO_MEMORY; - - goto quit; - } - - /* Allocate our array (+1 for the NULL entry) */ -#if defined(USE_WIN32_LDAP) - ludp->lud_attrs = calloc(count + 1, sizeof(TCHAR *)); -#else - ludp->lud_attrs = calloc(count + 1, sizeof(char *)); -#endif - if(!ludp->lud_attrs) { - free(attributes); - - rc = LDAP_NO_MEMORY; - - goto quit; - } - - for(i = 0; i < count; i++) { - char *unescaped; - - LDAP_TRACE (("attr[%d] '%s'\n", i, attributes[i])); - - /* Unescape the attribute */ - unescaped = curl_easy_unescape(conn->data, attributes[i], 0, NULL); - if(!unescaped) { - free(attributes); - - rc = LDAP_NO_MEMORY; - - goto quit; - } - -#if defined(USE_WIN32_LDAP) - /* Convert the unescaped string to a tchar */ - ludp->lud_attrs[i] = Curl_convert_UTF8_to_tchar(unescaped); - - /* Free the unescaped string as we are done with it */ - Curl_unicodefree(unescaped); - - if(!ludp->lud_attrs[i]) { - free(attributes); - - rc = LDAP_NO_MEMORY; - - goto quit; - } -#else - ludp->lud_attrs[i] = unescaped; -#endif - - ludp->lud_attrs_dups++; - } - - free(attributes); - } - - p = q; - if(!p) - goto quit; - - /* Parse the scope. skip "??" */ - q = strchr(p, '?'); - if(q) - *q++ = '\0'; - - if(*p) { - ludp->lud_scope = str2scope(p); - if(ludp->lud_scope == -1) { - rc = LDAP_INVALID_SYNTAX; - - goto quit; - } - LDAP_TRACE (("scope %d\n", ludp->lud_scope)); - } - - p = q; - if(!p) - goto quit; - - /* Parse the filter */ - q = strchr(p, '?'); - if(q) - *q++ = '\0'; - - if(*p) { - char *filter = p; - char *unescaped; - - LDAP_TRACE (("filter '%s'\n", filter)); - - /* Unescape the filter */ - unescaped = curl_easy_unescape(conn->data, filter, 0, NULL); - if(!unescaped) { - rc = LDAP_NO_MEMORY; - - goto quit; - } - -#if defined(USE_WIN32_LDAP) - /* Convert the unescaped string to a tchar */ - ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped); - - /* Free the unescaped string as we are done with it */ - Curl_unicodefree(unescaped); - - if(!ludp->lud_filter) { - rc = LDAP_NO_MEMORY; - - goto quit; - } -#else - ludp->lud_filter = unescaped; -#endif - } - - p = q; - if(p && !*p) { - rc = LDAP_INVALID_SYNTAX; - - goto quit; - } - -quit: - free(path); - - return rc; -} - -static int _ldap_url_parse (const struct connectdata *conn, - LDAPURLDesc **ludpp) -{ - LDAPURLDesc *ludp = calloc(1, sizeof(*ludp)); - int rc; - - *ludpp = NULL; - if(!ludp) - return LDAP_NO_MEMORY; - - rc = _ldap_url_parse2 (conn, ludp); - if(rc != LDAP_SUCCESS) { - _ldap_free_urldesc(ludp); - ludp = NULL; - } - *ludpp = ludp; - return (rc); -} - -static void _ldap_free_urldesc (LDAPURLDesc *ludp) -{ - size_t i; - - if(!ludp) - return; - - free(ludp->lud_dn); - free(ludp->lud_filter); - - if(ludp->lud_attrs) { - for(i = 0; i < ludp->lud_attrs_dups; i++) - free(ludp->lud_attrs[i]); - free(ludp->lud_attrs); - } - - free (ludp); -} -#endif /* !HAVE_LDAP_URL_PARSE */ -#endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */ diff --git a/Externals/curl/lib/libcurl.plist b/Externals/curl/lib/libcurl.plist deleted file mode 100644 index 4b19860a2f..0000000000 --- a/Externals/curl/lib/libcurl.plist +++ /dev/null @@ -1,35 +0,0 @@ - - - - - CFBundleInfoDictionaryVersion - 6.0 - - CFBundleDevelopmentRegion - English - - CFBundleExecutable - curl - - CFBundleIdentifier - se.haxx.curl.libcurl - - CFBundleVersion - 7.49.1 - - CFBundleName - libcurl - - CFBundlePackageType - FMWK - - CFBundleSignature - ???? - - CFBundleShortVersionString - libcurl 7.49.1 - - CFBundleGetInfoString - libcurl.plist 7.49.1 - - diff --git a/Externals/curl/lib/libcurl.rc b/Externals/curl/lib/libcurl.rc deleted file mode 100644 index 50b365dbbf..0000000000 --- a/Externals/curl/lib/libcurl.rc +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include -#include "../include/curl/curlver.h" - -LANGUAGE 0x09,0x01 - -#define RC_VERSION LIBCURL_VERSION_MAJOR, LIBCURL_VERSION_MINOR, LIBCURL_VERSION_PATCH, 0 - -VS_VERSION_INFO VERSIONINFO - FILEVERSION RC_VERSION - PRODUCTVERSION RC_VERSION - FILEFLAGSMASK 0x3fL -#if defined(DEBUGBUILD) || defined(_DEBUG) - FILEFLAGS 1 -#else - FILEFLAGS 0 -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE 0x0L - -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "The cURL library, https://curl.haxx.se/\0" - VALUE "FileDescription", "libcurl Shared Library\0" - VALUE "FileVersion", LIBCURL_VERSION "\0" - VALUE "InternalName", "libcurl\0" - VALUE "OriginalFilename", "libcurl.dll\0" - VALUE "ProductName", "The cURL library\0" - VALUE "ProductVersion", LIBCURL_VERSION "\0" - VALUE "LegalCopyright", " " LIBCURL_COPYRIGHT "\0" - VALUE "License", "https://curl.haxx.se/docs/copyright.html\0" - END - END - - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/Externals/curl/lib/libcurl.vers.in b/Externals/curl/lib/libcurl.vers.in deleted file mode 100644 index ae978a485d..0000000000 --- a/Externals/curl/lib/libcurl.vers.in +++ /dev/null @@ -1,13 +0,0 @@ -HIDDEN -{ - local: - __*; - _rest*; - _save*; -}; - -CURL_@CURL_LT_SHLIB_VERSIONED_FLAVOUR@4 -{ - global: curl_*; - local: *; -}; diff --git a/Externals/curl/lib/llist.c b/Externals/curl/lib/llist.c deleted file mode 100644 index 482aaa0410..0000000000 --- a/Externals/curl/lib/llist.c +++ /dev/null @@ -1,214 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "llist.h" -#include "curl_memory.h" - -/* this must be the last include file */ -#include "memdebug.h" - -/* - * @unittest: 1300 - */ -static void -llist_init(struct curl_llist *l, curl_llist_dtor dtor) -{ - l->size = 0; - l->dtor = dtor; - l->head = NULL; - l->tail = NULL; -} - -struct curl_llist * -Curl_llist_alloc(curl_llist_dtor dtor) -{ - struct curl_llist *list; - - list = malloc(sizeof(struct curl_llist)); - if(!list) - return NULL; - - llist_init(list, dtor); - - return list; -} - -/* - * Curl_llist_insert_next() - * - * Inserts a new list element after the given one 'e'. If the given existing - * entry is NULL and the list already has elements, the new one will be - * inserted first in the list. - * - * Returns: 1 on success and 0 on failure. - * - * @unittest: 1300 - */ -int -Curl_llist_insert_next(struct curl_llist *list, struct curl_llist_element *e, - const void *p) -{ - struct curl_llist_element *ne = malloc(sizeof(struct curl_llist_element)); - if(!ne) - return 0; - - ne->ptr = (void *) p; - if(list->size == 0) { - list->head = ne; - list->head->prev = NULL; - list->head->next = NULL; - list->tail = ne; - } - else { - /* if 'e' is NULL here, we insert the new element first in the list */ - ne->next = e?e->next:list->head; - ne->prev = e; - if(!e) { - list->head->prev = ne; - list->head = ne; - } - else if(e->next) { - e->next->prev = ne; - } - else { - list->tail = ne; - } - if(e) - e->next = ne; - } - - ++list->size; - - return 1; -} - -/* - * @unittest: 1300 - */ -int -Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e, - void *user) -{ - if(e == NULL || list->size == 0) - return 1; - - if(e == list->head) { - list->head = e->next; - - if(list->head == NULL) - list->tail = NULL; - else - e->next->prev = NULL; - } - else { - e->prev->next = e->next; - if(!e->next) - list->tail = e->prev; - else - e->next->prev = e->prev; - } - - list->dtor(user, e->ptr); - - e->ptr = NULL; - e->prev = NULL; - e->next = NULL; - - free(e); - --list->size; - - return 1; -} - -void -Curl_llist_destroy(struct curl_llist *list, void *user) -{ - if(list) { - while(list->size > 0) - Curl_llist_remove(list, list->tail, user); - - free(list); - } -} - -size_t -Curl_llist_count(struct curl_llist *list) -{ - return list->size; -} - -/* - * @unittest: 1300 - */ -int Curl_llist_move(struct curl_llist *list, struct curl_llist_element *e, - struct curl_llist *to_list, - struct curl_llist_element *to_e) -{ - /* Remove element from list */ - if(e == NULL || list->size == 0) - return 0; - - if(e == list->head) { - list->head = e->next; - - if(list->head == NULL) - list->tail = NULL; - else - e->next->prev = NULL; - } - else { - e->prev->next = e->next; - if(!e->next) - list->tail = e->prev; - else - e->next->prev = e->prev; - } - - --list->size; - - /* Add element to to_list after to_e */ - if(to_list->size == 0) { - to_list->head = e; - to_list->head->prev = NULL; - to_list->head->next = NULL; - to_list->tail = e; - } - else { - e->next = to_e->next; - e->prev = to_e; - if(to_e->next) { - to_e->next->prev = e; - } - else { - to_list->tail = e; - } - to_e->next = e; - } - - ++to_list->size; - - return 1; -} diff --git a/Externals/curl/lib/llist.h b/Externals/curl/lib/llist.h deleted file mode 100644 index 39ff408eeb..0000000000 --- a/Externals/curl/lib/llist.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef HEADER_CURL_LLIST_H -#define HEADER_CURL_LLIST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" -#include - -typedef void (*curl_llist_dtor)(void *, void *); - -struct curl_llist_element { - void *ptr; - - struct curl_llist_element *prev; - struct curl_llist_element *next; -}; - -struct curl_llist { - struct curl_llist_element *head; - struct curl_llist_element *tail; - - curl_llist_dtor dtor; - - size_t size; -}; - -struct curl_llist *Curl_llist_alloc(curl_llist_dtor); -int Curl_llist_insert_next(struct curl_llist *, struct curl_llist_element *, - const void *); -int Curl_llist_remove(struct curl_llist *, struct curl_llist_element *, - void *); -size_t Curl_llist_count(struct curl_llist *); -void Curl_llist_destroy(struct curl_llist *, void *); -int Curl_llist_move(struct curl_llist *, struct curl_llist_element *, - struct curl_llist *, struct curl_llist_element *); - -#endif /* HEADER_CURL_LLIST_H */ - diff --git a/Externals/curl/lib/makefile.amiga b/Externals/curl/lib/makefile.amiga deleted file mode 100644 index c692e5ebe3..0000000000 --- a/Externals/curl/lib/makefile.amiga +++ /dev/null @@ -1,21 +0,0 @@ -# -# libcurl Makefile for AmigaOS ... -# - -# change the follow to where you have the AmiTCP SDK v4.3 includes: - -ATCPSDKI= /GG/netinclude - - -CC = m68k-amigaos-gcc -CFLAGS = -I$(ATCPSDKI) -m68020-60 -O2 -msoft-float -noixemul -g -I. -I../include -W -Wall - -include Makefile.inc -OBJS = $(CSOURCES:.c=.o) - -all: $(OBJS) - ar cru libcurl.a $(OBJS) - ranlib libcurl.a - -install: - $(INSTALL) -c ./libcurl.a /lib/libcurl.a diff --git a/Externals/curl/lib/makefile.dj b/Externals/curl/lib/makefile.dj deleted file mode 100644 index 2331afe313..0000000000 --- a/Externals/curl/lib/makefile.dj +++ /dev/null @@ -1,73 +0,0 @@ -#*************************************************************************** -# _ _ ____ _ -# Project ___| | | | _ \| | -# / __| | | | |_) | | -# | (__| |_| | _ <| |___ -# \___|\___/|_| \_\_____| -# -# Copyright (C) 2003 - 2008, Gisle Vanem . -# Copyright (C) 2003 - 2015, Daniel Stenberg, , et al. -# -# This software is licensed as described in the file COPYING, which -# you should have received as part of this distribution. The terms -# are also available at https://curl.haxx.se/docs/copyright.html. -# -# You may opt to use, copy, modify, merge, publish, distribute and/or sell -# copies of the Software, and permit persons to whom the Software is -# furnished to do so, under the terms of the COPYING file. -# -# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# KIND, either express or implied. -# -#*************************************************************************** - -# -# Adapted for djgpp2 / Watt-32 / DOS -# - -DEPEND_PREREQ = curl_config.h -VPATH = vtls -TOPDIR = .. - -include ../packages/DOS/common.dj -include Makefile.inc - -SOURCES = $(sort $(CSOURCES)) -OBJECTS = $(addprefix $(OBJ_DIR)/, $(notdir $(SOURCES:.c=.o))) - -CURL_LIB = libcurl.a - -# NOTE: if ../include/curl/curlbuild.h is missing, you're probably building -# this from a git checkout and then you need to run buildconf.bat first. - -all: $(OBJ_DIR) curl_config.h $(CURL_LIB) - -$(CURL_LIB): $(OBJECTS) - ar rs $@ $? - -curl_config.h: config-dos.h - $(COPY) $^ $@ - -# clean generated files -# -genclean: - - $(DELETE) curl_config.h - -# clean object files and subdir -# -objclean: genclean - - $(DELETE) $(OBJ_DIR)$(DS)*.o - - $(RMDIR) $(OBJ_DIR) - -# clean without removing built library -# -clean: objclean - - $(DELETE) depend.dj - -# clean everything -# -realclean vclean: clean - - $(DELETE) $(CURL_LIB) - --include depend.dj - diff --git a/Externals/curl/lib/md4.c b/Externals/curl/lib/md4.c deleted file mode 100644 index 60f73a28bb..0000000000 --- a/Externals/curl/lib/md4.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD4 Message-Digest Algorithm (RFC 1320). - * - * Homepage: - http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 - * - * Author: - * Alexander Peslyak, better known as Solar Designer - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. In case - * this attempt to disclaim copyright and place the software in the public - * domain is deemed null and void, then the software is Copyright (c) 2001 - * Alexander Peslyak and it is hereby released to the general public under the - * following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - * - * This differs from Colin Plumb's older public domain implementation in that - * no exactly 32-bit integer data type is required (any 32-bit or wider - * unsigned integer data type will do), there's no compile-time endianness - * configuration, and the function prototypes match OpenSSL's. No code from - * Colin Plumb's implementation has been reused; this comment merely compares - * the properties of the two independent implementations. - * - * The primary goals of this implementation are portability and ease of use. - * It is meant to be fast, but not as fast as possible. Some known - * optimizations are not included to reduce source code size and avoid - * compile-time configuration. - */ - -#include "curl_setup.h" - -/* NSS and OS/400 crypto library do not provide the MD4 hash algorithm, so - * that we have a local implementation of it */ -#if defined(USE_NSS) || defined(USE_OS400CRYPTO) - -#include "curl_md4.h" -#include "warnless.h" - -#ifndef HAVE_OPENSSL - -#include - -/* Any 32-bit or wider unsigned integer data type will do */ -typedef unsigned int MD4_u32plus; - -typedef struct { - MD4_u32plus lo, hi; - MD4_u32plus a, b, c, d; - unsigned char buffer[64]; - MD4_u32plus block[16]; -} MD4_CTX; - -static void MD4_Init(MD4_CTX *ctx); -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size); -static void MD4_Final(unsigned char *result, MD4_CTX *ctx); - -/* - * The basic MD4 functions. - * - * F and G are optimized compared to their RFC 1320 definitions, with the - * optimization for F borrowed from Colin Plumb's MD5 implementation. - */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) - -/* - * The MD4 transformation for all three rounds. - */ -#define STEP(f, a, b, c, d, x, s) \ - (a) += f((b), (c), (d)) + (x); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); - -/* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned - * memory accesses is just an optimization. Nothing will break if it - * doesn't work. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -#define SET(n) \ - (*(MD4_u32plus *)&ptr[(n) * 4]) -#define GET(n) \ - SET(n) -#else -#define SET(n) \ - (ctx->block[(n)] = \ - (MD4_u32plus)ptr[(n) * 4] | \ - ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD4_u32plus)ptr[(n) * 4 + 3] << 24)) -#define GET(n) \ - (ctx->block[(n)]) -#endif - -/* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. - */ -static const void *body(MD4_CTX *ctx, const void *data, unsigned long size) -{ - const unsigned char *ptr; - MD4_u32plus a, b, c, d; - MD4_u32plus saved_a, saved_b, saved_c, saved_d; - - ptr = (const unsigned char *)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - -/* Round 1 */ - STEP(F, a, b, c, d, SET(0), 3) - STEP(F, d, a, b, c, SET(1), 7) - STEP(F, c, d, a, b, SET(2), 11) - STEP(F, b, c, d, a, SET(3), 19) - STEP(F, a, b, c, d, SET(4), 3) - STEP(F, d, a, b, c, SET(5), 7) - STEP(F, c, d, a, b, SET(6), 11) - STEP(F, b, c, d, a, SET(7), 19) - STEP(F, a, b, c, d, SET(8), 3) - STEP(F, d, a, b, c, SET(9), 7) - STEP(F, c, d, a, b, SET(10), 11) - STEP(F, b, c, d, a, SET(11), 19) - STEP(F, a, b, c, d, SET(12), 3) - STEP(F, d, a, b, c, SET(13), 7) - STEP(F, c, d, a, b, SET(14), 11) - STEP(F, b, c, d, a, SET(15), 19) - -/* Round 2 */ - STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13) - STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13) - STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13) - STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3) - STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5) - STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9) - STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13) - -/* Round 3 */ - STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15) - STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15) - STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15) - STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3) - STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9) - STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11) - STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while(size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; -} - -static void MD4_Init(MD4_CTX *ctx) -{ - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; -} - -static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) -{ - MD4_u32plus saved_lo; - unsigned long used, available; - - saved_lo = ctx->lo; - if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) - ctx->hi++; - ctx->hi += (MD4_u32plus)size >> 29; - - used = saved_lo & 0x3f; - - if(used) { - available = 64 - used; - - if(size < available) { - memcpy(&ctx->buffer[used], data, size); - return; - } - - memcpy(&ctx->buffer[used], data, available); - data = (const unsigned char *)data + available; - size -= available; - body(ctx, ctx->buffer, 64); - } - - if(size >= 64) { - data = body(ctx, data, size & ~(unsigned long)0x3f); - size &= 0x3f; - } - - memcpy(ctx->buffer, data, size); -} - -static void MD4_Final(unsigned char *result, MD4_CTX *ctx) -{ - unsigned long used, available; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - available = 64 - used; - - if(available < 8) { - memset(&ctx->buffer[used], 0, available); - body(ctx, ctx->buffer, 64); - used = 0; - available = 64; - } - - memset(&ctx->buffer[used], 0, available - 8); - - ctx->lo <<= 3; - ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff); - ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff); - ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff); - ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff); - ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff); - ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff); - ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff); - ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); - - body(ctx, ctx->buffer, 64); - - result[0] = curlx_ultouc((ctx->a)&0xff); - result[1] = curlx_ultouc((ctx->a >> 8)&0xff); - result[2] = curlx_ultouc((ctx->a >> 16)&0xff); - result[3] = curlx_ultouc(ctx->a >> 24); - result[4] = curlx_ultouc((ctx->b)&0xff); - result[5] = curlx_ultouc((ctx->b >> 8)&0xff); - result[6] = curlx_ultouc((ctx->b >> 16)&0xff); - result[7] = curlx_ultouc(ctx->b >> 24); - result[8] = curlx_ultouc((ctx->c)&0xff); - result[9] = curlx_ultouc((ctx->c >> 8)&0xff); - result[10] = curlx_ultouc((ctx->c >> 16)&0xff); - result[11] = curlx_ultouc(ctx->c >> 24); - result[12] = curlx_ultouc((ctx->d)&0xff); - result[13] = curlx_ultouc((ctx->d >> 8)&0xff); - result[14] = curlx_ultouc((ctx->d >> 16)&0xff); - result[15] = curlx_ultouc(ctx->d >> 24); - - memset(ctx, 0, sizeof(*ctx)); -} - -#endif - -void Curl_md4it(unsigned char *output, const unsigned char *input, size_t len) -{ - MD4_CTX ctx; - MD4_Init(&ctx); - MD4_Update(&ctx, input, curlx_uztoui(len)); - MD4_Final(output, &ctx); -} -#endif /* defined(USE_NSS) || defined(USE_OS400CRYPTO) */ diff --git a/Externals/curl/lib/md5.c b/Externals/curl/lib/md5.c deleted file mode 100644 index 84adb99265..0000000000 --- a/Externals/curl/lib/md5.c +++ /dev/null @@ -1,562 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_CRYPTO_AUTH - -#include - -#include "curl_md5.h" -#include "curl_hmac.h" -#include "warnless.h" - -#if defined(USE_GNUTLS_NETTLE) - -#include -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -typedef struct md5_ctx MD5_CTX; - -static void MD5_Init(MD5_CTX * ctx) -{ - md5_init(ctx); -} - -static void MD5_Update(MD5_CTX * ctx, - const unsigned char * input, - unsigned int inputLen) -{ - md5_update(ctx, inputLen, input); -} - -static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx) -{ - md5_digest(ctx, 16, digest); -} - -#elif defined(USE_GNUTLS) - -#include -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -typedef gcry_md_hd_t MD5_CTX; - -static void MD5_Init(MD5_CTX * ctx) -{ - gcry_md_open(ctx, GCRY_MD_MD5, 0); -} - -static void MD5_Update(MD5_CTX * ctx, - const unsigned char * input, - unsigned int inputLen) -{ - gcry_md_write(*ctx, input, inputLen); -} - -static void MD5_Final(unsigned char digest[16], MD5_CTX * ctx) -{ - memcpy(digest, gcry_md_read(*ctx, 0), 16); - gcry_md_close(*ctx); -} - -#elif defined(USE_OPENSSL) -/* When OpenSSL is available we use the MD5-function from OpenSSL */ -#include -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ - (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \ - (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ - (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000)) - -/* For Apple operating systems: CommonCrypto has the functions we need. - These functions are available on Tiger and later, as well as iOS 2.0 - and later. If you're building for an older cat, well, sorry. - - Declaring the functions as static like this seems to be a bit more - reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */ -# include -# define MD5_CTX CC_MD5_CTX -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -static void MD5_Init(MD5_CTX *ctx) -{ - CC_MD5_Init(ctx); -} - -static void MD5_Update(MD5_CTX *ctx, - const unsigned char *input, - unsigned int inputLen) -{ - CC_MD5_Update(ctx, input, inputLen); -} - -static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) -{ - CC_MD5_Final(digest, ctx); -} - -#elif defined(_WIN32) - -#include -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -typedef struct { - HCRYPTPROV hCryptProv; - HCRYPTHASH hHash; -} MD5_CTX; - -static void MD5_Init(MD5_CTX *ctx) -{ - if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { - CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash); - } -} - -static void MD5_Update(MD5_CTX *ctx, - const unsigned char *input, - unsigned int inputLen) -{ - CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0); -} - -static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) -{ - unsigned long length = 0; - CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); - if(length == 16) - CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); - if(ctx->hHash) - CryptDestroyHash(ctx->hHash); - if(ctx->hCryptProv) - CryptReleaseContext(ctx->hCryptProv, 0); -} - -#elif defined(USE_AXTLS) -#include -#include -#include -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" -#else -/* When no other crypto library is available we use this code segment */ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - * - * This differs from Colin Plumb's older public domain implementation in that - * no exactly 32-bit integer data type is required (any 32-bit or wider - * unsigned integer data type will do), there's no compile-time endianness - * configuration, and the function prototypes match OpenSSL's. No code from - * Colin Plumb's implementation has been reused; this comment merely compares - * the properties of the two independent implementations. - * - * The primary goals of this implementation are portability and ease of use. - * It is meant to be fast, but not as fast as possible. Some known - * optimizations are not included to reduce source code size and avoid - * compile-time configuration. - */ - -#include - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* Any 32-bit or wider unsigned integer data type will do */ -typedef unsigned int MD5_u32plus; - -typedef struct { - MD5_u32plus lo, hi; - MD5_u32plus a, b, c, d; - unsigned char buffer[64]; - MD5_u32plus block[16]; -} MD5_CTX; - -static void MD5_Init(MD5_CTX *ctx); -static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); -static void MD5_Final(unsigned char *result, MD5_CTX *ctx); - -/* - * The basic MD5 functions. - * - * F and G are optimized compared to their RFC 1321 definitions for - * architectures that lack an AND-NOT instruction, just like in Colin Plumb's - * implementation. - */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) (((x) ^ (y)) ^ (z)) -#define H2(x, y, z) ((x) ^ ((y) ^ (z))) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) - -/* - * The MD5 transformation for all four rounds. - */ -#define STEP(f, a, b, c, d, x, t, s) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); - -/* - * SET reads 4 input bytes in little-endian byte order and stores them - * in a properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned - * memory accesses is just an optimization. Nothing will break if it - * doesn't work. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -#define SET(n) \ - (*(MD5_u32plus *)&ptr[(n) * 4]) -#define GET(n) \ - SET(n) -#else -#define SET(n) \ - (ctx->block[(n)] = \ - (MD5_u32plus)ptr[(n) * 4] | \ - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) -#define GET(n) \ - (ctx->block[(n)]) -#endif - -/* - * This processes one or more 64-byte data blocks, but does NOT update - * the bit counters. There are no alignment requirements. - */ -static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) -{ - const unsigned char *ptr; - MD5_u32plus a, b, c, d; - MD5_u32plus saved_a, saved_b, saved_c, saved_d; - - ptr = (const unsigned char *)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - -/* Round 1 */ - STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) - STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) - STEP(F, c, d, a, b, SET(2), 0x242070db, 17) - STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) - STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) - STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) - STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) - STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) - STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) - STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) - STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) - STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) - STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) - STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) - STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) - STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) - -/* Round 2 */ - STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) - STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) - STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) - STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) - STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) - STEP(G, d, a, b, c, GET(10), 0x02441453, 9) - STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) - STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) - STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) - STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) - STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) - STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) - STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) - STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) - STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) - STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) - -/* Round 3 */ - STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) - STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) - STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) - STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) - STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) - STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) - STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) - STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) - -/* Round 4 */ - STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) - STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) - STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) - STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) - STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) - STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) - STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) - STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) - STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) - STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) - STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) - STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) - STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) - STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) - STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) - STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while(size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; -} - -static void MD5_Init(MD5_CTX *ctx) -{ - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; -} - -static void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) -{ - MD5_u32plus saved_lo; - unsigned long used, available; - - saved_lo = ctx->lo; - if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) - ctx->hi++; - ctx->hi += (MD5_u32plus)size >> 29; - - used = saved_lo & 0x3f; - - if(used) { - available = 64 - used; - - if(size < available) { - memcpy(&ctx->buffer[used], data, size); - return; - } - - memcpy(&ctx->buffer[used], data, available); - data = (const unsigned char *)data + available; - size -= available; - body(ctx, ctx->buffer, 64); - } - - if(size >= 64) { - data = body(ctx, data, size & ~(unsigned long)0x3f); - size &= 0x3f; - } - - memcpy(ctx->buffer, data, size); -} - -static void MD5_Final(unsigned char *result, MD5_CTX *ctx) -{ - unsigned long used, available; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - available = 64 - used; - - if(available < 8) { - memset(&ctx->buffer[used], 0, available); - body(ctx, ctx->buffer, 64); - used = 0; - available = 64; - } - - memset(&ctx->buffer[used], 0, available - 8); - - ctx->lo <<= 3; - ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff); - ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff); - ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff); - ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24); - ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff); - ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff); - ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff); - ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24); - - body(ctx, ctx->buffer, 64); - - result[0] = curlx_ultouc((ctx->a)&0xff); - result[1] = curlx_ultouc((ctx->a >> 8)&0xff); - result[2] = curlx_ultouc((ctx->a >> 16)&0xff); - result[3] = curlx_ultouc(ctx->a >> 24); - result[4] = curlx_ultouc((ctx->b)&0xff); - result[5] = curlx_ultouc((ctx->b >> 8)&0xff); - result[6] = curlx_ultouc((ctx->b >> 16)&0xff); - result[7] = curlx_ultouc(ctx->b >> 24); - result[8] = curlx_ultouc((ctx->c)&0xff); - result[9] = curlx_ultouc((ctx->c >> 8)&0xff); - result[10] = curlx_ultouc((ctx->c >> 16)&0xff); - result[11] = curlx_ultouc(ctx->c >> 24); - result[12] = curlx_ultouc((ctx->d)&0xff); - result[13] = curlx_ultouc((ctx->d >> 8)&0xff); - result[14] = curlx_ultouc((ctx->d >> 16)&0xff); - result[15] = curlx_ultouc(ctx->d >> 24); - - memset(ctx, 0, sizeof(*ctx)); -} - -#endif /* CRYPTO LIBS */ - -const HMAC_params Curl_HMAC_MD5[] = { - { - (HMAC_hinit_func) MD5_Init, /* Hash initialization function. */ - (HMAC_hupdate_func) MD5_Update, /* Hash update function. */ - (HMAC_hfinal_func) MD5_Final, /* Hash computation end function. */ - sizeof(MD5_CTX), /* Size of hash context structure. */ - 64, /* Maximum key length. */ - 16 /* Result size. */ - } -}; - -const MD5_params Curl_DIGEST_MD5[] = { - { - (Curl_MD5_init_func) MD5_Init, /* Digest initialization function */ - (Curl_MD5_update_func) MD5_Update, /* Digest update function */ - (Curl_MD5_final_func) MD5_Final, /* Digest computation end function */ - sizeof(MD5_CTX), /* Size of digest context struct */ - 16 /* Result size */ - } -}; - -/* - * @unittest: 1601 - */ -void Curl_md5it(unsigned char *outbuffer, /* 16 bytes */ - const unsigned char *input) -{ - MD5_CTX ctx; - MD5_Init(&ctx); - MD5_Update(&ctx, input, curlx_uztoui(strlen((char *)input))); - MD5_Final(outbuffer, &ctx); -} - -MD5_context *Curl_MD5_init(const MD5_params *md5params) -{ - MD5_context *ctxt; - - /* Create MD5 context */ - ctxt = malloc(sizeof *ctxt); - - if(!ctxt) - return ctxt; - - ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize); - - if(!ctxt->md5_hashctx) { - free(ctxt); - return NULL; - } - - ctxt->md5_hash = md5params; - - (*md5params->md5_init_func)(ctxt->md5_hashctx); - - return ctxt; -} - -int Curl_MD5_update(MD5_context *context, - const unsigned char *data, - unsigned int len) -{ - (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len); - - return 0; -} - -int Curl_MD5_final(MD5_context *context, unsigned char *result) -{ - (*context->md5_hash->md5_final_func)(result, context->md5_hashctx); - - free(context->md5_hashctx); - free(context); - - return 0; -} - -#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/Externals/curl/lib/memdebug.c b/Externals/curl/lib/memdebug.c deleted file mode 100644 index 1618bbaf31..0000000000 --- a/Externals/curl/lib/memdebug.c +++ /dev/null @@ -1,488 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef CURLDEBUG - -#include - -#include "urldata.h" - -#define MEMDEBUG_NODEFINES /* don't redefine the standard functions */ - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifndef HAVE_ASSERT_H -# define assert(x) Curl_nop_stmt -#endif - -/* - * Until 2011-08-17 libcurl's Memory Tracking feature also performed - * automatic malloc and free filling operations using 0xA5 and 0x13 - * values. Our own preinitialization of dynamically allocated memory - * might be useful when not using third party memory debuggers, but - * on the other hand this would fool memory debuggers into thinking - * that all dynamically allocated memory is properly initialized. - * - * As a default setting, libcurl's Memory Tracking feature no longer - * performs preinitialization of dynamically allocated memory on its - * own. If you know what you are doing, and really want to retain old - * behavior, you can achieve this compiling with preprocessor symbols - * CURL_MT_MALLOC_FILL and CURL_MT_FREE_FILL defined with appropriate - * values. - */ - -#ifdef CURL_MT_MALLOC_FILL -# if (CURL_MT_MALLOC_FILL < 0) || (CURL_MT_MALLOC_FILL > 0xff) -# error "invalid CURL_MT_MALLOC_FILL or out of range" -# endif -#endif - -#ifdef CURL_MT_FREE_FILL -# if (CURL_MT_FREE_FILL < 0) || (CURL_MT_FREE_FILL > 0xff) -# error "invalid CURL_MT_FREE_FILL or out of range" -# endif -#endif - -#if defined(CURL_MT_MALLOC_FILL) && defined(CURL_MT_FREE_FILL) -# if (CURL_MT_MALLOC_FILL == CURL_MT_FREE_FILL) -# error "CURL_MT_MALLOC_FILL same as CURL_MT_FREE_FILL" -# endif -#endif - -#ifdef CURL_MT_MALLOC_FILL -# define mt_malloc_fill(buf,len) memset((buf), CURL_MT_MALLOC_FILL, (len)) -#else -# define mt_malloc_fill(buf,len) Curl_nop_stmt -#endif - -#ifdef CURL_MT_FREE_FILL -# define mt_free_fill(buf,len) memset((buf), CURL_MT_FREE_FILL, (len)) -#else -# define mt_free_fill(buf,len) Curl_nop_stmt -#endif - -struct memdebug { - size_t size; - union { - curl_off_t o; - double d; - void * p; - } mem[1]; - /* I'm hoping this is the thing with the strictest alignment - * requirements. That also means we waste some space :-( */ -}; - -/* - * Note that these debug functions are very simple and they are meant to - * remain so. For advanced analysis, record a log file and write perl scripts - * to analyze them! - * - * Don't use these with multithreaded test programs! - */ - -#define logfile curl_debuglogfile -FILE *curl_debuglogfile = NULL; -static bool memlimit = FALSE; /* enable memory limit */ -static long memsize = 0; /* set number of mallocs allowed */ - -/* this sets the log file name */ -void curl_memdebug(const char *logname) -{ - if(!logfile) { - if(logname && *logname) - logfile = fopen(logname, FOPEN_WRITETEXT); - else - logfile = stderr; -#ifdef MEMDEBUG_LOG_SYNC - /* Flush the log file after every line so the log isn't lost in a crash */ - setvbuf(logfile, (char *)NULL, _IOLBF, 0); -#endif - } -} - -/* This function sets the number of malloc() calls that should return - successfully! */ -void curl_memlimit(long limit) -{ - if(!memlimit) { - memlimit = TRUE; - memsize = limit; - } -} - -/* returns TRUE if this isn't allowed! */ -static bool countcheck(const char *func, int line, const char *source) -{ - /* if source is NULL, then the call is made internally and this check - should not be made */ - if(memlimit && source) { - if(!memsize) { - if(source) { - /* log to file */ - curl_memlog("LIMIT %s:%d %s reached memlimit\n", - source, line, func); - /* log to stderr also */ - fprintf(stderr, "LIMIT %s:%d %s reached memlimit\n", - source, line, func); - fflush(logfile); /* because it might crash now */ - } - SET_ERRNO(ENOMEM); - return TRUE; /* RETURN ERROR! */ - } - else - memsize--; /* countdown */ - - - } - - return FALSE; /* allow this */ -} - -void *curl_domalloc(size_t wantedsize, int line, const char *source) -{ - struct memdebug *mem; - size_t size; - - assert(wantedsize != 0); - - if(countcheck("malloc", line, source)) - return NULL; - - /* alloc at least 64 bytes */ - size = sizeof(struct memdebug)+wantedsize; - - mem = (Curl_cmalloc)(size); - if(mem) { - /* fill memory with junk */ - mt_malloc_fill(mem->mem, wantedsize); - mem->size = wantedsize; - } - - if(source) - curl_memlog("MEM %s:%d malloc(%zu) = %p\n", - source, line, wantedsize, - mem ? (void *)mem->mem : (void *)0); - - return (mem ? mem->mem : NULL); -} - -void *curl_docalloc(size_t wanted_elements, size_t wanted_size, - int line, const char *source) -{ - struct memdebug *mem; - size_t size, user_size; - - assert(wanted_elements != 0); - assert(wanted_size != 0); - - if(countcheck("calloc", line, source)) - return NULL; - - /* alloc at least 64 bytes */ - user_size = wanted_size * wanted_elements; - size = sizeof(struct memdebug) + user_size; - - mem = (Curl_ccalloc)(1, size); - if(mem) - mem->size = user_size; - - if(source) - curl_memlog("MEM %s:%d calloc(%zu,%zu) = %p\n", - source, line, wanted_elements, wanted_size, - mem ? (void *)mem->mem : (void *)0); - - return (mem ? mem->mem : NULL); -} - -char *curl_dostrdup(const char *str, int line, const char *source) -{ - char *mem; - size_t len; - - assert(str != NULL); - - if(countcheck("strdup", line, source)) - return NULL; - - len=strlen(str)+1; - - mem=curl_domalloc(len, 0, NULL); /* NULL prevents logging */ - if(mem) - memcpy(mem, str, len); - - if(source) - curl_memlog("MEM %s:%d strdup(%p) (%zu) = %p\n", - source, line, (void *)str, len, (void *)mem); - - return mem; -} - -#if defined(WIN32) && defined(UNICODE) -wchar_t *curl_dowcsdup(const wchar_t *str, int line, const char *source) -{ - wchar_t *mem; - size_t wsiz, bsiz; - - assert(str != NULL); - - if(countcheck("wcsdup", line, source)) - return NULL; - - wsiz = wcslen(str) + 1; - bsiz = wsiz * sizeof(wchar_t); - - mem = curl_domalloc(bsiz, 0, NULL); /* NULL prevents logging */ - if(mem) - memcpy(mem, str, bsiz); - - if(source) - curl_memlog("MEM %s:%d wcsdup(%p) (%zu) = %p\n", - source, line, (void *)str, bsiz, (void *)mem); - - return mem; -} -#endif - -/* We provide a realloc() that accepts a NULL as pointer, which then - performs a malloc(). In order to work with ares. */ -void *curl_dorealloc(void *ptr, size_t wantedsize, - int line, const char *source) -{ - struct memdebug *mem=NULL; - - size_t size = sizeof(struct memdebug)+wantedsize; - - assert(wantedsize != 0); - - if(countcheck("realloc", line, source)) - return NULL; - -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:1684) - /* 1684: conversion from pointer to same-sized integral type */ -#endif - - if(ptr) - mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif - - mem = (Curl_crealloc)(mem, size); - if(source) - curl_memlog("MEM %s:%d realloc(%p, %zu) = %p\n", - source, line, (void *)ptr, wantedsize, - mem ? (void *)mem->mem : (void *)0); - - if(mem) { - mem->size = wantedsize; - return mem->mem; - } - - return NULL; -} - -void curl_dofree(void *ptr, int line, const char *source) -{ - struct memdebug *mem; - - if(ptr) { - -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:1684) - /* 1684: conversion from pointer to same-sized integral type */ -#endif - - mem = (void *)((char *)ptr - offsetof(struct memdebug, mem)); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif - - /* destroy */ - mt_free_fill(mem->mem, mem->size); - - /* free for real */ - (Curl_cfree)(mem); - } - - if(source) - curl_memlog("MEM %s:%d free(%p)\n", source, line, (void *)ptr); -} - -curl_socket_t curl_socket(int domain, int type, int protocol, - int line, const char *source) -{ - const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? - "FD %s:%d socket() = %d\n" : - (sizeof(curl_socket_t) == sizeof(long)) ? - "FD %s:%d socket() = %ld\n" : - "FD %s:%d socket() = %zd\n"; - - curl_socket_t sockfd = socket(domain, type, protocol); - - if(source && (sockfd != CURL_SOCKET_BAD)) - curl_memlog(fmt, source, line, sockfd); - - return sockfd; -} - -#ifdef HAVE_SOCKETPAIR -int curl_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source) -{ - const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? - "FD %s:%d socketpair() = %d %d\n" : - (sizeof(curl_socket_t) == sizeof(long)) ? - "FD %s:%d socketpair() = %ld %ld\n" : - "FD %s:%d socketpair() = %zd %zd\n"; - - int res = socketpair(domain, type, protocol, socket_vector); - - if(source && (0 == res)) - curl_memlog(fmt, source, line, socket_vector[0], socket_vector[1]); - - return res; -} -#endif - -curl_socket_t curl_accept(curl_socket_t s, void *saddr, void *saddrlen, - int line, const char *source) -{ - const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? - "FD %s:%d accept() = %d\n" : - (sizeof(curl_socket_t) == sizeof(long)) ? - "FD %s:%d accept() = %ld\n" : - "FD %s:%d accept() = %zd\n"; - - struct sockaddr *addr = (struct sockaddr *)saddr; - curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen; - - curl_socket_t sockfd = accept(s, addr, addrlen); - - if(source && (sockfd != CURL_SOCKET_BAD)) - curl_memlog(fmt, source, line, sockfd); - - return sockfd; -} - -/* separate function to allow libcurl to mark a "faked" close */ -void curl_mark_sclose(curl_socket_t sockfd, int line, const char *source) -{ - const char *fmt = (sizeof(curl_socket_t) == sizeof(int)) ? - "FD %s:%d sclose(%d)\n": - (sizeof(curl_socket_t) == sizeof(long)) ? - "FD %s:%d sclose(%ld)\n": - "FD %s:%d sclose(%zd)\n"; - - if(source) - curl_memlog(fmt, source, line, sockfd); -} - -/* this is our own defined way to close sockets on *ALL* platforms */ -int curl_sclose(curl_socket_t sockfd, int line, const char *source) -{ - int res=sclose(sockfd); - curl_mark_sclose(sockfd, line, source); - return res; -} - -FILE *curl_fopen(const char *file, const char *mode, - int line, const char *source) -{ - FILE *res=fopen(file, mode); - - if(source) - curl_memlog("FILE %s:%d fopen(\"%s\",\"%s\") = %p\n", - source, line, file, mode, (void *)res); - - return res; -} - -#ifdef HAVE_FDOPEN -FILE *curl_fdopen(int filedes, const char *mode, - int line, const char *source) -{ - FILE *res=fdopen(filedes, mode); - - if(source) - curl_memlog("FILE %s:%d fdopen(\"%d\",\"%s\") = %p\n", - source, line, filedes, mode, (void *)res); - - return res; -} -#endif - -int curl_fclose(FILE *file, int line, const char *source) -{ - int res; - - assert(file != NULL); - - res=fclose(file); - - if(source) - curl_memlog("FILE %s:%d fclose(%p)\n", - source, line, (void *)file); - - return res; -} - -#define LOGLINE_BUFSIZE 1024 - -/* this does the writting to the memory tracking log file */ -void curl_memlog(const char *format, ...) -{ - char *buf; - int nchars; - va_list ap; - - if(!logfile) - return; - - buf = (Curl_cmalloc)(LOGLINE_BUFSIZE); - if(!buf) - return; - - va_start(ap, format); - nchars = vsnprintf(buf, LOGLINE_BUFSIZE, format, ap); - va_end(ap); - - if(nchars > LOGLINE_BUFSIZE - 1) - nchars = LOGLINE_BUFSIZE - 1; - - if(nchars > 0) - fwrite(buf, 1, nchars, logfile); - - (Curl_cfree)(buf); -} - -#endif /* CURLDEBUG */ diff --git a/Externals/curl/lib/memdebug.h b/Externals/curl/lib/memdebug.h deleted file mode 100644 index 835dab38c7..0000000000 --- a/Externals/curl/lib/memdebug.h +++ /dev/null @@ -1,173 +0,0 @@ -#ifndef HEADER_CURL_MEMDEBUG_H -#define HEADER_CURL_MEMDEBUG_H -#ifdef CURLDEBUG -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * CAUTION: this header is designed to work when included by the app-side - * as well as the library. Do not mix with library internals! - */ - -#define CURL_MT_LOGFNAME_BUFSIZE 512 - -#define logfile curl_debuglogfile - -extern FILE *logfile; - -/* memory functions */ -CURL_EXTERN void *curl_domalloc(size_t size, int line, const char *source); -CURL_EXTERN void *curl_docalloc(size_t elements, size_t size, int line, - const char *source); -CURL_EXTERN void *curl_dorealloc(void *ptr, size_t size, int line, - const char *source); -CURL_EXTERN void curl_dofree(void *ptr, int line, const char *source); -CURL_EXTERN char *curl_dostrdup(const char *str, int line, const char *source); -#if defined(WIN32) && defined(UNICODE) -CURL_EXTERN wchar_t *curl_dowcsdup(const wchar_t *str, int line, - const char *source); -#endif - -CURL_EXTERN void curl_memdebug(const char *logname); -CURL_EXTERN void curl_memlimit(long limit); -CURL_EXTERN void curl_memlog(const char *format, ...); - -/* file descriptor manipulators */ -CURL_EXTERN curl_socket_t curl_socket(int domain, int type, int protocol, - int line, const char *source); -CURL_EXTERN void curl_mark_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN int curl_sclose(curl_socket_t sockfd, - int line, const char *source); -CURL_EXTERN curl_socket_t curl_accept(curl_socket_t s, void *a, void *alen, - int line, const char *source); -#ifdef HAVE_SOCKETPAIR -CURL_EXTERN int curl_socketpair(int domain, int type, int protocol, - curl_socket_t socket_vector[2], - int line, const char *source); -#endif - -/* FILE functions */ -CURL_EXTERN FILE *curl_fopen(const char *file, const char *mode, int line, - const char *source); -#ifdef HAVE_FDOPEN -CURL_EXTERN FILE *curl_fdopen(int filedes, const char *mode, int line, - const char *source); -#endif -CURL_EXTERN int curl_fclose(FILE *file, int line, const char *source); - -#ifndef MEMDEBUG_NODEFINES - -/* Set this symbol on the command-line, recompile all lib-sources */ -#undef strdup -#define strdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__) -#define malloc(size) curl_domalloc(size, __LINE__, __FILE__) -#define calloc(nbelem,size) curl_docalloc(nbelem, size, __LINE__, __FILE__) -#define realloc(ptr,size) curl_dorealloc(ptr, size, __LINE__, __FILE__) -#define free(ptr) curl_dofree(ptr, __LINE__, __FILE__) - -#ifdef WIN32 -# ifdef UNICODE -# undef wcsdup -# define wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__) -# undef _wcsdup -# define _wcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__) -# undef _tcsdup -# define _tcsdup(ptr) curl_dowcsdup(ptr, __LINE__, __FILE__) -# else -# undef _tcsdup -# define _tcsdup(ptr) curl_dostrdup(ptr, __LINE__, __FILE__) -# endif -#endif - -#undef socket -#define socket(domain,type,protocol)\ - curl_socket(domain, type, protocol, __LINE__, __FILE__) -#undef accept /* for those with accept as a macro */ -#define accept(sock,addr,len)\ - curl_accept(sock, addr, len, __LINE__, __FILE__) -#ifdef HAVE_SOCKETPAIR -#define socketpair(domain,type,protocol,socket_vector)\ - curl_socketpair(domain, type, protocol, socket_vector, __LINE__, __FILE__) -#endif - -#ifdef HAVE_GETADDRINFO -#if defined(getaddrinfo) && defined(__osf__) -/* OSF/1 and Tru64 have getaddrinfo as a define already, so we cannot define - our macro as for other platforms. Instead, we redefine the new name they - define getaddrinfo to become! */ -#define ogetaddrinfo(host,serv,hint,res) \ - curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__) -#else -#undef getaddrinfo -#define getaddrinfo(host,serv,hint,res) \ - curl_dogetaddrinfo(host, serv, hint, res, __LINE__, __FILE__) -#endif -#endif /* HAVE_GETADDRINFO */ - -#ifdef HAVE_GETNAMEINFO -#undef getnameinfo -#define getnameinfo(sa,salen,host,hostlen,serv,servlen,flags) \ - curl_dogetnameinfo(sa, salen, host, hostlen, serv, servlen, flags, \ - __LINE__, __FILE__) -#endif /* HAVE_GETNAMEINFO */ - -#ifdef HAVE_FREEADDRINFO -#undef freeaddrinfo -#define freeaddrinfo(data) \ - curl_dofreeaddrinfo(data, __LINE__, __FILE__) -#endif /* HAVE_FREEADDRINFO */ - -/* sclose is probably already defined, redefine it! */ -#undef sclose -#define sclose(sockfd) curl_sclose(sockfd,__LINE__,__FILE__) - -#define fake_sclose(sockfd) curl_mark_sclose(sockfd,__LINE__,__FILE__) - -#undef fopen -#define fopen(file,mode) curl_fopen(file,mode,__LINE__,__FILE__) -#undef fdopen -#define fdopen(file,mode) curl_fdopen(file,mode,__LINE__,__FILE__) -#define fclose(file) curl_fclose(file,__LINE__,__FILE__) - -#endif /* MEMDEBUG_NODEFINES */ - -#endif /* CURLDEBUG */ - -/* -** Following section applies even when CURLDEBUG is not defined. -*/ - -#ifndef fake_sclose -#define fake_sclose(x) Curl_nop_stmt -#endif - -/* - * Curl_safefree defined as a macro to allow MemoryTracking feature - * to log free() calls at same location where Curl_safefree is used. - * This macro also assigns NULL to given pointer when free'd. - */ - -#define Curl_safefree(ptr) \ - do { free((ptr)); (ptr) = NULL;} WHILE_FALSE - -#endif /* HEADER_CURL_MEMDEBUG_H */ diff --git a/Externals/curl/lib/mk-ca-bundle.pl b/Externals/curl/lib/mk-ca-bundle.pl deleted file mode 100755 index 5a1435c522..0000000000 --- a/Externals/curl/lib/mk-ca-bundle.pl +++ /dev/null @@ -1,499 +0,0 @@ -#!/usr/bin/perl -w -# *************************************************************************** -# * _ _ ____ _ -# * Project ___| | | | _ \| | -# * / __| | | | |_) | | -# * | (__| |_| | _ <| |___ -# * \___|\___/|_| \_\_____| -# * -# * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. -# * -# * This software is licensed as described in the file COPYING, which -# * you should have received as part of this distribution. The terms -# * are also available at https://curl.haxx.se/docs/copyright.html. -# * -# * You may opt to use, copy, modify, merge, publish, distribute and/or sell -# * copies of the Software, and permit persons to whom the Software is -# * furnished to do so, under the terms of the COPYING file. -# * -# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# * KIND, either express or implied. -# * -# *************************************************************************** -# This Perl script creates a fresh ca-bundle.crt file for use with libcurl. -# It downloads certdata.txt from Mozilla's source tree (see URL below), -# then parses certdata.txt and extracts CA Root Certificates into PEM format. -# These are then processed with the OpenSSL commandline tool to produce the -# final ca-bundle.crt file. -# The script is based on the parse-certs script written by Roland Krikava. -# This Perl script works on almost any platform since its only external -# dependency is the OpenSSL commandline tool for optional text listing. -# Hacked by Guenter Knauf. -# -use Getopt::Std; -use MIME::Base64; -use LWP::UserAgent; -use strict; -use vars qw($opt_b $opt_d $opt_f $opt_h $opt_i $opt_l $opt_n $opt_p $opt_q $opt_s $opt_t $opt_u $opt_v $opt_w); -use List::Util; -use Text::Wrap; -my $MOD_SHA = "Digest::SHA"; -eval "require $MOD_SHA"; -if ($@) { - $MOD_SHA = "Digest::SHA::PurePerl"; - eval "require $MOD_SHA"; -} - -my %urls = ( - 'nss' => - 'http://hg.mozilla.org/projects/nss/raw-file/tip/lib/ckfw/builtins/certdata.txt', - 'central' => - 'http://hg.mozilla.org/mozilla-central/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', - 'aurora' => - 'http://hg.mozilla.org/releases/mozilla-aurora/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', - 'beta' => - 'http://hg.mozilla.org/releases/mozilla-beta/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', - 'release' => - 'http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt', -); - -$opt_d = 'release'; - -# If the OpenSSL commandline is not in search path you can configure it here! -my $openssl = 'openssl'; - -my $version = '1.25'; - -$opt_w = 76; # default base64 encoded lines length - -# default cert types to include in the output (default is to include CAs which may issue SSL server certs) -my $default_mozilla_trust_purposes = "SERVER_AUTH"; -my $default_mozilla_trust_levels = "TRUSTED_DELEGATOR"; -$opt_p = $default_mozilla_trust_purposes . ":" . $default_mozilla_trust_levels; - -my @valid_mozilla_trust_purposes = ( - "DIGITAL_SIGNATURE", - "NON_REPUDIATION", - "KEY_ENCIPHERMENT", - "DATA_ENCIPHERMENT", - "KEY_AGREEMENT", - "KEY_CERT_SIGN", - "CRL_SIGN", - "SERVER_AUTH", - "CLIENT_AUTH", - "CODE_SIGNING", - "EMAIL_PROTECTION", - "IPSEC_END_SYSTEM", - "IPSEC_TUNNEL", - "IPSEC_USER", - "TIME_STAMPING", - "STEP_UP_APPROVED" -); - -my @valid_mozilla_trust_levels = ( - "TRUSTED_DELEGATOR", # CAs - "NOT_TRUSTED", # Don't trust these certs. - "MUST_VERIFY_TRUST", # This explicitly tells us that it ISN'T a CA but is otherwise ok. In other words, this should tell the app to ignore any other sources that claim this is a CA. - "TRUSTED" # This cert is trusted, but only for itself and not for delegates (i.e. it is not a CA). -); - -my $default_signature_algorithms = $opt_s = "MD5"; - -my @valid_signature_algorithms = ( - "MD5", - "SHA1", - "SHA256", - "SHA384", - "SHA512" -); - -$0 =~ s@.*(/|\\)@@; -$Getopt::Std::STANDARD_HELP_VERSION = 1; -getopts('bd:fhilnp:qs:tuvw:'); - -if(!defined($opt_d)) { - # to make plain "-d" use not cause warnings, and actually still work - $opt_d = 'release'; -} - -# Use predefined URL or else custom URL specified on command line. -my $url = ( defined( $urls{$opt_d} ) ) ? $urls{$opt_d} : $opt_d; - -my $curl = `curl -V`; - -if ($opt_i) { - print ("=" x 78 . "\n"); - print "Script Version : $version\n"; - print "Perl Version : $]\n"; - print "Operating System Name : $^O\n"; - print "Getopt::Std.pm Version : ${Getopt::Std::VERSION}\n"; - print "MIME::Base64.pm Version : ${MIME::Base64::VERSION}\n"; - print "LWP::UserAgent.pm Version : ${LWP::UserAgent::VERSION}\n"; - print "LWP.pm Version : ${LWP::VERSION}\n"; - print "Digest::SHA.pm Version : ${Digest::SHA::VERSION}\n" if ($Digest::SHA::VERSION); - print "Digest::SHA::PurePerl.pm Version : ${Digest::SHA::PurePerl::VERSION}\n" if ($Digest::SHA::PurePerl::VERSION); - print ("=" x 78 . "\n"); -} - -sub warning_message() { - if ( $opt_d =~ m/^risk$/i ) { # Long Form Warning and Exit - print "Warning: Use of this script may pose some risk:\n"; - print "\n"; - print " 1) Using http is subject to man in the middle attack of certdata content\n"; - print " 2) Default to 'release', but more recent updates may be found in other trees\n"; - print " 3) certdata.txt file format may change, lag time to update this script\n"; - print " 4) Generally unwise to blindly trust CAs without manual review & verification\n"; - print " 5) Mozilla apps use additional security checks aren't represented in certdata\n"; - print " 6) Use of this script will make a security engineer grind his teeth and\n"; - print " swear at you. ;)\n"; - exit; - } else { # Short Form Warning - print "Warning: Use of this script may pose some risk, -d risk for more details.\n"; - } -} - -sub HELP_MESSAGE() { - print "Usage:\t${0} [-b] [-d] [-f] [-i] [-l] [-n] [-p] [-q] [-s] [-t] [-u] [-v] [-w] []\n"; - print "\t-b\tbackup an existing version of ca-bundle.crt\n"; - print "\t-d\tspecify Mozilla tree to pull certdata.txt or custom URL\n"; - print "\t\t Valid names are:\n"; - print "\t\t ", join( ", ", map { ( $_ =~ m/$opt_d/ ) ? "$_ (default)" : "$_" } sort keys %urls ), "\n"; - print "\t-f\tforce rebuild even if certdata.txt is current\n"; - print "\t-i\tprint version info about used modules\n"; - print "\t-l\tprint license info about certdata.txt\n"; - print "\t-n\tno download of certdata.txt (to use existing)\n"; - print wrap("\t","\t\t", "-p\tlist of Mozilla trust purposes and levels for certificates to include in output. Takes the form of a comma separated list of purposes, a colon, and a comma separated list of levels. (default: $default_mozilla_trust_purposes:$default_mozilla_trust_levels)"), "\n"; - print "\t\t Valid purposes are:\n"; - print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_purposes ) ), "\n"; - print "\t\t Valid levels are:\n"; - print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_mozilla_trust_levels ) ), "\n"; - print "\t-q\tbe really quiet (no progress output at all)\n"; - print wrap("\t","\t\t", "-s\tcomma separated list of certificate signatures/hashes to output in plain text mode. (default: $default_signature_algorithms)\n"); - print "\t\t Valid signature algorithms are:\n"; - print wrap("\t\t ","\t\t ", join( ", ", "ALL", @valid_signature_algorithms ) ), "\n"; - print "\t-t\tinclude plain text listing of certificates\n"; - print "\t-u\tunlink (remove) certdata.txt after processing\n"; - print "\t-v\tbe verbose and print out processed CAs\n"; - print "\t-w \twrap base64 output lines after chars (default: ${opt_w})\n"; - exit; -} - -sub VERSION_MESSAGE() { - print "${0} version ${version} running Perl ${]} on ${^O}\n"; -} - -warning_message() unless ($opt_q || $url =~ m/^(ht|f)tps:/i ); -HELP_MESSAGE() if ($opt_h); - -sub report($@) { - my $output = shift; - - print STDERR $output . "\n" unless $opt_q; -} - -sub is_in_list($@) { - my $target = shift; - - return defined(List::Util::first { $target eq $_ } @_); -} - -# Parses $param_string as a case insensitive comma separated list with optional whitespace -# validates that only allowed parameters are supplied -sub parse_csv_param($$@) { - my $description = shift; - my $param_string = shift; - my @valid_values = @_; - - my @values = map { - s/^\s+//; # strip leading spaces - s/\s+$//; # strip trailing spaces - uc $_ # return the modified string as upper case - } split( ',', $param_string ); - - # Find all values which are not in the list of valid values or "ALL" - my @invalid = grep { !is_in_list($_,"ALL",@valid_values) } @values; - - if ( scalar(@invalid) > 0 ) { - # Tell the user which parameters were invalid and print the standard help message which will exit - print "Error: Invalid ", $description, scalar(@invalid) == 1 ? ": " : "s: ", join( ", ", map { "\"$_\"" } @invalid ), "\n"; - HELP_MESSAGE(); - } - - @values = @valid_values if ( is_in_list("ALL",@values) ); - - return @values; -} - -sub sha1 { - my $result; - if ($Digest::SHA::VERSION || $Digest::SHA::PurePerl::VERSION) { - open(FILE, $_[0]) or die "Can't open '$_[0]': $!"; - binmode(FILE); - $result = $MOD_SHA->new(1)->addfile(*FILE)->hexdigest; - close(FILE); - } else { - # Use OpenSSL command if Perl Digest::SHA modules not available - $result = (split(/ |\r|\n/,`$openssl dgst -sha1 $_[0]`))[1]; - } - return $result; -} - - -sub oldsha1 { - my $sha1 = ""; - open(C, "<$_[0]") || return 0; - while() { - chomp; - if($_ =~ /^\#\# SHA1: (.*)/) { - $sha1 = $1; - last; - } - } - close(C); - return $sha1; -} - -if ( $opt_p !~ m/:/ ) { - print "Error: Mozilla trust identifier list must include both purposes and levels\n"; - HELP_MESSAGE(); -} - -(my $included_mozilla_trust_purposes_string, my $included_mozilla_trust_levels_string) = split( ':', $opt_p ); -my @included_mozilla_trust_purposes = parse_csv_param( "trust purpose", $included_mozilla_trust_purposes_string, @valid_mozilla_trust_purposes ); -my @included_mozilla_trust_levels = parse_csv_param( "trust level", $included_mozilla_trust_levels_string, @valid_mozilla_trust_levels ); - -my @included_signature_algorithms = parse_csv_param( "signature algorithm", $opt_s, @valid_signature_algorithms ); - -sub should_output_cert(%) { - my %trust_purposes_by_level = @_; - - foreach my $level (@included_mozilla_trust_levels) { - # for each level we want to output, see if any of our desired purposes are included - return 1 if ( defined( List::Util::first { is_in_list( $_, @included_mozilla_trust_purposes ) } @{$trust_purposes_by_level{$level}} ) ); - } - - return 0; -} - -my $crt = $ARGV[0] || 'ca-bundle.crt'; -(my $txt = $url) =~ s@(.*/|\?.*)@@g; - -my $stdout = $crt eq '-'; -my $resp; -my $fetched; - -my $oldsha1 = oldsha1($crt); - -report "SHA1 of old file: $oldsha1"; - -report "Downloading '$txt' ..."; - -if($curl && !$opt_n) { - my $https = $url; - $https =~ s/^http:/https:/; - report "Get certdata over HTTPS with curl!"; - my $quiet = $opt_q ? "-s" : ""; - my @out = `curl -w %{response_code} $quiet -O $https`; - if(@out && $out[0] == 200) { - $fetched = 1; - } else { - report "Failed downloading HTTPS with curl, trying HTTP with LWP"; - } -} - -unless ($fetched || ($opt_n and -e $txt)) { - my $ua = new LWP::UserAgent(agent => "$0/$version"); - $ua->env_proxy(); - $resp = $ua->mirror($url, $txt); - if ($resp && $resp->code eq '304') { - report "Not modified"; - exit 0 if -e $crt && !$opt_f; - } else { - $fetched = 1; - } - if( !$resp || $resp->code !~ /^(?:200|304)$/ ) { - report "Unable to download latest data: " - . ($resp? $resp->code . ' - ' . $resp->message : "LWP failed"); - exit 1 if -e $crt || ! -r $txt; - } -} - -my $filedate = $resp ? $resp->last_modified : (stat($txt))[9]; -my $datesrc = "as of"; -if(!$filedate) { - # mxr.mozilla.org gave us a time, hg.mozilla.org does not! - $filedate = time(); - $datesrc="downloaded on"; -} - -# get the hash from the download file -my $newsha1= sha1($txt); - -if(!$opt_f && $oldsha1 eq $newsha1) { - report "Downloaded file identical to previous run\'s source file. Exiting"; - exit; -} - -report "SHA1 of new file: $newsha1"; - -my $currentdate = scalar gmtime($filedate); - -my $format = $opt_t ? "plain text and " : ""; -if( $stdout ) { - open(CRT, '> -') or die "Couldn't open STDOUT: $!\n"; -} else { - open(CRT,">$crt.~") or die "Couldn't open $crt.~: $!\n"; -} -print CRT <) { - if (/\*\*\*\*\* BEGIN LICENSE BLOCK \*\*\*\*\*/) { - print CRT; - print if ($opt_l); - while () { - print CRT; - print if ($opt_l); - last if (/\*\*\*\*\* END LICENSE BLOCK \*\*\*\*\*/); - } - } - next if /^#|^\s*$/; - chomp; - if (/^CVS_ID\s+\"(.*)\"/) { - print CRT "# $1\n"; - } - - # this is a match for the start of a certificate - if (/^CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE/) { - $start_of_cert = 1 - } - if ($start_of_cert && /^CKA_LABEL UTF8 \"(.*)\"/) { - $caname = $1; - } - my %trust_purposes_by_level; - if ($start_of_cert && /^CKA_VALUE MULTILINE_OCTAL/) { - my $data; - while () { - last if (/^END/); - chomp; - my @octets = split(/\\/); - shift @octets; - for (@octets) { - $data .= chr(oct); - } - } - # scan forwards until the trust part - while () { - last if (/^CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST/); - chomp; - } - # now scan the trust part to determine how we should trust this cert - while () { - last if (/^#/); - if (/^CKA_TRUST_([A-Z_]+)\s+CK_TRUST\s+CKT_NSS_([A-Z_]+)\s*$/) { - if ( !is_in_list($1,@valid_mozilla_trust_purposes) ) { - report "Warning: Unrecognized trust purpose for cert: $caname. Trust purpose: $1. Trust Level: $2"; - } elsif ( !is_in_list($2,@valid_mozilla_trust_levels) ) { - report "Warning: Unrecognized trust level for cert: $caname. Trust purpose: $1. Trust Level: $2"; - } else { - push @{$trust_purposes_by_level{$2}}, $1; - } - } - } - - if ( !should_output_cert(%trust_purposes_by_level) ) { - $skipnum ++; - } else { - my $encoded = MIME::Base64::encode_base64($data, ''); - $encoded =~ s/(.{1,${opt_w}})/$1\n/g; - my $pem = "-----BEGIN CERTIFICATE-----\n" - . $encoded - . "-----END CERTIFICATE-----\n"; - print CRT "\n$caname\n"; - - my $maxStringLength = length($caname); - if ($opt_t) { - foreach my $key (keys %trust_purposes_by_level) { - my $string = $key . ": " . join(", ", @{$trust_purposes_by_level{$key}}); - $maxStringLength = List::Util::max( length($string), $maxStringLength ); - print CRT $string . "\n"; - } - } - print CRT ("=" x $maxStringLength . "\n"); - if (!$opt_t) { - print CRT $pem; - } else { - my $pipe = ""; - foreach my $hash (@included_signature_algorithms) { - $pipe = "|$openssl x509 -" . $hash . " -fingerprint -noout -inform PEM"; - if (!$stdout) { - $pipe .= " >> $crt.~"; - close(CRT) or die "Couldn't close $crt.~: $!"; - } - open(TMP, $pipe) or die "Couldn't open openssl pipe: $!"; - print TMP $pem; - close(TMP) or die "Couldn't close openssl pipe: $!"; - if (!$stdout) { - open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!"; - } - } - $pipe = "|$openssl x509 -text -inform PEM"; - if (!$stdout) { - $pipe .= " >> $crt.~"; - close(CRT) or die "Couldn't close $crt.~: $!"; - } - open(TMP, $pipe) or die "Couldn't open openssl pipe: $!"; - print TMP $pem; - close(TMP) or die "Couldn't close openssl pipe: $!"; - if (!$stdout) { - open(CRT, ">>$crt.~") or die "Couldn't open $crt.~: $!"; - } - } - report "Parsing: $caname" if ($opt_v); - $certnum ++; - $start_of_cert = 0; - } - } -} -close(TXT) or die "Couldn't close $txt: $!\n"; -close(CRT) or die "Couldn't close $crt.~: $!\n"; -unless( $stdout ) { - if ($opt_b && -e $crt) { - my $bk = 1; - while (-e "$crt.~${bk}~") { - $bk++; - } - rename $crt, "$crt.~${bk}~" or die "Failed to create backup $crt.~$bk}~: $!\n"; - } elsif( -e $crt ) { - unlink( $crt ) or die "Failed to remove $crt: $!\n"; - } - rename "$crt.~", $crt or die "Failed to rename $crt.~ to $crt: $!\n"; -} -unlink $txt if ($opt_u); -report "Done ($certnum CA certs processed, $skipnum skipped)."; diff --git a/Externals/curl/lib/mk-ca-bundle.vbs b/Externals/curl/lib/mk-ca-bundle.vbs deleted file mode 100755 index b0d9427794..0000000000 --- a/Externals/curl/lib/mk-ca-bundle.vbs +++ /dev/null @@ -1,286 +0,0 @@ -'*************************************************************************** -'* _ _ ____ _ -'* Project ___| | | | _ \| | -'* / __| | | | |_) | | -'* | (__| |_| | _ <| |___ -'* \___|\___/|_| \_\_____| -'* -'* Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. -'* -'* This software is licensed as described in the file COPYING, which -'* you should have received as part of this distribution. The terms -'* are also available at https://curl.haxx.se/docs/copyright.html. -'* -'* You may opt to use, copy, modify, merge, publish, distribute and/or sell -'* copies of the Software, and permit persons to whom the Software is -'* furnished to do so, under the terms of the COPYING file. -'* -'* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -'* KIND, either express or implied. -'* -'*************************************************************************** -'* Script to fetch certdata.txt from Mozilla.org site and create a -'* ca-bundle.crt for use with OpenSSL / libcurl / libcurl bindings -'* Requires WinHttp.WinHttpRequest.5.1 and ADODB.Stream which are part of -'* W2000 SP3 or later, WXP SP1 or later, W2003 Server SP1 or later. -'* Hacked by Guenter Knauf -'*************************************************************************** -Option Explicit -Const myVersion = "0.3.9" - -Const myUrl = "http://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt" -Const myOpenssl = "openssl.exe" - -Const myCdSavF = FALSE ' Flag: save downloaded data to file certdata.txt -Const myCaBakF = TRUE ' Flag: backup existing ca-bundle certificate -Const myAskLiF = TRUE ' Flag: display certdata.txt license agreement -Const myAskTiF = TRUE ' Flag: ask to include certificate text info -Const myWrapLe = 76 ' Default length of base64 output lines - -'******************* Nothing to configure below! ******************* -Dim objShell, objNetwork, objFSO, objHttp -Dim myBase, mySelf, myFh, myTmpFh, myCdData, myCdFile, myCaFile, myTmpName, myBakNum, myOptTxt, i -Set objNetwork = WScript.CreateObject("WScript.Network") -Set objShell = WScript.CreateObject("WScript.Shell") -Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") -Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest.5.1") -If objHttp Is Nothing Then Set objHttp = WScript.CreateObject("WinHttp.WinHttpRequest") -myBase = Left(WScript.ScriptFullName, InstrRev(WScript.ScriptFullName, "\")) -mySelf = Left(WScript.ScriptName, InstrRev(WScript.ScriptName, ".") - 1) & " " & myVersion -myCdFile = Mid(myUrl, InstrRev(myUrl, "/") + 1) -myCaFile = "ca-bundle.crt" -myTmpName = InputBox("Enter output filename:", mySelf, myCaFile) -If Not (myTmpName = "") Then - myCaFile = myTmpName -End If -' Lets ignore SSL invalid cert errors -objHttp.Option(4) = 256 + 512 + 4096 + 8192 -objHttp.SetTimeouts 0, 5000, 10000, 10000 -objHttp.Open "GET", myUrl, FALSE -objHttp.setRequestHeader "User-Agent", WScript.ScriptName & "/" & myVersion -objHttp.Send "" -If Not (objHttp.Status = 200) Then - MsgBox("Failed to download '" & myCdFile & "': " & objHttp.Status & " - " & objHttp.StatusText), vbCritical, mySelf - WScript.Quit 1 -End If -' Convert data from ResponseBody instead of using ResponseText because of UTF-8 -myCdData = ConvertBinaryData(objHttp.ResponseBody) -Set objHttp = Nothing -' Write received data to file if enabled -If (myCdSavF = TRUE) Then - Set myFh = objFSO.OpenTextFile(myCdFile, 2, TRUE) - myFh.Write myCdData - myFh.Close -End If -' Backup exitsing ca-bundle certificate file -If (myCaBakF = TRUE) Then - If objFSO.FileExists(myCaFile) Then - Dim myBakFile, b - b = 1 - myBakFile = myCaFile & ".~" & b & "~" - While objFSO.FileExists(myBakFile) - b = b + 1 - myBakFile = myCaFile & ".~" & b & "~" - Wend - Set myTmpFh = objFSO.GetFile(myCaFile) - myTmpFh.Move myBakFile - End If -End If -If (myAskTiF = TRUE) Then - If (6 = objShell.PopUp("Do you want to include text information about each certificate?" & vbLf & _ - "(requires OpenSSL commandline in current directory or in search path)",, _ - mySelf, vbQuestion + vbYesNo + vbDefaultButton2)) Then - myOptTxt = TRUE - Else - myOptTxt = FALSE - End If -End If -' Process the received data -Dim myLines, myPattern, myInsideCert, myInsideLicense, myLicenseText, myNumCerts, myNumSkipped -Dim myLabel, myOctets, myData, myPem, myRev, myUntrusted, j -myNumSkipped = 0 -myNumCerts = 0 -myData = "" -myLines = Split(myCdData, vbLf, -1) -Set myFh = objFSO.OpenTextFile(myCaFile, 2, TRUE) -myFh.Write "##" & vbLf -myFh.Write "## " & myCaFile & " -- Bundle of CA Root Certificates" & vbLf -myFh.Write "##" & vbLf -myFh.Write "## Converted at: " & Now & vbLf -myFh.Write "##" & vbLf -myFh.Write "## This is a bundle of X.509 certificates of public Certificate Authorities" & vbLf -myFh.Write "## (CA). These were automatically extracted from Mozilla's root certificates" & vbLf -myFh.Write "## file (certdata.txt). This file can be found in the mozilla source tree:" & vbLf -myFh.Write "## '/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt'" & vbLf -myFh.Write "##" & vbLf -myFh.Write "## It contains the certificates in PEM format and therefore" & vbLf -myFh.Write "## can be directly used with curl / libcurl / php_curl, or with" & vbLf -myFh.Write "## an Apache+mod_ssl webserver for SSL client authentication." & vbLf -myFh.Write "## Just configure this file as the SSLCACertificateFile." & vbLf -myFh.Write "##" & vbLf -myFh.Write vbLf -For i = 0 To UBound(myLines) - If InstrRev(myLines(i), "CKA_LABEL ") Then - myPattern = "^CKA_LABEL\s+[A-Z0-9]+\s+""(.+?)""" - myLabel = RegExprFirst(myPattern, myLines(i)) - End If - If (myInsideCert = TRUE) Then - If InstrRev(myLines(i), "END") Then - myInsideCert = FALSE - While (i < UBound(myLines)) And Not (myLines(i) = "#") - i = i + 1 - If InstrRev(myLines(i), "CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR") Then - myUntrusted = FALSE - End If - Wend - If (myUntrusted = TRUE) Then - myNumSkipped = myNumSkipped + 1 - Else - myFh.Write myLabel & vbLf - myFh.Write String(Len(myLabel), "=") & vbLf - myPem = "-----BEGIN CERTIFICATE-----" & vbLf & _ - Base64Encode(myData) & vbLf & _ - "-----END CERTIFICATE-----" & vbLf - If (myOptTxt = FALSE) Then - myFh.Write myPem & vbLf - Else - Dim myCmd, myRval, myTmpIn, myTmpOut - myTmpIn = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName - myTmpOut = objFSO.GetSpecialFolder(2).Path & "\" & objFSO.GetTempName - Set myTmpFh = objFSO.OpenTextFile(myTmpIn, 2, TRUE) - myTmpFh.Write myPem - myTmpFh.Close - myCmd = myOpenssl & " x509 -md5 -fingerprint -text -inform PEM" & _ - " -in " & myTmpIn & " -out " & myTmpOut - myRval = objShell.Run (myCmd, 0, TRUE) - objFSO.DeleteFile myTmpIn, TRUE - If Not (myRval = 0) Then - MsgBox("Failed to process PEM cert with OpenSSL commandline!"), vbCritical, mySelf - objFSO.DeleteFile myTmpOut, TRUE - WScript.Quit 3 - End If - Set myTmpFh = objFSO.OpenTextFile(myTmpOut, 1) - myFh.Write myTmpFh.ReadAll & vbLf - myTmpFh.Close - objFSO.DeleteFile myTmpOut, TRUE - End If - myNumCerts = myNumCerts + 1 - End If - Else - myOctets = Split(myLines(i), "\") - For j = 1 To UBound(myOctets) - myData = myData & Chr(CByte("&o" & myOctets(j))) - Next - End If - End If - If InstrRev(myLines(i), "CVS_ID ") Then - myPattern = "^CVS_ID\s+""(.+?)""" - myRev = RegExprFirst(myPattern, myLines(i)) - myFh.Write "# " & myRev & vbLf & vbLf - End If - If InstrRev(myLines(i), "CKA_VALUE MULTILINE_OCTAL") Then - myInsideCert = TRUE - myUntrusted = TRUE - myData = "" - End If - If InstrRev(myLines(i), "***** BEGIN LICENSE BLOCK *****") Then - myInsideLicense = TRUE - End If - If (myInsideLicense = TRUE) Then - myFh.Write myLines(i) & vbLf - myLicenseText = myLicenseText & Mid(myLines(i), 2) & vbLf - End If - If InstrRev(myLines(i), "***** END LICENSE BLOCK *****") Then - myInsideLicense = FALSE - If (myAskLiF = TRUE) Then - If Not (6 = objShell.PopUp(myLicenseText & vbLf & _ - "Do you agree to the license shown above (required to proceed) ?",, _ - mySelf, vbQuestion + vbYesNo + vbDefaultButton1)) Then - myFh.Close - objFSO.DeleteFile myCaFile, TRUE - WScript.Quit 2 - End If - End If - End If -Next -myFh.Close -objShell.PopUp "Done (" & myNumCerts & " CA certs processed, " & myNumSkipped & _ - " untrusted skipped).", 20, mySelf, vbInformation -WScript.Quit 0 - -Function ConvertBinaryData(arrBytes) - Dim objStream - Set objStream = CreateObject("ADODB.Stream") - objStream.Open - objStream.Type = 1 - objStream.Write arrBytes - objStream.Position = 0 - objStream.Type = 2 - objStream.Charset = "ascii" - ConvertBinaryData = objStream.ReadText - Set objStream = Nothing -End Function - -Function RegExprFirst(SearchPattern, TheString) - Dim objRegExp, Matches ' create variables. - Set objRegExp = New RegExp ' create a regular expression. - objRegExp.Pattern = SearchPattern ' sets the search pattern. - objRegExp.IgnoreCase = TRUE ' set to ignores case. - objRegExp.Global = TRUE ' set to gloabal search. - Set Matches = objRegExp.Execute(TheString) ' do the search. - If (Matches.Count) Then - RegExprFirst = Matches(0).SubMatches(0) ' return first match. - Else - RegExprFirst = "" - End If - Set objRegExp = Nothing -End Function - -Function Base64Encode(inData) - Const Base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - Dim cOut, sOut, lWrap, I - lWrap = Int(myWrapLe * 3 / 4) - - 'For each group of 3 bytes - For I = 1 To Len(inData) Step 3 - Dim nGroup, pOut, sGroup - - 'Create one long from this 3 bytes. - nGroup = &H10000 * Asc(Mid(inData, I, 1)) + _ - &H100 * MyASC(Mid(inData, I + 1, 1)) + _ - MyASC(Mid(inData, I + 2, 1)) - - 'Oct splits the long To 8 groups with 3 bits - nGroup = Oct(nGroup) - - 'Add leading zeros - nGroup = String(8 - Len(nGroup), "0") & nGroup - - 'Convert To base64 - pOut = Mid(Base64, CLng("&o" & Mid(nGroup, 1, 2)) + 1, 1) & _ - Mid(Base64, CLng("&o" & Mid(nGroup, 3, 2)) + 1, 1) & _ - Mid(Base64, CLng("&o" & Mid(nGroup, 5, 2)) + 1, 1) & _ - Mid(Base64, CLng("&o" & Mid(nGroup, 7, 2)) + 1, 1) - - 'Add the part To OutPut string - sOut = sOut + pOut - - 'Add a new line For Each myWrapLe chars In dest - If (I < Len(inData) - 2) Then - If (I + 2) Mod lWrap = 0 Then sOut = sOut & vbLf - End If - Next - Select Case Len(inData) Mod 3 - Case 1: '8 bit final - sOut = Left(sOut, Len(sOut) - 2) & "==" - Case 2: '16 bit final - sOut = Left(sOut, Len(sOut) - 1) & "=" - End Select - Base64Encode = sOut -End Function - -Function MyASC(OneChar) - If OneChar = "" Then MyASC = 0 Else MyASC = Asc(OneChar) -End Function - - diff --git a/Externals/curl/lib/mprintf.c b/Externals/curl/lib/mprintf.c deleted file mode 100644 index 73f854bcbd..0000000000 --- a/Externals/curl/lib/mprintf.c +++ /dev/null @@ -1,1160 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1999 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * - * Purpose: - * A merge of Bjorn Reese's format() function and Daniel's dsprintf() - * 1.0. A full blooded printf() clone with full support for $ - * everywhere (parameters, widths and precisions) including variabled - * sized parameters (like doubles, long longs, long doubles and even - * void * in 64-bit architectures). - * - * Current restrictions: - * - Max 128 parameters - * - No 'long double' support. - * - * If you ever want truly portable and good *printf() clones, the project that - * took on from here is named 'Trio' and you find more details on the trio web - * page at https://daniel.haxx.se/projects/trio/ - */ - -#include "curl_setup.h" -#include - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#ifndef SIZEOF_LONG_DOUBLE -#define SIZEOF_LONG_DOUBLE 0 -#endif - -/* - * If SIZEOF_SIZE_T has not been defined, default to the size of long. - */ - -#ifndef SIZEOF_SIZE_T -# define SIZEOF_SIZE_T CURL_SIZEOF_LONG -#endif - -#ifdef HAVE_LONGLONG -# define LONG_LONG_TYPE long long -# define HAVE_LONG_LONG_TYPE -#else -# if defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) -# define LONG_LONG_TYPE __int64 -# define HAVE_LONG_LONG_TYPE -# else -# undef LONG_LONG_TYPE -# undef HAVE_LONG_LONG_TYPE -# endif -#endif - -/* - * Non-ANSI integer extensions - */ - -#if (defined(__BORLANDC__) && (__BORLANDC__ >= 0x520)) || \ - (defined(__WATCOMC__) && defined(__386__)) || \ - (defined(__POCC__) && defined(_MSC_VER)) || \ - (defined(_WIN32_WCE)) || \ - (defined(__MINGW32__)) || \ - (defined(_MSC_VER) && (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64)) -# define MP_HAVE_INT_EXTENSIONS -#endif - -/* - * Max integer data types that mprintf.c is capable - */ - -#ifdef HAVE_LONG_LONG_TYPE -# define mp_intmax_t LONG_LONG_TYPE -# define mp_uintmax_t unsigned LONG_LONG_TYPE -#else -# define mp_intmax_t long -# define mp_uintmax_t unsigned long -#endif - -#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */ -#define MAX_PARAMETERS 128 /* lame static limit */ - -#ifdef __AMIGA__ -# undef FORMAT_INT -#endif - -/* Lower-case digits. */ -static const char lower_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; - -/* Upper-case digits. */ -static const char upper_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -#define OUTCHAR(x) \ - do{ \ - if(stream((unsigned char)(x), (FILE *)data) != -1) \ - done++; \ - else \ - return done; /* return immediately on failure */ \ - } WHILE_FALSE - -/* Data type to read from the arglist */ -typedef enum { - FORMAT_UNKNOWN = 0, - FORMAT_STRING, - FORMAT_PTR, - FORMAT_INT, - FORMAT_INTPTR, - FORMAT_LONG, - FORMAT_LONGLONG, - FORMAT_DOUBLE, - FORMAT_LONGDOUBLE, - FORMAT_WIDTH /* For internal use */ -} FormatType; - -/* conversion and display flags */ -enum { - FLAGS_NEW = 0, - FLAGS_SPACE = 1<<0, - FLAGS_SHOWSIGN = 1<<1, - FLAGS_LEFT = 1<<2, - FLAGS_ALT = 1<<3, - FLAGS_SHORT = 1<<4, - FLAGS_LONG = 1<<5, - FLAGS_LONGLONG = 1<<6, - FLAGS_LONGDOUBLE = 1<<7, - FLAGS_PAD_NIL = 1<<8, - FLAGS_UNSIGNED = 1<<9, - FLAGS_OCTAL = 1<<10, - FLAGS_HEX = 1<<11, - FLAGS_UPPER = 1<<12, - FLAGS_WIDTH = 1<<13, /* '*' or '*$' used */ - FLAGS_WIDTHPARAM = 1<<14, /* width PARAMETER was specified */ - FLAGS_PREC = 1<<15, /* precision was specified */ - FLAGS_PRECPARAM = 1<<16, /* precision PARAMETER was specified */ - FLAGS_CHAR = 1<<17, /* %c story */ - FLAGS_FLOATE = 1<<18, /* %e or %E */ - FLAGS_FLOATG = 1<<19 /* %g or %G */ -}; - -typedef struct { - FormatType type; - int flags; - long width; /* width OR width parameter number */ - long precision; /* precision OR precision parameter number */ - union { - char *str; - void *ptr; - union { - mp_intmax_t as_signed; - mp_uintmax_t as_unsigned; - } num; - double dnum; - } data; -} va_stack_t; - -struct nsprintf { - char *buffer; - size_t length; - size_t max; -}; - -struct asprintf { - char *buffer; /* allocated buffer */ - size_t len; /* length of string */ - size_t alloc; /* length of alloc */ - int fail; /* (!= 0) if an alloc has failed and thus - the output is not the complete data */ -}; - -static long dprintf_DollarString(char *input, char **end) -{ - int number=0; - while(ISDIGIT(*input)) { - number *= 10; - number += *input-'0'; - input++; - } - if(number && ('$'==*input++)) { - *end = input; - return number; - } - return 0; -} - -static bool dprintf_IsQualifierNoDollar(const char *fmt) -{ -#if defined(MP_HAVE_INT_EXTENSIONS) - if(!strncmp(fmt, "I32", 3) || !strncmp(fmt, "I64", 3)) { - return TRUE; - } -#endif - - switch(*fmt) { - case '-': case '+': case ' ': case '#': case '.': - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - case 'h': case 'l': case 'L': case 'z': case 'q': - case '*': case 'O': -#if defined(MP_HAVE_INT_EXTENSIONS) - case 'I': -#endif - return TRUE; - - default: - return FALSE; - } -} - -/****************************************************************** - * - * Pass 1: - * Create an index with the type of each parameter entry and its - * value (may vary in size) - * - ******************************************************************/ - -static long dprintf_Pass1(const char *format, va_stack_t *vto, char **endpos, - va_list arglist) -{ - char *fmt = (char *)format; - int param_num = 0; - long this_param; - long width; - long precision; - int flags; - long max_param=0; - long i; - - while(*fmt) { - if(*fmt++ == '%') { - if(*fmt == '%') { - fmt++; - continue; /* while */ - } - - flags = FLAGS_NEW; - - /* Handle the positional case (N$) */ - - param_num++; - - this_param = dprintf_DollarString(fmt, &fmt); - if(0 == this_param) - /* we got no positional, get the next counter */ - this_param = param_num; - - if(this_param > max_param) - max_param = this_param; - - /* - * The parameter with number 'i' should be used. Next, we need - * to get SIZE and TYPE of the parameter. Add the information - * to our array. - */ - - width = 0; - precision = 0; - - /* Handle the flags */ - - while(dprintf_IsQualifierNoDollar(fmt)) { -#if defined(MP_HAVE_INT_EXTENSIONS) - if(!strncmp(fmt, "I32", 3)) { - flags |= FLAGS_LONG; - fmt += 3; - } - else if(!strncmp(fmt, "I64", 3)) { - flags |= FLAGS_LONGLONG; - fmt += 3; - } - else -#endif - - switch(*fmt++) { - case ' ': - flags |= FLAGS_SPACE; - break; - case '+': - flags |= FLAGS_SHOWSIGN; - break; - case '-': - flags |= FLAGS_LEFT; - flags &= ~FLAGS_PAD_NIL; - break; - case '#': - flags |= FLAGS_ALT; - break; - case '.': - flags |= FLAGS_PREC; - if('*' == *fmt) { - /* The precision is picked from a specified parameter */ - - flags |= FLAGS_PRECPARAM; - fmt++; - param_num++; - - i = dprintf_DollarString(fmt, &fmt); - if(i) - precision = i; - else - precision = param_num; - - if(precision > max_param) - max_param = precision; - } - else { - flags |= FLAGS_PREC; - precision = strtol(fmt, &fmt, 10); - } - break; - case 'h': - flags |= FLAGS_SHORT; - break; -#if defined(MP_HAVE_INT_EXTENSIONS) - case 'I': -#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG) - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; -#endif - case 'l': - if(flags & FLAGS_LONG) - flags |= FLAGS_LONGLONG; - else - flags |= FLAGS_LONG; - break; - case 'L': - flags |= FLAGS_LONGDOUBLE; - break; - case 'q': - flags |= FLAGS_LONGLONG; - break; - case 'z': - /* the code below generates a warning if -Wunreachable-code is - used */ -#if (SIZEOF_SIZE_T > CURL_SIZEOF_LONG) - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case 'O': -#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG) - flags |= FLAGS_LONGLONG; -#else - flags |= FLAGS_LONG; -#endif - break; - case '0': - if(!(flags & FLAGS_LEFT)) - flags |= FLAGS_PAD_NIL; - /* FALLTHROUGH */ - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - flags |= FLAGS_WIDTH; - width = strtol(fmt-1, &fmt, 10); - break; - case '*': /* Special case */ - flags |= FLAGS_WIDTHPARAM; - param_num++; - - i = dprintf_DollarString(fmt, &fmt); - if(i) - width = i; - else - width = param_num; - if(width > max_param) - max_param=width; - break; - default: - break; - } - } /* switch */ - - /* Handle the specifier */ - - i = this_param - 1; - - switch (*fmt) { - case 'S': - flags |= FLAGS_ALT; - /* FALLTHROUGH */ - case 's': - vto[i].type = FORMAT_STRING; - break; - case 'n': - vto[i].type = FORMAT_INTPTR; - break; - case 'p': - vto[i].type = FORMAT_PTR; - break; - case 'd': case 'i': - vto[i].type = FORMAT_INT; - break; - case 'u': - vto[i].type = FORMAT_INT; - flags |= FLAGS_UNSIGNED; - break; - case 'o': - vto[i].type = FORMAT_INT; - flags |= FLAGS_OCTAL; - break; - case 'x': - vto[i].type = FORMAT_INT; - flags |= FLAGS_HEX|FLAGS_UNSIGNED; - break; - case 'X': - vto[i].type = FORMAT_INT; - flags |= FLAGS_HEX|FLAGS_UPPER|FLAGS_UNSIGNED; - break; - case 'c': - vto[i].type = FORMAT_INT; - flags |= FLAGS_CHAR; - break; - case 'f': - vto[i].type = FORMAT_DOUBLE; - break; - case 'e': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATE; - break; - case 'E': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATE|FLAGS_UPPER; - break; - case 'g': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATG; - break; - case 'G': - vto[i].type = FORMAT_DOUBLE; - flags |= FLAGS_FLOATG|FLAGS_UPPER; - break; - default: - vto[i].type = FORMAT_UNKNOWN; - break; - } /* switch */ - - vto[i].flags = flags; - vto[i].width = width; - vto[i].precision = precision; - - if(flags & FLAGS_WIDTHPARAM) { - /* we have the width specified from a parameter, so we make that - parameter's info setup properly */ - long k = width - 1; - vto[i].width = k; - vto[k].type = FORMAT_WIDTH; - vto[k].flags = FLAGS_NEW; - /* can't use width or precision of width! */ - vto[k].width = 0; - vto[k].precision = 0; - } - if(flags & FLAGS_PRECPARAM) { - /* we have the precision specified from a parameter, so we make that - parameter's info setup properly */ - long k = precision - 1; - vto[i].precision = k; - vto[k].type = FORMAT_WIDTH; - vto[k].flags = FLAGS_NEW; - /* can't use width or precision of width! */ - vto[k].width = 0; - vto[k].precision = 0; - } - *endpos++ = fmt + 1; /* end of this sequence */ - } - } - - /* Read the arg list parameters into our data list */ - for(i=0; i$ sequence */ - param=dprintf_DollarString(f, &f); - - if(!param) - param = param_num; - else - --param; - - param_num++; /* increase this always to allow "%2$s %1$s %s" and then the - third %s will pick the 3rd argument */ - - p = &vto[param]; - - /* pick up the specified width */ - if(p->flags & FLAGS_WIDTHPARAM) { - width = (long)vto[p->width].data.num.as_signed; - param_num++; /* since the width is extracted from a parameter, we - must skip that to get to the next one properly */ - if(width < 0) { - /* "A negative field width is taken as a '-' flag followed by a - positive field width." */ - width = -width; - p->flags |= FLAGS_LEFT; - p->flags &= ~FLAGS_PAD_NIL; - } - } - else - width = p->width; - - /* pick up the specified precision */ - if(p->flags & FLAGS_PRECPARAM) { - prec = (long)vto[p->precision].data.num.as_signed; - param_num++; /* since the precision is extracted from a parameter, we - must skip that to get to the next one properly */ - if(prec < 0) - /* "A negative precision is taken as if the precision were - omitted." */ - prec = -1; - } - else if(p->flags & FLAGS_PREC) - prec = p->precision; - else - prec = -1; - - is_alt = (p->flags & FLAGS_ALT) ? 1 : 0; - - switch (p->type) { - case FORMAT_INT: - num = p->data.num.as_unsigned; - if(p->flags & FLAGS_CHAR) { - /* Character. */ - if(!(p->flags & FLAGS_LEFT)) - while(--width > 0) - OUTCHAR(' '); - OUTCHAR((char) num); - if(p->flags & FLAGS_LEFT) - while(--width > 0) - OUTCHAR(' '); - break; - } - if(p->flags & FLAGS_OCTAL) { - /* Octal unsigned integer. */ - base = 8; - goto unsigned_number; - } - else if(p->flags & FLAGS_HEX) { - /* Hexadecimal unsigned integer. */ - - digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; - base = 16; - goto unsigned_number; - } - else if(p->flags & FLAGS_UNSIGNED) { - /* Decimal unsigned integer. */ - base = 10; - goto unsigned_number; - } - - /* Decimal integer. */ - base = 10; - - is_neg = (p->data.num.as_signed < (mp_intmax_t)0) ? 1 : 0; - if(is_neg) { - /* signed_num might fail to hold absolute negative minimum by 1 */ - signed_num = p->data.num.as_signed + (mp_intmax_t)1; - signed_num = -signed_num; - num = (mp_uintmax_t)signed_num; - num += (mp_uintmax_t)1; - } - - goto number; - - unsigned_number: - /* Unsigned number of base BASE. */ - is_neg = 0; - - number: - /* Number of base BASE. */ - - /* Supply a default precision if none was given. */ - if(prec == -1) - prec = 1; - - /* Put the number in WORK. */ - w = workend; - while(num > 0) { - *w-- = digits[num % base]; - num /= base; - } - width -= (long)(workend - w); - prec -= (long)(workend - w); - - if(is_alt && base == 8 && prec <= 0) { - *w-- = '0'; - --width; - } - - if(prec > 0) { - width -= prec; - while(prec-- > 0) - *w-- = '0'; - } - - if(is_alt && base == 16) - width -= 2; - - if(is_neg || (p->flags & FLAGS_SHOWSIGN) || (p->flags & FLAGS_SPACE)) - --width; - - if(!(p->flags & FLAGS_LEFT) && !(p->flags & FLAGS_PAD_NIL)) - while(width-- > 0) - OUTCHAR(' '); - - if(is_neg) - OUTCHAR('-'); - else if(p->flags & FLAGS_SHOWSIGN) - OUTCHAR('+'); - else if(p->flags & FLAGS_SPACE) - OUTCHAR(' '); - - if(is_alt && base == 16) { - OUTCHAR('0'); - if(p->flags & FLAGS_UPPER) - OUTCHAR('X'); - else - OUTCHAR('x'); - } - - if(!(p->flags & FLAGS_LEFT) && (p->flags & FLAGS_PAD_NIL)) - while(width-- > 0) - OUTCHAR('0'); - - /* Write the number. */ - while(++w <= workend) { - OUTCHAR(*w); - } - - if(p->flags & FLAGS_LEFT) - while(width-- > 0) - OUTCHAR(' '); - break; - - case FORMAT_STRING: - /* String. */ - { - static const char null[] = "(nil)"; - const char *str; - size_t len; - - str = (char *) p->data.str; - if(str == NULL) { - /* Write null[] if there's space. */ - if(prec == -1 || prec >= (long) sizeof(null) - 1) { - str = null; - len = sizeof(null) - 1; - /* Disable quotes around (nil) */ - p->flags &= (~FLAGS_ALT); - } - else { - str = ""; - len = 0; - } - } - else if(prec != -1) - len = (size_t)prec; - else - len = strlen(str); - - width -= (len > LONG_MAX) ? LONG_MAX : (long)len; - - if(p->flags & FLAGS_ALT) - OUTCHAR('"'); - - if(!(p->flags&FLAGS_LEFT)) - while(width-- > 0) - OUTCHAR(' '); - - while((len-- > 0) && *str) - OUTCHAR(*str++); - if(p->flags&FLAGS_LEFT) - while(width-- > 0) - OUTCHAR(' '); - - if(p->flags & FLAGS_ALT) - OUTCHAR('"'); - } - break; - - case FORMAT_PTR: - /* Generic pointer. */ - { - void *ptr; - ptr = (void *) p->data.ptr; - if(ptr != NULL) { - /* If the pointer is not NULL, write it as a %#x spec. */ - base = 16; - digits = (p->flags & FLAGS_UPPER)? upper_digits : lower_digits; - is_alt = 1; - num = (size_t) ptr; - is_neg = 0; - goto number; - } - else { - /* Write "(nil)" for a nil pointer. */ - static const char strnil[] = "(nil)"; - const char *point; - - width -= (long)(sizeof(strnil) - 1); - if(p->flags & FLAGS_LEFT) - while(width-- > 0) - OUTCHAR(' '); - for(point = strnil; *point != '\0'; ++point) - OUTCHAR(*point); - if(! (p->flags & FLAGS_LEFT)) - while(width-- > 0) - OUTCHAR(' '); - } - } - break; - - case FORMAT_DOUBLE: - { - char formatbuf[32]="%"; - char *fptr = &formatbuf[1]; - size_t left = sizeof(formatbuf)-strlen(formatbuf); - int len; - - width = -1; - if(p->flags & FLAGS_WIDTH) - width = p->width; - else if(p->flags & FLAGS_WIDTHPARAM) - width = (long)vto[p->width].data.num.as_signed; - - prec = -1; - if(p->flags & FLAGS_PREC) - prec = p->precision; - else if(p->flags & FLAGS_PRECPARAM) - prec = (long)vto[p->precision].data.num.as_signed; - - if(p->flags & FLAGS_LEFT) - *fptr++ = '-'; - if(p->flags & FLAGS_SHOWSIGN) - *fptr++ = '+'; - if(p->flags & FLAGS_SPACE) - *fptr++ = ' '; - if(p->flags & FLAGS_ALT) - *fptr++ = '#'; - - *fptr = 0; - - if(width >= 0) { - /* RECURSIVE USAGE */ - len = curl_msnprintf(fptr, left, "%ld", width); - fptr += len; - left -= len; - } - if(prec >= 0) { - /* RECURSIVE USAGE */ - len = curl_msnprintf(fptr, left, ".%ld", prec); - fptr += len; - } - if(p->flags & FLAGS_LONG) - *fptr++ = 'l'; - - if(p->flags & FLAGS_FLOATE) - *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'E':'e'); - else if(p->flags & FLAGS_FLOATG) - *fptr++ = (char)((p->flags & FLAGS_UPPER) ? 'G' : 'g'); - else - *fptr++ = 'f'; - - *fptr = 0; /* and a final zero termination */ - - /* NOTE NOTE NOTE!! Not all sprintf implementations return number of - output characters */ - (sprintf)(work, formatbuf, p->data.dnum); - - for(fptr=work; *fptr; fptr++) - OUTCHAR(*fptr); - } - break; - - case FORMAT_INTPTR: - /* Answer the count of characters written. */ -#ifdef HAVE_LONG_LONG_TYPE - if(p->flags & FLAGS_LONGLONG) - *(LONG_LONG_TYPE *) p->data.ptr = (LONG_LONG_TYPE)done; - else -#endif - if(p->flags & FLAGS_LONG) - *(long *) p->data.ptr = (long)done; - else if(!(p->flags & FLAGS_SHORT)) - *(int *) p->data.ptr = (int)done; - else - *(short *) p->data.ptr = (short)done; - break; - - default: - break; - } - f = *end++; /* goto end of %-code */ - - } - return done; -} - -/* fputc() look-alike */ -static int addbyter(int output, FILE *data) -{ - struct nsprintf *infop=(struct nsprintf *)data; - unsigned char outc = (unsigned char)output; - - if(infop->length < infop->max) { - /* only do this if we haven't reached max length yet */ - infop->buffer[0] = outc; /* store */ - infop->buffer++; /* increase pointer */ - infop->length++; /* we are now one byte larger */ - return outc; /* fputc() returns like this on success */ - } - return -1; -} - -int curl_mvsnprintf(char *buffer, size_t maxlength, const char *format, - va_list ap_save) -{ - int retcode; - struct nsprintf info; - - info.buffer = buffer; - info.length = 0; - info.max = maxlength; - - retcode = dprintf_formatf(&info, addbyter, format, ap_save); - if(info.max) { - /* we terminate this with a zero byte */ - if(info.max == info.length) - /* we're at maximum, scrap the last letter */ - info.buffer[-1] = 0; - else - info.buffer[0] = 0; - } - return retcode; -} - -int curl_msnprintf(char *buffer, size_t maxlength, const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = curl_mvsnprintf(buffer, maxlength, format, ap_save); - va_end(ap_save); - return retcode; -} - -/* fputc() look-alike */ -static int alloc_addbyter(int output, FILE *data) -{ - struct asprintf *infop=(struct asprintf *)data; - unsigned char outc = (unsigned char)output; - - if(!infop->buffer) { - infop->buffer = malloc(32); - if(!infop->buffer) { - infop->fail = 1; - return -1; /* fail */ - } - infop->alloc = 32; - infop->len =0; - } - else if(infop->len+1 >= infop->alloc) { - char *newptr; - - newptr = realloc(infop->buffer, infop->alloc*2); - - if(!newptr) { - infop->fail = 1; - return -1; /* fail */ - } - infop->buffer = newptr; - infop->alloc *= 2; - } - - infop->buffer[ infop->len ] = outc; - - infop->len++; - - return outc; /* fputc() returns like this on success */ -} - -char *curl_maprintf(const char *format, ...) -{ - va_list ap_save; /* argument pointer */ - int retcode; - struct asprintf info; - - info.buffer = NULL; - info.len = 0; - info.alloc = 0; - info.fail = 0; - - va_start(ap_save, format); - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - va_end(ap_save); - if((-1 == retcode) || info.fail) { - if(info.alloc) - free(info.buffer); - return NULL; - } - if(info.alloc) { - info.buffer[info.len] = 0; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return strdup(""); -} - -char *curl_mvaprintf(const char *format, va_list ap_save) -{ - int retcode; - struct asprintf info; - - info.buffer = NULL; - info.len = 0; - info.alloc = 0; - info.fail = 0; - - retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save); - if((-1 == retcode) || info.fail) { - if(info.alloc) - free(info.buffer); - return NULL; - } - - if(info.alloc) { - info.buffer[info.len] = 0; /* we terminate this with a zero byte */ - return info.buffer; - } - else - return strdup(""); -} - -static int storebuffer(int output, FILE *data) -{ - char **buffer = (char **)data; - unsigned char outc = (unsigned char)output; - **buffer = outc; - (*buffer)++; - return outc; /* act like fputc() ! */ -} - -int curl_msprintf(char *buffer, const char *format, ...) -{ - va_list ap_save; /* argument pointer */ - int retcode; - va_start(ap_save, format); - retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); - va_end(ap_save); - *buffer=0; /* we terminate this with a zero byte */ - return retcode; -} - -int curl_mprintf(const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - - retcode = dprintf_formatf(stdout, fputc, format, ap_save); - va_end(ap_save); - return retcode; -} - -int curl_mfprintf(FILE *whereto, const char *format, ...) -{ - int retcode; - va_list ap_save; /* argument pointer */ - va_start(ap_save, format); - retcode = dprintf_formatf(whereto, fputc, format, ap_save); - va_end(ap_save); - return retcode; -} - -int curl_mvsprintf(char *buffer, const char *format, va_list ap_save) -{ - int retcode; - retcode = dprintf_formatf(&buffer, storebuffer, format, ap_save); - *buffer=0; /* we terminate this with a zero byte */ - return retcode; -} - -int curl_mvprintf(const char *format, va_list ap_save) -{ - return dprintf_formatf(stdout, fputc, format, ap_save); -} - -int curl_mvfprintf(FILE *whereto, const char *format, va_list ap_save) -{ - return dprintf_formatf(whereto, fputc, format, ap_save); -} diff --git a/Externals/curl/lib/multi.c b/Externals/curl/lib/multi.c deleted file mode 100644 index 7e2725bab6..0000000000 --- a/Externals/curl/lib/multi.c +++ /dev/null @@ -1,3118 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "urldata.h" -#include "transfer.h" -#include "url.h" -#include "connect.h" -#include "progress.h" -#include "easyif.h" -#include "share.h" -#include "multiif.h" -#include "sendf.h" -#include "timeval.h" -#include "http.h" -#include "select.h" -#include "warnless.h" -#include "speedcheck.h" -#include "conncache.h" -#include "multihandle.h" -#include "pipeline.h" -#include "sigpipe.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* - CURL_SOCKET_HASH_TABLE_SIZE should be a prime number. Increasing it from 97 - to 911 takes on a 32-bit machine 4 x 804 = 3211 more bytes. Still, every - CURL handle takes 45-50 K memory, therefore this 3K are not significant. -*/ -#ifndef CURL_SOCKET_HASH_TABLE_SIZE -#define CURL_SOCKET_HASH_TABLE_SIZE 911 -#endif - -#define CURL_CONNECTION_HASH_SIZE 97 - -#define CURL_MULTI_HANDLE 0x000bab1e - -#define GOOD_MULTI_HANDLE(x) \ - ((x) && (((struct Curl_multi *)(x))->type == CURL_MULTI_HANDLE)) - -static void singlesocket(struct Curl_multi *multi, - struct SessionHandle *data); -static int update_timer(struct Curl_multi *multi); - -static CURLMcode add_next_timeout(struct timeval now, - struct Curl_multi *multi, - struct SessionHandle *d); -static CURLMcode multi_timeout(struct Curl_multi *multi, - long *timeout_ms); - -#ifdef DEBUGBUILD -static const char * const statename[]={ - "INIT", - "CONNECT_PEND", - "CONNECT", - "WAITRESOLVE", - "WAITCONNECT", - "WAITPROXYCONNECT", - "SENDPROTOCONNECT", - "PROTOCONNECT", - "WAITDO", - "DO", - "DOING", - "DO_MORE", - "DO_DONE", - "WAITPERFORM", - "PERFORM", - "TOOFAST", - "DONE", - "COMPLETED", - "MSGSENT", -}; -#endif - -static void multi_freetimeout(void *a, void *b); - -/* function pointer called once when switching TO a state */ -typedef void (*init_multistate_func)(struct SessionHandle *data); - -/* always use this function to change state, to make debugging easier */ -static void mstate(struct SessionHandle *data, CURLMstate state -#ifdef DEBUGBUILD - , int lineno -#endif -) -{ - CURLMstate oldstate = data->mstate; - static const init_multistate_func finit[CURLM_STATE_LAST] = { - NULL, - NULL, - Curl_init_CONNECT, /* CONNECT */ - /* the rest is NULL too */ - }; - -#if defined(DEBUGBUILD) && defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) lineno; -#endif - - if(oldstate == state) - /* don't bother when the new state is the same as the old state */ - return; - - data->mstate = state; - -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - if(data->mstate >= CURLM_STATE_CONNECT_PEND && - data->mstate < CURLM_STATE_COMPLETED) { - long connection_id = -5000; - - if(data->easy_conn) - connection_id = data->easy_conn->connection_id; - - infof(data, - "STATE: %s => %s handle %p; line %d (connection #%ld)\n", - statename[oldstate], statename[data->mstate], - (void *)data, lineno, connection_id); - } -#endif - - if(state == CURLM_STATE_COMPLETED) - /* changing to COMPLETED means there's one less easy handle 'alive' */ - data->multi->num_alive--; - - /* if this state has an init-function, run it */ - if(finit[state]) - finit[state](data); -} - -#ifndef DEBUGBUILD -#define multistate(x,y) mstate(x,y) -#else -#define multistate(x,y) mstate(x,y, __LINE__) -#endif - -/* - * We add one of these structs to the sockhash for a particular socket - */ - -struct Curl_sh_entry { - struct SessionHandle *easy; - int action; /* what action READ/WRITE this socket waits for */ - curl_socket_t socket; /* mainly to ease debugging */ - void *socketp; /* settable by users with curl_multi_assign() */ -}; -/* bits for 'action' having no bits means this socket is not expecting any - action */ -#define SH_READ 1 -#define SH_WRITE 2 - -/* look up a given socket in the socket hash, skip invalid sockets */ -static struct Curl_sh_entry *sh_getentry(struct curl_hash *sh, - curl_socket_t s) -{ - if(s != CURL_SOCKET_BAD) - /* only look for proper sockets */ - return Curl_hash_pick(sh, (char *)&s, sizeof(curl_socket_t)); - return NULL; -} - -/* make sure this socket is present in the hash for this handle */ -static struct Curl_sh_entry *sh_addentry(struct curl_hash *sh, - curl_socket_t s, - struct SessionHandle *data) -{ - struct Curl_sh_entry *there = sh_getentry(sh, s); - struct Curl_sh_entry *check; - - if(there) - /* it is present, return fine */ - return there; - - /* not present, add it */ - check = calloc(1, sizeof(struct Curl_sh_entry)); - if(!check) - return NULL; /* major failure */ - - check->easy = data; - check->socket = s; - - /* make/add new hash entry */ - if(!Curl_hash_add(sh, (char *)&s, sizeof(curl_socket_t), check)) { - free(check); - return NULL; /* major failure */ - } - - return check; /* things are good in sockhash land */ -} - - -/* delete the given socket + handle from the hash */ -static void sh_delentry(struct curl_hash *sh, curl_socket_t s) -{ - /* We remove the hash entry. This will end up in a call to - sh_freeentry(). */ - Curl_hash_delete(sh, (char *)&s, sizeof(curl_socket_t)); -} - -/* - * free a sockhash entry - */ -static void sh_freeentry(void *freethis) -{ - struct Curl_sh_entry *p = (struct Curl_sh_entry *) freethis; - - free(p); -} - -static size_t fd_key_compare(void *k1, size_t k1_len, void *k2, size_t k2_len) -{ - (void) k1_len; (void) k2_len; - - return (*((curl_socket_t *) k1)) == (*((curl_socket_t *) k2)); -} - -static size_t hash_fd(void *key, size_t key_length, size_t slots_num) -{ - curl_socket_t fd = *((curl_socket_t *) key); - (void) key_length; - - return (fd % slots_num); -} - -/* - * sh_init() creates a new socket hash and returns the handle for it. - * - * Quote from README.multi_socket: - * - * "Some tests at 7000 and 9000 connections showed that the socket hash lookup - * is somewhat of a bottle neck. Its current implementation may be a bit too - * limiting. It simply has a fixed-size array, and on each entry in the array - * it has a linked list with entries. So the hash only checks which list to - * scan through. The code I had used so for used a list with merely 7 slots - * (as that is what the DNS hash uses) but with 7000 connections that would - * make an average of 1000 nodes in each list to run through. I upped that to - * 97 slots (I believe a prime is suitable) and noticed a significant speed - * increase. I need to reconsider the hash implementation or use a rather - * large default value like this. At 9000 connections I was still below 10us - * per call." - * - */ -static int sh_init(struct curl_hash *hash, int hashsize) -{ - return Curl_hash_init(hash, hashsize, hash_fd, fd_key_compare, - sh_freeentry); -} - -/* - * multi_addmsg() - * - * Called when a transfer is completed. Adds the given msg pointer to - * the list kept in the multi handle. - */ -static CURLMcode multi_addmsg(struct Curl_multi *multi, - struct Curl_message *msg) -{ - if(!Curl_llist_insert_next(multi->msglist, multi->msglist->tail, msg)) - return CURLM_OUT_OF_MEMORY; - - return CURLM_OK; -} - -/* - * multi_freeamsg() - * - * Callback used by the llist system when a single list entry is destroyed. - */ -static void multi_freeamsg(void *a, void *b) -{ - (void)a; - (void)b; -} - -struct Curl_multi *Curl_multi_handle(int hashsize, /* socket hash */ - int chashsize) /* connection hash */ -{ - struct Curl_multi *multi = calloc(1, sizeof(struct Curl_multi)); - - if(!multi) - return NULL; - - multi->type = CURL_MULTI_HANDLE; - - if(Curl_mk_dnscache(&multi->hostcache)) - goto error; - - if(sh_init(&multi->sockhash, hashsize)) - goto error; - - if(Curl_conncache_init(&multi->conn_cache, chashsize)) - goto error; - - multi->msglist = Curl_llist_alloc(multi_freeamsg); - if(!multi->msglist) - goto error; - - multi->pending = Curl_llist_alloc(multi_freeamsg); - if(!multi->pending) - goto error; - - /* allocate a new easy handle to use when closing cached connections */ - multi->closure_handle = curl_easy_init(); - if(!multi->closure_handle) - goto error; - - multi->closure_handle->multi = multi; - multi->closure_handle->state.conn_cache = &multi->conn_cache; - - multi->max_pipeline_length = 5; - - /* -1 means it not set by user, use the default value */ - multi->maxconnects = -1; - return (CURLM *) multi; - - error: - - Curl_hash_destroy(&multi->sockhash); - Curl_hash_destroy(&multi->hostcache); - Curl_conncache_destroy(&multi->conn_cache); - Curl_close(multi->closure_handle); - multi->closure_handle = NULL; - Curl_llist_destroy(multi->msglist, NULL); - Curl_llist_destroy(multi->pending, NULL); - - free(multi); - return NULL; -} - -CURLM *curl_multi_init(void) -{ - return Curl_multi_handle(CURL_SOCKET_HASH_TABLE_SIZE, - CURL_CONNECTION_HASH_SIZE); -} - -CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *easy_handle) -{ - struct curl_llist *timeoutlist; - struct Curl_multi *multi = (struct Curl_multi *)multi_handle; - struct SessionHandle *data = (struct SessionHandle *)easy_handle; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - /* Verify that we got a somewhat good easy handle too */ - if(!GOOD_EASY_HANDLE(easy_handle)) - return CURLM_BAD_EASY_HANDLE; - - /* Prevent users from adding same easy handle more than once and prevent - adding to more than one multi stack */ - if(data->multi) - return CURLM_ADDED_ALREADY; - - /* Allocate and initialize timeout list for easy handle */ - timeoutlist = Curl_llist_alloc(multi_freetimeout); - if(!timeoutlist) - return CURLM_OUT_OF_MEMORY; - - /* - * No failure allowed in this function beyond this point. And no - * modification of easy nor multi handle allowed before this except for - * potential multi's connection cache growing which won't be undone in this - * function no matter what. - */ - - /* Make easy handle use timeout list initialized above */ - data->state.timeoutlist = timeoutlist; - timeoutlist = NULL; - - /* set the easy handle */ - multistate(data, CURLM_STATE_INIT); - - if((data->set.global_dns_cache) && - (data->dns.hostcachetype != HCACHE_GLOBAL)) { - /* global dns cache was requested but still isn't */ - struct curl_hash *global = Curl_global_host_cache_init(); - if(global) { - /* only do this if the global cache init works */ - data->dns.hostcache = global; - data->dns.hostcachetype = HCACHE_GLOBAL; - } - } - /* for multi interface connections, we share DNS cache automatically if the - easy handle's one is currently not set. */ - else if(!data->dns.hostcache || - (data->dns.hostcachetype == HCACHE_NONE)) { - data->dns.hostcache = &multi->hostcache; - data->dns.hostcachetype = HCACHE_MULTI; - } - - /* Point to the multi's connection cache */ - data->state.conn_cache = &multi->conn_cache; - - /* This adds the new entry at the 'end' of the doubly-linked circular - list of SessionHandle structs to try and maintain a FIFO queue so - the pipelined requests are in order. */ - - /* We add this new entry last in the list. */ - - data->next = NULL; /* end of the line */ - if(multi->easyp) { - struct SessionHandle *last = multi->easylp; - last->next = data; - data->prev = last; - multi->easylp = data; /* the new last node */ - } - else { - /* first node, make prev NULL! */ - data->prev = NULL; - multi->easylp = multi->easyp = data; /* both first and last */ - } - - /* make the SessionHandle refer back to this multi handle */ - data->multi = multi_handle; - - /* Set the timeout for this handle to expire really soon so that it will - be taken care of even when this handle is added in the midst of operation - when only the curl_multi_socket() API is used. During that flow, only - sockets that time-out or have actions will be dealt with. Since this - handle has no action yet, we make sure it times out to get things to - happen. */ - Curl_expire(data, 1); - - /* increase the node-counter */ - multi->num_easy++; - - /* increase the alive-counter */ - multi->num_alive++; - - /* A somewhat crude work-around for a little glitch in update_timer() that - happens if the lastcall time is set to the same time when the handle is - removed as when the next handle is added, as then the check in - update_timer() that prevents calling the application multiple times with - the same timer infor will not trigger and then the new handle's timeout - will not be notified to the app. - - The work-around is thus simply to clear the 'lastcall' variable to force - update_timer() to always trigger a callback to the app when a new easy - handle is added */ - memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); - - update_timer(multi); - return CURLM_OK; -} - -#if 0 -/* Debug-function, used like this: - * - * Curl_hash_print(multi->sockhash, debug_print_sock_hash); - * - * Enable the hash print function first by editing hash.c - */ -static void debug_print_sock_hash(void *p) -{ - struct Curl_sh_entry *sh = (struct Curl_sh_entry *)p; - - fprintf(stderr, " [easy %p/magic %x/socket %d]", - (void *)sh->data, sh->data->magic, (int)sh->socket); -} -#endif - -/* Mark the connection as 'idle', or close it if the cache is full. - Returns TRUE if the connection is kept, or FALSE if it was closed. */ -static bool -ConnectionDone(struct SessionHandle *data, struct connectdata *conn) -{ - /* data->multi->maxconnects can be negative, deal with it. */ - size_t maxconnects = - (data->multi->maxconnects < 0) ? data->multi->num_easy * 4: - data->multi->maxconnects; - struct connectdata *conn_candidate = NULL; - - /* Mark the current connection as 'unused' */ - conn->inuse = FALSE; - - if(maxconnects > 0 && - data->state.conn_cache->num_connections > maxconnects) { - infof(data, "Connection cache is full, closing the oldest one.\n"); - - conn_candidate = Curl_oldest_idle_connection(data); - - if(conn_candidate) { - /* Set the connection's owner correctly */ - conn_candidate->data = data; - - /* the winner gets the honour of being disconnected */ - (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); - } - } - - return (conn_candidate == conn) ? FALSE : TRUE; -} - -static CURLcode multi_done(struct connectdata **connp, - CURLcode status, /* an error if this is called - after an error was detected */ - bool premature) -{ - CURLcode result; - struct connectdata *conn; - struct SessionHandle *data; - - DEBUGASSERT(*connp); - - conn = *connp; - data = conn->data; - - DEBUGF(infof(data, "multi_done\n")); - - if(data->state.done) - /* Stop if multi_done() has already been called */ - return CURLE_OK; - - Curl_getoff_all_pipelines(data, conn); - - /* Cleanup possible redirect junk */ - free(data->req.newurl); - data->req.newurl = NULL; - free(data->req.location); - data->req.location = NULL; - - switch(status) { - case CURLE_ABORTED_BY_CALLBACK: - case CURLE_READ_ERROR: - case CURLE_WRITE_ERROR: - /* When we're aborted due to a callback return code it basically have to - be counted as premature as there is trouble ahead if we don't. We have - many callbacks and protocols work differently, we could potentially do - this more fine-grained in the future. */ - premature = TRUE; - default: - break; - } - - /* this calls the protocol-specific function pointer previously set */ - if(conn->handler->done) - result = conn->handler->done(conn, status, premature); - else - result = status; - - if(CURLE_ABORTED_BY_CALLBACK != result) { - /* avoid this if we already aborted by callback to avoid this calling - another callback */ - CURLcode rc = Curl_pgrsDone(conn); - if(!result && rc) - result = CURLE_ABORTED_BY_CALLBACK; - } - - if((!premature && - conn->send_pipe->size + conn->recv_pipe->size != 0 && - !data->set.reuse_forbid && - !conn->bits.close)) { - /* Stop if pipeline is not empty and we do not have to close - connection. */ - DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n")); - return CURLE_OK; - } - - data->state.done = TRUE; /* called just now! */ - Curl_resolver_cancel(conn); - - if(conn->dns_entry) { - Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ - conn->dns_entry = NULL; - } - - /* if the transfer was completed in a paused state there can be buffered - data left to write and then kill */ - free(data->state.tempwrite); - data->state.tempwrite = NULL; - - /* if data->set.reuse_forbid is TRUE, it means the libcurl client has - forced us to close this connection. This is ignored for requests taking - place in a NTLM authentication handshake - - if conn->bits.close is TRUE, it means that the connection should be - closed in spite of all our efforts to be nice, due to protocol - restrictions in our or the server's end - - if premature is TRUE, it means this connection was said to be DONE before - the entire request operation is complete and thus we can't know in what - state it is for re-using, so we're forced to close it. In a perfect world - we can add code that keep track of if we really must close it here or not, - but currently we have no such detail knowledge. - */ - - if((data->set.reuse_forbid -#if defined(USE_NTLM) - && !(conn->ntlm.state == NTLMSTATE_TYPE2 || - conn->proxyntlm.state == NTLMSTATE_TYPE2) -#endif - ) || conn->bits.close || premature) { - CURLcode res2 = Curl_disconnect(conn, premature); /* close connection */ - - /* If we had an error already, make sure we return that one. But - if we got a new error, return that. */ - if(!result && res2) - result = res2; - } - else { - /* the connection is no longer in use */ - if(ConnectionDone(data, conn)) { - /* remember the most recently used connection */ - data->state.lastconnect = conn; - - infof(data, "Connection #%ld to host %s left intact\n", - conn->connection_id, - conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname); - } - else - data->state.lastconnect = NULL; - } - - *connp = NULL; /* to make the caller of this function better detect that - this was either closed or handed over to the connection - cache here, and therefore cannot be used from this point on - */ - Curl_free_request_state(data); - - return result; -} - -CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct SessionHandle *easy = curl_handle; - struct SessionHandle *data = easy; - bool premature; - bool easy_owns_conn; - struct curl_llist_element *e; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - /* Verify that we got a somewhat good easy handle too */ - if(!GOOD_EASY_HANDLE(curl_handle)) - return CURLM_BAD_EASY_HANDLE; - - /* Prevent users from trying to remove same easy handle more than once */ - if(!data->multi) - return CURLM_OK; /* it is already removed so let's say it is fine! */ - - premature = (data->mstate < CURLM_STATE_COMPLETED) ? TRUE : FALSE; - easy_owns_conn = (data->easy_conn && (data->easy_conn->data == easy)) ? - TRUE : FALSE; - - /* If the 'state' is not INIT or COMPLETED, we might need to do something - nice to put the easy_handle in a good known state when this returns. */ - if(premature) { - /* this handle is "alive" so we need to count down the total number of - alive connections when this is removed */ - multi->num_alive--; - - /* When this handle gets removed, other handles may be able to get the - connection */ - Curl_multi_process_pending_handles(multi); - } - - if(data->easy_conn && - data->mstate > CURLM_STATE_DO && - data->mstate < CURLM_STATE_COMPLETED) { - /* If the handle is in a pipeline and has started sending off its - request but not received its response yet, we need to close - connection. */ - connclose(data->easy_conn, "Removed with partial response"); - /* Set connection owner so that the DONE function closes it. We can - safely do this here since connection is killed. */ - data->easy_conn->data = easy; - easy_owns_conn = TRUE; - } - - /* The timer must be shut down before data->multi is set to NULL, - else the timenode will remain in the splay tree after - curl_easy_cleanup is called. */ - Curl_expire(data, 0); - - if(data->dns.hostcachetype == HCACHE_MULTI) { - /* stop using the multi handle's DNS cache */ - data->dns.hostcache = NULL; - data->dns.hostcachetype = HCACHE_NONE; - } - - if(data->easy_conn) { - - /* we must call multi_done() here (if we still own the connection) so that - we don't leave a half-baked one around */ - if(easy_owns_conn) { - - /* multi_done() clears the conn->data field to lose the association - between the easy handle and the connection - - Note that this ignores the return code simply because there's - nothing really useful to do with it anyway! */ - (void)multi_done(&data->easy_conn, data->result, premature); - } - else - /* Clear connection pipelines, if multi_done above was not called */ - Curl_getoff_all_pipelines(data, data->easy_conn); - } - - Curl_wildcard_dtor(&data->wildcard); - - /* destroy the timeout list that is held in the easy handle, do this *after* - multi_done() as that may actually call Curl_expire that uses this */ - if(data->state.timeoutlist) { - Curl_llist_destroy(data->state.timeoutlist, NULL); - data->state.timeoutlist = NULL; - } - - /* as this was using a shared connection cache we clear the pointer to that - since we're not part of that multi handle anymore */ - data->state.conn_cache = NULL; - - /* change state without using multistate(), only to make singlesocket() do - what we want */ - data->mstate = CURLM_STATE_COMPLETED; - singlesocket(multi, easy); /* to let the application know what sockets that - vanish with this handle */ - - /* Remove the association between the connection and the handle */ - if(data->easy_conn) { - data->easy_conn->data = NULL; - data->easy_conn = NULL; - } - - data->multi = NULL; /* clear the association to this multi handle */ - - /* make sure there's no pending message in the queue sent from this easy - handle */ - - for(e = multi->msglist->head; e; e = e->next) { - struct Curl_message *msg = e->ptr; - - if(msg->extmsg.easy_handle == easy) { - Curl_llist_remove(multi->msglist, e, NULL); - /* there can only be one from this specific handle */ - break; - } - } - - /* make the previous node point to our next */ - if(data->prev) - data->prev->next = data->next; - else - multi->easyp = data->next; /* point to first node */ - - /* make our next point to our previous node */ - if(data->next) - data->next->prev = data->prev; - else - multi->easylp = data->prev; /* point to last node */ - - /* NOTE NOTE NOTE - We do not touch the easy handle here! */ - multi->num_easy--; /* one less to care about now */ - - update_timer(multi); - return CURLM_OK; -} - -/* Return TRUE if the application asked for a certain set of pipelining */ -bool Curl_pipeline_wanted(const struct Curl_multi *multi, int bits) -{ - return (multi && (multi->pipelining & bits)) ? TRUE : FALSE; -} - -void Curl_multi_handlePipeBreak(struct SessionHandle *data) -{ - data->easy_conn = NULL; -} - -static int waitconnect_getsock(struct connectdata *conn, - curl_socket_t *sock, - int numsocks) -{ - int i; - int s=0; - int rc=0; - - if(!numsocks) - return GETSOCK_BLANK; - - for(i=0; i<2; i++) { - if(conn->tempsock[i] != CURL_SOCKET_BAD) { - sock[s] = conn->tempsock[i]; - rc |= GETSOCK_WRITESOCK(s++); - } - } - - return rc; -} - -static int waitproxyconnect_getsock(struct connectdata *conn, - curl_socket_t *sock, - int numsocks) -{ - if(!numsocks) - return GETSOCK_BLANK; - - sock[0] = conn->sock[FIRSTSOCKET]; - - /* when we've sent a CONNECT to a proxy, we should rather wait for the - socket to become readable to be able to get the response headers */ - if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) - return GETSOCK_READSOCK(0); - - return GETSOCK_WRITESOCK(0); -} - -static int domore_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - if(conn && conn->handler->domore_getsock) - return conn->handler->domore_getsock(conn, socks, numsocks); - return GETSOCK_BLANK; -} - -/* returns bitmapped flags for this handle and its sockets */ -static int multi_getsock(struct SessionHandle *data, - curl_socket_t *socks, /* points to numsocks number - of sockets */ - int numsocks) -{ - /* If the pipe broke, or if there's no connection left for this easy handle, - then we MUST bail out now with no bitmask set. The no connection case can - happen when this is called from curl_multi_remove_handle() => - singlesocket() => multi_getsock(). - */ - if(data->state.pipe_broke || !data->easy_conn) - return 0; - - if(data->mstate > CURLM_STATE_CONNECT && - data->mstate < CURLM_STATE_COMPLETED) { - /* Set up ownership correctly */ - data->easy_conn->data = data; - } - - switch(data->mstate) { - default: -#if 0 /* switch back on these cases to get the compiler to check for all enums - to be present */ - case CURLM_STATE_TOOFAST: /* returns 0, so will not select. */ - case CURLM_STATE_COMPLETED: - case CURLM_STATE_MSGSENT: - case CURLM_STATE_INIT: - case CURLM_STATE_CONNECT: - case CURLM_STATE_WAITDO: - case CURLM_STATE_DONE: - case CURLM_STATE_LAST: - /* this will get called with CURLM_STATE_COMPLETED when a handle is - removed */ -#endif - return 0; - - case CURLM_STATE_WAITRESOLVE: - return Curl_resolver_getsock(data->easy_conn, socks, numsocks); - - case CURLM_STATE_PROTOCONNECT: - case CURLM_STATE_SENDPROTOCONNECT: - return Curl_protocol_getsock(data->easy_conn, socks, numsocks); - - case CURLM_STATE_DO: - case CURLM_STATE_DOING: - return Curl_doing_getsock(data->easy_conn, socks, numsocks); - - case CURLM_STATE_WAITPROXYCONNECT: - return waitproxyconnect_getsock(data->easy_conn, socks, numsocks); - - case CURLM_STATE_WAITCONNECT: - return waitconnect_getsock(data->easy_conn, socks, numsocks); - - case CURLM_STATE_DO_MORE: - return domore_getsock(data->easy_conn, socks, numsocks); - - case CURLM_STATE_DO_DONE: /* since is set after DO is completed, we switch - to waiting for the same as the *PERFORM - states */ - case CURLM_STATE_PERFORM: - case CURLM_STATE_WAITPERFORM: - return Curl_single_getsock(data->easy_conn, socks, numsocks); - } - -} - -CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, fd_set *write_fd_set, - fd_set *exc_fd_set, int *max_fd) -{ - /* Scan through all the easy handles to get the file descriptors set. - Some easy handles may not have connected to the remote host yet, - and then we must make sure that is done. */ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct SessionHandle *data; - int this_max_fd=-1; - curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; - int bitmap; - int i; - (void)exc_fd_set; /* not used */ - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - data=multi->easyp; - while(data) { - bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); - - for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { - curl_socket_t s = CURL_SOCKET_BAD; - - if((bitmap & GETSOCK_READSOCK(i)) && VALID_SOCK((sockbunch[i]))) { - FD_SET(sockbunch[i], read_fd_set); - s = sockbunch[i]; - } - if((bitmap & GETSOCK_WRITESOCK(i)) && VALID_SOCK((sockbunch[i]))) { - FD_SET(sockbunch[i], write_fd_set); - s = sockbunch[i]; - } - if(s == CURL_SOCKET_BAD) - /* this socket is unused, break out of loop */ - break; - else { - if((int)s > this_max_fd) - this_max_fd = (int)s; - } - } - - data = data->next; /* check next handle */ - } - - *max_fd = this_max_fd; - - return CURLM_OK; -} - -CURLMcode curl_multi_wait(CURLM *multi_handle, - struct curl_waitfd extra_fds[], - unsigned int extra_nfds, - int timeout_ms, - int *ret) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct SessionHandle *data; - curl_socket_t sockbunch[MAX_SOCKSPEREASYHANDLE]; - int bitmap; - unsigned int i; - unsigned int nfds = 0; - unsigned int curlfds; - struct pollfd *ufds = NULL; - long timeout_internal; - int retcode = 0; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - /* If the internally desired timeout is actually shorter than requested from - the outside, then use the shorter time! But only if the internal timer - is actually larger than -1! */ - (void)multi_timeout(multi, &timeout_internal); - if((timeout_internal >= 0) && (timeout_internal < (long)timeout_ms)) - timeout_ms = (int)timeout_internal; - - /* Count up how many fds we have from the multi handle */ - data=multi->easyp; - while(data) { - bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); - - for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { - curl_socket_t s = CURL_SOCKET_BAD; - - if(bitmap & GETSOCK_READSOCK(i)) { - ++nfds; - s = sockbunch[i]; - } - if(bitmap & GETSOCK_WRITESOCK(i)) { - ++nfds; - s = sockbunch[i]; - } - if(s == CURL_SOCKET_BAD) { - break; - } - } - - data = data->next; /* check next handle */ - } - - curlfds = nfds; /* number of internal file descriptors */ - nfds += extra_nfds; /* add the externally provided ones */ - - if(nfds || extra_nfds) { - ufds = malloc(nfds * sizeof(struct pollfd)); - if(!ufds) - return CURLM_OUT_OF_MEMORY; - } - nfds = 0; - - /* only do the second loop if we found descriptors in the first stage run - above */ - - if(curlfds) { - /* Add the curl handles to our pollfds first */ - data=multi->easyp; - while(data) { - bitmap = multi_getsock(data, sockbunch, MAX_SOCKSPEREASYHANDLE); - - for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) { - curl_socket_t s = CURL_SOCKET_BAD; - - if(bitmap & GETSOCK_READSOCK(i)) { - ufds[nfds].fd = sockbunch[i]; - ufds[nfds].events = POLLIN; - ++nfds; - s = sockbunch[i]; - } - if(bitmap & GETSOCK_WRITESOCK(i)) { - ufds[nfds].fd = sockbunch[i]; - ufds[nfds].events = POLLOUT; - ++nfds; - s = sockbunch[i]; - } - if(s == CURL_SOCKET_BAD) { - break; - } - } - - data = data->next; /* check next handle */ - } - } - - /* Add external file descriptions from poll-like struct curl_waitfd */ - for(i = 0; i < extra_nfds; i++) { - ufds[nfds].fd = extra_fds[i].fd; - ufds[nfds].events = 0; - if(extra_fds[i].events & CURL_WAIT_POLLIN) - ufds[nfds].events |= POLLIN; - if(extra_fds[i].events & CURL_WAIT_POLLPRI) - ufds[nfds].events |= POLLPRI; - if(extra_fds[i].events & CURL_WAIT_POLLOUT) - ufds[nfds].events |= POLLOUT; - ++nfds; - } - - if(nfds) { - int pollrc; - /* wait... */ - pollrc = Curl_poll(ufds, nfds, timeout_ms); - DEBUGF(infof(data, "Curl_poll(%d ds, %d ms) == %d\n", - nfds, timeout_ms, pollrc)); - - if(pollrc > 0) { - retcode = pollrc; - /* copy revents results from the poll to the curl_multi_wait poll - struct, the bit values of the actual underlying poll() implementation - may not be the same as the ones in the public libcurl API! */ - for(i = 0; i < extra_nfds; i++) { - unsigned short mask = 0; - unsigned r = ufds[curlfds + i].revents; - - if(r & POLLIN) - mask |= CURL_WAIT_POLLIN; - if(r & POLLOUT) - mask |= CURL_WAIT_POLLOUT; - if(r & POLLPRI) - mask |= CURL_WAIT_POLLPRI; - - extra_fds[i].revents = mask; - } - } - } - - free(ufds); - if(ret) - *ret = retcode; - return CURLM_OK; -} - -/* - * Curl_multi_connchanged() is called to tell that there is a connection in - * this multi handle that has changed state (pipelining become possible, the - * number of allowed streams changed or similar), and a subsequent use of this - * multi handle should move CONNECT_PEND handles back to CONNECT to have them - * retry. - */ -void Curl_multi_connchanged(struct Curl_multi *multi) -{ - multi->recheckstate = TRUE; -} - -/* - * multi_ischanged() is called - * - * Returns TRUE/FALSE whether the state is changed to trigger a CONNECT_PEND - * => CONNECT action. - * - * Set 'clear' to TRUE to have it also clear the state variable. - */ -static bool multi_ischanged(struct Curl_multi *multi, bool clear) -{ - bool retval = multi->recheckstate; - if(clear) - multi->recheckstate = FALSE; - return retval; -} - -CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, - struct SessionHandle *data, - struct connectdata *conn) -{ - CURLMcode rc; - - rc = curl_multi_add_handle(multi, data); - if(!rc) { - struct SingleRequest *k = &data->req; - - /* pass in NULL for 'conn' here since we don't want to init the - connection, only this transfer */ - Curl_init_do(data, NULL); - - /* take this handle to the perform state right away */ - multistate(data, CURLM_STATE_PERFORM); - data->easy_conn = conn; - k->keepon |= KEEP_RECV; /* setup to receive! */ - } - return rc; -} - -static CURLcode multi_reconnect_request(struct connectdata **connp) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn = *connp; - struct SessionHandle *data = conn->data; - - /* This was a re-use of a connection and we got a write error in the - * DO-phase. Then we DISCONNECT this connection and have another attempt to - * CONNECT and then DO again! The retry cannot possibly find another - * connection to re-use, since we only keep one possible connection for - * each. */ - - infof(data, "Re-used connection seems dead, get a new one\n"); - - connclose(conn, "Reconnect dead connection"); /* enforce close */ - result = multi_done(&conn, result, FALSE); /* we are so done with this */ - - /* conn may no longer be a good pointer, clear it to avoid mistakes by - parent functions */ - *connp = NULL; - - /* - * We need to check for CURLE_SEND_ERROR here as well. This could happen - * when the request failed on a FTP connection and thus multi_done() itself - * tried to use the connection (again). - */ - if(!result || (CURLE_SEND_ERROR == result)) { - bool async; - bool protocol_done = TRUE; - - /* Now, redo the connect and get a new connection */ - result = Curl_connect(data, connp, &async, &protocol_done); - if(!result) { - /* We have connected or sent away a name resolve query fine */ - - conn = *connp; /* setup conn to again point to something nice */ - if(async) { - /* Now, if async is TRUE here, we need to wait for the name - to resolve */ - result = Curl_resolver_wait_resolv(conn, NULL); - if(result) - return result; - - /* Resolved, continue with the connection */ - result = Curl_async_resolved(conn, &protocol_done); - if(result) - return result; - } - } - } - - return result; -} - -/* - * do_complete is called when the DO actions are complete. - * - * We init chunking and trailer bits to their default values here immediately - * before receiving any header data for the current request in the pipeline. - */ -static void do_complete(struct connectdata *conn) -{ - conn->data->req.chunk=FALSE; - conn->data->req.maxfd = (conn->sockfd>conn->writesockfd? - conn->sockfd:conn->writesockfd)+1; - Curl_pgrsTime(conn->data, TIMER_PRETRANSFER); -} - -static CURLcode multi_do(struct connectdata **connp, bool *done) -{ - CURLcode result=CURLE_OK; - struct connectdata *conn = *connp; - struct SessionHandle *data = conn->data; - - if(conn->handler->do_it) { - /* generic protocol-specific function pointer set in curl_connect() */ - result = conn->handler->do_it(conn, done); - - /* This was formerly done in transfer.c, but we better do it here */ - if((CURLE_SEND_ERROR == result) && conn->bits.reuse) { - /* - * If the connection is using an easy handle, call reconnect - * to re-establish the connection. Otherwise, let the multi logic - * figure out how to re-establish the connection. - */ - if(!data->multi) { - result = multi_reconnect_request(connp); - - if(!result) { - /* ... finally back to actually retry the DO phase */ - conn = *connp; /* re-assign conn since multi_reconnect_request - creates a new connection */ - result = conn->handler->do_it(conn, done); - } - } - else - return result; - } - - if(!result && *done) - /* do_complete must be called after the protocol-specific DO function */ - do_complete(conn); - } - return result; -} - -/* - * multi_do_more() is called during the DO_MORE multi state. It is basically a - * second stage DO state which (wrongly) was introduced to support FTP's - * second connection. - * - * TODO: A future libcurl should be able to work away this state. - * - * 'complete' can return 0 for incomplete, 1 for done and -1 for go back to - * DOING state there's more work to do! - */ - -static CURLcode multi_do_more(struct connectdata *conn, int *complete) -{ - CURLcode result=CURLE_OK; - - *complete = 0; - - if(conn->handler->do_more) - result = conn->handler->do_more(conn, complete); - - if(!result && (*complete == 1)) - /* do_complete must be called after the protocol-specific DO function */ - do_complete(conn); - - return result; -} - -static CURLMcode multi_runsingle(struct Curl_multi *multi, - struct timeval now, - struct SessionHandle *data) -{ - struct Curl_message *msg = NULL; - bool connected; - bool async; - bool protocol_connect = FALSE; - bool dophase_done = FALSE; - bool done = FALSE; - CURLMcode rc; - CURLcode result = CURLE_OK; - struct SingleRequest *k; - long timeout_ms; - int control; - - if(!GOOD_EASY_HANDLE(data)) - return CURLM_BAD_EASY_HANDLE; - - do { - bool disconnect_conn = FALSE; - rc = CURLM_OK; - - /* Handle the case when the pipe breaks, i.e., the connection - we're using gets cleaned up and we're left with nothing. */ - if(data->state.pipe_broke) { - infof(data, "Pipe broke: handle %p, url = %s\n", - (void *)data, data->state.path); - - if(data->mstate < CURLM_STATE_COMPLETED) { - /* Head back to the CONNECT state */ - multistate(data, CURLM_STATE_CONNECT); - rc = CURLM_CALL_MULTI_PERFORM; - result = CURLE_OK; - } - - data->state.pipe_broke = FALSE; - data->easy_conn = NULL; - continue; - } - - if(!data->easy_conn && - data->mstate > CURLM_STATE_CONNECT && - data->mstate < CURLM_STATE_DONE) { - /* In all these states, the code will blindly access 'data->easy_conn' - so this is precaution that it isn't NULL. And it silences static - analyzers. */ - failf(data, "In state %d with no easy_conn, bail out!\n", data->mstate); - return CURLM_INTERNAL_ERROR; - } - - if(multi_ischanged(multi, TRUE)) { - DEBUGF(infof(data, "multi changed, check CONNECT_PEND queue!\n")); - Curl_multi_process_pending_handles(multi); - } - - if(data->easy_conn && data->mstate > CURLM_STATE_CONNECT && - data->mstate < CURLM_STATE_COMPLETED) - /* Make sure we set the connection's current owner */ - data->easy_conn->data = data; - - if(data->easy_conn && - (data->mstate >= CURLM_STATE_CONNECT) && - (data->mstate < CURLM_STATE_COMPLETED)) { - /* we need to wait for the connect state as only then is the start time - stored, but we must not check already completed handles */ - - timeout_ms = Curl_timeleft(data, &now, - (data->mstate <= CURLM_STATE_WAITDO)? - TRUE:FALSE); - - if(timeout_ms < 0) { - /* Handle timed out */ - if(data->mstate == CURLM_STATE_WAITRESOLVE) - failf(data, "Resolving timed out after %ld milliseconds", - Curl_tvdiff(now, data->progress.t_startsingle)); - else if(data->mstate == CURLM_STATE_WAITCONNECT) - failf(data, "Connection timed out after %ld milliseconds", - Curl_tvdiff(now, data->progress.t_startsingle)); - else { - k = &data->req; - if(k->size != -1) { - failf(data, "Operation timed out after %ld milliseconds with %" - CURL_FORMAT_CURL_OFF_T " out of %" - CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_tvdiff(now, data->progress.t_startsingle), - k->bytecount, k->size); - } - else { - failf(data, "Operation timed out after %ld milliseconds with %" - CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_tvdiff(now, data->progress.t_startsingle), - k->bytecount); - } - } - - /* Force connection closed if the connection has indeed been used */ - if(data->mstate > CURLM_STATE_DO) { - connclose(data->easy_conn, "Disconnected with pending data"); - disconnect_conn = TRUE; - } - result = CURLE_OPERATION_TIMEDOUT; - (void)multi_done(&data->easy_conn, result, TRUE); - /* Skip the statemachine and go directly to error handling section. */ - goto statemachine_end; - } - } - - switch(data->mstate) { - case CURLM_STATE_INIT: - /* init this transfer. */ - result=Curl_pretransfer(data); - - if(!result) { - /* after init, go CONNECT */ - multistate(data, CURLM_STATE_CONNECT); - Curl_pgrsTime(data, TIMER_STARTOP); - rc = CURLM_CALL_MULTI_PERFORM; - } - break; - - case CURLM_STATE_CONNECT_PEND: - /* We will stay here until there is a connection available. Then - we try again in the CURLM_STATE_CONNECT state. */ - break; - - case CURLM_STATE_CONNECT: - /* Connect. We want to get a connection identifier filled in. */ - Curl_pgrsTime(data, TIMER_STARTSINGLE); - result = Curl_connect(data, &data->easy_conn, - &async, &protocol_connect); - if(CURLE_NO_CONNECTION_AVAILABLE == result) { - /* There was no connection available. We will go to the pending - state and wait for an available connection. */ - multistate(data, CURLM_STATE_CONNECT_PEND); - - /* add this handle to the list of connect-pending handles */ - if(!Curl_llist_insert_next(multi->pending, multi->pending->tail, data)) - result = CURLE_OUT_OF_MEMORY; - else - result = CURLE_OK; - break; - } - - if(!result) { - /* Add this handle to the send or pend pipeline */ - result = Curl_add_handle_to_pipeline(data, data->easy_conn); - if(result) - disconnect_conn = TRUE; - else { - if(async) - /* We're now waiting for an asynchronous name lookup */ - multistate(data, CURLM_STATE_WAITRESOLVE); - else { - /* after the connect has been sent off, go WAITCONNECT unless the - protocol connect is already done and we can go directly to - WAITDO or DO! */ - rc = CURLM_CALL_MULTI_PERFORM; - - if(protocol_connect) - multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? - CURLM_STATE_WAITDO:CURLM_STATE_DO); - else { -#ifndef CURL_DISABLE_HTTP - if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) - multistate(data, CURLM_STATE_WAITPROXYCONNECT); - else -#endif - multistate(data, CURLM_STATE_WAITCONNECT); - } - } - } - } - break; - - case CURLM_STATE_WAITRESOLVE: - /* awaiting an asynch name resolve to complete */ - { - struct Curl_dns_entry *dns = NULL; - struct connectdata *conn = data->easy_conn; - const char *hostname; - - if(conn->bits.proxy) - hostname = conn->proxy.name; - else if(conn->bits.conn_to_host) - hostname = conn->conn_to_host.name; - else - hostname = conn->host.name; - - /* check if we have the name resolved by now */ - dns = Curl_fetch_addr(conn, hostname, (int)conn->port); - - if(dns) { -#ifdef CURLRES_ASYNCH - conn->async.dns = dns; - conn->async.done = TRUE; -#endif - result = CURLE_OK; - infof(data, "Hostname '%s' was found in DNS cache\n", hostname); - } - - if(!dns) - result = Curl_resolver_is_resolved(data->easy_conn, &dns); - - /* Update sockets here, because the socket(s) may have been - closed and the application thus needs to be told, even if it - is likely that the same socket(s) will again be used further - down. If the name has not yet been resolved, it is likely - that new sockets have been opened in an attempt to contact - another resolver. */ - singlesocket(multi, data); - - if(dns) { - /* Perform the next step in the connection phase, and then move on - to the WAITCONNECT state */ - result = Curl_async_resolved(data->easy_conn, &protocol_connect); - - if(result) - /* if Curl_async_resolved() returns failure, the connection struct - is already freed and gone */ - data->easy_conn = NULL; /* no more connection */ - else { - /* call again please so that we get the next socket setup */ - rc = CURLM_CALL_MULTI_PERFORM; - if(protocol_connect) - multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? - CURLM_STATE_WAITDO:CURLM_STATE_DO); - else { -#ifndef CURL_DISABLE_HTTP - if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT) - multistate(data, CURLM_STATE_WAITPROXYCONNECT); - else -#endif - multistate(data, CURLM_STATE_WAITCONNECT); - } - } - } - - if(result) { - /* failure detected */ - disconnect_conn = TRUE; - break; - } - } - break; - -#ifndef CURL_DISABLE_HTTP - case CURLM_STATE_WAITPROXYCONNECT: - /* this is HTTP-specific, but sending CONNECT to a proxy is HTTP... */ - result = Curl_http_connect(data->easy_conn, &protocol_connect); - - if(data->easy_conn->bits.proxy_connect_closed) { - rc = CURLM_CALL_MULTI_PERFORM; - /* connect back to proxy again */ - result = CURLE_OK; - multi_done(&data->easy_conn, CURLE_OK, FALSE); - multistate(data, CURLM_STATE_CONNECT); - } - else if(!result) { - if(data->easy_conn->tunnel_state[FIRSTSOCKET] == TUNNEL_COMPLETE) { - rc = CURLM_CALL_MULTI_PERFORM; - /* initiate protocol connect phase */ - multistate(data, CURLM_STATE_SENDPROTOCONNECT); - } - } - break; -#endif - - case CURLM_STATE_WAITCONNECT: - /* awaiting a completion of an asynch TCP connect */ - result = Curl_is_connected(data->easy_conn, FIRSTSOCKET, &connected); - if(connected && !result) { - rc = CURLM_CALL_MULTI_PERFORM; - multistate(data, data->easy_conn->bits.tunnel_proxy? - CURLM_STATE_WAITPROXYCONNECT: - CURLM_STATE_SENDPROTOCONNECT); - } - else if(result) { - /* failure detected */ - /* Just break, the cleaning up is handled all in one place */ - disconnect_conn = TRUE; - break; - } - break; - - case CURLM_STATE_SENDPROTOCONNECT: - result = Curl_protocol_connect(data->easy_conn, &protocol_connect); - if(!protocol_connect) - /* switch to waiting state */ - multistate(data, CURLM_STATE_PROTOCONNECT); - else if(!result) { - /* protocol connect has completed, go WAITDO or DO */ - multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? - CURLM_STATE_WAITDO:CURLM_STATE_DO); - rc = CURLM_CALL_MULTI_PERFORM; - } - else if(result) { - /* failure detected */ - Curl_posttransfer(data); - multi_done(&data->easy_conn, result, TRUE); - disconnect_conn = TRUE; - } - break; - - case CURLM_STATE_PROTOCONNECT: - /* protocol-specific connect phase */ - result = Curl_protocol_connecting(data->easy_conn, &protocol_connect); - if(!result && protocol_connect) { - /* after the connect has completed, go WAITDO or DO */ - multistate(data, Curl_pipeline_wanted(multi, CURLPIPE_HTTP1)? - CURLM_STATE_WAITDO:CURLM_STATE_DO); - rc = CURLM_CALL_MULTI_PERFORM; - } - else if(result) { - /* failure detected */ - Curl_posttransfer(data); - multi_done(&data->easy_conn, result, TRUE); - disconnect_conn = TRUE; - } - break; - - case CURLM_STATE_WAITDO: - /* Wait for our turn to DO when we're pipelining requests */ - if(Curl_pipeline_checkget_write(data, data->easy_conn)) { - /* Grabbed the channel */ - multistate(data, CURLM_STATE_DO); - rc = CURLM_CALL_MULTI_PERFORM; - } - break; - - case CURLM_STATE_DO: - if(data->set.connect_only) { - /* keep connection open for application to use the socket */ - connkeep(data->easy_conn, "CONNECT_ONLY"); - multistate(data, CURLM_STATE_DONE); - result = CURLE_OK; - rc = CURLM_CALL_MULTI_PERFORM; - } - else { - /* Perform the protocol's DO action */ - result = multi_do(&data->easy_conn, &dophase_done); - - /* When multi_do() returns failure, data->easy_conn might be NULL! */ - - if(!result) { - if(!dophase_done) { - /* some steps needed for wildcard matching */ - if(data->set.wildcardmatch) { - struct WildcardData *wc = &data->wildcard; - if(wc->state == CURLWC_DONE || wc->state == CURLWC_SKIP) { - /* skip some states if it is important */ - multi_done(&data->easy_conn, CURLE_OK, FALSE); - multistate(data, CURLM_STATE_DONE); - rc = CURLM_CALL_MULTI_PERFORM; - break; - } - } - /* DO was not completed in one function call, we must continue - DOING... */ - multistate(data, CURLM_STATE_DOING); - rc = CURLM_OK; - } - - /* after DO, go DO_DONE... or DO_MORE */ - else if(data->easy_conn->bits.do_more) { - /* we're supposed to do more, but we need to sit down, relax - and wait a little while first */ - multistate(data, CURLM_STATE_DO_MORE); - rc = CURLM_OK; - } - else { - /* we're done with the DO, now DO_DONE */ - multistate(data, CURLM_STATE_DO_DONE); - rc = CURLM_CALL_MULTI_PERFORM; - } - } - else if((CURLE_SEND_ERROR == result) && - data->easy_conn->bits.reuse) { - /* - * In this situation, a connection that we were trying to use - * may have unexpectedly died. If possible, send the connection - * back to the CONNECT phase so we can try again. - */ - char *newurl = NULL; - followtype follow=FOLLOW_NONE; - CURLcode drc; - bool retry = FALSE; - - drc = Curl_retry_request(data->easy_conn, &newurl); - if(drc) { - /* a failure here pretty much implies an out of memory */ - result = drc; - disconnect_conn = TRUE; - } - else - retry = (newurl)?TRUE:FALSE; - - Curl_posttransfer(data); - drc = multi_done(&data->easy_conn, result, FALSE); - - /* When set to retry the connection, we must to go back to - * the CONNECT state */ - if(retry) { - if(!drc || (drc == CURLE_SEND_ERROR)) { - follow = FOLLOW_RETRY; - drc = Curl_follow(data, newurl, follow); - if(!drc) { - multistate(data, CURLM_STATE_CONNECT); - rc = CURLM_CALL_MULTI_PERFORM; - result = CURLE_OK; - } - else { - /* Follow failed */ - result = drc; - free(newurl); - } - } - else { - /* done didn't return OK or SEND_ERROR */ - result = drc; - free(newurl); - } - } - else { - /* Have error handler disconnect conn if we can't retry */ - disconnect_conn = TRUE; - free(newurl); - } - } - else { - /* failure detected */ - Curl_posttransfer(data); - if(data->easy_conn) - multi_done(&data->easy_conn, result, FALSE); - disconnect_conn = TRUE; - } - } - break; - - case CURLM_STATE_DOING: - /* we continue DOING until the DO phase is complete */ - result = Curl_protocol_doing(data->easy_conn, - &dophase_done); - if(!result) { - if(dophase_done) { - /* after DO, go DO_DONE or DO_MORE */ - multistate(data, data->easy_conn->bits.do_more? - CURLM_STATE_DO_MORE: - CURLM_STATE_DO_DONE); - rc = CURLM_CALL_MULTI_PERFORM; - } /* dophase_done */ - } - else { - /* failure detected */ - Curl_posttransfer(data); - multi_done(&data->easy_conn, result, FALSE); - disconnect_conn = TRUE; - } - break; - - case CURLM_STATE_DO_MORE: - /* - * When we are connected, DO MORE and then go DO_DONE - */ - result = multi_do_more(data->easy_conn, &control); - - /* No need to remove this handle from the send pipeline here since that - is done in multi_done() */ - if(!result) { - if(control) { - /* if positive, advance to DO_DONE - if negative, go back to DOING */ - multistate(data, control==1? - CURLM_STATE_DO_DONE: - CURLM_STATE_DOING); - rc = CURLM_CALL_MULTI_PERFORM; - } - else - /* stay in DO_MORE */ - rc = CURLM_OK; - } - else { - /* failure detected */ - Curl_posttransfer(data); - multi_done(&data->easy_conn, result, FALSE); - disconnect_conn = TRUE; - } - break; - - case CURLM_STATE_DO_DONE: - /* Move ourselves from the send to recv pipeline */ - Curl_move_handle_from_send_to_recv_pipe(data, data->easy_conn); - /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); - - /* Only perform the transfer if there's a good socket to work with. - Having both BAD is a signal to skip immediately to DONE */ - if((data->easy_conn->sockfd != CURL_SOCKET_BAD) || - (data->easy_conn->writesockfd != CURL_SOCKET_BAD)) - multistate(data, CURLM_STATE_WAITPERFORM); - else - multistate(data, CURLM_STATE_DONE); - rc = CURLM_CALL_MULTI_PERFORM; - break; - - case CURLM_STATE_WAITPERFORM: - /* Wait for our turn to PERFORM */ - if(Curl_pipeline_checkget_read(data, data->easy_conn)) { - /* Grabbed the channel */ - multistate(data, CURLM_STATE_PERFORM); - rc = CURLM_CALL_MULTI_PERFORM; - } - break; - - case CURLM_STATE_TOOFAST: /* limit-rate exceeded in either direction */ - /* if both rates are within spec, resume transfer */ - if(Curl_pgrsUpdate(data->easy_conn)) - result = CURLE_ABORTED_BY_CALLBACK; - else - result = Curl_speedcheck(data, now); - - if(( (data->set.max_send_speed == 0) || - (data->progress.ulspeed < data->set.max_send_speed)) && - ( (data->set.max_recv_speed == 0) || - (data->progress.dlspeed < data->set.max_recv_speed))) - multistate(data, CURLM_STATE_PERFORM); - break; - - case CURLM_STATE_PERFORM: - { - char *newurl = NULL; - bool retry = FALSE; - - /* check if over send speed */ - if((data->set.max_send_speed > 0) && - (data->progress.ulspeed > data->set.max_send_speed)) { - int buffersize; - - multistate(data, CURLM_STATE_TOOFAST); - - /* calculate upload rate-limitation timeout. */ - buffersize = (int)(data->set.buffer_size ? - data->set.buffer_size : BUFSIZE); - timeout_ms = Curl_sleep_time(data->set.max_send_speed, - data->progress.ulspeed, buffersize); - Curl_expire_latest(data, timeout_ms); - break; - } - - /* check if over recv speed */ - if((data->set.max_recv_speed > 0) && - (data->progress.dlspeed > data->set.max_recv_speed)) { - int buffersize; - - multistate(data, CURLM_STATE_TOOFAST); - - /* Calculate download rate-limitation timeout. */ - buffersize = (int)(data->set.buffer_size ? - data->set.buffer_size : BUFSIZE); - timeout_ms = Curl_sleep_time(data->set.max_recv_speed, - data->progress.dlspeed, buffersize); - Curl_expire_latest(data, timeout_ms); - break; - } - - /* read/write data if it is ready to do so */ - result = Curl_readwrite(data->easy_conn, data, &done); - - k = &data->req; - - if(!(k->keepon & KEEP_RECV)) - /* We're done receiving */ - Curl_pipeline_leave_read(data->easy_conn); - - if(!(k->keepon & KEEP_SEND)) - /* We're done sending */ - Curl_pipeline_leave_write(data->easy_conn); - - if(done || (result == CURLE_RECV_ERROR)) { - /* If CURLE_RECV_ERROR happens early enough, we assume it was a race - * condition and the server closed the re-used connection exactly when - * we wanted to use it, so figure out if that is indeed the case. - */ - CURLcode ret = Curl_retry_request(data->easy_conn, &newurl); - if(!ret) - retry = (newurl)?TRUE:FALSE; - - if(retry) { - /* if we are to retry, set the result to OK and consider the - request as done */ - result = CURLE_OK; - done = TRUE; - } - } - - if(result) { - /* - * The transfer phase returned error, we mark the connection to get - * closed to prevent being re-used. This is because we can't possibly - * know if the connection is in a good shape or not now. Unless it is - * a protocol which uses two "channels" like FTP, as then the error - * happened in the data connection. - */ - - if(!(data->easy_conn->handler->flags & PROTOPT_DUAL) && - result != CURLE_HTTP2_STREAM) - connclose(data->easy_conn, "Transfer returned error"); - - Curl_posttransfer(data); - multi_done(&data->easy_conn, result, FALSE); - } - else if(done) { - followtype follow=FOLLOW_NONE; - - /* call this even if the readwrite function returned error */ - Curl_posttransfer(data); - - /* we're no longer receiving */ - Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe); - - /* expire the new receiving pipeline head */ - if(data->easy_conn->recv_pipe->head) - Curl_expire_latest(data->easy_conn->recv_pipe->head->ptr, 1); - - /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); - - /* When we follow redirects or is set to retry the connection, we must - to go back to the CONNECT state */ - if(data->req.newurl || retry) { - if(!retry) { - /* if the URL is a follow-location and not just a retried request - then figure out the URL here */ - free(newurl); - newurl = data->req.newurl; - data->req.newurl = NULL; - follow = FOLLOW_REDIR; - } - else - follow = FOLLOW_RETRY; - result = multi_done(&data->easy_conn, CURLE_OK, FALSE); - if(!result) { - result = Curl_follow(data, newurl, follow); - if(!result) { - multistate(data, CURLM_STATE_CONNECT); - rc = CURLM_CALL_MULTI_PERFORM; - newurl = NULL; /* handed over the memory ownership to - Curl_follow(), make sure we don't free() it - here */ - } - } - } - else { - /* after the transfer is done, go DONE */ - - /* but first check to see if we got a location info even though we're - not following redirects */ - if(data->req.location) { - free(newurl); - newurl = data->req.location; - data->req.location = NULL; - result = Curl_follow(data, newurl, FOLLOW_FAKE); - if(!result) - newurl = NULL; /* allocation was handed over Curl_follow() */ - else - disconnect_conn = TRUE; - } - - multistate(data, CURLM_STATE_DONE); - rc = CURLM_CALL_MULTI_PERFORM; - } - } - - free(newurl); - break; - } - - case CURLM_STATE_DONE: - /* this state is highly transient, so run another loop after this */ - rc = CURLM_CALL_MULTI_PERFORM; - - if(data->easy_conn) { - CURLcode res; - - /* Remove ourselves from the receive pipeline, if we are there. */ - Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe); - /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); - - /* post-transfer command */ - res = multi_done(&data->easy_conn, result, FALSE); - - /* allow a previously set error code take precedence */ - if(!result) - result = res; - - /* - * If there are other handles on the pipeline, multi_done won't set - * easy_conn to NULL. In such a case, curl_multi_remove_handle() can - * access free'd data, if the connection is free'd and the handle - * removed before we perform the processing in CURLM_STATE_COMPLETED - */ - if(data->easy_conn) - data->easy_conn = NULL; - } - - if(data->set.wildcardmatch) { - if(data->wildcard.state != CURLWC_DONE) { - /* if a wildcard is set and we are not ending -> lets start again - with CURLM_STATE_INIT */ - multistate(data, CURLM_STATE_INIT); - break; - } - } - - /* after we have DONE what we're supposed to do, go COMPLETED, and - it doesn't matter what the multi_done() returned! */ - multistate(data, CURLM_STATE_COMPLETED); - break; - - case CURLM_STATE_COMPLETED: - /* this is a completed transfer, it is likely to still be connected */ - - /* This node should be delinked from the list now and we should post - an information message that we are complete. */ - - /* Important: reset the conn pointer so that we don't point to memory - that could be freed anytime */ - data->easy_conn = NULL; - - Curl_expire(data, 0); /* stop all timers */ - break; - - case CURLM_STATE_MSGSENT: - data->result = result; - return CURLM_OK; /* do nothing */ - - default: - return CURLM_INTERNAL_ERROR; - } - statemachine_end: - - if(data->mstate < CURLM_STATE_COMPLETED) { - if(result) { - /* - * If an error was returned, and we aren't in completed state now, - * then we go to completed and consider this transfer aborted. - */ - - /* NOTE: no attempt to disconnect connections must be made - in the case blocks above - cleanup happens only here */ - - data->state.pipe_broke = FALSE; - - /* Check if we can move pending requests to send pipe */ - Curl_multi_process_pending_handles(multi); - - if(data->easy_conn) { - /* if this has a connection, unsubscribe from the pipelines */ - Curl_pipeline_leave_write(data->easy_conn); - Curl_pipeline_leave_read(data->easy_conn); - Curl_removeHandleFromPipeline(data, data->easy_conn->send_pipe); - Curl_removeHandleFromPipeline(data, data->easy_conn->recv_pipe); - - if(disconnect_conn) { - /* Don't attempt to send data over a connection that timed out */ - bool dead_connection = result == CURLE_OPERATION_TIMEDOUT; - /* disconnect properly */ - Curl_disconnect(data->easy_conn, dead_connection); - - /* This is where we make sure that the easy_conn pointer is reset. - We don't have to do this in every case block above where a - failure is detected */ - data->easy_conn = NULL; - } - } - else if(data->mstate == CURLM_STATE_CONNECT) { - /* Curl_connect() failed */ - (void)Curl_posttransfer(data); - } - - multistate(data, CURLM_STATE_COMPLETED); - } - /* if there's still a connection to use, call the progress function */ - else if(data->easy_conn && Curl_pgrsUpdate(data->easy_conn)) { - /* aborted due to progress callback return code must close the - connection */ - result = CURLE_ABORTED_BY_CALLBACK; - connclose(data->easy_conn, "Aborted by callback"); - - /* if not yet in DONE state, go there, otherwise COMPLETED */ - multistate(data, (data->mstate < CURLM_STATE_DONE)? - CURLM_STATE_DONE: CURLM_STATE_COMPLETED); - rc = CURLM_CALL_MULTI_PERFORM; - } - } - - if(CURLM_STATE_COMPLETED == data->mstate) { - /* now fill in the Curl_message with this info */ - msg = &data->msg; - - msg->extmsg.msg = CURLMSG_DONE; - msg->extmsg.easy_handle = data; - msg->extmsg.data.result = result; - - rc = multi_addmsg(multi, msg); - - multistate(data, CURLM_STATE_MSGSENT); - } - } while((rc == CURLM_CALL_MULTI_PERFORM) || multi_ischanged(multi, FALSE)); - - data->result = result; - - - return rc; -} - - -CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct SessionHandle *data; - CURLMcode returncode=CURLM_OK; - struct Curl_tree *t; - struct timeval now = Curl_tvnow(); - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - data=multi->easyp; - while(data) { - CURLMcode result; - SIGPIPE_VARIABLE(pipe_st); - - sigpipe_ignore(data, &pipe_st); - result = multi_runsingle(multi, now, data); - sigpipe_restore(&pipe_st); - - if(result) - returncode = result; - - data = data->next; /* operate on next handle */ - } - - /* - * Simply remove all expired timers from the splay since handles are dealt - * with unconditionally by this function and curl_multi_timeout() requires - * that already passed/handled expire times are removed from the splay. - * - * It is important that the 'now' value is set at the entry of this function - * and not for the current time as it may have ticked a little while since - * then and then we risk this loop to remove timers that actually have not - * been handled! - */ - do { - multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); - if(t) - /* the removed may have another timeout in queue */ - (void)add_next_timeout(now, multi, t->payload); - - } while(t); - - *running_handles = multi->num_alive; - - if(CURLM_OK >= returncode) - update_timer(multi); - - return returncode; -} - -static void close_all_connections(struct Curl_multi *multi) -{ - struct connectdata *conn; - - conn = Curl_conncache_find_first_connection(&multi->conn_cache); - while(conn) { - SIGPIPE_VARIABLE(pipe_st); - conn->data = multi->closure_handle; - - sigpipe_ignore(conn->data, &pipe_st); - /* This will remove the connection from the cache */ - (void)Curl_disconnect(conn, FALSE); - sigpipe_restore(&pipe_st); - - conn = Curl_conncache_find_first_connection(&multi->conn_cache); - } -} - -CURLMcode curl_multi_cleanup(CURLM *multi_handle) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct SessionHandle *data; - struct SessionHandle *nextdata; - - if(GOOD_MULTI_HANDLE(multi)) { - bool restore_pipe = FALSE; - SIGPIPE_VARIABLE(pipe_st); - - multi->type = 0; /* not good anymore */ - - /* Close all the connections in the connection cache */ - close_all_connections(multi); - - if(multi->closure_handle) { - sigpipe_ignore(multi->closure_handle, &pipe_st); - restore_pipe = TRUE; - - multi->closure_handle->dns.hostcache = &multi->hostcache; - Curl_hostcache_clean(multi->closure_handle, - multi->closure_handle->dns.hostcache); - - Curl_close(multi->closure_handle); - } - - Curl_hash_destroy(&multi->sockhash); - Curl_conncache_destroy(&multi->conn_cache); - Curl_llist_destroy(multi->msglist, NULL); - Curl_llist_destroy(multi->pending, NULL); - - /* remove all easy handles */ - data = multi->easyp; - while(data) { - nextdata=data->next; - if(data->dns.hostcachetype == HCACHE_MULTI) { - /* clear out the usage of the shared DNS cache */ - Curl_hostcache_clean(data, data->dns.hostcache); - data->dns.hostcache = NULL; - data->dns.hostcachetype = HCACHE_NONE; - } - - /* Clear the pointer to the connection cache */ - data->state.conn_cache = NULL; - data->multi = NULL; /* clear the association */ - - data = nextdata; - } - - Curl_hash_destroy(&multi->hostcache); - - /* Free the blacklists by setting them to NULL */ - Curl_pipeline_set_site_blacklist(NULL, &multi->pipelining_site_bl); - Curl_pipeline_set_server_blacklist(NULL, &multi->pipelining_server_bl); - - free(multi); - if(restore_pipe) - sigpipe_restore(&pipe_st); - - return CURLM_OK; - } - else - return CURLM_BAD_HANDLE; -} - -/* - * curl_multi_info_read() - * - * This function is the primary way for a multi/multi_socket application to - * figure out if a transfer has ended. We MUST make this function as fast as - * possible as it will be polled frequently and we MUST NOT scan any lists in - * here to figure out things. We must scale fine to thousands of handles and - * beyond. The current design is fully O(1). - */ - -CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct Curl_message *msg; - - *msgs_in_queue = 0; /* default to none */ - - if(GOOD_MULTI_HANDLE(multi) && Curl_llist_count(multi->msglist)) { - /* there is one or more messages in the list */ - struct curl_llist_element *e; - - /* extract the head of the list to return */ - e = multi->msglist->head; - - msg = e->ptr; - - /* remove the extracted entry */ - Curl_llist_remove(multi->msglist, e, NULL); - - *msgs_in_queue = curlx_uztosi(Curl_llist_count(multi->msglist)); - - return &msg->extmsg; - } - else - return NULL; -} - -/* - * singlesocket() checks what sockets we deal with and their "action state" - * and if we have a different state in any of those sockets from last time we - * call the callback accordingly. - */ -static void singlesocket(struct Curl_multi *multi, - struct SessionHandle *data) -{ - curl_socket_t socks[MAX_SOCKSPEREASYHANDLE]; - int i; - struct Curl_sh_entry *entry; - curl_socket_t s; - int num; - unsigned int curraction; - - for(i=0; i< MAX_SOCKSPEREASYHANDLE; i++) - socks[i] = CURL_SOCKET_BAD; - - /* Fill in the 'current' struct with the state as it is now: what sockets to - supervise and for what actions */ - curraction = multi_getsock(data, socks, MAX_SOCKSPEREASYHANDLE); - - /* We have 0 .. N sockets already and we get to know about the 0 .. M - sockets we should have from now on. Detect the differences, remove no - longer supervised ones and add new ones */ - - /* walk over the sockets we got right now */ - for(i=0; (i< MAX_SOCKSPEREASYHANDLE) && - (curraction & (GETSOCK_READSOCK(i) | GETSOCK_WRITESOCK(i))); - i++) { - int action = CURL_POLL_NONE; - - s = socks[i]; - - /* get it from the hash */ - entry = sh_getentry(&multi->sockhash, s); - - if(curraction & GETSOCK_READSOCK(i)) - action |= CURL_POLL_IN; - if(curraction & GETSOCK_WRITESOCK(i)) - action |= CURL_POLL_OUT; - - if(entry) { - /* yeps, already present so check if it has the same action set */ - if(entry->action == action) - /* same, continue */ - continue; - } - else { - /* this is a socket we didn't have before, add it! */ - entry = sh_addentry(&multi->sockhash, s, data); - if(!entry) - /* fatal */ - return; - } - - /* we know (entry != NULL) at this point, see the logic above */ - if(multi->socket_cb) - multi->socket_cb(data, - s, - action, - multi->socket_userp, - entry->socketp); - - entry->action = action; /* store the current action state */ - } - - num = i; /* number of sockets */ - - /* when we've walked over all the sockets we should have right now, we must - make sure to detect sockets that are removed */ - for(i=0; i< data->numsocks; i++) { - int j; - s = data->sockets[i]; - for(j=0; jsockhash, s); - if(entry) { - /* this socket has been removed. Tell the app to remove it */ - bool remove_sock_from_hash = TRUE; - - /* check if the socket to be removed serves a connection which has - other easy-s in a pipeline. In this case the socket should not be - removed. */ - struct connectdata *easy_conn = data->easy_conn; - if(easy_conn) { - if(easy_conn->recv_pipe && easy_conn->recv_pipe->size > 1) { - /* the handle should not be removed from the pipe yet */ - remove_sock_from_hash = FALSE; - - /* Update the sockhash entry to instead point to the next in line - for the recv_pipe, or the first (in case this particular easy - isn't already) */ - if(entry->easy == data) { - if(Curl_recvpipe_head(data, easy_conn)) - entry->easy = easy_conn->recv_pipe->head->next->ptr; - else - entry->easy = easy_conn->recv_pipe->head->ptr; - } - } - if(easy_conn->send_pipe && easy_conn->send_pipe->size > 1) { - /* the handle should not be removed from the pipe yet */ - remove_sock_from_hash = FALSE; - - /* Update the sockhash entry to instead point to the next in line - for the send_pipe, or the first (in case this particular easy - isn't already) */ - if(entry->easy == data) { - if(Curl_sendpipe_head(data, easy_conn)) - entry->easy = easy_conn->send_pipe->head->next->ptr; - else - entry->easy = easy_conn->send_pipe->head->ptr; - } - } - /* Don't worry about overwriting recv_pipe head with send_pipe_head, - when action will be asked on the socket (see multi_socket()), the - head of the correct pipe will be taken according to the - action. */ - } - - if(remove_sock_from_hash) { - /* in this case 'entry' is always non-NULL */ - if(multi->socket_cb) - multi->socket_cb(data, - s, - CURL_POLL_REMOVE, - multi->socket_userp, - entry->socketp); - sh_delentry(&multi->sockhash, s); - } - } /* if sockhash entry existed */ - } /* for loop over numsocks */ - - memcpy(data->sockets, socks, num*sizeof(curl_socket_t)); - data->numsocks = num; -} - -/* - * Curl_multi_closed() - * - * Used by the connect code to tell the multi_socket code that one of the - * sockets we were using is about to be closed. This function will then - * remove it from the sockethash for this handle to make the multi_socket API - * behave properly, especially for the case when libcurl will create another - * socket again and it gets the same file descriptor number. - */ - -void Curl_multi_closed(struct connectdata *conn, curl_socket_t s) -{ - struct Curl_multi *multi = conn->data->multi; - if(multi) { - /* this is set if this connection is part of a handle that is added to - a multi handle, and only then this is necessary */ - struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); - - if(entry) { - if(multi->socket_cb) - multi->socket_cb(conn->data, s, CURL_POLL_REMOVE, - multi->socket_userp, - entry->socketp); - - /* now remove it from the socket hash */ - sh_delentry(&multi->sockhash, s); - } - } -} - - - -/* - * add_next_timeout() - * - * Each SessionHandle has a list of timeouts. The add_next_timeout() is called - * when it has just been removed from the splay tree because the timeout has - * expired. This function is then to advance in the list to pick the next - * timeout to use (skip the already expired ones) and add this node back to - * the splay tree again. - * - * The splay tree only has each sessionhandle as a single node and the nearest - * timeout is used to sort it on. - */ -static CURLMcode add_next_timeout(struct timeval now, - struct Curl_multi *multi, - struct SessionHandle *d) -{ - struct timeval *tv = &d->state.expiretime; - struct curl_llist *list = d->state.timeoutlist; - struct curl_llist_element *e; - - /* move over the timeout list for this specific handle and remove all - timeouts that are now passed tense and store the next pending - timeout in *tv */ - for(e = list->head; e;) { - struct curl_llist_element *n = e->next; - long diff = curlx_tvdiff(*(struct timeval *)e->ptr, now); - if(diff <= 0) - /* remove outdated entry */ - Curl_llist_remove(list, e, NULL); - else - /* the list is sorted so get out on the first mismatch */ - break; - e = n; - } - e = list->head; - if(!e) { - /* clear the expire times within the handles that we remove from the - splay tree */ - tv->tv_sec = 0; - tv->tv_usec = 0; - } - else { - /* copy the first entry to 'tv' */ - memcpy(tv, e->ptr, sizeof(*tv)); - - /* remove first entry from list */ - Curl_llist_remove(list, e, NULL); - - /* insert this node again into the splay */ - multi->timetree = Curl_splayinsert(*tv, multi->timetree, - &d->state.timenode); - } - return CURLM_OK; -} - -static CURLMcode multi_socket(struct Curl_multi *multi, - bool checkall, - curl_socket_t s, - int ev_bitmask, - int *running_handles) -{ - CURLMcode result = CURLM_OK; - struct SessionHandle *data = NULL; - struct Curl_tree *t; - struct timeval now = Curl_tvnow(); - - if(checkall) { - /* *perform() deals with running_handles on its own */ - result = curl_multi_perform(multi, running_handles); - - /* walk through each easy handle and do the socket state change magic - and callbacks */ - if(result != CURLM_BAD_HANDLE) { - data=multi->easyp; - while(data) { - singlesocket(multi, data); - data = data->next; - } - } - - /* or should we fall-through and do the timer-based stuff? */ - return result; - } - else if(s != CURL_SOCKET_TIMEOUT) { - - struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); - - if(!entry) - /* Unmatched socket, we can't act on it but we ignore this fact. In - real-world tests it has been proved that libevent can in fact give - the application actions even though the socket was just previously - asked to get removed, so thus we better survive stray socket actions - and just move on. */ - ; - else { - SIGPIPE_VARIABLE(pipe_st); - - data = entry->easy; - - if(data->magic != CURLEASY_MAGIC_NUMBER) - /* bad bad bad bad bad bad bad */ - return CURLM_INTERNAL_ERROR; - - /* If the pipeline is enabled, take the handle which is in the head of - the pipeline. If we should write into the socket, take the send_pipe - head. If we should read from the socket, take the recv_pipe head. */ - if(data->easy_conn) { - if((ev_bitmask & CURL_POLL_OUT) && - data->easy_conn->send_pipe && - data->easy_conn->send_pipe->head) - data = data->easy_conn->send_pipe->head->ptr; - else if((ev_bitmask & CURL_POLL_IN) && - data->easy_conn->recv_pipe && - data->easy_conn->recv_pipe->head) - data = data->easy_conn->recv_pipe->head->ptr; - } - - if(data->easy_conn && - !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK)) - /* set socket event bitmask if they're not locked */ - data->easy_conn->cselect_bits = ev_bitmask; - - sigpipe_ignore(data, &pipe_st); - result = multi_runsingle(multi, now, data); - sigpipe_restore(&pipe_st); - - if(data->easy_conn && - !(data->easy_conn->handler->flags & PROTOPT_DIRLOCK)) - /* clear the bitmask only if not locked */ - data->easy_conn->cselect_bits = 0; - - if(CURLM_OK >= result) - /* get the socket(s) and check if the state has been changed since - last */ - singlesocket(multi, data); - - /* Now we fall-through and do the timer-based stuff, since we don't want - to force the user to have to deal with timeouts as long as at least - one connection in fact has traffic. */ - - data = NULL; /* set data to NULL again to avoid calling - multi_runsingle() in case there's no need to */ - now = Curl_tvnow(); /* get a newer time since the multi_runsingle() loop - may have taken some time */ - } - } - else { - /* Asked to run due to time-out. Clear the 'lastcall' variable to force - update_timer() to trigger a callback to the app again even if the same - timeout is still the one to run after this call. That handles the case - when the application asks libcurl to run the timeout prematurely. */ - memset(&multi->timer_lastcall, 0, sizeof(multi->timer_lastcall)); - } - - /* - * The loop following here will go on as long as there are expire-times left - * to process in the splay and 'data' will be re-assigned for every expired - * handle we deal with. - */ - do { - /* the first loop lap 'data' can be NULL */ - if(data) { - SIGPIPE_VARIABLE(pipe_st); - - sigpipe_ignore(data, &pipe_st); - result = multi_runsingle(multi, now, data); - sigpipe_restore(&pipe_st); - - if(CURLM_OK >= result) - /* get the socket(s) and check if the state has been changed since - last */ - singlesocket(multi, data); - } - - /* Check if there's one (more) expired timer to deal with! This function - extracts a matching node if there is one */ - - multi->timetree = Curl_splaygetbest(now, multi->timetree, &t); - if(t) { - data = t->payload; /* assign this for next loop */ - (void)add_next_timeout(now, multi, t->payload); - } - - } while(t); - - *running_handles = multi->num_alive; - return result; -} - -#undef curl_multi_setopt -CURLMcode curl_multi_setopt(CURLM *multi_handle, - CURLMoption option, ...) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - CURLMcode res = CURLM_OK; - va_list param; - - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - va_start(param, option); - - switch(option) { - case CURLMOPT_SOCKETFUNCTION: - multi->socket_cb = va_arg(param, curl_socket_callback); - break; - case CURLMOPT_SOCKETDATA: - multi->socket_userp = va_arg(param, void *); - break; - case CURLMOPT_PUSHFUNCTION: - multi->push_cb = va_arg(param, curl_push_callback); - break; - case CURLMOPT_PUSHDATA: - multi->push_userp = va_arg(param, void *); - break; - case CURLMOPT_PIPELINING: - multi->pipelining = va_arg(param, long); - break; - case CURLMOPT_TIMERFUNCTION: - multi->timer_cb = va_arg(param, curl_multi_timer_callback); - break; - case CURLMOPT_TIMERDATA: - multi->timer_userp = va_arg(param, void *); - break; - case CURLMOPT_MAXCONNECTS: - multi->maxconnects = va_arg(param, long); - break; - case CURLMOPT_MAX_HOST_CONNECTIONS: - multi->max_host_connections = va_arg(param, long); - break; - case CURLMOPT_MAX_PIPELINE_LENGTH: - multi->max_pipeline_length = va_arg(param, long); - break; - case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE: - multi->content_length_penalty_size = va_arg(param, long); - break; - case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE: - multi->chunk_length_penalty_size = va_arg(param, long); - break; - case CURLMOPT_PIPELINING_SITE_BL: - res = Curl_pipeline_set_site_blacklist(va_arg(param, char **), - &multi->pipelining_site_bl); - break; - case CURLMOPT_PIPELINING_SERVER_BL: - res = Curl_pipeline_set_server_blacklist(va_arg(param, char **), - &multi->pipelining_server_bl); - break; - case CURLMOPT_MAX_TOTAL_CONNECTIONS: - multi->max_total_connections = va_arg(param, long); - break; - default: - res = CURLM_UNKNOWN_OPTION; - break; - } - va_end(param); - return res; -} - -/* we define curl_multi_socket() in the public multi.h header */ -#undef curl_multi_socket - -CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, - int *running_handles) -{ - CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s, - 0, running_handles); - if(CURLM_OK >= result) - update_timer((struct Curl_multi *)multi_handle); - return result; -} - -CURLMcode curl_multi_socket_action(CURLM *multi_handle, curl_socket_t s, - int ev_bitmask, int *running_handles) -{ - CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, FALSE, s, - ev_bitmask, running_handles); - if(CURLM_OK >= result) - update_timer((struct Curl_multi *)multi_handle); - return result; -} - -CURLMcode curl_multi_socket_all(CURLM *multi_handle, int *running_handles) - -{ - CURLMcode result = multi_socket((struct Curl_multi *)multi_handle, - TRUE, CURL_SOCKET_BAD, 0, running_handles); - if(CURLM_OK >= result) - update_timer((struct Curl_multi *)multi_handle); - return result; -} - -static CURLMcode multi_timeout(struct Curl_multi *multi, - long *timeout_ms) -{ - static struct timeval tv_zero = {0, 0}; - - if(multi->timetree) { - /* we have a tree of expire times */ - struct timeval now = Curl_tvnow(); - - /* splay the lowest to the bottom */ - multi->timetree = Curl_splay(tv_zero, multi->timetree); - - if(Curl_splaycomparekeys(multi->timetree->key, now) > 0) { - /* some time left before expiration */ - *timeout_ms = curlx_tvdiff(multi->timetree->key, now); - if(!*timeout_ms) - /* - * Since we only provide millisecond resolution on the returned value - * and the diff might be less than one millisecond here, we don't - * return zero as that may cause short bursts of busyloops on fast - * processors while the diff is still present but less than one - * millisecond! instead we return 1 until the time is ripe. - */ - *timeout_ms=1; - } - else - /* 0 means immediately */ - *timeout_ms = 0; - } - else - *timeout_ms = -1; - - return CURLM_OK; -} - -CURLMcode curl_multi_timeout(CURLM *multi_handle, - long *timeout_ms) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - - /* First, make some basic checks that the CURLM handle is a good handle */ - if(!GOOD_MULTI_HANDLE(multi)) - return CURLM_BAD_HANDLE; - - return multi_timeout(multi, timeout_ms); -} - -/* - * Tell the application it should update its timers, if it subscribes to the - * update timer callback. - */ -static int update_timer(struct Curl_multi *multi) -{ - long timeout_ms; - - if(!multi->timer_cb) - return 0; - if(multi_timeout(multi, &timeout_ms)) { - return -1; - } - if(timeout_ms < 0) { - static const struct timeval none={0, 0}; - if(Curl_splaycomparekeys(none, multi->timer_lastcall)) { - multi->timer_lastcall = none; - /* there's no timeout now but there was one previously, tell the app to - disable it */ - return multi->timer_cb((CURLM*)multi, -1, multi->timer_userp); - } - return 0; - } - - /* When multi_timeout() is done, multi->timetree points to the node with the - * timeout we got the (relative) time-out time for. We can thus easily check - * if this is the same (fixed) time as we got in a previous call and then - * avoid calling the callback again. */ - if(Curl_splaycomparekeys(multi->timetree->key, multi->timer_lastcall) == 0) - return 0; - - multi->timer_lastcall = multi->timetree->key; - - return multi->timer_cb((CURLM*)multi, timeout_ms, multi->timer_userp); -} - -/* - * multi_freetimeout() - * - * Callback used by the llist system when a single timeout list entry is - * destroyed. - */ -static void multi_freetimeout(void *user, void *entryptr) -{ - (void)user; - - /* the entry was plain malloc()'ed */ - free(entryptr); -} - -/* - * multi_addtimeout() - * - * Add a timestamp to the list of timeouts. Keep the list sorted so that head - * of list is always the timeout nearest in time. - * - */ -static CURLMcode -multi_addtimeout(struct curl_llist *timeoutlist, - struct timeval *stamp) -{ - struct curl_llist_element *e; - struct timeval *timedup; - struct curl_llist_element *prev = NULL; - - timedup = malloc(sizeof(*timedup)); - if(!timedup) - return CURLM_OUT_OF_MEMORY; - - /* copy the timestamp */ - memcpy(timedup, stamp, sizeof(*timedup)); - - if(Curl_llist_count(timeoutlist)) { - /* find the correct spot in the list */ - for(e = timeoutlist->head; e; e = e->next) { - struct timeval *checktime = e->ptr; - long diff = curlx_tvdiff(*checktime, *timedup); - if(diff > 0) - break; - prev = e; - } - - } - /* else - this is the first timeout on the list */ - - if(!Curl_llist_insert_next(timeoutlist, prev, timedup)) { - free(timedup); - return CURLM_OUT_OF_MEMORY; - } - - return CURLM_OK; -} - -/* - * Curl_expire() - * - * given a number of milliseconds from now to use to set the 'act before - * this'-time for the transfer, to be extracted by curl_multi_timeout() - * - * Note that the timeout will be added to a queue of timeouts if it defines a - * moment in time that is later than the current head of queue. - * - * Pass zero to clear all timeout values for this handle. -*/ -void Curl_expire(struct SessionHandle *data, long milli) -{ - struct Curl_multi *multi = data->multi; - struct timeval *nowp = &data->state.expiretime; - int rc; - - /* this is only interesting while there is still an associated multi struct - remaining! */ - if(!multi) - return; - - if(!milli) { - /* No timeout, clear the time data. */ - if(nowp->tv_sec || nowp->tv_usec) { - /* Since this is an cleared time, we must remove the previous entry from - the splay tree */ - struct curl_llist *list = data->state.timeoutlist; - - rc = Curl_splayremovebyaddr(multi->timetree, - &data->state.timenode, - &multi->timetree); - if(rc) - infof(data, "Internal error clearing splay node = %d\n", rc); - - /* flush the timeout list too */ - while(list->size > 0) - Curl_llist_remove(list, list->tail, NULL); - -#ifdef DEBUGBUILD - infof(data, "Expire cleared\n"); -#endif - nowp->tv_sec = 0; - nowp->tv_usec = 0; - } - } - else { - struct timeval set; - - set = Curl_tvnow(); - set.tv_sec += milli/1000; - set.tv_usec += (milli%1000)*1000; - - if(set.tv_usec >= 1000000) { - set.tv_sec++; - set.tv_usec -= 1000000; - } - - if(nowp->tv_sec || nowp->tv_usec) { - /* This means that the struct is added as a node in the splay tree. - Compare if the new time is earlier, and only remove-old/add-new if it - is. */ - long diff = curlx_tvdiff(set, *nowp); - if(diff > 0) { - /* the new expire time was later so just add it to the queue - and get out */ - multi_addtimeout(data->state.timeoutlist, &set); - return; - } - - /* the new time is newer than the presently set one, so add the current - to the queue and update the head */ - multi_addtimeout(data->state.timeoutlist, nowp); - - /* Since this is an updated time, we must remove the previous entry from - the splay tree first and then re-add the new value */ - rc = Curl_splayremovebyaddr(multi->timetree, - &data->state.timenode, - &multi->timetree); - if(rc) - infof(data, "Internal error removing splay node = %d\n", rc); - } - - *nowp = set; - data->state.timenode.payload = data; - multi->timetree = Curl_splayinsert(*nowp, - multi->timetree, - &data->state.timenode); - } -#if 0 - Curl_splayprint(multi->timetree, 0, TRUE); -#endif -} - -/* - * Curl_expire_latest() - * - * This is like Curl_expire() but will only add a timeout node to the list of - * timers if there is no timeout that will expire before the given time. - * - * Use this function if the code logic risks calling this function many times - * or if there's no particular conditional wait in the code for this specific - * time-out period to expire. - * - */ -void Curl_expire_latest(struct SessionHandle *data, long milli) -{ - struct timeval *expire = &data->state.expiretime; - - struct timeval set; - - set = Curl_tvnow(); - set.tv_sec += milli / 1000; - set.tv_usec += (milli % 1000) * 1000; - - if(set.tv_usec >= 1000000) { - set.tv_sec++; - set.tv_usec -= 1000000; - } - - if(expire->tv_sec || expire->tv_usec) { - /* This means that the struct is added as a node in the splay tree. - Compare if the new time is earlier, and only remove-old/add-new if it - is. */ - long diff = curlx_tvdiff(set, *expire); - if(diff > 0) - /* the new expire time was later than the top time, so just skip this */ - return; - } - - /* Just add the timeout like normal */ - Curl_expire(data, milli); -} - -CURLMcode curl_multi_assign(CURLM *multi_handle, - curl_socket_t s, void *hashp) -{ - struct Curl_sh_entry *there = NULL; - struct Curl_multi *multi = (struct Curl_multi *)multi_handle; - - there = sh_getentry(&multi->sockhash, s); - - if(!there) - return CURLM_BAD_SOCKET; - - there->socketp = hashp; - - return CURLM_OK; -} - -size_t Curl_multi_max_host_connections(struct Curl_multi *multi) -{ - return multi ? multi->max_host_connections : 0; -} - -size_t Curl_multi_max_total_connections(struct Curl_multi *multi) -{ - return multi ? multi->max_total_connections : 0; -} - -curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi) -{ - return multi ? multi->content_length_penalty_size : 0; -} - -curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi) -{ - return multi ? multi->chunk_length_penalty_size : 0; -} - -struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi) -{ - return multi->pipelining_site_bl; -} - -struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi) -{ - return multi->pipelining_server_bl; -} - -void Curl_multi_process_pending_handles(struct Curl_multi *multi) -{ - struct curl_llist_element *e = multi->pending->head; - - while(e) { - struct SessionHandle *data = e->ptr; - struct curl_llist_element *next = e->next; - - if(data->mstate == CURLM_STATE_CONNECT_PEND) { - multistate(data, CURLM_STATE_CONNECT); - - /* Remove this node from the list */ - Curl_llist_remove(multi->pending, e, NULL); - - /* Make sure that the handle will be processed soonish. */ - Curl_expire_latest(data, 1); - } - - e = next; /* operate on next handle */ - } -} - -#ifdef DEBUGBUILD -void Curl_multi_dump(const struct Curl_multi *multi_handle) -{ - struct Curl_multi *multi=(struct Curl_multi *)multi_handle; - struct SessionHandle *data; - int i; - fprintf(stderr, "* Multi status: %d handles, %d alive\n", - multi->num_easy, multi->num_alive); - for(data=multi->easyp; data; data = data->next) { - if(data->mstate < CURLM_STATE_COMPLETED) { - /* only display handles that are not completed */ - fprintf(stderr, "handle %p, state %s, %d sockets\n", - (void *)data, - statename[data->mstate], data->numsocks); - for(i=0; i < data->numsocks; i++) { - curl_socket_t s = data->sockets[i]; - struct Curl_sh_entry *entry = sh_getentry(&multi->sockhash, s); - - fprintf(stderr, "%d ", (int)s); - if(!entry) { - fprintf(stderr, "INTERNAL CONFUSION\n"); - continue; - } - fprintf(stderr, "[%s %s] ", - entry->action&CURL_POLL_IN?"RECVING":"", - entry->action&CURL_POLL_OUT?"SENDING":""); - } - if(data->numsocks) - fprintf(stderr, "\n"); - } - } -} -#endif diff --git a/Externals/curl/lib/multihandle.h b/Externals/curl/lib/multihandle.h deleted file mode 100644 index fc81a55401..0000000000 --- a/Externals/curl/lib/multihandle.h +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef HEADER_CURL_MULTIHANDLE_H -#define HEADER_CURL_MULTIHANDLE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "conncache.h" - -struct Curl_message { - /* the 'CURLMsg' is the part that is visible to the external user */ - struct CURLMsg extmsg; -}; - -/* NOTE: if you add a state here, add the name to the statename[] array as - well! -*/ -typedef enum { - CURLM_STATE_INIT, /* 0 - start in this state */ - CURLM_STATE_CONNECT_PEND, /* 1 - no connections, waiting for one */ - CURLM_STATE_CONNECT, /* 2 - resolve/connect has been sent off */ - CURLM_STATE_WAITRESOLVE, /* 3 - awaiting the resolve to finalize */ - CURLM_STATE_WAITCONNECT, /* 4 - awaiting the TCP connect to finalize */ - CURLM_STATE_WAITPROXYCONNECT, /* 5 - awaiting proxy CONNECT to finalize */ - CURLM_STATE_SENDPROTOCONNECT, /* 6 - initiate protocol connect procedure */ - CURLM_STATE_PROTOCONNECT, /* 7 - completing the protocol-specific connect - phase */ - CURLM_STATE_WAITDO, /* 8 - wait for our turn to send the request */ - CURLM_STATE_DO, /* 9 - start send off the request (part 1) */ - CURLM_STATE_DOING, /* 10 - sending off the request (part 1) */ - CURLM_STATE_DO_MORE, /* 11 - send off the request (part 2) */ - CURLM_STATE_DO_DONE, /* 12 - done sending off request */ - CURLM_STATE_WAITPERFORM, /* 13 - wait for our turn to read the response */ - CURLM_STATE_PERFORM, /* 14 - transfer data */ - CURLM_STATE_TOOFAST, /* 15 - wait because limit-rate exceeded */ - CURLM_STATE_DONE, /* 16 - post data transfer operation */ - CURLM_STATE_COMPLETED, /* 17 - operation complete */ - CURLM_STATE_MSGSENT, /* 18 - the operation complete message is sent */ - CURLM_STATE_LAST /* 19 - not a true state, never use this */ -} CURLMstate; - -/* we support N sockets per easy handle. Set the corresponding bit to what - action we should wait for */ -#define MAX_SOCKSPEREASYHANDLE 5 -#define GETSOCK_READABLE (0x00ff) -#define GETSOCK_WRITABLE (0xff00) - -#define CURLPIPE_ANY (CURLPIPE_HTTP1 | CURLPIPE_MULTIPLEX) - -/* This is the struct known as CURLM on the outside */ -struct Curl_multi { - /* First a simple identifier to easier detect if a user mix up - this multi handle with an easy handle. Set this to CURL_MULTI_HANDLE. */ - long type; - - /* We have a doubly-linked circular list with easy handles */ - struct SessionHandle *easyp; - struct SessionHandle *easylp; /* last node */ - - int num_easy; /* amount of entries in the linked list above. */ - int num_alive; /* amount of easy handles that are added but have not yet - reached COMPLETE state */ - - struct curl_llist *msglist; /* a list of messages from completed transfers */ - - struct curl_llist *pending; /* SessionHandles that are in the - CURLM_STATE_CONNECT_PEND state */ - - /* callback function and user data pointer for the *socket() API */ - curl_socket_callback socket_cb; - void *socket_userp; - - /* callback function and user data pointer for server push */ - curl_push_callback push_cb; - void *push_userp; - - /* Hostname cache */ - struct curl_hash hostcache; - - /* timetree points to the splay-tree of time nodes to figure out expire - times of all currently set timers */ - struct Curl_tree *timetree; - - /* 'sockhash' is the lookup hash for socket descriptor => easy handles (note - the pluralis form, there can be more than one easy handle waiting on the - same actual socket) */ - struct curl_hash sockhash; - - /* pipelining wanted bits (CURLPIPE*) */ - long pipelining; - - bool recheckstate; /* see Curl_multi_connchanged */ - - /* Shared connection cache (bundles)*/ - struct conncache conn_cache; - - /* This handle will be used for closing the cached connections in - curl_multi_cleanup() */ - struct SessionHandle *closure_handle; - - long maxconnects; /* if >0, a fixed limit of the maximum number of entries - we're allowed to grow the connection cache to */ - - long max_host_connections; /* if >0, a fixed limit of the maximum number - of connections per host */ - - long max_total_connections; /* if >0, a fixed limit of the maximum number - of connections in total */ - - long max_pipeline_length; /* if >0, maximum number of requests in a - pipeline */ - - long content_length_penalty_size; /* a connection with a - content-length bigger than - this is not considered - for pipelining */ - - long chunk_length_penalty_size; /* a connection with a chunk length - bigger than this is not - considered for pipelining */ - - struct curl_llist *pipelining_site_bl; /* List of sites that are blacklisted - from pipelining */ - - struct curl_llist *pipelining_server_bl; /* List of server types that are - blacklisted from pipelining */ - - /* timer callback and user data pointer for the *socket() API */ - curl_multi_timer_callback timer_cb; - void *timer_userp; - struct timeval timer_lastcall; /* the fixed time for the timeout for the - previous callback */ -}; - -#endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/Externals/curl/lib/multiif.h b/Externals/curl/lib/multiif.h deleted file mode 100644 index b229f53eed..0000000000 --- a/Externals/curl/lib/multiif.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef HEADER_CURL_MULTIIF_H -#define HEADER_CURL_MULTIIF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Prototypes for library-wide functions provided by multi.c - */ -void Curl_expire(struct SessionHandle *data, long milli); -void Curl_expire_latest(struct SessionHandle *data, long milli); -bool Curl_pipeline_wanted(const struct Curl_multi* multi, int bits); -void Curl_multi_handlePipeBreak(struct SessionHandle *data); - -/* Internal version of curl_multi_init() accepts size parameters for the - socket and connection hashes */ -struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize); - -/* the write bits start at bit 16 for the *getsock() bitmap */ -#define GETSOCK_WRITEBITSTART 16 - -#define GETSOCK_BLANK 0 /* no bits set */ - -/* set the bit for the given sock number to make the bitmap for writable */ -#define GETSOCK_WRITESOCK(x) (1 << (GETSOCK_WRITEBITSTART + (x))) - -/* set the bit for the given sock number to make the bitmap for readable */ -#define GETSOCK_READSOCK(x) (1 << (x)) - -#ifdef DEBUGBUILD - /* - * Curl_multi_dump is not a stable public function, this is only meant to - * allow easier tracking of the internal handle's state and what sockets - * they use. Only for research and development DEBUGBUILD enabled builds. - */ -void Curl_multi_dump(const struct Curl_multi *multi_handle); -#endif - -void Curl_multi_process_pending_handles(struct Curl_multi *multi); - -/* Return the value of the CURLMOPT_MAX_HOST_CONNECTIONS option */ -size_t Curl_multi_max_host_connections(struct Curl_multi *multi); - -/* Return the value of the CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE option */ -curl_off_t Curl_multi_content_length_penalty_size(struct Curl_multi *multi); - -/* Return the value of the CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE option */ -curl_off_t Curl_multi_chunk_length_penalty_size(struct Curl_multi *multi); - -/* Return the value of the CURLMOPT_PIPELINING_SITE_BL option */ -struct curl_llist *Curl_multi_pipelining_site_bl(struct Curl_multi *multi); - -/* Return the value of the CURLMOPT_PIPELINING_SERVER_BL option */ -struct curl_llist *Curl_multi_pipelining_server_bl(struct Curl_multi *multi); - -/* Return the value of the CURLMOPT_MAX_TOTAL_CONNECTIONS option */ -size_t Curl_multi_max_total_connections(struct Curl_multi *multi); - -void Curl_multi_connchanged(struct Curl_multi *multi); - -/* - * Curl_multi_closed() - * - * Used by the connect code to tell the multi_socket code that one of the - * sockets we were using is about to be closed. This function will then - * remove it from the sockethash for this handle to make the multi_socket API - * behave properly, especially for the case when libcurl will create another - * socket again and it gets the same file descriptor number. - */ - -void Curl_multi_closed(struct connectdata *conn, curl_socket_t s); - -/* - * Add a handle and move it into PERFORM state at once. For pushed streams. - */ -CURLMcode Curl_multi_add_perform(struct Curl_multi *multi, - struct SessionHandle *data, - struct connectdata *conn); -#endif /* HEADER_CURL_MULTIIF_H */ diff --git a/Externals/curl/lib/netrc.c b/Externals/curl/lib/netrc.c deleted file mode 100644 index 46f427a2b3..0000000000 --- a/Externals/curl/lib/netrc.c +++ /dev/null @@ -1,203 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_PWD_H -#include -#endif - -#include -#include "netrc.h" - -#include "strequal.h" -#include "strtok.h" -#include "rawstr.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Get user and password from .netrc when given a machine name */ - -enum host_lookup_state { - NOTHING, - HOSTFOUND, /* the 'machine' keyword was found */ - HOSTVALID /* this is "our" machine! */ -}; - -/* - * @unittest: 1304 - * - * *loginp and *passwordp MUST be allocated if they aren't NULL when passed - * in. - */ -int Curl_parsenetrc(const char *host, - char **loginp, - char **passwordp, - char *netrcfile) -{ - FILE *file; - int retcode=1; - int specific_login = (*loginp && **loginp != 0); - bool netrc_alloc = FALSE; - enum host_lookup_state state=NOTHING; - - char state_login=0; /* Found a login keyword */ - char state_password=0; /* Found a password keyword */ - int state_our_login=FALSE; /* With specific_login, found *our* login name */ - -#define NETRC DOT_CHAR "netrc" - - if(!netrcfile) { - bool home_alloc = FALSE; - char *home = curl_getenv("HOME"); /* portable environment reader */ - if(home) { - home_alloc = TRUE; -#if defined(HAVE_GETPWUID_R) && defined(HAVE_GETEUID) - } - else { - struct passwd pw, *pw_res; - char pwbuf[1024]; - if(!getpwuid_r(geteuid(), &pw, pwbuf, sizeof(pwbuf), &pw_res) - && pw_res) { - home = strdup(pw.pw_dir); - if(!home) - return CURLE_OUT_OF_MEMORY; - home_alloc = TRUE; - } -#elif defined(HAVE_GETPWUID) && defined(HAVE_GETEUID) - } - else { - struct passwd *pw; - pw= getpwuid(geteuid()); - if(pw) { - home = pw->pw_dir; - } -#endif - } - - if(!home) - return retcode; /* no home directory found (or possibly out of memory) */ - - netrcfile = curl_maprintf("%s%s%s", home, DIR_CHAR, NETRC); - if(home_alloc) - free(home); - if(!netrcfile) { - return -1; - } - netrc_alloc = TRUE; - } - - file = fopen(netrcfile, FOPEN_READTEXT); - if(netrc_alloc) - free(netrcfile); - if(file) { - char *tok; - char *tok_buf; - bool done=FALSE; - char netrcbuffer[256]; - int netrcbuffsize = (int)sizeof(netrcbuffer); - - while(!done && fgets(netrcbuffer, netrcbuffsize, file)) { - tok=strtok_r(netrcbuffer, " \t\n", &tok_buf); - while(!done && tok) { - - if((*loginp && **loginp) && (*passwordp && **passwordp)) { - done=TRUE; - break; - } - - switch(state) { - case NOTHING: - if(Curl_raw_equal("machine", tok)) { - /* the next tok is the machine name, this is in itself the - delimiter that starts the stuff entered for this machine, - after this we need to search for 'login' and - 'password'. */ - state=HOSTFOUND; - } - else if(Curl_raw_equal("default", tok)) { - state=HOSTVALID; - retcode=0; /* we did find our host */ - } - break; - case HOSTFOUND: - if(Curl_raw_equal(host, tok)) { - /* and yes, this is our host! */ - state=HOSTVALID; - retcode=0; /* we did find our host */ - } - else - /* not our host */ - state=NOTHING; - break; - case HOSTVALID: - /* we are now parsing sub-keywords concerning "our" host */ - if(state_login) { - if(specific_login) { - state_our_login = Curl_raw_equal(*loginp, tok); - } - else { - free(*loginp); - *loginp = strdup(tok); - if(!*loginp) { - retcode = -1; /* allocation failed */ - goto out; - } - } - state_login=0; - } - else if(state_password) { - if(state_our_login || !specific_login) { - free(*passwordp); - *passwordp = strdup(tok); - if(!*passwordp) { - retcode = -1; /* allocation failed */ - goto out; - } - } - state_password=0; - } - else if(Curl_raw_equal("login", tok)) - state_login=1; - else if(Curl_raw_equal("password", tok)) - state_password=1; - else if(Curl_raw_equal("machine", tok)) { - /* ok, there's machine here go => */ - state = HOSTFOUND; - state_our_login = FALSE; - } - break; - } /* switch (state) */ - - tok = strtok_r(NULL, " \t\n", &tok_buf); - } /* while(tok) */ - } /* while fgets() */ - - out: - fclose(file); - } - - return retcode; -} diff --git a/Externals/curl/lib/netrc.h b/Externals/curl/lib/netrc.h deleted file mode 100644 index d980166e6b..0000000000 --- a/Externals/curl/lib/netrc.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef HEADER_CURL_NETRC_H -#define HEADER_CURL_NETRC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* returns -1 on failure, 0 if the host is found, 1 is the host isn't found */ -int Curl_parsenetrc(const char *host, - char **loginp, - char **passwordp, - char *filename); - /* Assume: (*passwordp)[0]=0, host[0] != 0. - * If (*loginp)[0] = 0, search for login and password within a machine - * section in the netrc. - * If (*loginp)[0] != 0, search for password within machine and login. - */ - -#endif /* HEADER_CURL_NETRC_H */ diff --git a/Externals/curl/lib/non-ascii.c b/Externals/curl/lib/non-ascii.c deleted file mode 100644 index 205ff04ba2..0000000000 --- a/Externals/curl/lib/non-ascii.c +++ /dev/null @@ -1,338 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef CURL_DOES_CONVERSIONS - -#include - -#include "non-ascii.h" -#include "formdata.h" -#include "sendf.h" -#include "urldata.h" - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -#ifdef HAVE_ICONV -#include -/* set default codesets for iconv */ -#ifndef CURL_ICONV_CODESET_OF_NETWORK -#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1" -#endif -#ifndef CURL_ICONV_CODESET_FOR_UTF8 -#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8" -#endif -#define ICONV_ERROR (size_t)-1 -#endif /* HAVE_ICONV */ - -/* - * Curl_convert_clone() returns a malloced copy of the source string (if - * returning CURLE_OK), with the data converted to network format. - */ -CURLcode Curl_convert_clone(struct SessionHandle *data, - const char *indata, - size_t insize, - char **outbuf) -{ - char *convbuf; - CURLcode result; - - convbuf = malloc(insize); - if(!convbuf) - return CURLE_OUT_OF_MEMORY; - - memcpy(convbuf, indata, insize); - result = Curl_convert_to_network(data, convbuf, insize); - if(result) { - free(convbuf); - return result; - } - - *outbuf = convbuf; /* return the converted buffer */ - - return CURLE_OK; -} - -/* - * Curl_convert_to_network() is an internal function for performing ASCII - * conversions on non-ASCII platforms. It convers the buffer _in place_. - */ -CURLcode Curl_convert_to_network(struct SessionHandle *data, - char *buffer, size_t length) -{ - if(data->set.convtonetwork) { - /* use translation callback */ - CURLcode result = data->set.convtonetwork(buffer, length); - if(result) { - failf(data, - "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s", - (int)result, curl_easy_strerror(result)); - } - - return result; - } - else { -#ifdef HAVE_ICONV - /* do the translation ourselves */ - char *input_ptr, *output_ptr; - size_t in_bytes, out_bytes, rc; - int error; - - /* open an iconv conversion descriptor if necessary */ - if(data->outbound_cd == (iconv_t)-1) { - data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, - CURL_ICONV_CODESET_OF_HOST); - if(data->outbound_cd == (iconv_t)-1) { - error = ERRNO; - failf(data, - "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", - CURL_ICONV_CODESET_OF_NETWORK, - CURL_ICONV_CODESET_OF_HOST, - error, strerror(error)); - return CURLE_CONV_FAILED; - } - } - /* call iconv */ - input_ptr = output_ptr = buffer; - in_bytes = out_bytes = length; - rc = iconv(data->outbound_cd, (const char**)&input_ptr, &in_bytes, - &output_ptr, &out_bytes); - if((rc == ICONV_ERROR) || (in_bytes != 0)) { - error = ERRNO; - failf(data, - "The Curl_convert_to_network iconv call failed with errno %i: %s", - error, strerror(error)); - return CURLE_CONV_FAILED; - } -#else - failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required"); - return CURLE_CONV_REQD; -#endif /* HAVE_ICONV */ - } - - return CURLE_OK; -} - -/* - * Curl_convert_from_network() is an internal function for performing ASCII - * conversions on non-ASCII platforms. It convers the buffer _in place_. - */ -CURLcode Curl_convert_from_network(struct SessionHandle *data, - char *buffer, size_t length) -{ - if(data->set.convfromnetwork) { - /* use translation callback */ - CURLcode result = data->set.convfromnetwork(buffer, length); - if(result) { - failf(data, - "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s", - (int)result, curl_easy_strerror(result)); - } - - return result; - } - else { -#ifdef HAVE_ICONV - /* do the translation ourselves */ - char *input_ptr, *output_ptr; - size_t in_bytes, out_bytes, rc; - int error; - - /* open an iconv conversion descriptor if necessary */ - if(data->inbound_cd == (iconv_t)-1) { - data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, - CURL_ICONV_CODESET_OF_NETWORK); - if(data->inbound_cd == (iconv_t)-1) { - error = ERRNO; - failf(data, - "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", - CURL_ICONV_CODESET_OF_HOST, - CURL_ICONV_CODESET_OF_NETWORK, - error, strerror(error)); - return CURLE_CONV_FAILED; - } - } - /* call iconv */ - input_ptr = output_ptr = buffer; - in_bytes = out_bytes = length; - rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes, - &output_ptr, &out_bytes); - if((rc == ICONV_ERROR) || (in_bytes != 0)) { - error = ERRNO; - failf(data, - "Curl_convert_from_network iconv call failed with errno %i: %s", - error, strerror(error)); - return CURLE_CONV_FAILED; - } -#else - failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required"); - return CURLE_CONV_REQD; -#endif /* HAVE_ICONV */ - } - - return CURLE_OK; -} - -/* - * Curl_convert_from_utf8() is an internal function for performing UTF-8 - * conversions on non-ASCII platforms. - */ -CURLcode Curl_convert_from_utf8(struct SessionHandle *data, - char *buffer, size_t length) -{ - if(data->set.convfromutf8) { - /* use translation callback */ - CURLcode result = data->set.convfromutf8(buffer, length); - if(result) { - failf(data, - "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s", - (int)result, curl_easy_strerror(result)); - } - - return result; - } - else { -#ifdef HAVE_ICONV - /* do the translation ourselves */ - const char *input_ptr; - char *output_ptr; - size_t in_bytes, out_bytes, rc; - int error; - - /* open an iconv conversion descriptor if necessary */ - if(data->utf8_cd == (iconv_t)-1) { - data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, - CURL_ICONV_CODESET_FOR_UTF8); - if(data->utf8_cd == (iconv_t)-1) { - error = ERRNO; - failf(data, - "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s", - CURL_ICONV_CODESET_OF_HOST, - CURL_ICONV_CODESET_FOR_UTF8, - error, strerror(error)); - return CURLE_CONV_FAILED; - } - } - /* call iconv */ - input_ptr = output_ptr = buffer; - in_bytes = out_bytes = length; - rc = iconv(data->utf8_cd, &input_ptr, &in_bytes, - &output_ptr, &out_bytes); - if((rc == ICONV_ERROR) || (in_bytes != 0)) { - error = ERRNO; - failf(data, - "The Curl_convert_from_utf8 iconv call failed with errno %i: %s", - error, strerror(error)); - return CURLE_CONV_FAILED; - } - if(output_ptr < input_ptr) { - /* null terminate the now shorter output string */ - *output_ptr = 0x00; - } -#else - failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required"); - return CURLE_CONV_REQD; -#endif /* HAVE_ICONV */ - } - - return CURLE_OK; -} - -/* - * Init conversion stuff for a SessionHandle - */ -void Curl_convert_init(struct SessionHandle *data) -{ -#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) - /* conversion descriptors for iconv calls */ - data->outbound_cd = (iconv_t)-1; - data->inbound_cd = (iconv_t)-1; - data->utf8_cd = (iconv_t)-1; -#else - (void)data; -#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ -} - -/* - * Setup conversion stuff for a SessionHandle - */ -void Curl_convert_setup(struct SessionHandle *data) -{ - data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, - CURL_ICONV_CODESET_OF_NETWORK); - data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, - CURL_ICONV_CODESET_OF_HOST); - data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, - CURL_ICONV_CODESET_FOR_UTF8); -} - -/* - * Close conversion stuff for a SessionHandle - */ - -void Curl_convert_close(struct SessionHandle *data) -{ -#ifdef HAVE_ICONV - /* close iconv conversion descriptors */ - if(data->inbound_cd != (iconv_t)-1) { - iconv_close(data->inbound_cd); - } - if(data->outbound_cd != (iconv_t)-1) { - iconv_close(data->outbound_cd); - } - if(data->utf8_cd != (iconv_t)-1) { - iconv_close(data->utf8_cd); - } -#else - (void)data; -#endif /* HAVE_ICONV */ -} - -/* - * Curl_convert_form() is used from http.c, this converts any form items that - need to be sent in the network encoding. Returns CURLE_OK on success. - */ -CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form) -{ - CURLcode result; - - if(!data) - return CURLE_BAD_FUNCTION_ARGUMENT; - - while(form) { - if(form->type == FORM_DATA) { - result = Curl_convert_to_network(data, form->line, form->length); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) - return result; - } - - form = form->next; - } - - return CURLE_OK; -} - -#endif /* CURL_DOES_CONVERSIONS */ diff --git a/Externals/curl/lib/non-ascii.h b/Externals/curl/lib/non-ascii.h deleted file mode 100644 index f3e2049e4e..0000000000 --- a/Externals/curl/lib/non-ascii.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef HEADER_CURL_NON_ASCII_H -#define HEADER_CURL_NON_ASCII_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef CURL_DOES_CONVERSIONS - -#include "urldata.h" - -/* - * Curl_convert_clone() returns a malloced copy of the source string (if - * returning CURLE_OK), with the data converted to network format. - * - * If no conversion was needed *outbuf may be NULL. - */ -CURLcode Curl_convert_clone(struct SessionHandle *data, - const char *indata, - size_t insize, - char **outbuf); - -void Curl_convert_init(struct SessionHandle *data); -void Curl_convert_setup(struct SessionHandle *data); -void Curl_convert_close(struct SessionHandle *data); - -CURLcode Curl_convert_to_network(struct SessionHandle *data, - char *buffer, size_t length); -CURLcode Curl_convert_from_network(struct SessionHandle *data, - char *buffer, size_t length); -CURLcode Curl_convert_from_utf8(struct SessionHandle *data, - char *buffer, size_t length); -CURLcode Curl_convert_form(struct SessionHandle *data, struct FormData *form); -#else -#define Curl_convert_clone(a,b,c,d) ((void)a, CURLE_OK) -#define Curl_convert_init(x) Curl_nop_stmt -#define Curl_convert_setup(x) Curl_nop_stmt -#define Curl_convert_close(x) Curl_nop_stmt -#define Curl_convert_to_network(a,b,c) ((void)a, CURLE_OK) -#define Curl_convert_from_network(a,b,c) ((void)a, CURLE_OK) -#define Curl_convert_from_utf8(a,b,c) ((void)a, CURLE_OK) -#define Curl_convert_form(a,b) CURLE_OK -#endif - -#endif /* HEADER_CURL_NON_ASCII_H */ diff --git a/Externals/curl/lib/nonblock.c b/Externals/curl/lib/nonblock.c deleted file mode 100644 index b764278a51..0000000000 --- a/Externals/curl/lib/nonblock.c +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -#if (defined(HAVE_IOCTL_FIONBIO) && defined(NETWARE)) -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#include "nonblock.h" - -/* - * curlx_nonblock() set the given socket to either blocking or non-blocking - * mode based on the 'nonblock' boolean argument. This function is highly - * portable. - */ -int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */) -{ -#if defined(USE_BLOCKING_SOCKETS) - - return 0; /* returns success */ - -#elif defined(HAVE_FCNTL_O_NONBLOCK) - - /* most recent unix versions */ - int flags; - flags = sfcntl(sockfd, F_GETFL, 0); - if(nonblock) - return sfcntl(sockfd, F_SETFL, flags | O_NONBLOCK); - else - return sfcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); - -#elif defined(HAVE_IOCTL_FIONBIO) - - /* older unix versions */ - int flags = nonblock ? 1 : 0; - return ioctl(sockfd, FIONBIO, &flags); - -#elif defined(HAVE_IOCTLSOCKET_FIONBIO) - - /* Windows */ - unsigned long flags = nonblock ? 1UL : 0UL; - return ioctlsocket(sockfd, FIONBIO, &flags); - -#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO) - - /* Amiga */ - long flags = nonblock ? 1L : 0L; - return IoctlSocket(sockfd, FIONBIO, (char *)&flags); - -#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK) - - /* BeOS */ - long b = nonblock ? 1L : 0L; - return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); - -#else -# error "no non-blocking method was found/used/set" -#endif -} diff --git a/Externals/curl/lib/nonblock.h b/Externals/curl/lib/nonblock.h deleted file mode 100644 index 98cdc25ab9..0000000000 --- a/Externals/curl/lib/nonblock.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_NONBLOCK_H -#define HEADER_CURL_NONBLOCK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include /* for curl_socket_t */ - -int curlx_nonblock(curl_socket_t sockfd, /* operate on this */ - int nonblock /* TRUE or FALSE */); - -#endif /* HEADER_CURL_NONBLOCK_H */ - diff --git a/Externals/curl/lib/nwlib.c b/Externals/curl/lib/nwlib.c deleted file mode 100644 index 42b6aa0da9..0000000000 --- a/Externals/curl/lib/nwlib.c +++ /dev/null @@ -1,325 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef NETWARE /* Novell NetWare */ - -#ifdef __NOVELL_LIBC__ -/* For native LibC-based NLM we need to register as a real lib. */ -#include -#include -#include -#include -#include - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -typedef struct -{ - int _errno; - void *twentybytes; -} libthreaddata_t; - -typedef struct -{ - int x; - int y; - int z; - void *tenbytes; - NXKey_t perthreadkey; /* if -1, no key obtained... */ - NXMutex_t *lock; -} libdata_t; - -int gLibId = -1; -void *gLibHandle = (void *) NULL; -rtag_t gAllocTag = (rtag_t) NULL; -NXMutex_t *gLibLock = (NXMutex_t *) NULL; - -/* internal library function prototypes... */ -int DisposeLibraryData(void *); -void DisposeThreadData(void *); -int GetOrSetUpData(int id, libdata_t **data, libthreaddata_t **threaddata); - - -int _NonAppStart(void *NLMHandle, - void *errorScreen, - const char *cmdLine, - const char *loadDirPath, - size_t uninitializedDataLength, - void *NLMFileHandle, - int (*readRoutineP)(int conn, - void *fileHandle, size_t offset, - size_t nbytes, - size_t *bytesRead, - void *buffer), - size_t customDataOffset, - size_t customDataSize, - int messageCount, - const char **messages) -{ - NX_LOCK_INFO_ALLOC(liblock, "Per-Application Data Lock", 0); - -#ifndef __GNUC__ -#pragma unused(cmdLine) -#pragma unused(loadDirPath) -#pragma unused(uninitializedDataLength) -#pragma unused(NLMFileHandle) -#pragma unused(readRoutineP) -#pragma unused(customDataOffset) -#pragma unused(customDataSize) -#pragma unused(messageCount) -#pragma unused(messages) -#endif - - /* - * Here we process our command line, post errors (to the error screen), - * perform initializations and anything else we need to do before being able - * to accept calls into us. If we succeed, we return non-zero and the NetWare - * Loader will leave us up, otherwise we fail to load and get dumped. - */ - gAllocTag = AllocateResourceTag(NLMHandle, - " memory allocations", - AllocSignature); - - if(!gAllocTag) { - OutputToScreen(errorScreen, "Unable to allocate resource tag for " - "library memory allocations.\n"); - return -1; - } - - gLibId = register_library(DisposeLibraryData); - - if(gLibId < -1) { - OutputToScreen(errorScreen, "Unable to register library with kernel.\n"); - return -1; - } - - gLibHandle = NLMHandle; - - gLibLock = NXMutexAlloc(0, 0, &liblock); - - if(!gLibLock) { - OutputToScreen(errorScreen, "Unable to allocate library data lock.\n"); - return -1; - } - - return 0; -} - -/* - * Here we clean up any resources we allocated. Resource tags is a big part - * of what we created, but NetWare doesn't ask us to free those. - */ -void _NonAppStop(void) -{ - (void) unregister_library(gLibId); - NXMutexFree(gLibLock); -} - -/* - * This function cannot be the first in the file for if the file is linked - * first, then the check-unload function's offset will be nlmname.nlm+0 - * which is how to tell that there isn't one. When the check function is - * first in the linked objects, it is ambiguous. For this reason, we will - * put it inside this file after the stop function. - * - * Here we check to see if it's alright to ourselves to be unloaded. If not, - * we return a non-zero value. Right now, there isn't any reason not to allow - * it. - */ -int _NonAppCheckUnload(void) -{ - return 0; -} - -int GetOrSetUpData(int id, libdata_t **appData, - libthreaddata_t **threadData) -{ - int err; - libdata_t *app_data; - libthreaddata_t *thread_data; - NXKey_t key; - NX_LOCK_INFO_ALLOC(liblock, "Application Data Lock", 0); - - err = 0; - thread_data = (libthreaddata_t *) NULL; - - /* - * Attempt to get our data for the application calling us. This is where we - * store whatever application-specific information we need to carry in - * support of calling applications. - */ - app_data = (libdata_t *) get_app_data(id); - - if(!app_data) { - /* - * This application hasn't called us before; set up application AND - * per-thread data. Of course, just in case a thread from this same - * application is calling us simultaneously, we better lock our application - * data-creation mutex. We also need to recheck for data after we acquire - * the lock because WE might be that other thread that was too late to - * create the data and the first thread in will have created it. - */ - NXLock(gLibLock); - - if(!(app_data = (libdata_t *) get_app_data(id))) { - app_data = malloc(sizeof(libdata_t)); - - if(app_data) { - memset(app_data, 0, sizeof(libdata_t)); - - app_data->tenbytes = malloc(10); - app_data->lock = NXMutexAlloc(0, 0, &liblock); - - if(!app_data->tenbytes || !app_data->lock) { - if(app_data->lock) - NXMutexFree(app_data->lock); - - free(app_data); - app_data = (libdata_t *) NULL; - err = ENOMEM; - } - - if(app_data) { - /* - * Here we burn in the application data that we were trying to get - * by calling get_app_data(). Next time we call the first function, - * we'll get this data we're just now setting. We also go on here to - * establish the per-thread data for the calling thread, something - * we'll have to do on each application thread the first time - * it calls us. - */ - err = set_app_data(gLibId, app_data); - - if(err) { - free(app_data); - app_data = (libdata_t *) NULL; - err = ENOMEM; - } - else { - /* create key for thread-specific data... */ - err = NXKeyCreate(DisposeThreadData, (void *) NULL, &key); - - if(err) /* (no more keys left?) */ - key = -1; - - app_data->perthreadkey = key; - } - } - } - } - - NXUnlock(gLibLock); - } - - if(app_data) { - key = app_data->perthreadkey; - - if(key != -1 /* couldn't create a key? no thread data */ - && !(err = NXKeyGetValue(key, (void **) &thread_data)) - && !thread_data) { - /* - * Allocate the per-thread data for the calling thread. Regardless of - * whether there was already application data or not, this may be the - * first call by a new thread. The fact that we allocation 20 bytes on - * a pointer is not very important, this just helps to demonstrate that - * we can have arbitrarily complex per-thread data. - */ - thread_data = malloc(sizeof(libthreaddata_t)); - - if(thread_data) { - thread_data->_errno = 0; - thread_data->twentybytes = malloc(20); - - if(!thread_data->twentybytes) { - free(thread_data); - thread_data = (libthreaddata_t *) NULL; - err = ENOMEM; - } - - if((err = NXKeySetValue(key, thread_data))) { - free(thread_data->twentybytes); - free(thread_data); - thread_data = (libthreaddata_t *) NULL; - } - } - } - } - - if(appData) - *appData = app_data; - - if(threadData) - *threadData = thread_data; - - return err; -} - -int DisposeLibraryData(void *data) -{ - if(data) { - void *tenbytes = ((libdata_t *) data)->tenbytes; - - free(tenbytes); - free(data); - } - - return 0; -} - -void DisposeThreadData(void *data) -{ - if(data) { - void *twentybytes = ((libthreaddata_t *) data)->twentybytes; - - free(twentybytes); - free(data); - } -} - -#else /* __NOVELL_LIBC__ */ -/* For native CLib-based NLM seems we can do a bit more simple. */ -#include - -int main (void) -{ - /* initialize any globals here... */ - - /* do this if any global initializing was done - SynchronizeStart(); - */ - ExitThread (TSR_THREAD, 0); - return 0; -} - -#endif /* __NOVELL_LIBC__ */ - -#else /* NETWARE */ - -#ifdef __POCC__ -# pragma warn(disable:2024) /* Disable warning #2024: Empty input file */ -#endif - -#endif /* NETWARE */ diff --git a/Externals/curl/lib/nwos.c b/Externals/curl/lib/nwos.c deleted file mode 100644 index 385f9c8ad5..0000000000 --- a/Externals/curl/lib/nwos.c +++ /dev/null @@ -1,88 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef NETWARE /* Novell NetWare */ - -#ifdef __NOVELL_LIBC__ -/* For native LibC-based NLM we need to do nothing. */ -int netware_init (void) -{ - return 0; -} - -#else /* __NOVELL_LIBC__ */ - -/* For native CLib-based NLM we need to initialize the LONG namespace. */ -#include -#include -#include -/* Make the CLIB Ctx stuff link */ -#include -NETDB_DEFINE_CONTEXT -/* Make the CLIB Inet stuff link */ -#include -#include -NETINET_DEFINE_CONTEXT - -int netware_init (void) -{ - int rc = 0; - unsigned int myHandle = GetNLMHandle(); - /* import UnAugmentAsterisk dynamically for NW4.x compatibility */ - void (*pUnAugmentAsterisk)(int) = (void(*)(int)) - ImportSymbol(myHandle, "UnAugmentAsterisk"); - /* import UseAccurateCaseForPaths dynamically for NW3.x compatibility */ - void (*pUseAccurateCaseForPaths)(int) = (void(*)(int)) - ImportSymbol(myHandle, "UseAccurateCaseForPaths"); - if(pUnAugmentAsterisk) - pUnAugmentAsterisk(1); - if(pUseAccurateCaseForPaths) - pUseAccurateCaseForPaths(1); - UnimportSymbol(myHandle, "UnAugmentAsterisk"); - UnimportSymbol(myHandle, "UseAccurateCaseForPaths"); - /* set long name space */ - if((SetCurrentNameSpace(4) == 255)) { - rc = 1; - } - if((SetTargetNameSpace(4) == 255)) { - rc = rc + 2; - } - return rc; -} - -/* dummy function to satisfy newer prelude */ -int __init_environment (void) -{ - return 0; -} - -/* dummy function to satisfy newer prelude */ -int __deinit_environment (void) -{ - return 0; -} - -#endif /* __NOVELL_LIBC__ */ - -#endif /* NETWARE */ diff --git a/Externals/curl/lib/objnames-test08.sh b/Externals/curl/lib/objnames-test08.sh deleted file mode 100755 index 485975765c..0000000000 --- a/Externals/curl/lib/objnames-test08.sh +++ /dev/null @@ -1,217 +0,0 @@ -#!/bin/sh -# *************************************************************************** -# * _ _ ____ _ -# * Project ___| | | | _ \| | -# * / __| | | | |_) | | -# * | (__| |_| | _ <| |___ -# * \___|\___/|_| \_\_____| -# * -# * Copyright (C) 2013, Daniel Stenberg, , et al. -# * -# * This software is licensed as described in the file COPYING, which -# * you should have received as part of this distribution. The terms -# * are also available at https://curl.haxx.se/docs/copyright.html. -# * -# * You may opt to use, copy, modify, merge, publish, distribute and/or sell -# * copies of the Software, and permit persons to whom the Software is -# * furnished to do so, under the terms of the COPYING file. -# * -# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# * KIND, either express or implied. -# * -# *************************************************************************** - -# -# This Bourne shell script file is used by test case 1222 to do -# unit testing of curl_8char_object_name() shell function which -# is defined in file objnames.inc and sourced by this file and -# any other shell script that may use it. -# - -# -# argument validation -# - -if test $# -eq 1; then - : -else - echo "Usage: ${0} srcdir" - exit 1 -fi - -if test -f "${1}/runtests.pl"; then - : -else - echo "${0}: Wrong srcdir" - exit 1 -fi - -srcdir=${1} - -if test -f "$srcdir/../lib/objnames.inc"; then - : -else - echo "$0: Missing objnames.inc" - exit 1 -fi - -# -# Some variables -# - -logdir=log -tstnum=1222 - -list_c=$logdir/${tstnum}_list_c -list_obj=$logdir/${tstnum}_list_obj -list_obj_c=$logdir/${tstnum}_list_obj_c -list_obj_uniq=$logdir/${tstnum}_list_obj_uniq - - -# -# Source curl_8char_object_name() function definition -# - -. $srcdir/../lib/objnames.inc - -# -# Some curl_8char_object_name() unit tests -# - -echo 'Testing curl_8char_object_name...' -echo "" - -argstr=123__678__ABC__FGH__KLM__PQRSTUV -expect=16AFKPQR -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123__678__ABC__FGH__KLM__PQ.S.UV -expect=16AFKPQ -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123__678__ABC..FGH..KLM..PQRSTUV -expect=16ABC -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123__678_.ABC._FGH__KLM__PQRSTUV -expect=16 -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV -expect=123 -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV -expect=1234567 -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV -expect=12345678 -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV -expect=1470AB -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV -expect=12345678 -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV -expect=159CGHIJ -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV -expect=159CDEFG -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV -expect=1590ABCD -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV -expect=1567890A -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV -expect=12345678 -outstr=`curl_8char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -# -# Verify that generated object name is distinct for -# all *.c source files in lib and src subdirectories. -# - -ls $srcdir/../lib/*.c > $list_c -ls $srcdir/../src/*.c >> $list_c - -rm -f $list_obj - -for c_fname in `cat $list_c`; do - obj_name=`curl_8char_object_name $c_fname` - echo "$obj_name" >> $list_obj -done - -sort -u $list_obj > $list_obj_uniq - -cnt_c=`cat $list_c | wc -l` -cnt_u=`cat $list_obj_uniq | wc -l` - -echo "" -echo "" -echo "" -if test $cnt_c -eq $cnt_u; then - echo "8-characters-or-less generated object names are unique." - obj_name_clash="no" -else - echo "8-characters-or-less generated object names are clashing..." - obj_name_clash="yes" -fi - -if test $obj_name_clash = "yes"; then - # - # Show clashing object names and respective source file names - # - echo "" - paste $list_obj $list_c | sort > $list_obj_c - prev_match="no" - prev_line="unknown" - prev_obj_name="unknown" - while read this_line; do - obj_name=`echo "$this_line" | cut -f1` - if test "x$obj_name" = "x$prev_obj_name"; then - if test "x$prev_match" != "xyes"; then - echo "$prev_line" - echo "$this_line" - prev_match="yes" - else - echo "$this_line" - fi - else - prev_match="no" - fi - prev_line=$this_line - prev_obj_name=$obj_name - done < $list_obj_c -fi - -rm -f $list_c -rm -f $list_obj -rm -f $list_obj_c -rm -f $list_obj_uniq - -# end of objnames-test.sh diff --git a/Externals/curl/lib/objnames-test10.sh b/Externals/curl/lib/objnames-test10.sh deleted file mode 100755 index 62184b8640..0000000000 --- a/Externals/curl/lib/objnames-test10.sh +++ /dev/null @@ -1,217 +0,0 @@ -#!/bin/sh -# *************************************************************************** -# * _ _ ____ _ -# * Project ___| | | | _ \| | -# * / __| | | | |_) | | -# * | (__| |_| | _ <| |___ -# * \___|\___/|_| \_\_____| -# * -# * Copyright (C) 2013, Daniel Stenberg, , et al. -# * -# * This software is licensed as described in the file COPYING, which -# * you should have received as part of this distribution. The terms -# * are also available at https://curl.haxx.se/docs/copyright.html. -# * -# * You may opt to use, copy, modify, merge, publish, distribute and/or sell -# * copies of the Software, and permit persons to whom the Software is -# * furnished to do so, under the terms of the COPYING file. -# * -# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# * KIND, either express or implied. -# * -# *************************************************************************** - -# -# This Bourne shell script file is used by test case 1221 to do -# unit testing of curl_10char_object_name() shell function which -# is defined in file objnames.inc and sourced by this file and -# any other shell script that may use it. -# - -# -# argument validation -# - -if test $# -eq 1; then - : -else - echo "Usage: ${0} srcdir" - exit 1 -fi - -if test -f "${1}/runtests.pl"; then - : -else - echo "${0}: Wrong srcdir" - exit 1 -fi - -srcdir=${1} - -if test -f "$srcdir/../lib/objnames.inc"; then - : -else - echo "$0: Missing objnames.inc" - exit 1 -fi - -# -# Some variables -# - -logdir=log -tstnum=1221 - -list_c=$logdir/${tstnum}_list_c -list_obj=$logdir/${tstnum}_list_obj -list_obj_c=$logdir/${tstnum}_list_obj_c -list_obj_uniq=$logdir/${tstnum}_list_obj_uniq - - -# -# Source curl_10char_object_name() function definition -# - -. $srcdir/../lib/objnames.inc - -# -# Some curl_10char_object_name() unit tests -# - -echo 'Testing curl_10char_object_name...' -echo "" - -argstr=123__678__ABC__FGH__KLM__PQRSTUV -expect=16AFKPQRST -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123__678__ABC__FGH__KLM__PQ.S.UV -expect=16AFKPQ -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123__678__ABC..FGH..KLM..PQRSTUV -expect=16ABC -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123__678_.ABC._FGH__KLM__PQRSTUV -expect=16 -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123.567.90ABCDEFGHIJKLMNOPQRSTUV -expect=123 -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567.90A.CDEFGHIJKLMNOPQRSTUV -expect=1234567 -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567890.BCD.FGHIJKLMNOPQRSTUV -expect=1234567890 -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=12=45-78+0AB.DE.GHIJKLMNOPQRSTUV -expect=1470AB -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV -expect=1234567890 -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567_90A_CDE_GHIJKLMNOPQRSTUV -expect=159CGHIJKL -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567_90A_CDEFGHIJKLMNOPQRSTUV -expect=159CDEFGHI -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567_90ABCDEFGHIJKLMNOPQRSTUV -expect=1590ABCDEF -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=123_567890ABCDEFGHIJKLMNOPQRSTUV -expect=1567890ABC -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -argstr=1234567890ABCDEFGHIJKLMNOPQRSTUV -expect=1234567890 -outstr=`curl_10char_object_name $argstr` -echo "result: $outstr expected: $expect input: $argstr" - -# -# Verify that generated object name is distinct for -# all *.c source files in lib and src subdirectories. -# - -ls $srcdir/../lib/*.c > $list_c -ls $srcdir/../src/*.c >> $list_c - -rm -f $list_obj - -for c_fname in `cat $list_c`; do - obj_name=`curl_10char_object_name $c_fname` - echo "$obj_name" >> $list_obj -done - -sort -u $list_obj > $list_obj_uniq - -cnt_c=`cat $list_c | wc -l` -cnt_u=`cat $list_obj_uniq | wc -l` - -echo "" -echo "" -echo "" -if test $cnt_c -eq $cnt_u; then - echo "10-characters-or-less generated object names are unique." - obj_name_clash="no" -else - echo "10-characters-or-less generated object names are clashing..." - obj_name_clash="yes" -fi - -if test $obj_name_clash = "yes"; then - # - # Show clashing object names and respective source file names - # - echo "" - paste $list_obj $list_c | sort > $list_obj_c - prev_match="no" - prev_line="unknown" - prev_obj_name="unknown" - while read this_line; do - obj_name=`echo "$this_line" | cut -f1` - if test "x$obj_name" = "x$prev_obj_name"; then - if test "x$prev_match" != "xyes"; then - echo "$prev_line" - echo "$this_line" - prev_match="yes" - else - echo "$this_line" - fi - else - prev_match="no" - fi - prev_line=$this_line - prev_obj_name=$obj_name - done < $list_obj_c -fi - -rm -f $list_c -rm -f $list_obj -rm -f $list_obj_c -rm -f $list_obj_uniq - -# end of objnames-test10.sh diff --git a/Externals/curl/lib/objnames.inc b/Externals/curl/lib/objnames.inc deleted file mode 100644 index b895528afd..0000000000 --- a/Externals/curl/lib/objnames.inc +++ /dev/null @@ -1,107 +0,0 @@ -# *************************************************************************** -# * _ _ ____ _ -# * Project ___| | | | _ \| | -# * / __| | | | |_) | | -# * | (__| |_| | _ <| |___ -# * \___|\___/|_| \_\_____| -# * -# * Copyright (C) 2012, Daniel Stenberg, , et al. -# * -# * This software is licensed as described in the file COPYING, which -# * you should have received as part of this distribution. The terms -# * are also available at https://curl.haxx.se/docs/copyright.html. -# * -# * You may opt to use, copy, modify, merge, publish, distribute and/or sell -# * copies of the Software, and permit persons to whom the Software is -# * furnished to do so, under the terms of the COPYING file. -# * -# * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY -# * KIND, either express or implied. -# * -# *************************************************************************** - -# -# This file is sourced from curl/packages/OS400/initscript.sh and -# other Bourne shell scripts. Keep it as portable as possible. -# - -# -# curl_10char_object_name -# -# This shell function accepts a single string argument with unspecified -# length representing a (*.c) source file name and returns a string which -# is a transformation of given argument. -# -# The intended purpose of this function is to transliterate a (*.c) source -# file name that may be longer than 10 characters, or not, into a string -# with at most 10 characters which may be used as an OS/400 object name. -# -# This function might not be universally usefull, nor we care about it. -# -# It is intended to be used with libcurl's (*.c) source file names, so -# dependency on libcurl's source file naming scheme is acceptable and -# good enough for its intended use. Specifically it makes use of the fact -# that libcurl's (*.c) source file names which may be longer than 10 chars -# are conformed with underscore '_' separated substrings, or separated by -# other character which does not belong to the [0-9], [a-z] or [A-Z] sets. -# -# This allows repeatable and automatic short object name generation with -# no need for a hardcoded mapping table. -# -# Transformation is done in the following way: -# -# 1) Leading directory components are removed. -# 2) Leftmost dot character and any other char following it are removed. -# 3) Lowercase characters are transliterated to uppercase. -# 4) Characters not in [A-Z] or [0-9] are transliterated to underscore '_'. -# 5) Every sequence of one or more underscores is replaced with a single one. -# 6) Five leftmost substrings which end in an underscore character are -# replaced by the first character of each substring, while retaining -# the rest of the string. -# 7) Finally the result is truncated to 10 characters. -# -# Resulting object name may be shorter than 10 characters. -# -# Test case 1221 does unit testng of this function and also verifies -# that it is possible to generate distinct short object names for all -# curl and libcurl *.c source file names. -# - -curl_10char_object_name() { - echo "${1}" | \ - sed -e 's:.*/::' \ - -e 's:[.].*::' \ - -e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \ - -e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \ - -e 's:__*:_:g' \ - -e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \ - -e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \ - -e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \ - -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \ - -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \ - -e 's:^\(..........\).*:\1:' -} - -# -# curl_8char_object_name -# -# Same as curl_10char_object_name() description and details above, except -# that object name is limited to 8 charcters maximum. -# - -curl_8char_object_name() { - echo "${1}" | \ - sed -e 's:.*/::' \ - -e 's:[.].*::' \ - -e 'y:abcdefghijklmnopqrstuvwxyz:ABCDEFGHIJKLMNOPQRSTUVWXYZ:' \ - -e 's:[^ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_]:_:g' \ - -e 's:__*:_:g' \ - -e 's:\([^_]\)[^_]*_\(.*\):\1\2:' \ - -e 's:\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3:' \ - -e 's:\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4:' \ - -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5:' \ - -e 's:\([^_]\)\([^_]\)\([^_]\)\([^_]\)\([^_]\)[^_]*_\(.*\):\1\2\3\4\5\6:' \ - -e 's:^\(........\).*:\1:' -} - -# end of objectname.inc diff --git a/Externals/curl/lib/openldap.c b/Externals/curl/lib/openldap.c deleted file mode 100644 index 01567acd1d..0000000000 --- a/Externals/curl/lib/openldap.c +++ /dev/null @@ -1,711 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010, Howard Chu, - * Copyright (C) 2011 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_LDAP) && defined(USE_OPENLDAP) - -/* - * Notice that USE_OPENLDAP is only a source code selection switch. When - * libcurl is built with USE_OPENLDAP defined the libcurl source code that - * gets compiled is the code from openldap.c, otherwise the code that gets - * compiled is the code from ldap.c. - * - * When USE_OPENLDAP is defined a recent version of the OpenLDAP library - * might be required for compilation and runtime. In order to use ancient - * OpenLDAP library versions, USE_OPENLDAP shall not be defined. - */ - -#include - -#include "urldata.h" -#include -#include "sendf.h" -#include "vtls/vtls.h" -#include "transfer.h" -#include "curl_ldap.h" -#include "curl_base64.h" -#include "connect.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifndef _LDAP_PVT_H -extern int ldap_pvt_url_scheme2proto(const char *); -extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, - LDAP **ld); -#endif - -static CURLcode ldap_setup_connection(struct connectdata *conn); -static CURLcode ldap_do(struct connectdata *conn, bool *done); -static CURLcode ldap_done(struct connectdata *conn, CURLcode, bool); -static CURLcode ldap_connect(struct connectdata *conn, bool *done); -static CURLcode ldap_connecting(struct connectdata *conn, bool *done); -static CURLcode ldap_disconnect(struct connectdata *conn, bool dead); - -static Curl_recv ldap_recv; - -/* - * LDAP protocol handler. - */ - -const struct Curl_handler Curl_handler_ldap = { - "LDAP", /* scheme */ - ldap_setup_connection, /* setup_connection */ - ldap_do, /* do_it */ - ldap_done, /* done */ - ZERO_NULL, /* do_more */ - ldap_connect, /* connect_it */ - ldap_connecting, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ldap_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_LDAP, /* defport */ - CURLPROTO_LDAP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -#ifdef USE_SSL -/* - * LDAPS protocol handler. - */ - -const struct Curl_handler Curl_handler_ldaps = { - "LDAPS", /* scheme */ - ldap_setup_connection, /* setup_connection */ - ldap_do, /* do_it */ - ldap_done, /* done */ - ZERO_NULL, /* do_more */ - ldap_connect, /* connect_it */ - ldap_connecting, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ldap_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_LDAPS, /* defport */ - CURLPROTO_LDAP, /* protocol */ - PROTOPT_SSL /* flags */ -}; -#endif - -static const char *url_errs[] = { - "success", - "out of memory", - "bad parameter", - "unrecognized scheme", - "unbalanced delimiter", - "bad URL", - "bad host or port", - "bad or missing attributes", - "bad or missing scope", - "bad or missing filter", - "bad or missing extensions" -}; - -typedef struct ldapconninfo { - LDAP *ld; - Curl_recv *recv; /* for stacking SSL handler */ - Curl_send *send; - int proto; - int msgid; - bool ssldone; - bool sslinst; - bool didbind; -} ldapconninfo; - -typedef struct ldapreqinfo { - int msgid; - int nument; -} ldapreqinfo; - -static CURLcode ldap_setup_connection(struct connectdata *conn) -{ - ldapconninfo *li; - LDAPURLDesc *lud; - struct SessionHandle *data=conn->data; - int rc, proto; - CURLcode status; - - rc = ldap_url_parse(data->change.url, &lud); - if(rc != LDAP_URL_SUCCESS) { - const char *msg = "url parsing problem"; - status = CURLE_URL_MALFORMAT; - if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) { - if(rc == LDAP_URL_ERR_MEM) - status = CURLE_OUT_OF_MEMORY; - msg = url_errs[rc]; - } - failf(conn->data, "LDAP local: %s", msg); - return status; - } - proto = ldap_pvt_url_scheme2proto(lud->lud_scheme); - ldap_free_urldesc(lud); - - li = calloc(1, sizeof(ldapconninfo)); - if(!li) - return CURLE_OUT_OF_MEMORY; - li->proto = proto; - conn->proto.generic = li; - connkeep(conn, "OpenLDAP default"); - /* TODO: - * - provide option to choose SASL Binds instead of Simple - */ - return CURLE_OK; -} - -#ifdef USE_SSL -static Sockbuf_IO ldapsb_tls; -#endif - -static CURLcode ldap_connect(struct connectdata *conn, bool *done) -{ - ldapconninfo *li = conn->proto.generic; - struct SessionHandle *data = conn->data; - int rc, proto = LDAP_VERSION3; - char hosturl[1024]; - char *ptr; - - (void)done; - - strcpy(hosturl, "ldap"); - ptr = hosturl+4; - if(conn->handler->flags & PROTOPT_SSL) - *ptr++ = 's'; - snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d", - conn->host.name, conn->remote_port); - - rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld); - if(rc) { - failf(data, "LDAP local: Cannot connect to %s, %s", - hosturl, ldap_err2string(rc)); - return CURLE_COULDNT_CONNECT; - } - - ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); - -#ifdef USE_SSL - if(conn->handler->flags & PROTOPT_SSL) { - CURLcode result; - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &li->ssldone); - if(result) - return result; - } -#endif - - return CURLE_OK; -} - -static CURLcode ldap_connecting(struct connectdata *conn, bool *done) -{ - ldapconninfo *li = conn->proto.generic; - struct SessionHandle *data = conn->data; - LDAPMessage *msg = NULL; - struct timeval tv = {0, 1}, *tvp; - int rc, err; - char *info = NULL; - -#ifdef USE_SSL - if(conn->handler->flags & PROTOPT_SSL) { - /* Is the SSL handshake complete yet? */ - if(!li->ssldone) { - CURLcode result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, - &li->ssldone); - if(result || !li->ssldone) - return result; - } - - /* Have we installed the libcurl SSL handlers into the sockbuf yet? */ - if(!li->sslinst) { - Sockbuf *sb; - ldap_get_option(li->ld, LDAP_OPT_SOCKBUF, &sb); - ber_sockbuf_add_io(sb, &ldapsb_tls, LBER_SBIOD_LEVEL_TRANSPORT, conn); - li->sslinst = TRUE; - li->recv = conn->recv[FIRSTSOCKET]; - li->send = conn->send[FIRSTSOCKET]; - } - } -#endif - - tvp = &tv; - -retry: - if(!li->didbind) { - char *binddn; - struct berval passwd; - - if(conn->bits.user_passwd) { - binddn = conn->user; - passwd.bv_val = conn->passwd; - passwd.bv_len = strlen(passwd.bv_val); - } - else { - binddn = NULL; - passwd.bv_val = NULL; - passwd.bv_len = 0; - } - rc = ldap_sasl_bind(li->ld, binddn, LDAP_SASL_SIMPLE, &passwd, - NULL, NULL, &li->msgid); - if(rc) - return CURLE_LDAP_CANNOT_BIND; - li->didbind = TRUE; - if(tvp) - return CURLE_OK; - } - - rc = ldap_result(li->ld, li->msgid, LDAP_MSG_ONE, tvp, &msg); - if(rc < 0) { - failf(data, "LDAP local: bind ldap_result %s", ldap_err2string(rc)); - return CURLE_LDAP_CANNOT_BIND; - } - if(rc == 0) { - /* timed out */ - return CURLE_OK; - } - - rc = ldap_parse_result(li->ld, msg, &err, NULL, &info, NULL, NULL, 1); - if(rc) { - failf(data, "LDAP local: bind ldap_parse_result %s", ldap_err2string(rc)); - return CURLE_LDAP_CANNOT_BIND; - } - - /* Try to fallback to LDAPv2? */ - if(err == LDAP_PROTOCOL_ERROR) { - int proto; - ldap_get_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); - if(proto == LDAP_VERSION3) { - if(info) { - ldap_memfree(info); - info = NULL; - } - proto = LDAP_VERSION2; - ldap_set_option(li->ld, LDAP_OPT_PROTOCOL_VERSION, &proto); - li->didbind = FALSE; - goto retry; - } - } - - if(err) { - failf(data, "LDAP remote: bind failed %s %s", ldap_err2string(rc), - info ? info : ""); - if(info) - ldap_memfree(info); - return CURLE_LOGIN_DENIED; - } - - if(info) - ldap_memfree(info); - conn->recv[FIRSTSOCKET] = ldap_recv; - *done = TRUE; - - return CURLE_OK; -} - -static CURLcode ldap_disconnect(struct connectdata *conn, bool dead_connection) -{ - ldapconninfo *li = conn->proto.generic; - (void) dead_connection; - - if(li) { - if(li->ld) { - ldap_unbind_ext(li->ld, NULL, NULL); - li->ld = NULL; - } - conn->proto.generic = NULL; - free(li); - } - return CURLE_OK; -} - -static CURLcode ldap_do(struct connectdata *conn, bool *done) -{ - ldapconninfo *li = conn->proto.generic; - ldapreqinfo *lr; - CURLcode status = CURLE_OK; - int rc = 0; - LDAPURLDesc *ludp = NULL; - int msgid; - struct SessionHandle *data=conn->data; - - connkeep(conn, "OpenLDAP do"); - - infof(data, "LDAP local: %s\n", data->change.url); - - rc = ldap_url_parse(data->change.url, &ludp); - if(rc != LDAP_URL_SUCCESS) { - const char *msg = "url parsing problem"; - status = CURLE_URL_MALFORMAT; - if(rc > LDAP_URL_SUCCESS && rc <= LDAP_URL_ERR_BADEXTS) { - if(rc == LDAP_URL_ERR_MEM) - status = CURLE_OUT_OF_MEMORY; - msg = url_errs[rc]; - } - failf(conn->data, "LDAP local: %s", msg); - return status; - } - - rc = ldap_search_ext(li->ld, ludp->lud_dn, ludp->lud_scope, - ludp->lud_filter, ludp->lud_attrs, 0, - NULL, NULL, NULL, 0, &msgid); - ldap_free_urldesc(ludp); - if(rc != LDAP_SUCCESS) { - failf(data, "LDAP local: ldap_search_ext %s", ldap_err2string(rc)); - return CURLE_LDAP_SEARCH_FAILED; - } - lr = calloc(1, sizeof(ldapreqinfo)); - if(!lr) - return CURLE_OUT_OF_MEMORY; - lr->msgid = msgid; - data->req.protop = lr; - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); - *done = TRUE; - return CURLE_OK; -} - -static CURLcode ldap_done(struct connectdata *conn, CURLcode res, - bool premature) -{ - ldapreqinfo *lr = conn->data->req.protop; - - (void)res; - (void)premature; - - if(lr) { - /* if there was a search in progress, abandon it */ - if(lr->msgid) { - ldapconninfo *li = conn->proto.generic; - ldap_abandon_ext(li->ld, lr->msgid, NULL, NULL); - lr->msgid = 0; - } - conn->data->req.protop = NULL; - free(lr); - } - - return CURLE_OK; -} - -static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf, - size_t len, CURLcode *err) -{ - ldapconninfo *li = conn->proto.generic; - struct SessionHandle *data = conn->data; - ldapreqinfo *lr = data->req.protop; - int rc, ret; - LDAPMessage *msg = NULL; - LDAPMessage *ent; - BerElement *ber = NULL; - struct timeval tv = {0, 1}; - - (void)len; - (void)buf; - (void)sockindex; - - rc = ldap_result(li->ld, lr->msgid, LDAP_MSG_RECEIVED, &tv, &msg); - if(rc < 0) { - failf(data, "LDAP local: search ldap_result %s", ldap_err2string(rc)); - *err = CURLE_RECV_ERROR; - return -1; - } - - *err = CURLE_AGAIN; - ret = -1; - - /* timed out */ - if(!msg) - return ret; - - for(ent = ldap_first_message(li->ld, msg); ent; - ent = ldap_next_message(li->ld, ent)) { - struct berval bv, *bvals, **bvp = &bvals; - int binary = 0, msgtype; - CURLcode writeerr; - - msgtype = ldap_msgtype(ent); - if(msgtype == LDAP_RES_SEARCH_RESULT) { - int code; - char *info = NULL; - rc = ldap_parse_result(li->ld, ent, &code, NULL, &info, NULL, NULL, 0); - if(rc) { - failf(data, "LDAP local: search ldap_parse_result %s", - ldap_err2string(rc)); - *err = CURLE_LDAP_SEARCH_FAILED; - } - else if(code && code != LDAP_SIZELIMIT_EXCEEDED) { - failf(data, "LDAP remote: search failed %s %s", ldap_err2string(rc), - info ? info : ""); - *err = CURLE_LDAP_SEARCH_FAILED; - } - else { - /* successful */ - if(code == LDAP_SIZELIMIT_EXCEEDED) - infof(data, "There are more than %d entries\n", lr->nument); - data->req.size = data->req.bytecount; - *err = CURLE_OK; - ret = 0; - } - lr->msgid = 0; - ldap_memfree(info); - break; - } - else if(msgtype != LDAP_RES_SEARCH_ENTRY) - continue; - - lr->nument++; - rc = ldap_get_dn_ber(li->ld, ent, &ber, &bv); - if(rc < 0) { - /* TODO: verify that this is really how this return code should be - handled */ - *err = CURLE_RECV_ERROR; - return -1; - } - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4); - if(writeerr) { - *err = writeerr; - return -1; - } - - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, - bv.bv_len); - if(writeerr) { - *err = writeerr; - return -1; - } - - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1); - if(writeerr) { - *err = writeerr; - return -1; - } - data->req.bytecount += bv.bv_len + 5; - - for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp); - rc == LDAP_SUCCESS; - rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) { - int i; - - if(bv.bv_val == NULL) break; - - if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7)) - binary = 1; - else - binary = 0; - - for(i=0; bvals[i].bv_val != NULL; i++) { - int binval = 0; - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1); - if(writeerr) { - *err = writeerr; - return -1; - } - - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val, - bv.bv_len); - if(writeerr) { - *err = writeerr; - return -1; - } - - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1); - if(writeerr) { - *err = writeerr; - return -1; - } - data->req.bytecount += bv.bv_len + 2; - - if(!binary) { - /* check for leading or trailing whitespace */ - if(ISSPACE(bvals[i].bv_val[0]) || - ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1])) - binval = 1; - else { - /* check for unprintable characters */ - unsigned int j; - for(j=0; jreq.bytecount += 2; - if(val_b64_sz > 0) { - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64, - val_b64_sz); - if(writeerr) { - *err = writeerr; - return -1; - } - free(val_b64); - data->req.bytecount += val_b64_sz; - } - } - else { - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1); - if(writeerr) { - *err = writeerr; - return -1; - } - - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val, - bvals[i].bv_len); - if(writeerr) { - *err = writeerr; - return -1; - } - - data->req.bytecount += bvals[i].bv_len + 1; - } - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); - if(writeerr) { - *err = writeerr; - return -1; - } - - data->req.bytecount++; - } - ber_memfree(bvals); - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); - if(writeerr) { - *err = writeerr; - return -1; - } - data->req.bytecount++; - } - writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0); - if(writeerr) { - *err = writeerr; - return -1; - } - data->req.bytecount++; - ber_free(ber, 0); - } - ldap_msgfree(msg); - return ret; -} - -#ifdef USE_SSL -static int -ldapsb_tls_setup(Sockbuf_IO_Desc *sbiod, void *arg) -{ - sbiod->sbiod_pvt = arg; - return 0; -} - -static int -ldapsb_tls_remove(Sockbuf_IO_Desc *sbiod) -{ - sbiod->sbiod_pvt = NULL; - return 0; -} - -/* We don't need to do anything because libcurl does it already */ -static int -ldapsb_tls_close(Sockbuf_IO_Desc *sbiod) -{ - (void)sbiod; - return 0; -} - -static int -ldapsb_tls_ctrl(Sockbuf_IO_Desc *sbiod, int opt, void *arg) -{ - (void)arg; - if(opt == LBER_SB_OPT_DATA_READY) { - struct connectdata *conn = sbiod->sbiod_pvt; - return Curl_ssl_data_pending(conn, FIRSTSOCKET); - } - return 0; -} - -static ber_slen_t -ldapsb_tls_read(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) -{ - struct connectdata *conn = sbiod->sbiod_pvt; - ldapconninfo *li = conn->proto.generic; - ber_slen_t ret; - CURLcode err = CURLE_RECV_ERROR; - - ret = li->recv(conn, FIRSTSOCKET, buf, len, &err); - if(ret < 0 && err == CURLE_AGAIN) { - SET_SOCKERRNO(EWOULDBLOCK); - } - return ret; -} - -static ber_slen_t -ldapsb_tls_write(Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) -{ - struct connectdata *conn = sbiod->sbiod_pvt; - ldapconninfo *li = conn->proto.generic; - ber_slen_t ret; - CURLcode err = CURLE_SEND_ERROR; - - ret = li->send(conn, FIRSTSOCKET, buf, len, &err); - if(ret < 0 && err == CURLE_AGAIN) { - SET_SOCKERRNO(EWOULDBLOCK); - } - return ret; -} - -static Sockbuf_IO ldapsb_tls = -{ - ldapsb_tls_setup, - ldapsb_tls_remove, - ldapsb_tls_ctrl, - ldapsb_tls_read, - ldapsb_tls_write, - ldapsb_tls_close -}; -#endif /* USE_SSL */ - -#endif /* !CURL_DISABLE_LDAP && USE_OPENLDAP */ diff --git a/Externals/curl/lib/parsedate.c b/Externals/curl/lib/parsedate.c deleted file mode 100644 index dfcf855c80..0000000000 --- a/Externals/curl/lib/parsedate.c +++ /dev/null @@ -1,583 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* - A brief summary of the date string formats this parser groks: - - RFC 2616 3.3.1 - - Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 - Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 - Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format - - we support dates without week day name: - - 06 Nov 1994 08:49:37 GMT - 06-Nov-94 08:49:37 GMT - Nov 6 08:49:37 1994 - - without the time zone: - - 06 Nov 1994 08:49:37 - 06-Nov-94 08:49:37 - - weird order: - - 1994 Nov 6 08:49:37 (GNU date fails) - GMT 08:49:37 06-Nov-94 Sunday - 94 6 Nov 08:49:37 (GNU date fails) - - time left out: - - 1994 Nov 6 - 06-Nov-94 - Sun Nov 6 94 - - unusual separators: - - 1994.Nov.6 - Sun/Nov/6/94/GMT - - commonly used time zone names: - - Sun, 06 Nov 1994 08:49:37 CET - 06 Nov 1994 08:49:37 EST - - time zones specified using RFC822 style: - - Sun, 12 Sep 2004 15:05:58 -0700 - Sat, 11 Sep 2004 21:32:11 +0200 - - compact numerical date strings: - - 20040912 15:05:58 -0700 - 20040911 +0200 - -*/ - -#include "curl_setup.h" - -#ifdef HAVE_LIMITS_H -#include -#endif - -#include -#include "rawstr.h" -#include "warnless.h" -#include "parsedate.h" - -const char * const Curl_wkday[] = -{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; -static const char * const weekday[] = -{ "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday", "Sunday" }; -const char * const Curl_month[]= -{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -struct tzinfo { - char name[5]; - int offset; /* +/- in minutes */ -}; - -/* - * parsedate() - * - * Returns: - * - * PARSEDATE_OK - a fine conversion - * PARSEDATE_FAIL - failed to convert - * PARSEDATE_LATER - time overflow at the far end of time_t - * PARSEDATE_SOONER - time underflow at the low end of time_t - */ - -static int parsedate(const char *date, time_t *output); - -#define PARSEDATE_OK 0 -#define PARSEDATE_FAIL -1 -#define PARSEDATE_LATER 1 -#define PARSEDATE_SOONER 2 - -/* Here's a bunch of frequently used time zone names. These were supported - by the old getdate parser. */ -#define tDAYZONE -60 /* offset for daylight savings time */ -static const struct tzinfo tz[]= { - {"GMT", 0}, /* Greenwich Mean */ - {"UTC", 0}, /* Universal (Coordinated) */ - {"WET", 0}, /* Western European */ - {"BST", 0 tDAYZONE}, /* British Summer */ - {"WAT", 60}, /* West Africa */ - {"AST", 240}, /* Atlantic Standard */ - {"ADT", 240 tDAYZONE}, /* Atlantic Daylight */ - {"EST", 300}, /* Eastern Standard */ - {"EDT", 300 tDAYZONE}, /* Eastern Daylight */ - {"CST", 360}, /* Central Standard */ - {"CDT", 360 tDAYZONE}, /* Central Daylight */ - {"MST", 420}, /* Mountain Standard */ - {"MDT", 420 tDAYZONE}, /* Mountain Daylight */ - {"PST", 480}, /* Pacific Standard */ - {"PDT", 480 tDAYZONE}, /* Pacific Daylight */ - {"YST", 540}, /* Yukon Standard */ - {"YDT", 540 tDAYZONE}, /* Yukon Daylight */ - {"HST", 600}, /* Hawaii Standard */ - {"HDT", 600 tDAYZONE}, /* Hawaii Daylight */ - {"CAT", 600}, /* Central Alaska */ - {"AHST", 600}, /* Alaska-Hawaii Standard */ - {"NT", 660}, /* Nome */ - {"IDLW", 720}, /* International Date Line West */ - {"CET", -60}, /* Central European */ - {"MET", -60}, /* Middle European */ - {"MEWT", -60}, /* Middle European Winter */ - {"MEST", -60 tDAYZONE}, /* Middle European Summer */ - {"CEST", -60 tDAYZONE}, /* Central European Summer */ - {"MESZ", -60 tDAYZONE}, /* Middle European Summer */ - {"FWT", -60}, /* French Winter */ - {"FST", -60 tDAYZONE}, /* French Summer */ - {"EET", -120}, /* Eastern Europe, USSR Zone 1 */ - {"WAST", -420}, /* West Australian Standard */ - {"WADT", -420 tDAYZONE}, /* West Australian Daylight */ - {"CCT", -480}, /* China Coast, USSR Zone 7 */ - {"JST", -540}, /* Japan Standard, USSR Zone 8 */ - {"EAST", -600}, /* Eastern Australian Standard */ - {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */ - {"GST", -600}, /* Guam Standard, USSR Zone 9 */ - {"NZT", -720}, /* New Zealand */ - {"NZST", -720}, /* New Zealand Standard */ - {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */ - {"IDLE", -720}, /* International Date Line East */ - /* Next up: Military timezone names. RFC822 allowed these, but (as noted in - RFC 1123) had their signs wrong. Here we use the correct signs to match - actual military usage. - */ - {"A", +1 * 60}, /* Alpha */ - {"B", +2 * 60}, /* Bravo */ - {"C", +3 * 60}, /* Charlie */ - {"D", +4 * 60}, /* Delta */ - {"E", +5 * 60}, /* Echo */ - {"F", +6 * 60}, /* Foxtrot */ - {"G", +7 * 60}, /* Golf */ - {"H", +8 * 60}, /* Hotel */ - {"I", +9 * 60}, /* India */ - /* "J", Juliet is not used as a timezone, to indicate the observer's local - time */ - {"K", +10 * 60}, /* Kilo */ - {"L", +11 * 60}, /* Lima */ - {"M", +12 * 60}, /* Mike */ - {"N", -1 * 60}, /* November */ - {"O", -2 * 60}, /* Oscar */ - {"P", -3 * 60}, /* Papa */ - {"Q", -4 * 60}, /* Quebec */ - {"R", -5 * 60}, /* Romeo */ - {"S", -6 * 60}, /* Sierra */ - {"T", -7 * 60}, /* Tango */ - {"U", -8 * 60}, /* Uniform */ - {"V", -9 * 60}, /* Victor */ - {"W", -10 * 60}, /* Whiskey */ - {"X", -11 * 60}, /* X-ray */ - {"Y", -12 * 60}, /* Yankee */ - {"Z", 0}, /* Zulu, zero meridian, a.k.a. UTC */ -}; - -/* returns: - -1 no day - 0 monday - 6 sunday -*/ - -static int checkday(const char *check, size_t len) -{ - int i; - const char * const *what; - bool found= FALSE; - if(len > 3) - what = &weekday[0]; - else - what = &Curl_wkday[0]; - for(i=0; i<7; i++) { - if(Curl_raw_equal(check, what[0])) { - found=TRUE; - break; - } - what++; - } - return found?i:-1; -} - -static int checkmonth(const char *check) -{ - int i; - const char * const *what; - bool found= FALSE; - - what = &Curl_month[0]; - for(i=0; i<12; i++) { - if(Curl_raw_equal(check, what[0])) { - found=TRUE; - break; - } - what++; - } - return found?i:-1; /* return the offset or -1, no real offset is -1 */ -} - -/* return the time zone offset between GMT and the input one, in number - of seconds or -1 if the timezone wasn't found/legal */ - -static int checktz(const char *check) -{ - unsigned int i; - const struct tzinfo *what; - bool found= FALSE; - - what = tz; - for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) { - if(Curl_raw_equal(check, what->name)) { - found=TRUE; - break; - } - what++; - } - return found?what->offset*60:-1; -} - -static void skip(const char **date) -{ - /* skip everything that aren't letters or digits */ - while(**date && !ISALNUM(**date)) - (*date)++; -} - -enum assume { - DATE_MDAY, - DATE_YEAR, - DATE_TIME -}; - -/* this is a clone of 'struct tm' but with all fields we don't need or use - cut out */ -struct my_tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; -}; - -/* struct tm to time since epoch in GMT time zone. - * This is similar to the standard mktime function but for GMT only, and - * doesn't suffer from the various bugs and portability problems that - * some systems' implementations have. - */ -static time_t my_timegm(struct my_tm *tm) -{ - static const int month_days_cumulative [12] = - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - int month, year, leap_days; - - if(tm->tm_year < 70) - /* we don't support years before 1970 as they will cause this function - to return a negative value */ - return -1; - - year = tm->tm_year + 1900; - month = tm->tm_mon; - if(month < 0) { - year += (11 - month) / 12; - month = 11 - (11 - month) % 12; - } - else if(month >= 12) { - year -= month / 12; - month = month % 12; - } - - leap_days = year - (tm->tm_mon <= 1); - leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400) - - (1969 / 4) + (1969 / 100) - (1969 / 400)); - - return ((((time_t) (year - 1970) * 365 - + leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24 - + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; -} - -/* - * parsedate() - * - * Returns: - * - * PARSEDATE_OK - a fine conversion - * PARSEDATE_FAIL - failed to convert - * PARSEDATE_LATER - time overflow at the far end of time_t - * PARSEDATE_SOONER - time underflow at the low end of time_t - */ - -static int parsedate(const char *date, time_t *output) -{ - time_t t = 0; - int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */ - int monnum=-1; /* month of the year number, 0-11 */ - int mdaynum=-1; /* day of month, 1 - 31 */ - int hournum=-1; - int minnum=-1; - int secnum=-1; - int yearnum=-1; - int tzoff=-1; - struct my_tm tm; - enum assume dignext = DATE_MDAY; - const char *indate = date; /* save the original pointer */ - int part = 0; /* max 6 parts */ - - while(*date && (part < 6)) { - bool found=FALSE; - - skip(&date); - - if(ISALPHA(*date)) { - /* a name coming up */ - char buf[32]=""; - size_t len; - if(sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz]", buf)) - len = strlen(buf); - else - len = 0; - - if(wdaynum == -1) { - wdaynum = checkday(buf, len); - if(wdaynum != -1) - found = TRUE; - } - if(!found && (monnum == -1)) { - monnum = checkmonth(buf); - if(monnum != -1) - found = TRUE; - } - - if(!found && (tzoff == -1)) { - /* this just must be a time zone string */ - tzoff = checktz(buf); - if(tzoff != -1) - found = TRUE; - } - - if(!found) - return PARSEDATE_FAIL; /* bad string */ - - date += len; - } - else if(ISDIGIT(*date)) { - /* a digit */ - int val; - char *end; - if((secnum == -1) && - (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) { - /* time stamp! */ - date += 8; - } - else if((secnum == -1) && - (2 == sscanf(date, "%02d:%02d", &hournum, &minnum))) { - /* time stamp without seconds */ - date += 5; - secnum = 0; - } - else { - long lval; - int error; - int old_errno; - - old_errno = ERRNO; - SET_ERRNO(0); - lval = strtol(date, &end, 10); - error = ERRNO; - if(error != old_errno) - SET_ERRNO(old_errno); - - if(error) - return PARSEDATE_FAIL; - -#if LONG_MAX != INT_MAX - if((lval > (long)INT_MAX) || (lval < (long)INT_MIN)) - return PARSEDATE_FAIL; -#endif - - val = curlx_sltosi(lval); - - if((tzoff == -1) && - ((end - date) == 4) && - (val <= 1400) && - (indate< date) && - ((date[-1] == '+' || date[-1] == '-'))) { - /* four digits and a value less than or equal to 1400 (to take into - account all sorts of funny time zone diffs) and it is preceded - with a plus or minus. This is a time zone indication. 1400 is - picked since +1300 is frequently used and +1400 is mentioned as - an edge number in the document "ISO C 200X Proposal: Timezone - Functions" at http://david.tribble.com/text/c0xtimezone.html If - anyone has a more authoritative source for the exact maximum time - zone offsets, please speak up! */ - found = TRUE; - tzoff = (val/100 * 60 + val%100)*60; - - /* the + and - prefix indicates the local time compared to GMT, - this we need ther reversed math to get what we want */ - tzoff = date[-1]=='+'?-tzoff:tzoff; - } - - if(((end - date) == 8) && - (yearnum == -1) && - (monnum == -1) && - (mdaynum == -1)) { - /* 8 digits, no year, month or day yet. This is YYYYMMDD */ - found = TRUE; - yearnum = val/10000; - monnum = (val%10000)/100-1; /* month is 0 - 11 */ - mdaynum = val%100; - } - - if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) { - if((val > 0) && (val<32)) { - mdaynum = val; - found = TRUE; - } - dignext = DATE_YEAR; - } - - if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) { - yearnum = val; - found = TRUE; - if(yearnum < 1900) { - if(yearnum > 70) - yearnum += 1900; - else - yearnum += 2000; - } - if(mdaynum == -1) - dignext = DATE_MDAY; - } - - if(!found) - return PARSEDATE_FAIL; - - date = end; - } - } - - part++; - } - - if(-1 == secnum) - secnum = minnum = hournum = 0; /* no time, make it zero */ - - if((-1 == mdaynum) || - (-1 == monnum) || - (-1 == yearnum)) - /* lacks vital info, fail */ - return PARSEDATE_FAIL; - -#if SIZEOF_TIME_T < 5 - /* 32 bit time_t can only hold dates to the beginning of 2038 */ - if(yearnum > 2037) { - *output = 0x7fffffff; - return PARSEDATE_LATER; - } -#endif - - if(yearnum < 1970) { - *output = 0; - return PARSEDATE_SOONER; - } - - if((mdaynum > 31) || (monnum > 11) || - (hournum > 23) || (minnum > 59) || (secnum > 60)) - return PARSEDATE_FAIL; /* clearly an illegal date */ - - tm.tm_sec = secnum; - tm.tm_min = minnum; - tm.tm_hour = hournum; - tm.tm_mday = mdaynum; - tm.tm_mon = monnum; - tm.tm_year = yearnum - 1900; - - /* my_timegm() returns a time_t. time_t is often 32 bits, even on many - architectures that feature 64 bit 'long'. - - Some systems have 64 bit time_t and deal with years beyond 2038. However, - even on some of the systems with 64 bit time_t mktime() returns -1 for - dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06) - */ - t = my_timegm(&tm); - - /* time zone adjust (cast t to int to compare to negative one) */ - if(-1 != (int)t) { - - /* Add the time zone diff between local time zone and GMT. */ - long delta = (long)(tzoff!=-1?tzoff:0); - - if((delta>0) && (t > LONG_MAX - delta)) { - *output = 0x7fffffff; - return PARSEDATE_LATER; /* time_t overflow */ - } - - t += delta; - } - - *output = t; - - return PARSEDATE_OK; -} - -time_t curl_getdate(const char *p, const time_t *now) -{ - time_t parsed = -1; - int rc = parsedate(p, &parsed); - (void)now; /* legacy argument from the past that we ignore */ - - switch(rc) { - case PARSEDATE_OK: - case PARSEDATE_LATER: - case PARSEDATE_SOONER: - return parsed; - } - /* everything else is fail */ - return -1; -} - -/* - * Curl_gmtime() is a gmtime() replacement for portability. Do not use the - * gmtime_r() or gmtime() functions anywhere else but here. - * - */ - -CURLcode Curl_gmtime(time_t intime, struct tm *store) -{ - const struct tm *tm; -#ifdef HAVE_GMTIME_R - /* thread-safe version */ - tm = (struct tm *)gmtime_r(&intime, store); -#else - tm = gmtime(&intime); - if(tm) - *store = *tm; /* copy the pointed struct to the local copy */ -#endif - - if(!tm) - return CURLE_BAD_FUNCTION_ARGUMENT; - return CURLE_OK; -} diff --git a/Externals/curl/lib/parsedate.h b/Externals/curl/lib/parsedate.h deleted file mode 100644 index 2e59eb17c2..0000000000 --- a/Externals/curl/lib/parsedate.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_PARSEDATE_H -#define HEADER_CURL_PARSEDATE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -extern const char * const Curl_wkday[7]; -extern const char * const Curl_month[12]; - -CURLcode Curl_gmtime(time_t intime, struct tm *store); - -#endif /* HEADER_CURL_PARSEDATE_H */ - diff --git a/Externals/curl/lib/pingpong.c b/Externals/curl/lib/pingpong.c deleted file mode 100644 index ce2b58612f..0000000000 --- a/Externals/curl/lib/pingpong.c +++ /dev/null @@ -1,507 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * 'pingpong' is for generic back-and-forth support functions used by FTP, - * IMAP, POP3, SMTP and whatever more that likes them. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "urldata.h" -#include "sendf.h" -#include "select.h" -#include "progress.h" -#include "speedcheck.h" -#include "pingpong.h" -#include "multiif.h" -#include "non-ascii.h" -#include "vtls/vtls.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifdef USE_PINGPONG - -/* Returns timeout in ms. 0 or negative number means the timeout has already - triggered */ -long Curl_pp_state_timeout(struct pingpong *pp) -{ - struct connectdata *conn = pp->conn; - struct SessionHandle *data=conn->data; - long timeout_ms; /* in milliseconds */ - long timeout2_ms; /* in milliseconds */ - long response_time= (data->set.server_response_timeout)? - data->set.server_response_timeout: pp->response_time; - - /* if CURLOPT_SERVER_RESPONSE_TIMEOUT is set, use that to determine - remaining time, or use pp->response because SERVER_RESPONSE_TIMEOUT is - supposed to govern the response for any given server response, not for - the time from connect to the given server response. */ - - /* Without a requested timeout, we only wait 'response_time' seconds for the - full response to arrive before we bail out */ - timeout_ms = response_time - - Curl_tvdiff(Curl_tvnow(), pp->response); /* spent time */ - - if(data->set.timeout) { - /* if timeout is requested, find out how much remaining time we have */ - timeout2_ms = data->set.timeout - /* timeout time */ - Curl_tvdiff(Curl_tvnow(), conn->now); /* spent time */ - - /* pick the lowest number */ - timeout_ms = CURLMIN(timeout_ms, timeout2_ms); - } - - return timeout_ms; -} - -/* - * Curl_pp_statemach() - */ -CURLcode Curl_pp_statemach(struct pingpong *pp, bool block) -{ - struct connectdata *conn = pp->conn; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int rc; - long interval_ms; - long timeout_ms = Curl_pp_state_timeout(pp); - struct SessionHandle *data=conn->data; - CURLcode result = CURLE_OK; - - if(timeout_ms <=0) { - failf(data, "server response timeout"); - return CURLE_OPERATION_TIMEDOUT; /* already too little time */ - } - - if(block) { - interval_ms = 1000; /* use 1 second timeout intervals */ - if(timeout_ms < interval_ms) - interval_ms = timeout_ms; - } - else - interval_ms = 0; /* immediate */ - - if(Curl_pp_moredata(pp)) - /* We are receiving and there is data in the cache so just read it */ - rc = 1; - else if(!pp->sendleft && Curl_ssl_data_pending(conn, FIRSTSOCKET)) - /* We are receiving and there is data ready in the SSL library */ - rc = 1; - else - rc = Curl_socket_ready(pp->sendleft?CURL_SOCKET_BAD:sock, /* reading */ - pp->sendleft?sock:CURL_SOCKET_BAD, /* writing */ - interval_ms); - - if(block) { - /* if we didn't wait, we don't have to spend time on this now */ - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - else - result = Curl_speedcheck(data, Curl_tvnow()); - - if(result) - return result; - } - - if(rc == -1) { - failf(data, "select/poll error"); - result = CURLE_OUT_OF_MEMORY; - } - else if(rc) - result = pp->statemach_act(conn); - - return result; -} - -/* initialize stuff to prepare for reading a fresh new response */ -void Curl_pp_init(struct pingpong *pp) -{ - struct connectdata *conn = pp->conn; - pp->nread_resp = 0; - pp->linestart_resp = conn->data->state.buffer; - pp->pending_resp = TRUE; - pp->response = Curl_tvnow(); /* start response time-out now! */ -} - - - -/*********************************************************************** - * - * Curl_pp_vsendf() - * - * Send the formated string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_vsendf(struct pingpong *pp, - const char *fmt, - va_list args) -{ - ssize_t bytes_written; - size_t write_len; - char *fmt_crlf; - char *s; - CURLcode result; - struct connectdata *conn = pp->conn; - struct SessionHandle *data = conn->data; - -#ifdef HAVE_GSSAPI - enum protection_level data_sec = conn->data_prot; -#endif - - DEBUGASSERT(pp->sendleft == 0); - DEBUGASSERT(pp->sendsize == 0); - DEBUGASSERT(pp->sendthis == NULL); - - fmt_crlf = aprintf("%s\r\n", fmt); /* append a trailing CRLF */ - if(!fmt_crlf) - return CURLE_OUT_OF_MEMORY; - - s = vaprintf(fmt_crlf, args); /* trailing CRLF appended */ - free(fmt_crlf); - if(!s) - return CURLE_OUT_OF_MEMORY; - - bytes_written = 0; - write_len = strlen(s); - - Curl_pp_init(pp); - - result = Curl_convert_to_network(data, s, write_len); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) { - free(s); - return result; - } - -#ifdef HAVE_GSSAPI - conn->data_prot = PROT_CMD; -#endif - result = Curl_write(conn, conn->sock[FIRSTSOCKET], s, write_len, - &bytes_written); -#ifdef HAVE_GSSAPI - DEBUGASSERT(data_sec > PROT_NONE && data_sec < PROT_LAST); - conn->data_prot = data_sec; -#endif - - if(result) { - free(s); - return result; - } - - if(conn->data->set.verbose) - Curl_debug(conn->data, CURLINFO_HEADER_OUT, - s, (size_t)bytes_written, conn); - - if(bytes_written != (ssize_t)write_len) { - /* the whole chunk was not sent, keep it around and adjust sizes */ - pp->sendthis = s; - pp->sendsize = write_len; - pp->sendleft = write_len - bytes_written; - } - else { - free(s); - pp->sendthis = NULL; - pp->sendleft = pp->sendsize = 0; - pp->response = Curl_tvnow(); - } - - return CURLE_OK; -} - - -/*********************************************************************** - * - * Curl_pp_sendf() - * - * Send the formated string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_sendf(struct pingpong *pp, - const char *fmt, ...) -{ - CURLcode result; - va_list ap; - va_start(ap, fmt); - - result = Curl_pp_vsendf(pp, fmt, ap); - - va_end(ap); - - return result; -} - -/* - * Curl_pp_readresp() - * - * Reads a piece of a server response. - */ -CURLcode Curl_pp_readresp(curl_socket_t sockfd, - struct pingpong *pp, - int *code, /* return the server code if done */ - size_t *size) /* size of the response */ -{ - ssize_t perline; /* count bytes per line */ - bool keepon=TRUE; - ssize_t gotbytes; - char *ptr; - struct connectdata *conn = pp->conn; - struct SessionHandle *data = conn->data; - char * const buf = data->state.buffer; - CURLcode result = CURLE_OK; - - *code = 0; /* 0 for errors or not done */ - *size = 0; - - ptr=buf + pp->nread_resp; - - /* number of bytes in the current line, so far */ - perline = (ssize_t)(ptr-pp->linestart_resp); - - while((pp->nread_respcache) { - /* we had data in the "cache", copy that instead of doing an actual - * read - * - * pp->cache_size is cast to ssize_t here. This should be safe, because - * it would have been populated with something of size int to begin - * with, even though its datatype may be larger than an int. - */ - DEBUGASSERT((ptr+pp->cache_size) <= (buf+BUFSIZE+1)); - memcpy(ptr, pp->cache, pp->cache_size); - gotbytes = (ssize_t)pp->cache_size; - free(pp->cache); /* free the cache */ - pp->cache = NULL; /* clear the pointer */ - pp->cache_size = 0; /* zero the size just in case */ - } - else { -#ifdef HAVE_GSSAPI - enum protection_level prot = conn->data_prot; - conn->data_prot = PROT_CLEAR; -#endif - DEBUGASSERT((ptr+BUFSIZE-pp->nread_resp) <= (buf+BUFSIZE+1)); - result = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp, - &gotbytes); -#ifdef HAVE_GSSAPI - DEBUGASSERT(prot > PROT_NONE && prot < PROT_LAST); - conn->data_prot = prot; -#endif - if(result == CURLE_AGAIN) - return CURLE_OK; /* return */ - - if(!result && (gotbytes > 0)) - /* convert from the network encoding */ - result = Curl_convert_from_network(data, ptr, gotbytes); - /* Curl_convert_from_network calls failf if unsuccessful */ - - if(result) - /* Set outer result variable to this error. */ - keepon = FALSE; - } - - if(!keepon) - ; - else if(gotbytes <= 0) { - keepon = FALSE; - result = CURLE_RECV_ERROR; - failf(data, "response reading failed"); - } - else { - /* we got a whole chunk of data, which can be anything from one - * byte to a set of lines and possible just a piece of the last - * line */ - ssize_t i; - ssize_t clipamount = 0; - bool restart = FALSE; - - data->req.headerbytecount += (long)gotbytes; - - pp->nread_resp += gotbytes; - for(i = 0; i < gotbytes; ptr++, i++) { - perline++; - if(*ptr=='\n') { - /* a newline is CRLF in pp-talk, so the CR is ignored as - the line isn't really terminated until the LF comes */ - - /* output debug output if that is requested */ -#ifdef HAVE_GSSAPI - if(!conn->sec_complete) -#endif - if(data->set.verbose) - Curl_debug(data, CURLINFO_HEADER_IN, - pp->linestart_resp, (size_t)perline, conn); - - /* - * We pass all response-lines to the callback function registered - * for "headers". The response lines can be seen as a kind of - * headers. - */ - result = Curl_client_write(conn, CLIENTWRITE_HEADER, - pp->linestart_resp, perline); - if(result) - return result; - - if(pp->endofresp(conn, pp->linestart_resp, perline, code)) { - /* This is the end of the last line, copy the last line to the - start of the buffer and zero terminate, for old times sake */ - size_t n = ptr - pp->linestart_resp; - memmove(buf, pp->linestart_resp, n); - buf[n]=0; /* zero terminate */ - keepon=FALSE; - pp->linestart_resp = ptr+1; /* advance pointer */ - i++; /* skip this before getting out */ - - *size = pp->nread_resp; /* size of the response */ - pp->nread_resp = 0; /* restart */ - break; - } - perline=0; /* line starts over here */ - pp->linestart_resp = ptr+1; - } - } - - if(!keepon && (i != gotbytes)) { - /* We found the end of the response lines, but we didn't parse the - full chunk of data we have read from the server. We therefore need - to store the rest of the data to be checked on the next invoke as - it may actually contain another end of response already! */ - clipamount = gotbytes - i; - restart = TRUE; - DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing " - "server response left\n", - (int)clipamount)); - } - else if(keepon) { - - if((perline == gotbytes) && (gotbytes > BUFSIZE/2)) { - /* We got an excessive line without newlines and we need to deal - with it. We keep the first bytes of the line then we throw - away the rest. */ - infof(data, "Excessive server response line length received, " - "%zd bytes. Stripping\n", gotbytes); - restart = TRUE; - - /* we keep 40 bytes since all our pingpong protocols are only - interested in the first piece */ - clipamount = 40; - } - else if(pp->nread_resp > BUFSIZE/2) { - /* We got a large chunk of data and there's potentially still - trailing data to take care of, so we put any such part in the - "cache", clear the buffer to make space and restart. */ - clipamount = perline; - restart = TRUE; - } - } - else if(i == gotbytes) - restart = TRUE; - - if(clipamount) { - pp->cache_size = clipamount; - pp->cache = malloc(pp->cache_size); - if(pp->cache) - memcpy(pp->cache, pp->linestart_resp, pp->cache_size); - else - return CURLE_OUT_OF_MEMORY; - } - if(restart) { - /* now reset a few variables to start over nicely from the start of - the big buffer */ - pp->nread_resp = 0; /* start over from scratch in the buffer */ - ptr = pp->linestart_resp = buf; - perline = 0; - } - - } /* there was data */ - - } /* while there's buffer left and loop is requested */ - - pp->pending_resp = FALSE; - - return result; -} - -int Curl_pp_getsock(struct pingpong *pp, - curl_socket_t *socks, - int numsocks) -{ - struct connectdata *conn = pp->conn; - - if(!numsocks) - return GETSOCK_BLANK; - - socks[0] = conn->sock[FIRSTSOCKET]; - - if(pp->sendleft) { - /* write mode */ - return GETSOCK_WRITESOCK(0); - } - - /* read mode */ - return GETSOCK_READSOCK(0); -} - -CURLcode Curl_pp_flushsend(struct pingpong *pp) -{ - /* we have a piece of a command still left to send */ - struct connectdata *conn = pp->conn; - ssize_t written; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - CURLcode result = Curl_write(conn, sock, pp->sendthis + pp->sendsize - - pp->sendleft, pp->sendleft, &written); - if(result) - return result; - - if(written != (ssize_t)pp->sendleft) { - /* only a fraction was sent */ - pp->sendleft -= written; - } - else { - free(pp->sendthis); - pp->sendthis=NULL; - pp->sendleft = pp->sendsize = 0; - pp->response = Curl_tvnow(); - } - return CURLE_OK; -} - -CURLcode Curl_pp_disconnect(struct pingpong *pp) -{ - free(pp->cache); - pp->cache = NULL; - return CURLE_OK; -} - -bool Curl_pp_moredata(struct pingpong *pp) -{ - return (!pp->sendleft && pp->cache && pp->nread_resp < pp->cache_size) ? - TRUE : FALSE; -} - -#endif diff --git a/Externals/curl/lib/pingpong.h b/Externals/curl/lib/pingpong.h deleted file mode 100644 index 2f649d5bfb..0000000000 --- a/Externals/curl/lib/pingpong.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef HEADER_CURL_PINGPONG_H -#define HEADER_CURL_PINGPONG_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_FTP) || \ - !defined(CURL_DISABLE_POP3) || !defined(CURL_DISABLE_SMTP) -#define USE_PINGPONG -#endif - -/* forward-declaration, this is defined in urldata.h */ -struct connectdata; - -typedef enum { - FTPTRANSFER_BODY, /* yes do transfer a body */ - FTPTRANSFER_INFO, /* do still go through to get info/headers */ - FTPTRANSFER_NONE, /* don't get anything and don't get info */ - FTPTRANSFER_LAST /* end of list marker, never used */ -} curl_pp_transfer; - -/* - * 'pingpong' is the generic struct used for protocols doing server<->client - * conversations in a back-and-forth style such as FTP, IMAP, POP3, SMTP etc. - * - * It holds response cache and non-blocking sending data. - */ -struct pingpong { - char *cache; /* data cache between getresponse()-calls */ - size_t cache_size; /* size of cache in bytes */ - size_t nread_resp; /* number of bytes currently read of a server response */ - char *linestart_resp; /* line start pointer for the server response - reader function */ - bool pending_resp; /* set TRUE when a server response is pending or in - progress, and is cleared once the last response is - read */ - char *sendthis; /* allocated pointer to a buffer that is to be sent to the - server */ - size_t sendleft; /* number of bytes left to send from the sendthis buffer */ - size_t sendsize; /* total size of the sendthis buffer */ - struct timeval response; /* set to Curl_tvnow() when a command has been sent - off, used to time-out response reading */ - long response_time; /* When no timeout is given, this is the amount of - milliseconds we await for a server response. */ - - struct connectdata *conn; /* points to the connectdata struct that this - belongs to */ - - /* Function pointers the protocols MUST implement and provide for the - pingpong layer to function */ - - CURLcode (*statemach_act)(struct connectdata *conn); - - bool (*endofresp)(struct connectdata *conn, char *ptr, size_t len, - int *code); -}; - -/* - * Curl_pp_statemach() - * - * called repeatedly until done. Set 'wait' to make it wait a while on the - * socket if there's no traffic. - */ -CURLcode Curl_pp_statemach(struct pingpong *pp, bool block); - -/* initialize stuff to prepare for reading a fresh new response */ -void Curl_pp_init(struct pingpong *pp); - -/* Returns timeout in ms. 0 or negative number means the timeout has already - triggered */ -long Curl_pp_state_timeout(struct pingpong *pp); - - -/*********************************************************************** - * - * Curl_pp_sendf() - * - * Send the formated string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_sendf(struct pingpong *pp, - const char *fmt, ...); - -/*********************************************************************** - * - * Curl_pp_vsendf() - * - * Send the formated string as a command to a pingpong server. Note that - * the string should not have any CRLF appended, as this function will - * append the necessary things itself. - * - * made to never block - */ -CURLcode Curl_pp_vsendf(struct pingpong *pp, - const char *fmt, - va_list args); - -/* - * Curl_pp_readresp() - * - * Reads a piece of a server response. - */ -CURLcode Curl_pp_readresp(curl_socket_t sockfd, - struct pingpong *pp, - int *code, /* return the server code if done */ - size_t *size); /* size of the response */ - - -CURLcode Curl_pp_flushsend(struct pingpong *pp); - -/* call this when a pingpong connection is disconnected */ -CURLcode Curl_pp_disconnect(struct pingpong *pp); - -int Curl_pp_getsock(struct pingpong *pp, curl_socket_t *socks, - int numsocks); - - -/*********************************************************************** - * - * Curl_pp_moredata() - * - * Returns whether there are still more data in the cache and so a call - * to Curl_pp_readresp() will not block. - */ -bool Curl_pp_moredata(struct pingpong *pp); - -#endif /* HEADER_CURL_PINGPONG_H */ diff --git a/Externals/curl/lib/pipeline.c b/Externals/curl/lib/pipeline.c deleted file mode 100644 index 95b89b54bc..0000000000 --- a/Externals/curl/lib/pipeline.c +++ /dev/null @@ -1,434 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2013, Linus Nielsen Feltzing, - * Copyright (C) 2013-2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "urldata.h" -#include "url.h" -#include "progress.h" -#include "multiif.h" -#include "pipeline.h" -#include "sendf.h" -#include "rawstr.h" - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -struct site_blacklist_entry { - char *hostname; - unsigned short port; -}; - -static void site_blacklist_llist_dtor(void *user, void *element) -{ - struct site_blacklist_entry *entry = element; - (void)user; - - Curl_safefree(entry->hostname); - free(entry); -} - -static void server_blacklist_llist_dtor(void *user, void *element) -{ - (void)user; - free(element); -} - -bool Curl_pipeline_penalized(struct SessionHandle *data, - struct connectdata *conn) -{ - if(data) { - bool penalized = FALSE; - curl_off_t penalty_size = - Curl_multi_content_length_penalty_size(data->multi); - curl_off_t chunk_penalty_size = - Curl_multi_chunk_length_penalty_size(data->multi); - curl_off_t recv_size = -2; /* Make it easy to spot in the log */ - - /* Find the head of the recv pipe, if any */ - if(conn->recv_pipe && conn->recv_pipe->head) { - struct SessionHandle *recv_handle = conn->recv_pipe->head->ptr; - - recv_size = recv_handle->req.size; - - if(penalty_size > 0 && recv_size > penalty_size) - penalized = TRUE; - } - - if(chunk_penalty_size > 0 && - (curl_off_t)conn->chunk.datasize > chunk_penalty_size) - penalized = TRUE; - - infof(data, "Conn: %ld (%p) Receive pipe weight: (%" - CURL_FORMAT_CURL_OFF_T "/%zu), penalized: %s\n", - conn->connection_id, (void *)conn, recv_size, - conn->chunk.datasize, penalized?"TRUE":"FALSE"); - return penalized; - } - return FALSE; -} - -static CURLcode addHandleToPipeline(struct SessionHandle *data, - struct curl_llist *pipeline) -{ - if(!Curl_llist_insert_next(pipeline, pipeline->tail, data)) - return CURLE_OUT_OF_MEMORY; - return CURLE_OK; -} - - -CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle, - struct connectdata *conn) -{ - struct curl_llist_element *sendhead = conn->send_pipe->head; - struct curl_llist *pipeline; - CURLcode result; - - pipeline = conn->send_pipe; - - result = addHandleToPipeline(handle, pipeline); - - if(pipeline == conn->send_pipe && sendhead != conn->send_pipe->head) { - /* this is a new one as head, expire it */ - Curl_pipeline_leave_write(conn); /* not in use yet */ - Curl_expire(conn->send_pipe->head->ptr, 1); - } - -#if 0 /* enable for pipeline debugging */ - print_pipeline(conn); -#endif - - return result; -} - -/* Move this transfer from the sending list to the receiving list. - - Pay special attention to the new sending list "leader" as it needs to get - checked to update what sockets it acts on. - -*/ -void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle, - struct connectdata *conn) -{ - struct curl_llist_element *curr; - - curr = conn->send_pipe->head; - while(curr) { - if(curr->ptr == handle) { - Curl_llist_move(conn->send_pipe, curr, - conn->recv_pipe, conn->recv_pipe->tail); - - if(conn->send_pipe->head) { - /* Since there's a new easy handle at the start of the send pipeline, - set its timeout value to 1ms to make it trigger instantly */ - Curl_pipeline_leave_write(conn); /* not used now */ -#ifdef DEBUGBUILD - infof(conn->data, "%p is at send pipe head B!\n", - (void *)conn->send_pipe->head->ptr); -#endif - Curl_expire(conn->send_pipe->head->ptr, 1); - } - - /* The receiver's list is not really interesting here since either this - handle is now first in the list and we'll deal with it soon, or - another handle is already first and thus is already taken care of */ - - break; /* we're done! */ - } - curr = curr->next; - } -} - -bool Curl_pipeline_site_blacklisted(struct SessionHandle *handle, - struct connectdata *conn) -{ - if(handle->multi) { - struct curl_llist *blacklist = - Curl_multi_pipelining_site_bl(handle->multi); - - if(blacklist) { - struct curl_llist_element *curr; - - curr = blacklist->head; - while(curr) { - struct site_blacklist_entry *site; - - site = curr->ptr; - if(Curl_raw_equal(site->hostname, conn->host.name) && - site->port == conn->remote_port) { - infof(handle, "Site %s:%d is pipeline blacklisted\n", - conn->host.name, conn->remote_port); - return TRUE; - } - curr = curr->next; - } - } - } - return FALSE; -} - -CURLMcode Curl_pipeline_set_site_blacklist(char **sites, - struct curl_llist **list_ptr) -{ - struct curl_llist *old_list = *list_ptr; - struct curl_llist *new_list = NULL; - - if(sites) { - new_list = Curl_llist_alloc((curl_llist_dtor) site_blacklist_llist_dtor); - if(!new_list) - return CURLM_OUT_OF_MEMORY; - - /* Parse the URLs and populate the list */ - while(*sites) { - char *hostname; - char *port; - struct site_blacklist_entry *entry; - - hostname = strdup(*sites); - if(!hostname) { - Curl_llist_destroy(new_list, NULL); - return CURLM_OUT_OF_MEMORY; - } - - entry = malloc(sizeof(struct site_blacklist_entry)); - if(!entry) { - free(hostname); - Curl_llist_destroy(new_list, NULL); - return CURLM_OUT_OF_MEMORY; - } - - port = strchr(hostname, ':'); - if(port) { - *port = '\0'; - port++; - entry->port = (unsigned short)strtol(port, NULL, 10); - } - else { - /* Default port number for HTTP */ - entry->port = 80; - } - - entry->hostname = hostname; - - if(!Curl_llist_insert_next(new_list, new_list->tail, entry)) { - site_blacklist_llist_dtor(NULL, entry); - Curl_llist_destroy(new_list, NULL); - return CURLM_OUT_OF_MEMORY; - } - - sites++; - } - } - - /* Free the old list */ - if(old_list) { - Curl_llist_destroy(old_list, NULL); - } - - /* This might be NULL if sites == NULL, i.e the blacklist is cleared */ - *list_ptr = new_list; - - return CURLM_OK; -} - -bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle, - char *server_name) -{ - if(handle->multi && server_name) { - struct curl_llist *blacklist = - Curl_multi_pipelining_server_bl(handle->multi); - - if(blacklist) { - struct curl_llist_element *curr; - - curr = blacklist->head; - while(curr) { - char *bl_server_name; - - bl_server_name = curr->ptr; - if(Curl_raw_nequal(bl_server_name, server_name, - strlen(bl_server_name))) { - infof(handle, "Server %s is blacklisted\n", server_name); - return TRUE; - } - curr = curr->next; - } - } - - DEBUGF(infof(handle, "Server %s is not blacklisted\n", server_name)); - } - return FALSE; -} - -CURLMcode Curl_pipeline_set_server_blacklist(char **servers, - struct curl_llist **list_ptr) -{ - struct curl_llist *old_list = *list_ptr; - struct curl_llist *new_list = NULL; - - if(servers) { - new_list = Curl_llist_alloc((curl_llist_dtor) server_blacklist_llist_dtor); - if(!new_list) - return CURLM_OUT_OF_MEMORY; - - /* Parse the URLs and populate the list */ - while(*servers) { - char *server_name; - - server_name = strdup(*servers); - if(!server_name) - return CURLM_OUT_OF_MEMORY; - - if(!Curl_llist_insert_next(new_list, new_list->tail, server_name)) - return CURLM_OUT_OF_MEMORY; - - servers++; - } - } - - /* Free the old list */ - if(old_list) { - Curl_llist_destroy(old_list, NULL); - } - - /* This might be NULL if sites == NULL, i.e the blacklist is cleared */ - *list_ptr = new_list; - - return CURLM_OK; -} - -static bool pipe_head(struct SessionHandle *data, - struct curl_llist *pipeline) -{ - if(pipeline) { - struct curl_llist_element *curr = pipeline->head; - if(curr) - return (curr->ptr == data) ? TRUE : FALSE; - } - return FALSE; -} - -/* returns TRUE if the given handle is head of the recv pipe */ -bool Curl_recvpipe_head(struct SessionHandle *data, - struct connectdata *conn) -{ - return pipe_head(data, conn->recv_pipe); -} - -/* returns TRUE if the given handle is head of the send pipe */ -bool Curl_sendpipe_head(struct SessionHandle *data, - struct connectdata *conn) -{ - return pipe_head(data, conn->send_pipe); -} - - -/* - * Check if the write channel is available and this handle as at the head, - * then grab the channel and return TRUE. - * - * If not available, return FALSE. - */ - -bool Curl_pipeline_checkget_write(struct SessionHandle *data, - struct connectdata *conn) -{ - if(conn->bits.multiplex) - /* when multiplexing, we can use it at once */ - return TRUE; - - if(!conn->writechannel_inuse && Curl_sendpipe_head(data, conn)) { - /* Grab the channel */ - conn->writechannel_inuse = TRUE; - return TRUE; - } - return FALSE; -} - - -/* - * Check if the read channel is available and this handle as at the head, then - * grab the channel and return TRUE. - * - * If not available, return FALSE. - */ - -bool Curl_pipeline_checkget_read(struct SessionHandle *data, - struct connectdata *conn) -{ - if(conn->bits.multiplex) - /* when multiplexing, we can use it at once */ - return TRUE; - - if(!conn->readchannel_inuse && Curl_recvpipe_head(data, conn)) { - /* Grab the channel */ - conn->readchannel_inuse = TRUE; - return TRUE; - } - return FALSE; -} - -/* - * The current user of the pipeline write channel gives it up. - */ -void Curl_pipeline_leave_write(struct connectdata *conn) -{ - conn->writechannel_inuse = FALSE; -} - -/* - * The current user of the pipeline read channel gives it up. - */ -void Curl_pipeline_leave_read(struct connectdata *conn) -{ - conn->readchannel_inuse = FALSE; -} - - -#if 0 -void print_pipeline(struct connectdata *conn) -{ - struct curl_llist_element *curr; - struct connectbundle *cb_ptr; - struct SessionHandle *data = conn->data; - - cb_ptr = conn->bundle; - - if(cb_ptr) { - curr = cb_ptr->conn_list->head; - while(curr) { - conn = curr->ptr; - infof(data, "- Conn %ld (%p) send_pipe: %zu, recv_pipe: %zu\n", - conn->connection_id, - (void *)conn, - conn->send_pipe->size, - conn->recv_pipe->size); - curr = curr->next; - } - } -} - -#endif diff --git a/Externals/curl/lib/pipeline.h b/Externals/curl/lib/pipeline.h deleted file mode 100644 index a39dfa8dec..0000000000 --- a/Externals/curl/lib/pipeline.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef HEADER_CURL_PIPELINE_H -#define HEADER_CURL_PIPELINE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2015, Daniel Stenberg, , et al. - * Copyright (C) 2013 - 2014, Linus Nielsen Feltzing, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -CURLcode Curl_add_handle_to_pipeline(struct SessionHandle *handle, - struct connectdata *conn); -void Curl_move_handle_from_send_to_recv_pipe(struct SessionHandle *handle, - struct connectdata *conn); -bool Curl_pipeline_penalized(struct SessionHandle *data, - struct connectdata *conn); - -bool Curl_pipeline_site_blacklisted(struct SessionHandle *handle, - struct connectdata *conn); - -CURLMcode Curl_pipeline_set_site_blacklist(char **sites, - struct curl_llist **list_ptr); - -bool Curl_pipeline_server_blacklisted(struct SessionHandle *handle, - char *server_name); - -CURLMcode Curl_pipeline_set_server_blacklist(char **servers, - struct curl_llist **list_ptr); - -bool Curl_pipeline_checkget_write(struct SessionHandle *data, - struct connectdata *conn); -bool Curl_pipeline_checkget_read(struct SessionHandle *data, - struct connectdata *conn); -void Curl_pipeline_leave_write(struct connectdata *conn); -void Curl_pipeline_leave_read(struct connectdata *conn); -bool Curl_recvpipe_head(struct SessionHandle *data, - struct connectdata *conn); -bool Curl_sendpipe_head(struct SessionHandle *data, - struct connectdata *conn); - -#endif /* HEADER_CURL_PIPELINE_H */ diff --git a/Externals/curl/lib/pop3.c b/Externals/curl/lib/pop3.c deleted file mode 100644 index a6b2c3f75b..0000000000 --- a/Externals/curl/lib/pop3.c +++ /dev/null @@ -1,1613 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC1734 POP3 Authentication - * RFC1939 POP3 protocol - * RFC2195 CRAM-MD5 authentication - * RFC2384 POP URL Scheme - * RFC2449 POP3 Extension Mechanism - * RFC2595 Using TLS with IMAP, POP3 and ACAP - * RFC2831 DIGEST-MD5 authentication - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * RFC5034 POP3 SASL Authentication Mechanism - * RFC6749 OAuth 2.0 Authorization Framework - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_POP3 - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_UTSNAME_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "socks.h" -#include "pop3.h" - -#include "strtoofft.h" -#include "strequal.h" -#include "vtls/vtls.h" -#include "connect.h" -#include "strerror.h" -#include "select.h" -#include "multiif.h" -#include "url.h" -#include "rawstr.h" -#include "curl_sasl.h" -#include "curl_md5.h" -#include "warnless.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Local API functions */ -static CURLcode pop3_regular_transfer(struct connectdata *conn, bool *done); -static CURLcode pop3_do(struct connectdata *conn, bool *done); -static CURLcode pop3_done(struct connectdata *conn, CURLcode status, - bool premature); -static CURLcode pop3_connect(struct connectdata *conn, bool *done); -static CURLcode pop3_disconnect(struct connectdata *conn, bool dead); -static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done); -static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks); -static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done); -static CURLcode pop3_setup_connection(struct connectdata *conn); -static CURLcode pop3_parse_url_options(struct connectdata *conn); -static CURLcode pop3_parse_url_path(struct connectdata *conn); -static CURLcode pop3_parse_custom_request(struct connectdata *conn); -static CURLcode pop3_perform_auth(struct connectdata *conn, const char *mech, - const char *initresp); -static CURLcode pop3_continue_auth(struct connectdata *conn, const char *resp); -static void pop3_get_message(char *buffer, char** outptr); - -/* - * POP3 protocol handler. - */ - -const struct Curl_handler Curl_handler_pop3 = { - "POP3", /* scheme */ - pop3_setup_connection, /* setup_connection */ - pop3_do, /* do_it */ - pop3_done, /* done */ - ZERO_NULL, /* do_more */ - pop3_connect, /* connect_it */ - pop3_multi_statemach, /* connecting */ - pop3_doing, /* doing */ - pop3_getsock, /* proto_getsock */ - pop3_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - pop3_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_POP3, /* defport */ - CURLPROTO_POP3, /* protocol */ - PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ -}; - -#ifdef USE_SSL -/* - * POP3S protocol handler. - */ - -const struct Curl_handler Curl_handler_pop3s = { - "POP3S", /* scheme */ - pop3_setup_connection, /* setup_connection */ - pop3_do, /* do_it */ - pop3_done, /* done */ - ZERO_NULL, /* do_more */ - pop3_connect, /* connect_it */ - pop3_multi_statemach, /* connecting */ - pop3_doing, /* doing */ - pop3_getsock, /* proto_getsock */ - pop3_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - pop3_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_POP3S, /* defport */ - CURLPROTO_POP3S, /* protocol */ - PROTOPT_CLOSEACTION | PROTOPT_SSL - | PROTOPT_NOURLQUERY /* flags */ -}; -#endif - -#ifndef CURL_DISABLE_HTTP -/* - * HTTP-proxyed POP3 protocol handler. - */ - -static const struct Curl_handler Curl_handler_pop3_proxy = { - "POP3", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_POP3, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -#ifdef USE_SSL -/* - * HTTP-proxyed POP3S protocol handler. - */ - -static const struct Curl_handler Curl_handler_pop3s_proxy = { - "POP3S", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_POP3S, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; -#endif -#endif - -/* SASL parameters for the pop3 protocol */ -static const struct SASLproto saslpop3 = { - "pop", /* The service name */ - '*', /* Code received when continuation is expected */ - '+', /* Code to receive upon authentication success */ - 255 - 8, /* Maximum initial response length (no max) */ - pop3_perform_auth, /* Send authentication command */ - pop3_continue_auth, /* Send authentication continuation */ - pop3_get_message /* Get SASL response message */ -}; - -#ifdef USE_SSL -static void pop3_to_pop3s(struct connectdata *conn) -{ - /* Change the connection handler */ - conn->handler = &Curl_handler_pop3s; - - /* Set the connection's upgraded to TLS flag */ - conn->tls_upgraded = TRUE; -} -#else -#define pop3_to_pop3s(x) Curl_nop_stmt -#endif - -/*********************************************************************** - * - * pop3_endofresp() - * - * Checks for an ending POP3 status code at the start of the given string, but - * also detects the APOP timestamp from the server greeting and various - * capabilities from the CAPA response including the supported authentication - * types and allowed SASL mechanisms. - */ -static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len, - int *resp) -{ - struct pop3_conn *pop3c = &conn->proto.pop3c; - - /* Do we have an error response? */ - if(len >= 4 && !memcmp("-ERR", line, 4)) { - *resp = '-'; - - return TRUE; - } - - /* Are we processing CAPA command responses? */ - if(pop3c->state == POP3_CAPA) { - /* Do we have the terminating line? */ - if(len >= 1 && !memcmp(line, ".", 1)) - /* Treat the response as a success */ - *resp = '+'; - else - /* Treat the response as an untagged continuation */ - *resp = '*'; - - return TRUE; - } - - /* Do we have a success response? */ - if(len >= 3 && !memcmp("+OK", line, 3)) { - *resp = '+'; - - return TRUE; - } - - /* Do we have a continuation response? */ - if(len >= 1 && !memcmp("+", line, 1)) { - *resp = '*'; - - return TRUE; - } - - return FALSE; /* Nothing for us */ -} - -/*********************************************************************** - * - * pop3_get_message() - * - * Gets the authentication message from the response buffer. - */ -static void pop3_get_message(char *buffer, char** outptr) -{ - size_t len = 0; - char* message = NULL; - - /* Find the start of the message */ - for(message = buffer + 2; *message == ' ' || *message == '\t'; message++) - ; - - /* Find the end of the message */ - for(len = strlen(message); len--;) - if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && - message[len] != '\t') - break; - - /* Terminate the message */ - if(++len) { - message[len] = '\0'; - } - - *outptr = message; -} - -/*********************************************************************** - * - * state() - * - * This is the ONLY way to change POP3 state! - */ -static void state(struct connectdata *conn, pop3state newstate) -{ - struct pop3_conn *pop3c = &conn->proto.pop3c; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char * const names[] = { - "STOP", - "SERVERGREET", - "CAPA", - "STARTTLS", - "UPGRADETLS", - "AUTH", - "APOP", - "USER", - "PASS", - "COMMAND", - "QUIT", - /* LAST */ - }; - - if(pop3c->state != newstate) - infof(conn->data, "POP3 %p state change from %s to %s\n", - (void *)pop3c, names[pop3c->state], names[newstate]); -#endif - - pop3c->state = newstate; -} - -/*********************************************************************** - * - * pop3_perform_capa() - * - * Sends the CAPA command in order to obtain a list of server side supported - * capabilities. - */ -static CURLcode pop3_perform_capa(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - - pop3c->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanisms yet */ - pop3c->sasl.authused = SASL_AUTH_NONE; /* Clear the auth. mechanism used */ - pop3c->tls_supported = FALSE; /* Clear the TLS capability */ - - /* Send the CAPA command */ - result = Curl_pp_sendf(&pop3c->pp, "%s", "CAPA"); - - if(!result) - state(conn, POP3_CAPA); - - return result; -} - -/*********************************************************************** - * - * pop3_perform_starttls() - * - * Sends the STLS command to start the upgrade to TLS. - */ -static CURLcode pop3_perform_starttls(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* Send the STLS command */ - result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "STLS"); - - if(!result) - state(conn, POP3_STARTTLS); - - return result; -} - -/*********************************************************************** - * - * pop3_perform_upgrade_tls() - * - * Performs the upgrade to TLS. - */ -static CURLcode pop3_perform_upgrade_tls(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - - /* Start the SSL connection */ - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone); - - if(!result) { - if(pop3c->state != POP3_UPGRADETLS) - state(conn, POP3_UPGRADETLS); - - if(pop3c->ssldone) { - pop3_to_pop3s(conn); - result = pop3_perform_capa(conn); - } - } - - return result; -} - -/*********************************************************************** - * - * pop3_perform_user() - * - * Sends a clear text USER command to authenticate with. - */ -static CURLcode pop3_perform_user(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* Check we have a username and password to authenticate with and end the - connect phase if we don't */ - if(!conn->bits.user_passwd) { - state(conn, POP3_STOP); - - return result; - } - - /* Send the USER command */ - result = Curl_pp_sendf(&conn->proto.pop3c.pp, "USER %s", - conn->user ? conn->user : ""); - if(!result) - state(conn, POP3_USER); - - return result; -} - -#ifndef CURL_DISABLE_CRYPTO_AUTH -/*********************************************************************** - * - * pop3_perform_apop() - * - * Sends an APOP command to authenticate with. - */ -static CURLcode pop3_perform_apop(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - size_t i; - MD5_context *ctxt; - unsigned char digest[MD5_DIGEST_LEN]; - char secret[2 * MD5_DIGEST_LEN + 1]; - - /* Check we have a username and password to authenticate with and end the - connect phase if we don't */ - if(!conn->bits.user_passwd) { - state(conn, POP3_STOP); - - return result; - } - - /* Create the digest */ - ctxt = Curl_MD5_init(Curl_DIGEST_MD5); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - Curl_MD5_update(ctxt, (const unsigned char *) pop3c->apoptimestamp, - curlx_uztoui(strlen(pop3c->apoptimestamp))); - - Curl_MD5_update(ctxt, (const unsigned char *) conn->passwd, - curlx_uztoui(strlen(conn->passwd))); - - /* Finalise the digest */ - Curl_MD5_final(ctxt, digest); - - /* Convert the calculated 16 octet digest into a 32 byte hex string */ - for(i = 0; i < MD5_DIGEST_LEN; i++) - snprintf(&secret[2 * i], 3, "%02x", digest[i]); - - result = Curl_pp_sendf(&pop3c->pp, "APOP %s %s", conn->user, secret); - - if(!result) - state(conn, POP3_APOP); - - return result; -} -#endif - -/*********************************************************************** - * - * pop3_perform_auth() - * - * Sends an AUTH command allowing the client to login with the given SASL - * authentication mechanism. - */ -static CURLcode pop3_perform_auth(struct connectdata *conn, - const char *mech, - const char *initresp) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - - if(initresp) { /* AUTH ... */ - /* Send the AUTH command with the initial response */ - result = Curl_pp_sendf(&pop3c->pp, "AUTH %s %s", mech, initresp); - } - else { - /* Send the AUTH command */ - result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech); - } - - return result; -} - -/*********************************************************************** - * - * pop3_continue_auth() - * - * Sends SASL continuation data or cancellation. - */ -static CURLcode pop3_continue_auth(struct connectdata *conn, - const char *resp) -{ - struct pop3_conn *pop3c = &conn->proto.pop3c; - - return Curl_pp_sendf(&pop3c->pp, "%s", resp); -} - -/*********************************************************************** - * - * pop3_perform_authentication() - * - * Initiates the authentication sequence, with the appropriate SASL - * authentication mechanism, falling back to APOP and clear text should a - * common mechanism not be available between the client and server. - */ -static CURLcode pop3_perform_authentication(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - saslprogress progress = SASL_IDLE; - - /* Check we have enough data to authenticate with and end the - connect phase if we don't */ - if(!Curl_sasl_can_authenticate(&pop3c->sasl, conn)) { - state(conn, POP3_STOP); - return result; - } - - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_SASL) { - /* Calculate the SASL login details */ - result = Curl_sasl_start(&pop3c->sasl, conn, FALSE, &progress); - - if(!result) - if(progress == SASL_INPROGRESS) - state(conn, POP3_AUTH); - } - - if(!result && progress == SASL_IDLE) { -#ifndef CURL_DISABLE_CRYPTO_AUTH - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP) - /* Perform APOP authentication */ - result = pop3_perform_apop(conn); - else -#endif - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT) - /* Perform clear text authentication */ - result = pop3_perform_user(conn); - else { - /* Other mechanisms not supported */ - infof(conn->data, "No known authentication mechanisms supported!\n"); - result = CURLE_LOGIN_DENIED; - } - } - - return result; -} - -/*********************************************************************** - * - * pop3_perform_command() - * - * Sends a POP3 based command. - */ -static CURLcode pop3_perform_command(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct POP3 *pop3 = data->req.protop; - const char *command = NULL; - - /* Calculate the default command */ - if(pop3->id[0] == '\0' || conn->data->set.ftp_list_only) { - command = "LIST"; - - if(pop3->id[0] != '\0') - /* Message specific LIST so skip the BODY transfer */ - pop3->transfer = FTPTRANSFER_INFO; - } - else - command = "RETR"; - - /* Send the command */ - if(pop3->id[0] != '\0') - result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s %s", - (pop3->custom && pop3->custom[0] != '\0' ? - pop3->custom : command), pop3->id); - else - result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", - (pop3->custom && pop3->custom[0] != '\0' ? - pop3->custom : command)); - - if(!result) - state(conn, POP3_COMMAND); - - return result; -} - -/*********************************************************************** - * - * pop3_perform_quit() - * - * Performs the quit action prior to sclose() be called. - */ -static CURLcode pop3_perform_quit(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* Send the QUIT command */ - result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "QUIT"); - - if(!result) - state(conn, POP3_QUIT); - - return result; -} - -/* For the initial server greeting */ -static CURLcode pop3_state_servergreet_resp(struct connectdata *conn, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct pop3_conn *pop3c = &conn->proto.pop3c; - const char *line = data->state.buffer; - size_t len = strlen(line); - size_t i; - - (void)instate; /* no use for this yet */ - - if(pop3code != '+') { - failf(data, "Got unexpected pop3-server response"); - result = CURLE_FTP_WEIRD_SERVER_REPLY; - } - else { - /* Does the server support APOP authentication? */ - if(len >= 4 && line[len - 2] == '>') { - /* Look for the APOP timestamp */ - for(i = 3; i < len - 2; ++i) { - if(line[i] == '<') { - /* Calculate the length of the timestamp */ - size_t timestamplen = len - 1 - i; - if(!timestamplen) - break; - - /* Allocate some memory for the timestamp */ - pop3c->apoptimestamp = (char *)calloc(1, timestamplen + 1); - - if(!pop3c->apoptimestamp) - break; - - /* Copy the timestamp */ - memcpy(pop3c->apoptimestamp, line + i, timestamplen); - pop3c->apoptimestamp[timestamplen] = '\0'; - - /* Store the APOP capability */ - pop3c->authtypes |= POP3_TYPE_APOP; - break; - } - } - } - - result = pop3_perform_capa(conn); - } - - return result; -} - -/* For CAPA responses */ -static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct pop3_conn *pop3c = &conn->proto.pop3c; - const char *line = data->state.buffer; - size_t len = strlen(line); - size_t wordlen; - - (void)instate; /* no use for this yet */ - - /* Do we have a untagged continuation response? */ - if(pop3code == '*') { - /* Does the server support the STLS capability? */ - if(len >= 4 && !memcmp(line, "STLS", 4)) - pop3c->tls_supported = TRUE; - - /* Does the server support clear text authentication? */ - else if(len >= 4 && !memcmp(line, "USER", 4)) - pop3c->authtypes |= POP3_TYPE_CLEARTEXT; - - /* Does the server support SASL based authentication? */ - else if(len >= 5 && !memcmp(line, "SASL ", 5)) { - pop3c->authtypes |= POP3_TYPE_SASL; - - /* Advance past the SASL keyword */ - line += 5; - len -= 5; - - /* Loop through the data line */ - for(;;) { - size_t llen; - unsigned int mechbit; - - while(len && - (*line == ' ' || *line == '\t' || - *line == '\r' || *line == '\n')) { - - line++; - len--; - } - - if(!len) - break; - - /* Extract the word */ - for(wordlen = 0; wordlen < len && line[wordlen] != ' ' && - line[wordlen] != '\t' && line[wordlen] != '\r' && - line[wordlen] != '\n';) - wordlen++; - - /* Test the word for a matching authentication mechanism */ - mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); - if(mechbit && llen == wordlen) - pop3c->sasl.authmechs |= mechbit; - - line += wordlen; - len -= wordlen; - } - } - } - else if(pop3code == '+') { - if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { - /* We don't have a SSL/TLS connection yet, but SSL is requested */ - if(pop3c->tls_supported) - /* Switch to TLS connection now */ - result = pop3_perform_starttls(conn); - else if(data->set.use_ssl == CURLUSESSL_TRY) - /* Fallback and carry on with authentication */ - result = pop3_perform_authentication(conn); - else { - failf(data, "STLS not supported."); - result = CURLE_USE_SSL_FAILED; - } - } - else - result = pop3_perform_authentication(conn); - } - else { - /* Clear text is supported when CAPA isn't recognised */ - pop3c->authtypes |= POP3_TYPE_CLEARTEXT; - - result = pop3_perform_authentication(conn); - } - - return result; -} - -/* For STARTTLS responses */ -static CURLcode pop3_state_starttls_resp(struct connectdata *conn, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(pop3code != '+') { - if(data->set.use_ssl != CURLUSESSL_TRY) { - failf(data, "STARTTLS denied. %c", pop3code); - result = CURLE_USE_SSL_FAILED; - } - else - result = pop3_perform_authentication(conn); - } - else - result = pop3_perform_upgrade_tls(conn); - - return result; -} - -/* For SASL authentication responses */ -static CURLcode pop3_state_auth_resp(struct connectdata *conn, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct pop3_conn *pop3c = &conn->proto.pop3c; - saslprogress progress; - - (void)instate; /* no use for this yet */ - - result = Curl_sasl_continue(&pop3c->sasl, conn, pop3code, &progress); - if(!result) - switch(progress) { - case SASL_DONE: - state(conn, POP3_STOP); /* Authenticated */ - break; - case SASL_IDLE: /* No mechanism left after cancellation */ -#ifndef CURL_DISABLE_CRYPTO_AUTH - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_APOP) - /* Perform APOP authentication */ - result = pop3_perform_apop(conn); - else -#endif - if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT) - /* Perform clear text authentication */ - result = pop3_perform_user(conn); - else { - failf(data, "Authentication cancelled"); - result = CURLE_LOGIN_DENIED; - } - break; - default: - break; - } - - return result; -} - -#ifndef CURL_DISABLE_CRYPTO_AUTH -/* For APOP responses */ -static CURLcode pop3_state_apop_resp(struct connectdata *conn, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(pop3code != '+') { - failf(data, "Authentication failed: %d", pop3code); - result = CURLE_LOGIN_DENIED; - } - else - /* End of connect phase */ - state(conn, POP3_STOP); - - return result; -} -#endif - -/* For USER responses */ -static CURLcode pop3_state_user_resp(struct connectdata *conn, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(pop3code != '+') { - failf(data, "Access denied. %c", pop3code); - result = CURLE_LOGIN_DENIED; - } - else - /* Send the PASS command */ - result = Curl_pp_sendf(&conn->proto.pop3c.pp, "PASS %s", - conn->passwd ? conn->passwd : ""); - if(!result) - state(conn, POP3_PASS); - - return result; -} - -/* For PASS responses */ -static CURLcode pop3_state_pass_resp(struct connectdata *conn, int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(pop3code != '+') { - failf(data, "Access denied. %c", pop3code); - result = CURLE_LOGIN_DENIED; - } - else - /* End of connect phase */ - state(conn, POP3_STOP); - - return result; -} - -/* For command responses */ -static CURLcode pop3_state_command_resp(struct connectdata *conn, - int pop3code, - pop3state instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct POP3 *pop3 = data->req.protop; - struct pop3_conn *pop3c = &conn->proto.pop3c; - struct pingpong *pp = &pop3c->pp; - - (void)instate; /* no use for this yet */ - - if(pop3code != '+') { - state(conn, POP3_STOP); - return CURLE_RECV_ERROR; - } - - /* This 'OK' line ends with a CR LF pair which is the two first bytes of the - EOB string so count this is two matching bytes. This is necessary to make - the code detect the EOB if the only data than comes now is %2e CR LF like - when there is no body to return. */ - pop3c->eob = 2; - - /* But since this initial CR LF pair is not part of the actual body, we set - the strip counter here so that these bytes won't be delivered. */ - pop3c->strip = 2; - - if(pop3->transfer == FTPTRANSFER_BODY) { - /* POP3 download */ - Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, NULL, -1, NULL); - - if(pp->cache) { - /* The header "cache" contains a bunch of data that is actually body - content so send it as such. Note that there may even be additional - "headers" after the body */ - - if(!data->set.opt_no_body) { - result = Curl_pop3_write(conn, pp->cache, pp->cache_size); - if(result) - return result; - } - - /* Free the cache */ - Curl_safefree(pp->cache); - - /* Reset the cache size */ - pp->cache_size = 0; - } - } - - /* End of DO phase */ - state(conn, POP3_STOP); - - return result; -} - -static CURLcode pop3_statemach_act(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - int pop3code; - struct pop3_conn *pop3c = &conn->proto.pop3c; - struct pingpong *pp = &pop3c->pp; - size_t nread = 0; - - /* Busy upgrading the connection; right now all I/O is SSL/TLS, not POP3 */ - if(pop3c->state == POP3_UPGRADETLS) - return pop3_perform_upgrade_tls(conn); - - /* Flush any data that needs to be sent */ - if(pp->sendleft) - return Curl_pp_flushsend(pp); - - do { - /* Read the response from the server */ - result = Curl_pp_readresp(sock, pp, &pop3code, &nread); - if(result) - return result; - - if(!pop3code) - break; - - /* We have now received a full POP3 server response */ - switch(pop3c->state) { - case POP3_SERVERGREET: - result = pop3_state_servergreet_resp(conn, pop3code, pop3c->state); - break; - - case POP3_CAPA: - result = pop3_state_capa_resp(conn, pop3code, pop3c->state); - break; - - case POP3_STARTTLS: - result = pop3_state_starttls_resp(conn, pop3code, pop3c->state); - break; - - case POP3_AUTH: - result = pop3_state_auth_resp(conn, pop3code, pop3c->state); - break; - -#ifndef CURL_DISABLE_CRYPTO_AUTH - case POP3_APOP: - result = pop3_state_apop_resp(conn, pop3code, pop3c->state); - break; -#endif - - case POP3_USER: - result = pop3_state_user_resp(conn, pop3code, pop3c->state); - break; - - case POP3_PASS: - result = pop3_state_pass_resp(conn, pop3code, pop3c->state); - break; - - case POP3_COMMAND: - result = pop3_state_command_resp(conn, pop3code, pop3c->state); - break; - - case POP3_QUIT: - /* fallthrough, just stop! */ - default: - /* internal error */ - state(conn, POP3_STOP); - break; - } - } while(!result && pop3c->state != POP3_STOP && Curl_pp_moredata(pp)); - - return result; -} - -/* Called repeatedly until done from multi.c */ -static CURLcode pop3_multi_statemach(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - - if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) { - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &pop3c->ssldone); - if(result || !pop3c->ssldone) - return result; - } - - result = Curl_pp_statemach(&pop3c->pp, FALSE); - *done = (pop3c->state == POP3_STOP) ? TRUE : FALSE; - - return result; -} - -static CURLcode pop3_block_statemach(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - - while(pop3c->state != POP3_STOP && !result) - result = Curl_pp_statemach(&pop3c->pp, TRUE); - - return result; -} - -/* Allocate and initialize the POP3 struct for the current SessionHandle if - required */ -static CURLcode pop3_init(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct POP3 *pop3; - - pop3 = data->req.protop = calloc(sizeof(struct POP3), 1); - if(!pop3) - result = CURLE_OUT_OF_MEMORY; - - return result; -} - -/* For the POP3 "protocol connect" and "doing" phases only */ -static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks) -{ - return Curl_pp_getsock(&conn->proto.pop3c.pp, socks, numsocks); -} - -/*********************************************************************** - * - * pop3_connect() - * - * This function should do everything that is to be considered a part of the - * connection phase. - * - * The variable 'done' points to will be TRUE if the protocol-layer connect - * phase is done when this function returns, or FALSE if not. - */ -static CURLcode pop3_connect(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - struct pingpong *pp = &pop3c->pp; - - *done = FALSE; /* default to not done yet */ - - /* We always support persistent connections in POP3 */ - connkeep(conn, "POP3 default"); - - /* Set the default response time-out */ - pp->response_time = RESP_TIMEOUT; - pp->statemach_act = pop3_statemach_act; - pp->endofresp = pop3_endofresp; - pp->conn = conn; - - /* Set the default preferred authentication type and mechanism */ - pop3c->preftype = POP3_TYPE_ANY; - Curl_sasl_init(&pop3c->sasl, &saslpop3); - - /* Initialise the pingpong layer */ - Curl_pp_init(pp); - - /* Parse the URL options */ - result = pop3_parse_url_options(conn); - if(result) - return result; - - /* Start off waiting for the server greeting response */ - state(conn, POP3_SERVERGREET); - - result = pop3_multi_statemach(conn, done); - - return result; -} - -/*********************************************************************** - * - * pop3_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode pop3_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct POP3 *pop3 = data->req.protop; - - (void)premature; - - if(!pop3) - return CURLE_OK; - - if(status) { - connclose(conn, "POP3 done with bad status"); - result = status; /* use the already set error code */ - } - - /* Cleanup our per-request based variables */ - Curl_safefree(pop3->id); - Curl_safefree(pop3->custom); - - /* Clear the transfer mode for the next request */ - pop3->transfer = FTPTRANSFER_BODY; - - return result; -} - -/*********************************************************************** - * - * pop3_perform() - * - * This is the actual DO function for POP3. Get a message/listing according to - * the options previously setup. - */ -static CURLcode pop3_perform(struct connectdata *conn, bool *connected, - bool *dophase_done) -{ - /* This is POP3 and no proxy */ - CURLcode result = CURLE_OK; - struct POP3 *pop3 = conn->data->req.protop; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - if(conn->data->set.opt_no_body) { - /* Requested no body means no transfer */ - pop3->transfer = FTPTRANSFER_INFO; - } - - *dophase_done = FALSE; /* not done yet */ - - /* Start the first command in the DO phase */ - result = pop3_perform_command(conn); - if(result) - return result; - - /* Run the state-machine */ - result = pop3_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) - DEBUGF(infof(conn->data, "DO phase is complete\n")); - - return result; -} - -/*********************************************************************** - * - * pop3_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (pop3_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode pop3_do(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - - *done = FALSE; /* default to false */ - - /* Parse the URL path */ - result = pop3_parse_url_path(conn); - if(result) - return result; - - /* Parse the custom request */ - result = pop3_parse_custom_request(conn); - if(result) - return result; - - result = pop3_regular_transfer(conn, done); - - return result; -} - -/*********************************************************************** - * - * pop3_disconnect() - * - * Disconnect from an POP3 server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode pop3_disconnect(struct connectdata *conn, bool dead_connection) -{ - struct pop3_conn *pop3c = &conn->proto.pop3c; - - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. */ - - /* The POP3 session may or may not have been allocated/setup at this - point! */ - if(!dead_connection && pop3c->pp.conn && pop3c->pp.conn->bits.protoconnstart) - if(!pop3_perform_quit(conn)) - (void)pop3_block_statemach(conn); /* ignore errors on QUIT */ - - /* Disconnect from the server */ - Curl_pp_disconnect(&pop3c->pp); - - /* Cleanup the SASL module */ - Curl_sasl_cleanup(conn, pop3c->sasl.authused); - - /* Cleanup our connection based variables */ - Curl_safefree(pop3c->apoptimestamp); - - return CURLE_OK; -} - -/* Call this when the DO phase has completed */ -static CURLcode pop3_dophase_done(struct connectdata *conn, bool connected) -{ - (void)conn; - (void)connected; - - return CURLE_OK; -} - -/* Called from multi.c while DOing */ -static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done) -{ - CURLcode result = pop3_multi_statemach(conn, dophase_done); - - if(result) - DEBUGF(infof(conn->data, "DO phase failed\n")); - else if(*dophase_done) { - result = pop3_dophase_done(conn, FALSE /* not connected */); - - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/*********************************************************************** - * - * pop3_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - */ -static CURLcode pop3_regular_transfer(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - bool connected = FALSE; - struct SessionHandle *data = conn->data; - - /* Make sure size is unknown at this point */ - data->req.size = -1; - - /* Set the progress data */ - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - - /* Carry out the perform */ - result = pop3_perform(conn, &connected, dophase_done); - - /* Perform post DO phase operations if necessary */ - if(!result && *dophase_done) - result = pop3_dophase_done(conn, connected); - - return result; -} - -static CURLcode pop3_setup_connection(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - - /* Initialise the POP3 layer */ - CURLcode result = pop3_init(conn); - if(result) - return result; - - /* Clear the TLS upgraded flag */ - conn->tls_upgraded = FALSE; - - /* Set up the proxy if necessary */ - if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) { - /* Unless we have asked to tunnel POP3 operations through the proxy, we - switch and use HTTP operations only */ -#ifndef CURL_DISABLE_HTTP - if(conn->handler == &Curl_handler_pop3) - conn->handler = &Curl_handler_pop3_proxy; - else { -#ifdef USE_SSL - conn->handler = &Curl_handler_pop3s_proxy; -#else - failf(data, "POP3S not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - /* set it up as an HTTP connection instead */ - return conn->handler->setup_connection(conn); -#else - failf(data, "POP3 over http proxy requires HTTP support built-in!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - data->state.path++; /* don't include the initial slash */ - - return CURLE_OK; -} - -/*********************************************************************** - * - * pop3_parse_url_options() - * - * Parse the URL login options. - */ -static CURLcode pop3_parse_url_options(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct pop3_conn *pop3c = &conn->proto.pop3c; - const char *ptr = conn->options; - - pop3c->sasl.resetprefs = TRUE; - - while(!result && ptr && *ptr) { - const char *key = ptr; - const char *value; - - while(*ptr && *ptr != '=') - ptr++; - - value = ptr + 1; - - while(*ptr && *ptr != ';') - ptr++; - - if(strnequal(key, "AUTH=", 5)) { - result = Curl_sasl_parse_url_auth_option(&pop3c->sasl, - value, ptr - value); - - if(result && strnequal(value, "+APOP", ptr - value)) { - pop3c->preftype = POP3_TYPE_APOP; - pop3c->sasl.prefmech = SASL_AUTH_NONE; - result = CURLE_OK; - } - } - else - result = CURLE_URL_MALFORMAT; - - if(*ptr == ';') - ptr++; - } - - if(pop3c->preftype != POP3_TYPE_APOP) - switch(pop3c->sasl.prefmech) { - case SASL_AUTH_NONE: - pop3c->preftype = POP3_TYPE_NONE; - break; - case SASL_AUTH_DEFAULT: - pop3c->preftype = POP3_TYPE_ANY; - break; - default: - pop3c->preftype = POP3_TYPE_SASL; - break; - } - - return result; -} - -/*********************************************************************** - * - * pop3_parse_url_path() - * - * Parse the URL path into separate path components. - */ -static CURLcode pop3_parse_url_path(struct connectdata *conn) -{ - /* The POP3 struct is already initialised in pop3_connect() */ - struct SessionHandle *data = conn->data; - struct POP3 *pop3 = data->req.protop; - const char *path = data->state.path; - - /* URL decode the path for the message ID */ - return Curl_urldecode(data, path, 0, &pop3->id, NULL, TRUE); -} - -/*********************************************************************** - * - * pop3_parse_custom_request() - * - * Parse the custom request. - */ -static CURLcode pop3_parse_custom_request(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct POP3 *pop3 = data->req.protop; - const char *custom = data->set.str[STRING_CUSTOMREQUEST]; - - /* URL decode the custom request */ - if(custom) - result = Curl_urldecode(data, custom, 0, &pop3->custom, NULL, TRUE); - - return result; -} - -/*********************************************************************** - * - * Curl_pop3_write() - * - * This function scans the body after the end-of-body and writes everything - * until the end is found. - */ -CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread) -{ - /* This code could be made into a special function in the handler struct */ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SingleRequest *k = &data->req; - - struct pop3_conn *pop3c = &conn->proto.pop3c; - bool strip_dot = FALSE; - size_t last = 0; - size_t i; - - /* Search through the buffer looking for the end-of-body marker which is - 5 bytes (0d 0a 2e 0d 0a). Note that a line starting with a dot matches - the eob so the server will have prefixed it with an extra dot which we - need to strip out. Additionally the marker could of course be spread out - over 5 different data chunks. */ - for(i = 0; i < nread; i++) { - size_t prev = pop3c->eob; - - switch(str[i]) { - case 0x0d: - if(pop3c->eob == 0) { - pop3c->eob++; - - if(i) { - /* Write out the body part that didn't match */ - result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last], - i - last); - - if(result) - return result; - - last = i; - } - } - else if(pop3c->eob == 3) - pop3c->eob++; - else - /* If the character match wasn't at position 0 or 3 then restart the - pattern matching */ - pop3c->eob = 1; - break; - - case 0x0a: - if(pop3c->eob == 1 || pop3c->eob == 4) - pop3c->eob++; - else - /* If the character match wasn't at position 1 or 4 then start the - search again */ - pop3c->eob = 0; - break; - - case 0x2e: - if(pop3c->eob == 2) - pop3c->eob++; - else if(pop3c->eob == 3) { - /* We have an extra dot after the CRLF which we need to strip off */ - strip_dot = TRUE; - pop3c->eob = 0; - } - else - /* If the character match wasn't at position 2 then start the search - again */ - pop3c->eob = 0; - break; - - default: - pop3c->eob = 0; - break; - } - - /* Did we have a partial match which has subsequently failed? */ - if(prev && prev >= pop3c->eob) { - /* Strip can only be non-zero for the very first mismatch after CRLF - and then both prev and strip are equal and nothing will be output - below */ - while(prev && pop3c->strip) { - prev--; - pop3c->strip--; - } - - if(prev) { - /* If the partial match was the CRLF and dot then only write the CRLF - as the server would have inserted the dot */ - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char*)POP3_EOB, - strip_dot ? prev - 1 : prev); - - if(result) - return result; - - last = i; - strip_dot = FALSE; - } - } - } - - if(pop3c->eob == POP3_EOB_LEN) { - /* We have a full match so the transfer is done, however we must transfer - the CRLF at the start of the EOB as this is considered to be part of the - message as per RFC-1939, sect. 3 */ - result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)POP3_EOB, 2); - - k->keepon &= ~KEEP_RECV; - pop3c->eob = 0; - - return result; - } - - if(pop3c->eob) - /* While EOB is matching nothing should be output */ - return CURLE_OK; - - if(nread - last) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, &str[last], - nread - last); - } - - return result; -} - -#endif /* CURL_DISABLE_POP3 */ diff --git a/Externals/curl/lib/pop3.h b/Externals/curl/lib/pop3.h deleted file mode 100644 index 2d9610168e..0000000000 --- a/Externals/curl/lib/pop3.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef HEADER_CURL_POP3_H -#define HEADER_CURL_POP3_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2009 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "pingpong.h" -#include "curl_sasl.h" - -/**************************************************************************** - * POP3 unique setup - ***************************************************************************/ -typedef enum { - POP3_STOP, /* do nothing state, stops the state machine */ - POP3_SERVERGREET, /* waiting for the initial greeting immediately after - a connect */ - POP3_CAPA, - POP3_STARTTLS, - POP3_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS - (multi mode only) */ - POP3_AUTH, - POP3_APOP, - POP3_USER, - POP3_PASS, - POP3_COMMAND, - POP3_QUIT, - POP3_LAST /* never used */ -} pop3state; - -/* This POP3 struct is used in the SessionHandle. All POP3 data that is - connection-oriented must be in pop3_conn to properly deal with the fact that - perhaps the SessionHandle is changed between the times the connection is - used. */ -struct POP3 { - curl_pp_transfer transfer; - char *id; /* Message ID */ - char *custom; /* Custom Request */ -}; - -/* pop3_conn is used for struct connection-oriented data in the connectdata - struct */ -struct pop3_conn { - struct pingpong pp; - pop3state state; /* Always use pop3.c:state() to change state! */ - bool ssldone; /* Is connect() over SSL done? */ - size_t eob; /* Number of bytes of the EOB (End Of Body) that - have been received so far */ - size_t strip; /* Number of bytes from the start to ignore as - non-body */ - struct SASL sasl; /* SASL-related storage */ - unsigned int authtypes; /* Accepted authentication types */ - unsigned int preftype; /* Preferred authentication type */ - char *apoptimestamp; /* APOP timestamp from the server greeting */ - bool tls_supported; /* StartTLS capability supported by server */ -}; - -extern const struct Curl_handler Curl_handler_pop3; -extern const struct Curl_handler Curl_handler_pop3s; - -/* Authentication type flags */ -#define POP3_TYPE_CLEARTEXT (1 << 0) -#define POP3_TYPE_APOP (1 << 1) -#define POP3_TYPE_SASL (1 << 2) - -/* Authentication type values */ -#define POP3_TYPE_NONE 0 -#define POP3_TYPE_ANY ~0U - -/* This is the 5-bytes End-Of-Body marker for POP3 */ -#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a" -#define POP3_EOB_LEN 5 - -/* This function scans the body after the end-of-body and writes everything - * until the end is found */ -CURLcode Curl_pop3_write(struct connectdata *conn, char *str, size_t nread); - -#endif /* HEADER_CURL_POP3_H */ diff --git a/Externals/curl/lib/progress.c b/Externals/curl/lib/progress.c deleted file mode 100644 index 713ab08523..0000000000 --- a/Externals/curl/lib/progress.c +++ /dev/null @@ -1,492 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "urldata.h" -#include "sendf.h" -#include "progress.h" -#include "curl_printf.h" - -/* Provide a string that is 2 + 1 + 2 + 1 + 2 = 8 letters long (plus the zero - byte) */ -static void time2str(char *r, curl_off_t seconds) -{ - curl_off_t d, h, m, s; - if(seconds <= 0) { - strcpy(r, "--:--:--"); - return; - } - h = seconds / CURL_OFF_T_C(3600); - if(h <= CURL_OFF_T_C(99)) { - m = (seconds - (h*CURL_OFF_T_C(3600))) / CURL_OFF_T_C(60); - s = (seconds - (h*CURL_OFF_T_C(3600))) - (m*CURL_OFF_T_C(60)); - snprintf(r, 9, "%2" CURL_FORMAT_CURL_OFF_T ":%02" CURL_FORMAT_CURL_OFF_T - ":%02" CURL_FORMAT_CURL_OFF_T, h, m, s); - } - else { - /* this equals to more than 99 hours, switch to a more suitable output - format to fit within the limits. */ - d = seconds / CURL_OFF_T_C(86400); - h = (seconds - (d*CURL_OFF_T_C(86400))) / CURL_OFF_T_C(3600); - if(d <= CURL_OFF_T_C(999)) - snprintf(r, 9, "%3" CURL_FORMAT_CURL_OFF_T - "d %02" CURL_FORMAT_CURL_OFF_T "h", d, h); - else - snprintf(r, 9, "%7" CURL_FORMAT_CURL_OFF_T "d", d); - } -} - -/* The point of this function would be to return a string of the input data, - but never longer than 5 columns (+ one zero byte). - Add suffix k, M, G when suitable... */ -static char *max5data(curl_off_t bytes, char *max5) -{ -#define ONE_KILOBYTE CURL_OFF_T_C(1024) -#define ONE_MEGABYTE (CURL_OFF_T_C(1024) * ONE_KILOBYTE) -#define ONE_GIGABYTE (CURL_OFF_T_C(1024) * ONE_MEGABYTE) -#define ONE_TERABYTE (CURL_OFF_T_C(1024) * ONE_GIGABYTE) -#define ONE_PETABYTE (CURL_OFF_T_C(1024) * ONE_TERABYTE) - - if(bytes < CURL_OFF_T_C(100000)) - snprintf(max5, 6, "%5" CURL_FORMAT_CURL_OFF_T, bytes); - - else if(bytes < CURL_OFF_T_C(10000) * ONE_KILOBYTE) - snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "k", bytes/ONE_KILOBYTE); - - else if(bytes < CURL_OFF_T_C(100) * ONE_MEGABYTE) - /* 'XX.XM' is good as long as we're less than 100 megs */ - snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" - CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE, - (bytes%ONE_MEGABYTE) / (ONE_MEGABYTE/CURL_OFF_T_C(10)) ); - -#if (CURL_SIZEOF_CURL_OFF_T > 4) - - else if(bytes < CURL_OFF_T_C(10000) * ONE_MEGABYTE) - /* 'XXXXM' is good until we're at 10000MB or above */ - snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE); - - else if(bytes < CURL_OFF_T_C(100) * ONE_GIGABYTE) - /* 10000 MB - 100 GB, we show it as XX.XG */ - snprintf(max5, 6, "%2" CURL_FORMAT_CURL_OFF_T ".%0" - CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE, - (bytes%ONE_GIGABYTE) / (ONE_GIGABYTE/CURL_OFF_T_C(10)) ); - - else if(bytes < CURL_OFF_T_C(10000) * ONE_GIGABYTE) - /* up to 10000GB, display without decimal: XXXXG */ - snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "G", bytes/ONE_GIGABYTE); - - else if(bytes < CURL_OFF_T_C(10000) * ONE_TERABYTE) - /* up to 10000TB, display without decimal: XXXXT */ - snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "T", bytes/ONE_TERABYTE); - - else - /* up to 10000PB, display without decimal: XXXXP */ - snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "P", bytes/ONE_PETABYTE); - - /* 16384 petabytes (16 exabytes) is the maximum a 64 bit unsigned number - can hold, but our data type is signed so 8192PB will be the maximum. */ - -#else - - else - snprintf(max5, 6, "%4" CURL_FORMAT_CURL_OFF_T "M", bytes/ONE_MEGABYTE); - -#endif - - return max5; -} - -/* - - New proposed interface, 9th of February 2000: - - pgrsStartNow() - sets start time - pgrsSetDownloadSize(x) - known expected download size - pgrsSetUploadSize(x) - known expected upload size - pgrsSetDownloadCounter() - amount of data currently downloaded - pgrsSetUploadCounter() - amount of data currently uploaded - pgrsUpdate() - show progress - pgrsDone() - transfer complete - -*/ - -int Curl_pgrsDone(struct connectdata *conn) -{ - int rc; - struct SessionHandle *data = conn->data; - data->progress.lastshow=0; - rc = Curl_pgrsUpdate(conn); /* the final (forced) update */ - if(rc) - return rc; - - if(!(data->progress.flags & PGRS_HIDE) && - !data->progress.callback) - /* only output if we don't use a progress callback and we're not - * hidden */ - fprintf(data->set.err, "\n"); - - data->progress.speeder_c = 0; /* reset the progress meter display */ - return 0; -} - -/* reset all times except redirect, and reset the known transfer sizes */ -void Curl_pgrsResetTimesSizes(struct SessionHandle *data) -{ - data->progress.t_nslookup = 0.0; - data->progress.t_connect = 0.0; - data->progress.t_pretransfer = 0.0; - data->progress.t_starttransfer = 0.0; - - Curl_pgrsSetDownloadSize(data, -1); - Curl_pgrsSetUploadSize(data, -1); -} - -void Curl_pgrsTime(struct SessionHandle *data, timerid timer) -{ - struct timeval now = Curl_tvnow(); - - switch(timer) { - default: - case TIMER_NONE: - /* mistake filter */ - break; - case TIMER_STARTOP: - /* This is set at the start of a transfer */ - data->progress.t_startop = now; - break; - case TIMER_STARTSINGLE: - /* This is set at the start of each single fetch */ - data->progress.t_startsingle = now; - break; - - case TIMER_STARTACCEPT: - data->progress.t_acceptdata = Curl_tvnow(); - break; - - case TIMER_NAMELOOKUP: - data->progress.t_nslookup = - Curl_tvdiff_secs(now, data->progress.t_startsingle); - break; - case TIMER_CONNECT: - data->progress.t_connect = - Curl_tvdiff_secs(now, data->progress.t_startsingle); - break; - case TIMER_APPCONNECT: - data->progress.t_appconnect = - Curl_tvdiff_secs(now, data->progress.t_startsingle); - break; - case TIMER_PRETRANSFER: - data->progress.t_pretransfer = - Curl_tvdiff_secs(now, data->progress.t_startsingle); - break; - case TIMER_STARTTRANSFER: - data->progress.t_starttransfer = - Curl_tvdiff_secs(now, data->progress.t_startsingle); - break; - case TIMER_POSTRANSFER: - /* this is the normal end-of-transfer thing */ - break; - case TIMER_REDIRECT: - data->progress.t_redirect = Curl_tvdiff_secs(now, data->progress.start); - break; - } -} - -void Curl_pgrsStartNow(struct SessionHandle *data) -{ - data->progress.speeder_c = 0; /* reset the progress meter display */ - data->progress.start = Curl_tvnow(); - /* clear all bits except HIDE and HEADERS_OUT */ - data->progress.flags &= PGRS_HIDE|PGRS_HEADERS_OUT; -} - -void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size) -{ - data->progress.downloaded = size; -} - -void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size) -{ - data->progress.uploaded = size; -} - -void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size) -{ - if(size >= 0) { - data->progress.size_dl = size; - data->progress.flags |= PGRS_DL_SIZE_KNOWN; - } - else { - data->progress.size_dl = 0; - data->progress.flags &= ~PGRS_DL_SIZE_KNOWN; - } -} - -void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size) -{ - if(size >= 0) { - data->progress.size_ul = size; - data->progress.flags |= PGRS_UL_SIZE_KNOWN; - } - else { - data->progress.size_ul = 0; - data->progress.flags &= ~PGRS_UL_SIZE_KNOWN; - } -} - -/* - * Curl_pgrsUpdate() returns 0 for success or the value returned by the - * progress callback! - */ -int Curl_pgrsUpdate(struct connectdata *conn) -{ - struct timeval now; - int result; - char max5[6][10]; - curl_off_t dlpercen=0; - curl_off_t ulpercen=0; - curl_off_t total_percen=0; - curl_off_t total_transfer; - curl_off_t total_expected_transfer; - curl_off_t timespent; - struct SessionHandle *data = conn->data; - int nowindex = data->progress.speeder_c% CURR_TIME; - int checkindex; - int countindex; /* amount of seconds stored in the speeder array */ - char time_left[10]; - char time_total[10]; - char time_spent[10]; - curl_off_t ulestimate=0; - curl_off_t dlestimate=0; - curl_off_t total_estimate; - bool shownow=FALSE; - - now = Curl_tvnow(); /* what time is it */ - - /* The time spent so far (from the start) */ - data->progress.timespent = - (double)(now.tv_sec - data->progress.start.tv_sec) + - (double)(now.tv_usec - data->progress.start.tv_usec)/1000000.0; - timespent = (curl_off_t)data->progress.timespent; - - /* The average download speed this far */ - data->progress.dlspeed = (curl_off_t) - ((double)data->progress.downloaded/ - (data->progress.timespent>0?data->progress.timespent:1)); - - /* The average upload speed this far */ - data->progress.ulspeed = (curl_off_t) - ((double)data->progress.uploaded/ - (data->progress.timespent>0?data->progress.timespent:1)); - - /* Calculations done at most once a second, unless end is reached */ - if(data->progress.lastshow != (long)now.tv_sec) { - shownow = TRUE; - - data->progress.lastshow = now.tv_sec; - - /* Let's do the "current speed" thing, which should use the fastest - of the dl/ul speeds. Store the faster speed at entry 'nowindex'. */ - data->progress.speeder[ nowindex ] = - data->progress.downloaded>data->progress.uploaded? - data->progress.downloaded:data->progress.uploaded; - - /* remember the exact time for this moment */ - data->progress.speeder_time [ nowindex ] = now; - - /* advance our speeder_c counter, which is increased every time we get - here and we expect it to never wrap as 2^32 is a lot of seconds! */ - data->progress.speeder_c++; - - /* figure out how many index entries of data we have stored in our speeder - array. With N_ENTRIES filled in, we have about N_ENTRIES-1 seconds of - transfer. Imagine, after one second we have filled in two entries, - after two seconds we've filled in three entries etc. */ - countindex = ((data->progress.speeder_c>=CURR_TIME)? - CURR_TIME:data->progress.speeder_c) - 1; - - /* first of all, we don't do this if there's no counted seconds yet */ - if(countindex) { - long span_ms; - - /* Get the index position to compare with the 'nowindex' position. - Get the oldest entry possible. While we have less than CURR_TIME - entries, the first entry will remain the oldest. */ - checkindex = (data->progress.speeder_c>=CURR_TIME)? - data->progress.speeder_c%CURR_TIME:0; - - /* Figure out the exact time for the time span */ - span_ms = Curl_tvdiff(now, - data->progress.speeder_time[checkindex]); - if(0 == span_ms) - span_ms=1; /* at least one millisecond MUST have passed */ - - /* Calculate the average speed the last 'span_ms' milliseconds */ - { - curl_off_t amount = data->progress.speeder[nowindex]- - data->progress.speeder[checkindex]; - - if(amount > CURL_OFF_T_C(4294967) /* 0xffffffff/1000 */) - /* the 'amount' value is bigger than would fit in 32 bits if - multiplied with 1000, so we use the double math for this */ - data->progress.current_speed = (curl_off_t) - ((double)amount/((double)span_ms/1000.0)); - else - /* the 'amount' value is small enough to fit within 32 bits even - when multiplied with 1000 */ - data->progress.current_speed = amount*CURL_OFF_T_C(1000)/span_ms; - } - } - else - /* the first second we use the main average */ - data->progress.current_speed = - (data->progress.ulspeed>data->progress.dlspeed)? - data->progress.ulspeed:data->progress.dlspeed; - - } /* Calculations end */ - - if(!(data->progress.flags & PGRS_HIDE)) { - /* progress meter has not been shut off */ - - if(data->set.fxferinfo) { - /* There's a callback set, call that */ - result= data->set.fxferinfo(data->set.progress_client, - data->progress.size_dl, - data->progress.downloaded, - data->progress.size_ul, - data->progress.uploaded); - if(result) - failf(data, "Callback aborted"); - return result; - } - else if(data->set.fprogress) { - /* The older deprecated callback is set, call that */ - result= data->set.fprogress(data->set.progress_client, - (double)data->progress.size_dl, - (double)data->progress.downloaded, - (double)data->progress.size_ul, - (double)data->progress.uploaded); - if(result) - failf(data, "Callback aborted"); - return result; - } - - if(!shownow) - /* only show the internal progress meter once per second */ - return 0; - - /* If there's no external callback set, use internal code to show - progress */ - - if(!(data->progress.flags & PGRS_HEADERS_OUT)) { - if(data->state.resume_from) { - fprintf(data->set.err, - "** Resuming transfer from byte position %" - CURL_FORMAT_CURL_OFF_T "\n", data->state.resume_from); - } - fprintf(data->set.err, - " %% Total %% Received %% Xferd Average Speed " - "Time Time Time Current\n" - " Dload Upload " - "Total Spent Left Speed\n"); - data->progress.flags |= PGRS_HEADERS_OUT; /* headers are shown */ - } - - /* Figure out the estimated time of arrival for the upload */ - if((data->progress.flags & PGRS_UL_SIZE_KNOWN) && - (data->progress.ulspeed > CURL_OFF_T_C(0))) { - ulestimate = data->progress.size_ul / data->progress.ulspeed; - - if(data->progress.size_ul > CURL_OFF_T_C(10000)) - ulpercen = data->progress.uploaded / - (data->progress.size_ul/CURL_OFF_T_C(100)); - else if(data->progress.size_ul > CURL_OFF_T_C(0)) - ulpercen = (data->progress.uploaded*100) / - data->progress.size_ul; - } - - /* ... and the download */ - if((data->progress.flags & PGRS_DL_SIZE_KNOWN) && - (data->progress.dlspeed > CURL_OFF_T_C(0))) { - dlestimate = data->progress.size_dl / data->progress.dlspeed; - - if(data->progress.size_dl > CURL_OFF_T_C(10000)) - dlpercen = data->progress.downloaded / - (data->progress.size_dl/CURL_OFF_T_C(100)); - else if(data->progress.size_dl > CURL_OFF_T_C(0)) - dlpercen = (data->progress.downloaded*100) / - data->progress.size_dl; - } - - /* Now figure out which of them is slower and use that one for the - total estimate! */ - total_estimate = ulestimate>dlestimate?ulestimate:dlestimate; - - /* create the three time strings */ - time2str(time_left, total_estimate > 0?(total_estimate - timespent):0); - time2str(time_total, total_estimate); - time2str(time_spent, timespent); - - /* Get the total amount of data expected to get transferred */ - total_expected_transfer = - (data->progress.flags & PGRS_UL_SIZE_KNOWN? - data->progress.size_ul:data->progress.uploaded)+ - (data->progress.flags & PGRS_DL_SIZE_KNOWN? - data->progress.size_dl:data->progress.downloaded); - - /* We have transferred this much so far */ - total_transfer = data->progress.downloaded + data->progress.uploaded; - - /* Get the percentage of data transferred so far */ - if(total_expected_transfer > CURL_OFF_T_C(10000)) - total_percen = total_transfer / - (total_expected_transfer/CURL_OFF_T_C(100)); - else if(total_expected_transfer > CURL_OFF_T_C(0)) - total_percen = (total_transfer*100) / total_expected_transfer; - - fprintf(data->set.err, - "\r" - "%3" CURL_FORMAT_CURL_OFF_T " %s " - "%3" CURL_FORMAT_CURL_OFF_T " %s " - "%3" CURL_FORMAT_CURL_OFF_T " %s %s %s %s %s %s %s", - total_percen, /* 3 letters */ /* total % */ - max5data(total_expected_transfer, max5[2]), /* total size */ - dlpercen, /* 3 letters */ /* rcvd % */ - max5data(data->progress.downloaded, max5[0]), /* rcvd size */ - ulpercen, /* 3 letters */ /* xfer % */ - max5data(data->progress.uploaded, max5[1]), /* xfer size */ - max5data(data->progress.dlspeed, max5[3]), /* avrg dl speed */ - max5data(data->progress.ulspeed, max5[4]), /* avrg ul speed */ - time_total, /* 8 letters */ /* total time */ - time_spent, /* 8 letters */ /* time spent */ - time_left, /* 8 letters */ /* time left */ - max5data(data->progress.current_speed, max5[5]) /* current speed */ - ); - - /* we flush the output stream to make it appear as soon as possible */ - fflush(data->set.err); - - } /* !(data->progress.flags & PGRS_HIDE) */ - - return 0; -} diff --git a/Externals/curl/lib/progress.h b/Externals/curl/lib/progress.h deleted file mode 100644 index ea00afa91f..0000000000 --- a/Externals/curl/lib/progress.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef HEADER_CURL_PROGRESS_H -#define HEADER_CURL_PROGRESS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "timeval.h" - - -typedef enum { - TIMER_NONE, - TIMER_STARTOP, - TIMER_STARTSINGLE, - TIMER_NAMELOOKUP, - TIMER_CONNECT, - TIMER_APPCONNECT, - TIMER_PRETRANSFER, - TIMER_STARTTRANSFER, - TIMER_POSTRANSFER, - TIMER_STARTACCEPT, - TIMER_REDIRECT, - TIMER_LAST /* must be last */ -} timerid; - -int Curl_pgrsDone(struct connectdata *); -void Curl_pgrsStartNow(struct SessionHandle *data); -void Curl_pgrsSetDownloadSize(struct SessionHandle *data, curl_off_t size); -void Curl_pgrsSetUploadSize(struct SessionHandle *data, curl_off_t size); -void Curl_pgrsSetDownloadCounter(struct SessionHandle *data, curl_off_t size); -void Curl_pgrsSetUploadCounter(struct SessionHandle *data, curl_off_t size); -int Curl_pgrsUpdate(struct connectdata *); -void Curl_pgrsResetTimesSizes(struct SessionHandle *data); -void Curl_pgrsTime(struct SessionHandle *data, timerid timer); - - -/* Don't show progress for sizes smaller than: */ -#define LEAST_SIZE_PROGRESS BUFSIZE - -#define PROGRESS_DOWNLOAD (1<<0) -#define PROGRESS_UPLOAD (1<<1) -#define PROGRESS_DOWN_AND_UP (PROGRESS_UPLOAD | PROGRESS_DOWNLOAD) - -#define PGRS_SHOW_DL (1<<0) -#define PGRS_SHOW_UL (1<<1) -#define PGRS_DONE_DL (1<<2) -#define PGRS_DONE_UL (1<<3) -#define PGRS_HIDE (1<<4) -#define PGRS_UL_SIZE_KNOWN (1<<5) -#define PGRS_DL_SIZE_KNOWN (1<<6) - -#define PGRS_HEADERS_OUT (1<<7) /* set when the headers have been written */ - - -#endif /* HEADER_CURL_PROGRESS_H */ - diff --git a/Externals/curl/lib/rawstr.c b/Externals/curl/lib/rawstr.c deleted file mode 100644 index 5665ebd361..0000000000 --- a/Externals/curl/lib/rawstr.c +++ /dev/null @@ -1,148 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "rawstr.h" - -/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because - its behavior is altered by the current locale. */ -char Curl_raw_toupper(char in) -{ -#if !defined(CURL_DOES_CONVERSIONS) - if(in >= 'a' && in <= 'z') - return (char)('A' + in - 'a'); -#else - switch (in) { - case 'a': - return 'A'; - case 'b': - return 'B'; - case 'c': - return 'C'; - case 'd': - return 'D'; - case 'e': - return 'E'; - case 'f': - return 'F'; - case 'g': - return 'G'; - case 'h': - return 'H'; - case 'i': - return 'I'; - case 'j': - return 'J'; - case 'k': - return 'K'; - case 'l': - return 'L'; - case 'm': - return 'M'; - case 'n': - return 'N'; - case 'o': - return 'O'; - case 'p': - return 'P'; - case 'q': - return 'Q'; - case 'r': - return 'R'; - case 's': - return 'S'; - case 't': - return 'T'; - case 'u': - return 'U'; - case 'v': - return 'V'; - case 'w': - return 'W'; - case 'x': - return 'X'; - case 'y': - return 'Y'; - case 'z': - return 'Z'; - } -#endif - - return in; -} - -/* - * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant - * to be locale independent and only compare strings we know are safe for - * this. See https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for - * some further explanation to why this function is necessary. - * - * The function is capable of comparing a-z case insensitively even for - * non-ascii. - */ - -int Curl_raw_equal(const char *first, const char *second) -{ - while(*first && *second) { - if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) - /* get out of the loop as soon as they don't match */ - break; - first++; - second++; - } - /* we do the comparison here (possibly again), just to make sure that if the - loop above is skipped because one of the strings reached zero, we must not - return this as a successful match */ - return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second)); -} - -int Curl_raw_nequal(const char *first, const char *second, size_t max) -{ - while(*first && *second && max) { - if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) { - break; - } - max--; - first++; - second++; - } - if(0 == max) - return 1; /* they are equal this far */ - - return Curl_raw_toupper(*first) == Curl_raw_toupper(*second); -} - -/* Copy an upper case version of the string from src to dest. The - * strings may overlap. No more than n characters of the string are copied - * (including any NUL) and the destination string will NOT be - * NUL-terminated if that limit is reached. - */ -void Curl_strntoupper(char *dest, const char *src, size_t n) -{ - if(n < 1) - return; - - do { - *dest++ = Curl_raw_toupper(*src); - } while(*src++ && --n); -} diff --git a/Externals/curl/lib/rawstr.h b/Externals/curl/lib/rawstr.h deleted file mode 100644 index 4af00f14ad..0000000000 --- a/Externals/curl/lib/rawstr.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef HEADER_CURL_RAWSTR_H -#define HEADER_CURL_RAWSTR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -/* - * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant - * to be locale independent and only compare strings we know are safe for - * this. - * - * The function is capable of comparing a-z case insensitively even for - * non-ascii. - */ -int Curl_raw_equal(const char *first, const char *second); -int Curl_raw_nequal(const char *first, const char *second, size_t max); - -char Curl_raw_toupper(char in); - -/* checkprefix() is a shorter version of the above, used when the first - argument is zero-byte terminated */ -#define checkprefix(a,b) Curl_raw_nequal(a,b,strlen(a)) - -void Curl_strntoupper(char *dest, const char *src, size_t n); - -#endif /* HEADER_CURL_RAWSTR_H */ - diff --git a/Externals/curl/lib/rtsp.c b/Externals/curl/lib/rtsp.c deleted file mode 100644 index 5cb1044880..0000000000 --- a/Externals/curl/lib/rtsp.c +++ /dev/null @@ -1,825 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_RTSP - -#include "urldata.h" -#include -#include "transfer.h" -#include "sendf.h" -#include "multiif.h" -#include "http.h" -#include "url.h" -#include "progress.h" -#include "rtsp.h" -#include "rawstr.h" -#include "select.h" -#include "connect.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* - * TODO (general) - * -incoming server requests - * -server CSeq counter - * -digest authentication - * -connect thru proxy - * -pipelining? - */ - - -#define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1]))) - -#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \ - ((int)((unsigned char)((p)[3])))) - -/* protocol-specific functions set up to be called by the main engine */ -static CURLcode rtsp_do(struct connectdata *conn, bool *done); -static CURLcode rtsp_done(struct connectdata *conn, CURLcode, bool premature); -static CURLcode rtsp_connect(struct connectdata *conn, bool *done); -static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead); - -static int rtsp_getsock_do(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); - -/* - * Parse and write out any available RTP data. - * - * nread: amount of data left after k->str. will be modified if RTP - * data is parsed and k->str is moved up - * readmore: whether or not the RTP parser needs more data right away - */ -static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data, - struct connectdata *conn, - ssize_t *nread, - bool *readmore); - -static CURLcode rtsp_setup_connection(struct connectdata *conn); - - -/* this returns the socket to wait for in the DO and DOING state for the multi - interface and then we're always _sending_ a request and thus we wait for - the single socket to become writable only */ -static int rtsp_getsock_do(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - /* write mode */ - (void)numsocks; /* unused, we trust it to be at least 1 */ - socks[0] = conn->sock[FIRSTSOCKET]; - return GETSOCK_WRITESOCK(0); -} - -static -CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len); - - -/* - * RTSP handler interface. - */ -const struct Curl_handler Curl_handler_rtsp = { - "RTSP", /* scheme */ - rtsp_setup_connection, /* setup_connection */ - rtsp_do, /* do_it */ - rtsp_done, /* done */ - ZERO_NULL, /* do_more */ - rtsp_connect, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - rtsp_getsock_do, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - rtsp_disconnect, /* disconnect */ - rtsp_rtp_readwrite, /* readwrite */ - PORT_RTSP, /* defport */ - CURLPROTO_RTSP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - - -static CURLcode rtsp_setup_connection(struct connectdata *conn) -{ - struct RTSP *rtsp; - - conn->data->req.protop = rtsp = calloc(1, sizeof(struct RTSP)); - if(!rtsp) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - - -/* - * The server may send us RTP data at any point, and RTSPREQ_RECEIVE does not - * want to block the application forever while receiving a stream. Therefore, - * we cannot assume that an RTSP socket is dead just because it is readable. - * - * Instead, if it is readable, run Curl_getconnectinfo() to peek at the socket - * and distinguish between closed and data. - */ -bool Curl_rtsp_connisdead(struct connectdata *check) -{ - int sval; - bool ret_val = TRUE; - - sval = Curl_socket_ready(check->sock[FIRSTSOCKET], CURL_SOCKET_BAD, 0); - if(sval == 0) { - /* timeout */ - ret_val = FALSE; - } - else if(sval & CURL_CSELECT_ERR) { - /* socket is in an error state */ - ret_val = TRUE; - } - else if((sval & CURL_CSELECT_IN) && check->data) { - /* readable with no error. could be closed or could be alive but we can - only check if we have a proper SessionHandle for the connection */ - curl_socket_t connectinfo = Curl_getconnectinfo(check->data, &check); - if(connectinfo != CURL_SOCKET_BAD) - ret_val = FALSE; - } - - return ret_val; -} - -static CURLcode rtsp_connect(struct connectdata *conn, bool *done) -{ - CURLcode httpStatus; - struct SessionHandle *data = conn->data; - - httpStatus = Curl_http_connect(conn, done); - - /* Initialize the CSeq if not already done */ - if(data->state.rtsp_next_client_CSeq == 0) - data->state.rtsp_next_client_CSeq = 1; - if(data->state.rtsp_next_server_CSeq == 0) - data->state.rtsp_next_server_CSeq = 1; - - conn->proto.rtspc.rtp_channel = -1; - - return httpStatus; -} - -static CURLcode rtsp_disconnect(struct connectdata *conn, bool dead) -{ - (void) dead; - Curl_safefree(conn->proto.rtspc.rtp_buf); - return CURLE_OK; -} - - -static CURLcode rtsp_done(struct connectdata *conn, - CURLcode status, bool premature) -{ - struct SessionHandle *data = conn->data; - struct RTSP *rtsp = data->req.protop; - CURLcode httpStatus; - long CSeq_sent; - long CSeq_recv; - - /* Bypass HTTP empty-reply checks on receive */ - if(data->set.rtspreq == RTSPREQ_RECEIVE) - premature = TRUE; - - httpStatus = Curl_http_done(conn, status, premature); - - if(rtsp) { - /* Check the sequence numbers */ - CSeq_sent = rtsp->CSeq_sent; - CSeq_recv = rtsp->CSeq_recv; - if((data->set.rtspreq != RTSPREQ_RECEIVE) && (CSeq_sent != CSeq_recv)) { - failf(data, - "The CSeq of this request %ld did not match the response %ld", - CSeq_sent, CSeq_recv); - return CURLE_RTSP_CSEQ_ERROR; - } - else if(data->set.rtspreq == RTSPREQ_RECEIVE && - (conn->proto.rtspc.rtp_channel == -1)) { - infof(data, "Got an RTP Receive with a CSeq of %ld\n", CSeq_recv); - /* TODO CPC: Server -> Client logic here */ - } - } - - return httpStatus; -} - -static CURLcode rtsp_do(struct connectdata *conn, bool *done) -{ - struct SessionHandle *data = conn->data; - CURLcode result=CURLE_OK; - Curl_RtspReq rtspreq = data->set.rtspreq; - struct RTSP *rtsp = data->req.protop; - struct HTTP *http; - Curl_send_buffer *req_buffer; - curl_off_t postsize = 0; /* for ANNOUNCE and SET_PARAMETER */ - curl_off_t putsize = 0; /* for ANNOUNCE and SET_PARAMETER */ - - const char *p_request = NULL; - const char *p_session_id = NULL; - const char *p_accept = NULL; - const char *p_accept_encoding = NULL; - const char *p_range = NULL; - const char *p_referrer = NULL; - const char *p_stream_uri = NULL; - const char *p_transport = NULL; - const char *p_uagent = NULL; - const char *p_proxyuserpwd = NULL; - const char *p_userpwd = NULL; - - *done = TRUE; - - http = &(rtsp->http_wrapper); - /* Assert that no one has changed the RTSP struct in an evil way */ - DEBUGASSERT((void *)http == (void *)rtsp); - - rtsp->CSeq_sent = data->state.rtsp_next_client_CSeq; - rtsp->CSeq_recv = 0; - - /* Setup the 'p_request' pointer to the proper p_request string - * Since all RTSP requests are included here, there is no need to - * support custom requests like HTTP. - **/ - data->set.opt_no_body = TRUE; /* most requests don't contain a body */ - switch(rtspreq) { - default: - failf(data, "Got invalid RTSP request"); - return CURLE_BAD_FUNCTION_ARGUMENT; - case RTSPREQ_OPTIONS: - p_request = "OPTIONS"; - break; - case RTSPREQ_DESCRIBE: - p_request = "DESCRIBE"; - data->set.opt_no_body = FALSE; - break; - case RTSPREQ_ANNOUNCE: - p_request = "ANNOUNCE"; - break; - case RTSPREQ_SETUP: - p_request = "SETUP"; - break; - case RTSPREQ_PLAY: - p_request = "PLAY"; - break; - case RTSPREQ_PAUSE: - p_request = "PAUSE"; - break; - case RTSPREQ_TEARDOWN: - p_request = "TEARDOWN"; - break; - case RTSPREQ_GET_PARAMETER: - /* GET_PARAMETER's no_body status is determined later */ - p_request = "GET_PARAMETER"; - data->set.opt_no_body = FALSE; - break; - case RTSPREQ_SET_PARAMETER: - p_request = "SET_PARAMETER"; - break; - case RTSPREQ_RECORD: - p_request = "RECORD"; - break; - case RTSPREQ_RECEIVE: - p_request = ""; - /* Treat interleaved RTP as body*/ - data->set.opt_no_body = FALSE; - break; - case RTSPREQ_LAST: - failf(data, "Got invalid RTSP request: RTSPREQ_LAST"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - if(rtspreq == RTSPREQ_RECEIVE) { - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, - &http->readbytecount, -1, NULL); - - return result; - } - - p_session_id = data->set.str[STRING_RTSP_SESSION_ID]; - if(!p_session_id && - (rtspreq & ~(RTSPREQ_OPTIONS | RTSPREQ_DESCRIBE | RTSPREQ_SETUP))) { - failf(data, "Refusing to issue an RTSP request [%s] without a session ID.", - p_request); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - /* TODO: proxy? */ - - /* Stream URI. Default to server '*' if not specified */ - if(data->set.str[STRING_RTSP_STREAM_URI]) { - p_stream_uri = data->set.str[STRING_RTSP_STREAM_URI]; - } - else { - p_stream_uri = "*"; - } - - /* Transport Header for SETUP requests */ - p_transport = Curl_checkheaders(conn, "Transport:"); - if(rtspreq == RTSPREQ_SETUP && !p_transport) { - /* New Transport: setting? */ - if(data->set.str[STRING_RTSP_TRANSPORT]) { - Curl_safefree(conn->allocptr.rtsp_transport); - - conn->allocptr.rtsp_transport = - aprintf("Transport: %s\r\n", - data->set.str[STRING_RTSP_TRANSPORT]); - if(!conn->allocptr.rtsp_transport) - return CURLE_OUT_OF_MEMORY; - } - else { - failf(data, - "Refusing to issue an RTSP SETUP without a Transport: header."); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - p_transport = conn->allocptr.rtsp_transport; - } - - /* Accept Headers for DESCRIBE requests */ - if(rtspreq == RTSPREQ_DESCRIBE) { - /* Accept Header */ - p_accept = Curl_checkheaders(conn, "Accept:")? - NULL:"Accept: application/sdp\r\n"; - - /* Accept-Encoding header */ - if(!Curl_checkheaders(conn, "Accept-Encoding:") && - data->set.str[STRING_ENCODING]) { - Curl_safefree(conn->allocptr.accept_encoding); - conn->allocptr.accept_encoding = - aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]); - - if(!conn->allocptr.accept_encoding) - return CURLE_OUT_OF_MEMORY; - - p_accept_encoding = conn->allocptr.accept_encoding; - } - } - - /* The User-Agent string might have been allocated in url.c already, because - it might have been used in the proxy connect, but if we have got a header - with the user-agent string specified, we erase the previously made string - here. */ - if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) { - Curl_safefree(conn->allocptr.uagent); - conn->allocptr.uagent = NULL; - } - else if(!Curl_checkheaders(conn, "User-Agent:") && - data->set.str[STRING_USERAGENT]) { - p_uagent = conn->allocptr.uagent; - } - - /* setup the authentication headers */ - result = Curl_http_output_auth(conn, p_request, p_stream_uri, FALSE); - if(result) - return result; - - p_proxyuserpwd = conn->allocptr.proxyuserpwd; - p_userpwd = conn->allocptr.userpwd; - - /* Referrer */ - Curl_safefree(conn->allocptr.ref); - if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) - conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer); - else - conn->allocptr.ref = NULL; - - p_referrer = conn->allocptr.ref; - - /* - * Range Header - * Only applies to PLAY, PAUSE, RECORD - * - * Go ahead and use the Range stuff supplied for HTTP - */ - if(data->state.use_range && - (rtspreq & (RTSPREQ_PLAY | RTSPREQ_PAUSE | RTSPREQ_RECORD))) { - - /* Check to see if there is a range set in the custom headers */ - if(!Curl_checkheaders(conn, "Range:") && data->state.range) { - Curl_safefree(conn->allocptr.rangeline); - conn->allocptr.rangeline = aprintf("Range: %s\r\n", data->state.range); - p_range = conn->allocptr.rangeline; - } - } - - /* - * Sanity check the custom headers - */ - if(Curl_checkheaders(conn, "CSeq:")) { - failf(data, "CSeq cannot be set as a custom header."); - return CURLE_RTSP_CSEQ_ERROR; - } - if(Curl_checkheaders(conn, "Session:")) { - failf(data, "Session ID cannot be set as a custom header."); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - /* Initialize a dynamic send buffer */ - req_buffer = Curl_add_buffer_init(); - - if(!req_buffer) - return CURLE_OUT_OF_MEMORY; - - result = - Curl_add_bufferf(req_buffer, - "%s %s RTSP/1.0\r\n" /* Request Stream-URI RTSP/1.0 */ - "CSeq: %ld\r\n", /* CSeq */ - p_request, p_stream_uri, rtsp->CSeq_sent); - if(result) - return result; - - /* - * Rather than do a normal alloc line, keep the session_id unformatted - * to make comparison easier - */ - if(p_session_id) { - result = Curl_add_bufferf(req_buffer, "Session: %s\r\n", p_session_id); - if(result) - return result; - } - - /* - * Shared HTTP-like options - */ - result = Curl_add_bufferf(req_buffer, - "%s" /* transport */ - "%s" /* accept */ - "%s" /* accept-encoding */ - "%s" /* range */ - "%s" /* referrer */ - "%s" /* user-agent */ - "%s" /* proxyuserpwd */ - "%s" /* userpwd */ - , - p_transport ? p_transport : "", - p_accept ? p_accept : "", - p_accept_encoding ? p_accept_encoding : "", - p_range ? p_range : "", - p_referrer ? p_referrer : "", - p_uagent ? p_uagent : "", - p_proxyuserpwd ? p_proxyuserpwd : "", - p_userpwd ? p_userpwd : ""); - - /* - * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM - * with basic and digest, it will be freed anyway by the next request - */ - Curl_safefree (conn->allocptr.userpwd); - conn->allocptr.userpwd = NULL; - - if(result) - return result; - - if((rtspreq == RTSPREQ_SETUP) || (rtspreq == RTSPREQ_DESCRIBE)) { - result = Curl_add_timecondition(data, req_buffer); - if(result) - return result; - } - - result = Curl_add_custom_headers(conn, FALSE, req_buffer); - if(result) - return result; - - if(rtspreq == RTSPREQ_ANNOUNCE || - rtspreq == RTSPREQ_SET_PARAMETER || - rtspreq == RTSPREQ_GET_PARAMETER) { - - if(data->set.upload) { - putsize = data->state.infilesize; - data->set.httpreq = HTTPREQ_PUT; - - } - else { - postsize = (data->state.infilesize != -1)? - data->state.infilesize: - (data->set.postfields? (curl_off_t)strlen(data->set.postfields):0); - data->set.httpreq = HTTPREQ_POST; - } - - if(putsize > 0 || postsize > 0) { - /* As stated in the http comments, it is probably not wise to - * actually set a custom Content-Length in the headers */ - if(!Curl_checkheaders(conn, "Content-Length:")) { - result = Curl_add_bufferf(req_buffer, - "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", - (data->set.upload ? putsize : postsize)); - if(result) - return result; - } - - if(rtspreq == RTSPREQ_SET_PARAMETER || - rtspreq == RTSPREQ_GET_PARAMETER) { - if(!Curl_checkheaders(conn, "Content-Type:")) { - result = Curl_add_bufferf(req_buffer, - "Content-Type: text/parameters\r\n"); - if(result) - return result; - } - } - - if(rtspreq == RTSPREQ_ANNOUNCE) { - if(!Curl_checkheaders(conn, "Content-Type:")) { - result = Curl_add_bufferf(req_buffer, - "Content-Type: application/sdp\r\n"); - if(result) - return result; - } - } - - data->state.expect100header = FALSE; /* RTSP posts are simple/small */ - } - else if(rtspreq == RTSPREQ_GET_PARAMETER) { - /* Check for an empty GET_PARAMETER (heartbeat) request */ - data->set.httpreq = HTTPREQ_HEAD; - data->set.opt_no_body = TRUE; - } - } - - /* RTSP never allows chunked transfer */ - data->req.forbidchunk = TRUE; - /* Finish the request buffer */ - result = Curl_add_buffer(req_buffer, "\r\n", 2); - if(result) - return result; - - if(postsize > 0) { - result = Curl_add_buffer(req_buffer, data->set.postfields, - (size_t)postsize); - if(result) - return result; - } - - /* issue the request */ - result = Curl_add_buffer_send(req_buffer, conn, - &data->info.request_size, 0, FIRSTSOCKET); - if(result) { - failf(data, "Failed sending RTSP request"); - return result; - } - - Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, - putsize?FIRSTSOCKET:-1, - putsize?&http->writebytecount:NULL); - - /* Increment the CSeq on success */ - data->state.rtsp_next_client_CSeq++; - - if(http->writebytecount) { - /* if a request-body has been sent off, we make sure this progress is - noted properly */ - Curl_pgrsSetUploadCounter(data, http->writebytecount); - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - } - - return result; -} - - -static CURLcode rtsp_rtp_readwrite(struct SessionHandle *data, - struct connectdata *conn, - ssize_t *nread, - bool *readmore) { - struct SingleRequest *k = &data->req; - struct rtsp_conn *rtspc = &(conn->proto.rtspc); - - char *rtp; /* moving pointer to rtp data */ - ssize_t rtp_dataleft; /* how much data left to parse in this round */ - char *scratch; - CURLcode result; - - if(rtspc->rtp_buf) { - /* There was some leftover data the last time. Merge buffers */ - char *newptr = realloc(rtspc->rtp_buf, rtspc->rtp_bufsize + *nread); - if(!newptr) { - Curl_safefree(rtspc->rtp_buf); - rtspc->rtp_buf = NULL; - rtspc->rtp_bufsize = 0; - return CURLE_OUT_OF_MEMORY; - } - rtspc->rtp_buf = newptr; - memcpy(rtspc->rtp_buf + rtspc->rtp_bufsize, k->str, *nread); - rtspc->rtp_bufsize += *nread; - rtp = rtspc->rtp_buf; - rtp_dataleft = rtspc->rtp_bufsize; - } - else { - /* Just parse the request buffer directly */ - rtp = k->str; - rtp_dataleft = *nread; - } - - while((rtp_dataleft > 0) && - (rtp[0] == '$')) { - if(rtp_dataleft > 4) { - int rtp_length; - - /* Parse the header */ - /* The channel identifier immediately follows and is 1 byte */ - rtspc->rtp_channel = RTP_PKT_CHANNEL(rtp); - - /* The length is two bytes */ - rtp_length = RTP_PKT_LENGTH(rtp); - - if(rtp_dataleft < rtp_length + 4) { - /* Need more - incomplete payload*/ - *readmore = TRUE; - break; - } - else { - /* We have the full RTP interleaved packet - * Write out the header including the leading '$' */ - DEBUGF(infof(data, "RTP write channel %d rtp_length %d\n", - rtspc->rtp_channel, rtp_length)); - result = rtp_client_write(conn, &rtp[0], rtp_length + 4); - if(result) { - failf(data, "Got an error writing an RTP packet"); - *readmore = FALSE; - Curl_safefree(rtspc->rtp_buf); - rtspc->rtp_buf = NULL; - rtspc->rtp_bufsize = 0; - return result; - } - - /* Move forward in the buffer */ - rtp_dataleft -= rtp_length + 4; - rtp += rtp_length + 4; - - if(data->set.rtspreq == RTSPREQ_RECEIVE) { - /* If we are in a passive receive, give control back - * to the app as often as we can. - */ - k->keepon &= ~KEEP_RECV; - } - } - } - else { - /* Need more - incomplete header */ - *readmore = TRUE; - break; - } - } - - if(rtp_dataleft != 0 && rtp[0] == '$') { - DEBUGF(infof(data, "RTP Rewinding %zd %s\n", rtp_dataleft, - *readmore ? "(READMORE)" : "")); - - /* Store the incomplete RTP packet for a "rewind" */ - scratch = malloc(rtp_dataleft); - if(!scratch) { - Curl_safefree(rtspc->rtp_buf); - rtspc->rtp_buf = NULL; - rtspc->rtp_bufsize = 0; - return CURLE_OUT_OF_MEMORY; - } - memcpy(scratch, rtp, rtp_dataleft); - Curl_safefree(rtspc->rtp_buf); - rtspc->rtp_buf = scratch; - rtspc->rtp_bufsize = rtp_dataleft; - - /* As far as the transfer is concerned, this data is consumed */ - *nread = 0; - return CURLE_OK; - } - else { - /* Fix up k->str to point just after the last RTP packet */ - k->str += *nread - rtp_dataleft; - - /* either all of the data has been read or... - * rtp now points at the next byte to parse - */ - if(rtp_dataleft > 0) - DEBUGASSERT(k->str[0] == rtp[0]); - - DEBUGASSERT(rtp_dataleft <= *nread); /* sanity check */ - - *nread = rtp_dataleft; - } - - /* If we get here, we have finished with the leftover/merge buffer */ - Curl_safefree(rtspc->rtp_buf); - rtspc->rtp_buf = NULL; - rtspc->rtp_bufsize = 0; - - return CURLE_OK; -} - -static -CURLcode rtp_client_write(struct connectdata *conn, char *ptr, size_t len) -{ - struct SessionHandle *data = conn->data; - size_t wrote; - curl_write_callback writeit; - - if(len == 0) { - failf (data, "Cannot write a 0 size RTP packet."); - return CURLE_WRITE_ERROR; - } - - writeit = data->set.fwrite_rtp?data->set.fwrite_rtp:data->set.fwrite_func; - wrote = writeit(ptr, 1, len, data->set.rtp_out); - - if(CURL_WRITEFUNC_PAUSE == wrote) { - failf (data, "Cannot pause RTP"); - return CURLE_WRITE_ERROR; - } - - if(wrote != len) { - failf (data, "Failed writing RTP data"); - return CURLE_WRITE_ERROR; - } - - return CURLE_OK; -} - -CURLcode Curl_rtsp_parseheader(struct connectdata *conn, - char *header) -{ - struct SessionHandle *data = conn->data; - long CSeq = 0; - - if(checkprefix("CSeq:", header)) { - /* Store the received CSeq. Match is verified in rtsp_done */ - int nc = sscanf(&header[4], ": %ld", &CSeq); - if(nc == 1) { - struct RTSP *rtsp = data->req.protop; - rtsp->CSeq_recv = CSeq; /* mark the request */ - data->state.rtsp_CSeq_recv = CSeq; /* update the handle */ - } - else { - failf(data, "Unable to read the CSeq header: [%s]", header); - return CURLE_RTSP_CSEQ_ERROR; - } - } - else if(checkprefix("Session:", header)) { - char *start; - - /* Find the first non-space letter */ - start = header + 8; - while(*start && ISSPACE(*start)) - start++; - - if(!*start) { - failf(data, "Got a blank Session ID"); - } - else if(data->set.str[STRING_RTSP_SESSION_ID]) { - /* If the Session ID is set, then compare */ - if(strncmp(start, data->set.str[STRING_RTSP_SESSION_ID], - strlen(data->set.str[STRING_RTSP_SESSION_ID])) != 0) { - failf(data, "Got RTSP Session ID Line [%s], but wanted ID [%s]", - start, data->set.str[STRING_RTSP_SESSION_ID]); - return CURLE_RTSP_SESSION_ERROR; - } - } - else { - /* If the Session ID is not set, and we find it in a response, then - set it */ - - /* The session ID can be an alphanumeric or a 'safe' character - * - * RFC 2326 15.1 Base Syntax: - * safe = "\$" | "-" | "_" | "." | "+" - * */ - char *end = start; - while(*end && - (ISALNUM(*end) || *end == '-' || *end == '_' || *end == '.' || - *end == '+' || - (*end == '\\' && *(end + 1) && *(end + 1) == '$' && (++end, 1)))) - end++; - - /* Copy the id substring into a new buffer */ - data->set.str[STRING_RTSP_SESSION_ID] = malloc(end - start + 1); - if(data->set.str[STRING_RTSP_SESSION_ID] == NULL) - return CURLE_OUT_OF_MEMORY; - memcpy(data->set.str[STRING_RTSP_SESSION_ID], start, end - start); - (data->set.str[STRING_RTSP_SESSION_ID])[end - start] = '\0'; - } - } - return CURLE_OK; -} - -#endif /* CURL_DISABLE_RTSP */ diff --git a/Externals/curl/lib/rtsp.h b/Externals/curl/lib/rtsp.h deleted file mode 100644 index 5a8d5556fc..0000000000 --- a/Externals/curl/lib/rtsp.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef HEADER_CURL_RTSP_H -#define HEADER_CURL_RTSP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifndef CURL_DISABLE_RTSP - -extern const struct Curl_handler Curl_handler_rtsp; - -bool Curl_rtsp_connisdead(struct connectdata *check); -CURLcode Curl_rtsp_parseheader(struct connectdata *conn, char *header); - -#else -/* disabled */ -#define Curl_rtsp_parseheader(x,y) CURLE_NOT_BUILT_IN -#define Curl_rtsp_connisdead(x) TRUE - -#endif /* CURL_DISABLE_RTSP */ - -/* - * RTSP Connection data - * - * Currently, only used for tracking incomplete RTP data reads - */ -struct rtsp_conn { - char *rtp_buf; - ssize_t rtp_bufsize; - int rtp_channel; -}; - -/**************************************************************************** - * RTSP unique setup - ***************************************************************************/ -struct RTSP { - /* - * http_wrapper MUST be the first element of this structure for the wrap - * logic to work. In this way, we get a cheap polymorphism because - * &(data->state.proto.rtsp) == &(data->state.proto.http) per the C spec - * - * HTTP functions can safely treat this as an HTTP struct, but RTSP aware - * functions can also index into the later elements. - */ - struct HTTP http_wrapper; /*wrap HTTP to do the heavy lifting */ - - long CSeq_sent; /* CSeq of this request */ - long CSeq_recv; /* CSeq received */ -}; - - -#endif /* HEADER_CURL_RTSP_H */ - diff --git a/Externals/curl/lib/security.c b/Externals/curl/lib/security.c deleted file mode 100644 index 014bbf1b89..0000000000 --- a/Externals/curl/lib/security.c +++ /dev/null @@ -1,580 +0,0 @@ -/* This source code was modified by Martin Hedenfalk for - * use in Curl. His latest changes were done 2000-09-18. - * - * It has since been patched and modified a lot by Daniel Stenberg - * to make it better applied to curl conditions, and to make - * it not use globals, pollute name space and more. This source code awaits a - * rewrite to work around the paragraph 2 in the BSD licenses as explained - * below. - * - * Copyright (c) 1998, 1999 Kungliga Tekniska Hgskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * - * Copyright (C) 2001 - 2015, Daniel Stenberg, , et al. - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_FTP -#ifdef HAVE_GSSAPI - -#ifdef HAVE_NETDB_H -#include -#endif - -#ifdef HAVE_LIMITS_H -#include -#endif - -#include "urldata.h" -#include "curl_base64.h" -#include "curl_memory.h" -#include "curl_sec.h" -#include "ftp.h" -#include "sendf.h" -#include "rawstr.h" -#include "warnless.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -static const struct { - enum protection_level level; - const char *name; -} level_names[] = { - { PROT_CLEAR, "clear" }, - { PROT_SAFE, "safe" }, - { PROT_CONFIDENTIAL, "confidential" }, - { PROT_PRIVATE, "private" } -}; - -static enum protection_level -name_to_level(const char *name) -{ - int i; - for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++) - if(checkprefix(name, level_names[i].name)) - return level_names[i].level; - return PROT_NONE; -} - -/* Convert a protocol |level| to its char representation. - We take an int to catch programming mistakes. */ -static char level_to_char(int level) { - switch(level) { - case PROT_CLEAR: - return 'C'; - case PROT_SAFE: - return 'S'; - case PROT_CONFIDENTIAL: - return 'E'; - case PROT_PRIVATE: - return 'P'; - case PROT_CMD: - /* Fall through */ - default: - /* Those 2 cases should not be reached! */ - break; - } - DEBUGASSERT(0); - /* Default to the most secure alternative. */ - return 'P'; -} - -/* Send an FTP command defined by |message| and the optional arguments. The - function returns the ftp_code. If an error occurs, -1 is returned. */ -static int ftp_send_command(struct connectdata *conn, const char *message, ...) -{ - int ftp_code; - ssize_t nread=0; - va_list args; - char print_buffer[50]; - - va_start(args, message); - vsnprintf(print_buffer, sizeof(print_buffer), message, args); - va_end(args); - - if(Curl_ftpsendf(conn, print_buffer)) { - ftp_code = -1; - } - else { - if(Curl_GetFTPResponse(&nread, conn, &ftp_code)) - ftp_code = -1; - } - - (void)nread; /* Unused */ - return ftp_code; -} - -/* Read |len| from the socket |fd| and store it in |to|. Return a CURLcode - saying whether an error occurred or CURLE_OK if |len| was read. */ -static CURLcode -socket_read(curl_socket_t fd, void *to, size_t len) -{ - char *to_p = to; - CURLcode result; - ssize_t nread; - - while(len > 0) { - result = Curl_read_plain(fd, to_p, len, &nread); - if(!result) { - len -= nread; - to_p += nread; - } - else { - /* FIXME: We are doing a busy wait */ - if(result == CURLE_AGAIN) - continue; - return result; - } - } - return CURLE_OK; -} - - -/* Write |len| bytes from the buffer |to| to the socket |fd|. Return a - CURLcode saying whether an error occurred or CURLE_OK if |len| was - written. */ -static CURLcode -socket_write(struct connectdata *conn, curl_socket_t fd, const void *to, - size_t len) -{ - const char *to_p = to; - CURLcode result; - ssize_t written; - - while(len > 0) { - result = Curl_write_plain(conn, fd, to_p, len, &written); - if(!result) { - len -= written; - to_p += written; - } - else { - /* FIXME: We are doing a busy wait */ - if(result == CURLE_AGAIN) - continue; - return result; - } - } - return CURLE_OK; -} - -static CURLcode read_data(struct connectdata *conn, - curl_socket_t fd, - struct krb5buffer *buf) -{ - int len; - void* tmp; - CURLcode result; - - result = socket_read(fd, &len, sizeof(len)); - if(result) - return result; - - len = ntohl(len); - tmp = realloc(buf->data, len); - if(tmp == NULL) - return CURLE_OUT_OF_MEMORY; - - buf->data = tmp; - result = socket_read(fd, buf->data, len); - if(result) - return result; - buf->size = conn->mech->decode(conn->app_data, buf->data, len, - conn->data_prot, conn); - buf->index = 0; - return CURLE_OK; -} - -static size_t -buffer_read(struct krb5buffer *buf, void *data, size_t len) -{ - if(buf->size - buf->index < len) - len = buf->size - buf->index; - memcpy(data, (char*)buf->data + buf->index, len); - buf->index += len; - return len; -} - -/* Matches Curl_recv signature */ -static ssize_t sec_recv(struct connectdata *conn, int sockindex, - char *buffer, size_t len, CURLcode *err) -{ - size_t bytes_read; - size_t total_read = 0; - curl_socket_t fd = conn->sock[sockindex]; - - *err = CURLE_OK; - - /* Handle clear text response. */ - if(conn->sec_complete == 0 || conn->data_prot == PROT_CLEAR) - return read(fd, buffer, len); - - if(conn->in_buffer.eof_flag) { - conn->in_buffer.eof_flag = 0; - return 0; - } - - bytes_read = buffer_read(&conn->in_buffer, buffer, len); - len -= bytes_read; - total_read += bytes_read; - buffer += bytes_read; - - while(len > 0) { - if(read_data(conn, fd, &conn->in_buffer)) - return -1; - if(conn->in_buffer.size == 0) { - if(bytes_read > 0) - conn->in_buffer.eof_flag = 1; - return bytes_read; - } - bytes_read = buffer_read(&conn->in_buffer, buffer, len); - len -= bytes_read; - total_read += bytes_read; - buffer += bytes_read; - } - /* FIXME: Check for overflow */ - return total_read; -} - -/* Send |length| bytes from |from| to the |fd| socket taking care of encoding - and negociating with the server. |from| can be NULL. */ -/* FIXME: We don't check for errors nor report any! */ -static void do_sec_send(struct connectdata *conn, curl_socket_t fd, - const char *from, int length) -{ - int bytes, htonl_bytes; /* 32-bit integers for htonl */ - char *buffer = NULL; - char *cmd_buffer; - size_t cmd_size = 0; - CURLcode error; - enum protection_level prot_level = conn->data_prot; - bool iscmd = (prot_level == PROT_CMD)?TRUE:FALSE; - - DEBUGASSERT(prot_level > PROT_NONE && prot_level < PROT_LAST); - - if(iscmd) { - if(!strncmp(from, "PASS ", 5) || !strncmp(from, "ACCT ", 5)) - prot_level = PROT_PRIVATE; - else - prot_level = conn->command_prot; - } - bytes = conn->mech->encode(conn->app_data, from, length, prot_level, - (void**)&buffer); - if(!buffer || bytes <= 0) - return; /* error */ - - if(iscmd) { - error = Curl_base64_encode(conn->data, buffer, curlx_sitouz(bytes), - &cmd_buffer, &cmd_size); - if(error) { - free(buffer); - return; /* error */ - } - if(cmd_size > 0) { - static const char *enc = "ENC "; - static const char *mic = "MIC "; - if(prot_level == PROT_PRIVATE) - socket_write(conn, fd, enc, 4); - else - socket_write(conn, fd, mic, 4); - - socket_write(conn, fd, cmd_buffer, cmd_size); - socket_write(conn, fd, "\r\n", 2); - infof(conn->data, "Send: %s%s\n", prot_level == PROT_PRIVATE?enc:mic, - cmd_buffer); - free(cmd_buffer); - } - } - else { - htonl_bytes = htonl(bytes); - socket_write(conn, fd, &htonl_bytes, sizeof(htonl_bytes)); - socket_write(conn, fd, buffer, curlx_sitouz(bytes)); - } - free(buffer); -} - -static ssize_t sec_write(struct connectdata *conn, curl_socket_t fd, - const char *buffer, size_t length) -{ - ssize_t tx = 0, len = conn->buffer_size; - - len -= conn->mech->overhead(conn->app_data, conn->data_prot, - curlx_sztosi(len)); - if(len <= 0) - len = length; - while(length) { - if(length < (size_t)len) - len = length; - - do_sec_send(conn, fd, buffer, curlx_sztosi(len)); - length -= len; - buffer += len; - tx += len; - } - return tx; -} - -/* Matches Curl_send signature */ -static ssize_t sec_send(struct connectdata *conn, int sockindex, - const void *buffer, size_t len, CURLcode *err) -{ - curl_socket_t fd = conn->sock[sockindex]; - *err = CURLE_OK; - return sec_write(conn, fd, buffer, len); -} - -int Curl_sec_read_msg(struct connectdata *conn, char *buffer, - enum protection_level level) -{ - /* decoded_len should be size_t or ssize_t but conn->mech->decode returns an - int */ - int decoded_len; - char *buf; - int ret_code = 0; - size_t decoded_sz = 0; - CURLcode error; - - DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); - - error = Curl_base64_decode(buffer + 4, (unsigned char **)&buf, &decoded_sz); - if(error || decoded_sz == 0) - return -1; - - if(decoded_sz > (size_t)INT_MAX) { - free(buf); - return -1; - } - decoded_len = curlx_uztosi(decoded_sz); - - decoded_len = conn->mech->decode(conn->app_data, buf, decoded_len, - level, conn); - if(decoded_len <= 0) { - free(buf); - return -1; - } - - if(conn->data->set.verbose) { - buf[decoded_len] = '\n'; - Curl_debug(conn->data, CURLINFO_HEADER_IN, buf, decoded_len + 1, conn); - } - - buf[decoded_len] = '\0'; - if(decoded_len <= 3) - /* suspiciously short */ - return 0; - - if(buf[3] != '-') - /* safe to ignore return code */ - (void)sscanf(buf, "%d", &ret_code); - - if(buf[decoded_len - 1] == '\n') - buf[decoded_len - 1] = '\0'; - /* FIXME: Is |buffer| length always greater than |decoded_len|? */ - strcpy(buffer, buf); - free(buf); - return ret_code; -} - -/* FIXME: The error code returned here is never checked. */ -static int sec_set_protection_level(struct connectdata *conn) -{ - int code; - char* pbsz; - static unsigned int buffer_size = 1 << 20; /* 1048576 */ - enum protection_level level = conn->request_data_prot; - - DEBUGASSERT(level > PROT_NONE && level < PROT_LAST); - - if(!conn->sec_complete) { - infof(conn->data, "Trying to change the protection level after the" - "completion of the data exchange.\n"); - return -1; - } - - /* Bail out if we try to set up the same level */ - if(conn->data_prot == level) - return 0; - - if(level) { - code = ftp_send_command(conn, "PBSZ %u", buffer_size); - if(code < 0) - return -1; - - if(code/100 != 2) { - failf(conn->data, "Failed to set the protection's buffer size."); - return -1; - } - conn->buffer_size = buffer_size; - - pbsz = strstr(conn->data->state.buffer, "PBSZ="); - if(pbsz) { - /* ignore return code, use default value if it fails */ - (void)sscanf(pbsz, "PBSZ=%u", &buffer_size); - if(buffer_size < conn->buffer_size) - conn->buffer_size = buffer_size; - } - } - - /* Now try to negiociate the protection level. */ - code = ftp_send_command(conn, "PROT %c", level_to_char(level)); - - if(code < 0) - return -1; - - if(code/100 != 2) { - failf(conn->data, "Failed to set the protection level."); - return -1; - } - - conn->data_prot = level; - if(level == PROT_PRIVATE) - conn->command_prot = level; - - return 0; -} - -int -Curl_sec_request_prot(struct connectdata *conn, const char *level) -{ - enum protection_level l = name_to_level(level); - if(l == PROT_NONE) - return -1; - DEBUGASSERT(l > PROT_NONE && l < PROT_LAST); - conn->request_data_prot = l; - return 0; -} - -static CURLcode choose_mech(struct connectdata *conn) -{ - int ret; - struct SessionHandle *data = conn->data; - void *tmp_allocation; - const struct Curl_sec_client_mech *mech = &Curl_krb5_client_mech; - - tmp_allocation = realloc(conn->app_data, mech->size); - if(tmp_allocation == NULL) { - failf(data, "Failed realloc of size %u", mech->size); - mech = NULL; - return CURLE_OUT_OF_MEMORY; - } - conn->app_data = tmp_allocation; - - if(mech->init) { - ret = mech->init(conn->app_data); - if(ret) { - infof(data, "Failed initialization for %s. Skipping it.\n", - mech->name); - return CURLE_FAILED_INIT; - } - } - - infof(data, "Trying mechanism %s...\n", mech->name); - ret = ftp_send_command(conn, "AUTH %s", mech->name); - if(ret < 0) - /* FIXME: This error is too generic but it is OK for now. */ - return CURLE_COULDNT_CONNECT; - - if(ret/100 != 3) { - switch(ret) { - case 504: - infof(data, "Mechanism %s is not supported by the server (server " - "returned ftp code: 504).\n", mech->name); - break; - case 534: - infof(data, "Mechanism %s was rejected by the server (server returned " - "ftp code: 534).\n", mech->name); - break; - default: - if(ret/100 == 5) { - infof(data, "server does not support the security extensions\n"); - return CURLE_USE_SSL_FAILED; - } - break; - } - return CURLE_LOGIN_DENIED; - } - - /* Authenticate */ - ret = mech->auth(conn->app_data, conn); - - if(ret != AUTH_CONTINUE) { - if(ret != AUTH_OK) { - /* Mechanism has dumped the error to stderr, don't error here. */ - return -1; - } - DEBUGASSERT(ret == AUTH_OK); - - conn->mech = mech; - conn->sec_complete = 1; - conn->recv[FIRSTSOCKET] = sec_recv; - conn->send[FIRSTSOCKET] = sec_send; - conn->recv[SECONDARYSOCKET] = sec_recv; - conn->send[SECONDARYSOCKET] = sec_send; - conn->command_prot = PROT_SAFE; - /* Set the requested protection level */ - /* BLOCKING */ - (void)sec_set_protection_level(conn); - } - - return CURLE_OK; -} - -CURLcode -Curl_sec_login(struct connectdata *conn) -{ - return choose_mech(conn); -} - - -void -Curl_sec_end(struct connectdata *conn) -{ - if(conn->mech != NULL && conn->mech->end) - conn->mech->end(conn->app_data); - free(conn->app_data); - conn->app_data = NULL; - if(conn->in_buffer.data) { - free(conn->in_buffer.data); - conn->in_buffer.data = NULL; - conn->in_buffer.size = 0; - conn->in_buffer.index = 0; - /* FIXME: Is this really needed? */ - conn->in_buffer.eof_flag = 0; - } - conn->sec_complete = 0; - conn->data_prot = PROT_CLEAR; - conn->mech = NULL; -} - -#endif /* HAVE_GSSAPI */ - -#endif /* CURL_DISABLE_FTP */ diff --git a/Externals/curl/lib/select.c b/Externals/curl/lib/select.c deleted file mode 100644 index abf55d878f..0000000000 --- a/Externals/curl/lib/select.c +++ /dev/null @@ -1,578 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#if !defined(HAVE_SELECT) && !defined(HAVE_POLL_FINE) -#error "We can't compile without select() or poll() support." -#endif - -#if defined(__BEOS__) && !defined(__HAIKU__) -/* BeOS has FD_SET defined in socket.h */ -#include -#endif - -#ifdef MSDOS -#include /* delay() */ -#endif - -#ifdef __VXWORKS__ -#include /* bzero() in FD_SET */ -#endif - -#include - -#include "urldata.h" -#include "connect.h" -#include "select.h" -#include "warnless.h" - -/* Convenience local macros */ - -#define elapsed_ms (int)curlx_tvdiff(curlx_tvnow(), initial_tv) - -int Curl_ack_eintr = 0; -#define error_not_EINTR (Curl_ack_eintr || error != EINTR) - -/* - * Internal function used for waiting a specific amount of ms - * in Curl_socket_ready() and Curl_poll() when no file descriptor - * is provided to wait on, just being used to delay execution. - * WinSock select() and poll() timeout mechanisms need a valid - * socket descriptor in a not null file descriptor set to work. - * Waiting indefinitely with this function is not allowed, a - * zero or negative timeout value will return immediately. - * Timeout resolution, accuracy, as well as maximum supported - * value is system dependent, neither factor is a citical issue - * for the intended use of this function in the library. - * - * Return values: - * -1 = system call error, invalid timeout value, or interrupted - * 0 = specified timeout has elapsed - */ -int Curl_wait_ms(int timeout_ms) -{ -#if !defined(MSDOS) && !defined(USE_WINSOCK) -#ifndef HAVE_POLL_FINE - struct timeval pending_tv; -#endif - struct timeval initial_tv; - int pending_ms; - int error; -#endif - int r = 0; - - if(!timeout_ms) - return 0; - if(timeout_ms < 0) { - SET_SOCKERRNO(EINVAL); - return -1; - } -#if defined(MSDOS) - delay(timeout_ms); -#elif defined(USE_WINSOCK) - Sleep(timeout_ms); -#else - pending_ms = timeout_ms; - initial_tv = curlx_tvnow(); - do { -#if defined(HAVE_POLL_FINE) - r = poll(NULL, 0, pending_ms); -#else - pending_tv.tv_sec = pending_ms / 1000; - pending_tv.tv_usec = (pending_ms % 1000) * 1000; - r = select(0, NULL, NULL, NULL, &pending_tv); -#endif /* HAVE_POLL_FINE */ - if(r != -1) - break; - error = SOCKERRNO; - if(error && error_not_EINTR) - break; - pending_ms = timeout_ms - elapsed_ms; - if(pending_ms <= 0) { - r = 0; /* Simulate a "call timed out" case */ - break; - } - } while(r == -1); -#endif /* USE_WINSOCK */ - if(r) - r = -1; - return r; -} - -/* - * Wait for read or write events on a set of file descriptors. It uses poll() - * when a fine poll() is available, in order to avoid limits with FD_SETSIZE, - * otherwise select() is used. An error is returned if select() is being used - * and a file descriptor is too large for FD_SETSIZE. - * - * A negative timeout value makes this function wait indefinitely, - * unles no valid file descriptor is given, when this happens the - * negative timeout is ignored and the function times out immediately. - * - * Return values: - * -1 = system call error or fd >= FD_SETSIZE - * 0 = timeout - * [bitmask] = action as described below - * - * CURL_CSELECT_IN - first socket is readable - * CURL_CSELECT_IN2 - second socket is readable - * CURL_CSELECT_OUT - write socket is writable - * CURL_CSELECT_ERR - an error condition occurred - */ -int Curl_socket_check(curl_socket_t readfd0, /* two sockets to read from */ - curl_socket_t readfd1, - curl_socket_t writefd, /* socket to write to */ - long timeout_ms) /* milliseconds to wait */ -{ -#ifdef HAVE_POLL_FINE - struct pollfd pfd[3]; - int num; -#else - struct timeval pending_tv; - struct timeval *ptimeout; - fd_set fds_read; - fd_set fds_write; - fd_set fds_err; - curl_socket_t maxfd; -#endif - struct timeval initial_tv = {0, 0}; - int pending_ms = 0; - int error; - int r; - int ret; - - if((readfd0 == CURL_SOCKET_BAD) && (readfd1 == CURL_SOCKET_BAD) && - (writefd == CURL_SOCKET_BAD)) { - /* no sockets, just wait */ - r = Curl_wait_ms((int)timeout_ms); - return r; - } - - /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed - time in this function does not need to be measured. This happens - when function is called with a zero timeout or a negative timeout - value indicating a blocking call should be performed. */ - - if(timeout_ms > 0) { - pending_ms = (int)timeout_ms; - initial_tv = curlx_tvnow(); - } - -#ifdef HAVE_POLL_FINE - - num = 0; - if(readfd0 != CURL_SOCKET_BAD) { - pfd[num].fd = readfd0; - pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI; - pfd[num].revents = 0; - num++; - } - if(readfd1 != CURL_SOCKET_BAD) { - pfd[num].fd = readfd1; - pfd[num].events = POLLRDNORM|POLLIN|POLLRDBAND|POLLPRI; - pfd[num].revents = 0; - num++; - } - if(writefd != CURL_SOCKET_BAD) { - pfd[num].fd = writefd; - pfd[num].events = POLLWRNORM|POLLOUT; - pfd[num].revents = 0; - num++; - } - - do { - if(timeout_ms < 0) - pending_ms = -1; - else if(!timeout_ms) - pending_ms = 0; - r = poll(pfd, num, pending_ms); - if(r != -1) - break; - error = SOCKERRNO; - if(error && error_not_EINTR) - break; - if(timeout_ms > 0) { - pending_ms = (int)(timeout_ms - elapsed_ms); - if(pending_ms <= 0) { - r = 0; /* Simulate a "call timed out" case */ - break; - } - } - } while(r == -1); - - if(r < 0) - return -1; - if(r == 0) - return 0; - - ret = 0; - num = 0; - if(readfd0 != CURL_SOCKET_BAD) { - if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) - ret |= CURL_CSELECT_IN; - if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) - ret |= CURL_CSELECT_ERR; - num++; - } - if(readfd1 != CURL_SOCKET_BAD) { - if(pfd[num].revents & (POLLRDNORM|POLLIN|POLLERR|POLLHUP)) - ret |= CURL_CSELECT_IN2; - if(pfd[num].revents & (POLLRDBAND|POLLPRI|POLLNVAL)) - ret |= CURL_CSELECT_ERR; - num++; - } - if(writefd != CURL_SOCKET_BAD) { - if(pfd[num].revents & (POLLWRNORM|POLLOUT)) - ret |= CURL_CSELECT_OUT; - if(pfd[num].revents & (POLLERR|POLLHUP|POLLNVAL)) - ret |= CURL_CSELECT_ERR; - } - - return ret; - -#else /* HAVE_POLL_FINE */ - - FD_ZERO(&fds_err); - maxfd = (curl_socket_t)-1; - - FD_ZERO(&fds_read); - if(readfd0 != CURL_SOCKET_BAD) { - VERIFY_SOCK(readfd0); - FD_SET(readfd0, &fds_read); - FD_SET(readfd0, &fds_err); - maxfd = readfd0; - } - if(readfd1 != CURL_SOCKET_BAD) { - VERIFY_SOCK(readfd1); - FD_SET(readfd1, &fds_read); - FD_SET(readfd1, &fds_err); - if(readfd1 > maxfd) - maxfd = readfd1; - } - - FD_ZERO(&fds_write); - if(writefd != CURL_SOCKET_BAD) { - VERIFY_SOCK(writefd); - FD_SET(writefd, &fds_write); - FD_SET(writefd, &fds_err); - if(writefd > maxfd) - maxfd = writefd; - } - - ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; - - do { - if(timeout_ms > 0) { - pending_tv.tv_sec = pending_ms / 1000; - pending_tv.tv_usec = (pending_ms % 1000) * 1000; - } - else if(!timeout_ms) { - pending_tv.tv_sec = 0; - pending_tv.tv_usec = 0; - } - - /* WinSock select() must not be called with an fd_set that contains zero - fd flags, or it will return WSAEINVAL. But, it also can't be called - with no fd_sets at all! From the documentation: - - Any two of the parameters, readfds, writefds, or exceptfds, can be - given as null. At least one must be non-null, and any non-null - descriptor set must contain at least one handle to a socket. - - We know that we have at least one bit set in at least two fd_sets in - this case, but we may have no bits set in either fds_read or fd_write, - so check for that and handle it. Luckily, with WinSock, we can _also_ - ask how many bits are set on an fd_set. - - It is unclear why WinSock doesn't just handle this for us instead of - calling this an error. - - Note also that WinSock ignores the first argument, so we don't worry - about the fact that maxfd is computed incorrectly with WinSock (since - curl_socket_t is unsigned in such cases and thus -1 is the largest - value). - */ -#ifdef USE_WINSOCK - r = select((int)maxfd + 1, - fds_read.fd_count ? &fds_read : NULL, - fds_write.fd_count ? &fds_write : NULL, - &fds_err, ptimeout); -#else - r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); -#endif - - if(r != -1) - break; - error = SOCKERRNO; - if(error && error_not_EINTR) - break; - if(timeout_ms > 0) { - pending_ms = timeout_ms - elapsed_ms; - if(pending_ms <= 0) { - r = 0; /* Simulate a "call timed out" case */ - break; - } - } - } while(r == -1); - - if(r < 0) - return -1; - if(r == 0) - return 0; - - ret = 0; - if(readfd0 != CURL_SOCKET_BAD) { - if(FD_ISSET(readfd0, &fds_read)) - ret |= CURL_CSELECT_IN; - if(FD_ISSET(readfd0, &fds_err)) - ret |= CURL_CSELECT_ERR; - } - if(readfd1 != CURL_SOCKET_BAD) { - if(FD_ISSET(readfd1, &fds_read)) - ret |= CURL_CSELECT_IN2; - if(FD_ISSET(readfd1, &fds_err)) - ret |= CURL_CSELECT_ERR; - } - if(writefd != CURL_SOCKET_BAD) { - if(FD_ISSET(writefd, &fds_write)) - ret |= CURL_CSELECT_OUT; - if(FD_ISSET(writefd, &fds_err)) - ret |= CURL_CSELECT_ERR; - } - - return ret; - -#endif /* HAVE_POLL_FINE */ - -} - -/* - * This is a wrapper around poll(). If poll() does not exist, then - * select() is used instead. An error is returned if select() is - * being used and a file descriptor is too large for FD_SETSIZE. - * A negative timeout value makes this function wait indefinitely, - * unles no valid file descriptor is given, when this happens the - * negative timeout is ignored and the function times out immediately. - * - * Return values: - * -1 = system call error or fd >= FD_SETSIZE - * 0 = timeout - * N = number of structures with non zero revent fields - */ -int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms) -{ -#ifndef HAVE_POLL_FINE - struct timeval pending_tv; - struct timeval *ptimeout; - fd_set fds_read; - fd_set fds_write; - fd_set fds_err; - curl_socket_t maxfd; -#endif - struct timeval initial_tv = {0, 0}; - bool fds_none = TRUE; - unsigned int i; - int pending_ms = 0; - int error; - int r; - - if(ufds) { - for(i = 0; i < nfds; i++) { - if(ufds[i].fd != CURL_SOCKET_BAD) { - fds_none = FALSE; - break; - } - } - } - if(fds_none) { - r = Curl_wait_ms(timeout_ms); - return r; - } - - /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed - time in this function does not need to be measured. This happens - when function is called with a zero timeout or a negative timeout - value indicating a blocking call should be performed. */ - - if(timeout_ms > 0) { - pending_ms = timeout_ms; - initial_tv = curlx_tvnow(); - } - -#ifdef HAVE_POLL_FINE - - do { - if(timeout_ms < 0) - pending_ms = -1; - else if(!timeout_ms) - pending_ms = 0; - r = poll(ufds, nfds, pending_ms); - if(r != -1) - break; - error = SOCKERRNO; - if(error && error_not_EINTR) - break; - if(timeout_ms > 0) { - pending_ms = timeout_ms - elapsed_ms; - if(pending_ms <= 0) { - r = 0; /* Simulate a "call timed out" case */ - break; - } - } - } while(r == -1); - - if(r < 0) - return -1; - if(r == 0) - return 0; - - for(i = 0; i < nfds; i++) { - if(ufds[i].fd == CURL_SOCKET_BAD) - continue; - if(ufds[i].revents & POLLHUP) - ufds[i].revents |= POLLIN; - if(ufds[i].revents & POLLERR) - ufds[i].revents |= (POLLIN|POLLOUT); - } - -#else /* HAVE_POLL_FINE */ - - FD_ZERO(&fds_read); - FD_ZERO(&fds_write); - FD_ZERO(&fds_err); - maxfd = (curl_socket_t)-1; - - for(i = 0; i < nfds; i++) { - ufds[i].revents = 0; - if(ufds[i].fd == CURL_SOCKET_BAD) - continue; - VERIFY_SOCK(ufds[i].fd); - if(ufds[i].events & (POLLIN|POLLOUT|POLLPRI| - POLLRDNORM|POLLWRNORM|POLLRDBAND)) { - if(ufds[i].fd > maxfd) - maxfd = ufds[i].fd; - if(ufds[i].events & (POLLRDNORM|POLLIN)) - FD_SET(ufds[i].fd, &fds_read); - if(ufds[i].events & (POLLWRNORM|POLLOUT)) - FD_SET(ufds[i].fd, &fds_write); - if(ufds[i].events & (POLLRDBAND|POLLPRI)) - FD_SET(ufds[i].fd, &fds_err); - } - } - -#ifdef USE_WINSOCK - /* WinSock select() can't handle zero events. See the comment about this in - Curl_check_socket(). */ - if(fds_read.fd_count == 0 && fds_write.fd_count == 0 - && fds_err.fd_count == 0) { - r = Curl_wait_ms(timeout_ms); - return r; - } -#endif - - ptimeout = (timeout_ms < 0) ? NULL : &pending_tv; - - do { - if(timeout_ms > 0) { - pending_tv.tv_sec = pending_ms / 1000; - pending_tv.tv_usec = (pending_ms % 1000) * 1000; - } - else if(!timeout_ms) { - pending_tv.tv_sec = 0; - pending_tv.tv_usec = 0; - } - -#ifdef USE_WINSOCK - r = select((int)maxfd + 1, - /* WinSock select() can't handle fd_sets with zero bits set, so - don't give it such arguments. See the comment about this in - Curl_check_socket(). - */ - fds_read.fd_count ? &fds_read : NULL, - fds_write.fd_count ? &fds_write : NULL, - fds_err.fd_count ? &fds_err : NULL, ptimeout); -#else - r = select((int)maxfd + 1, &fds_read, &fds_write, &fds_err, ptimeout); -#endif - if(r != -1) - break; - error = SOCKERRNO; - if(error && error_not_EINTR) - break; - if(timeout_ms > 0) { - pending_ms = timeout_ms - elapsed_ms; - if(pending_ms <= 0) { - r = 0; /* Simulate a "call timed out" case */ - break; - } - } - } while(r == -1); - - if(r < 0) - return -1; - if(r == 0) - return 0; - - r = 0; - for(i = 0; i < nfds; i++) { - ufds[i].revents = 0; - if(ufds[i].fd == CURL_SOCKET_BAD) - continue; - if(FD_ISSET(ufds[i].fd, &fds_read)) - ufds[i].revents |= POLLIN; - if(FD_ISSET(ufds[i].fd, &fds_write)) - ufds[i].revents |= POLLOUT; - if(FD_ISSET(ufds[i].fd, &fds_err)) - ufds[i].revents |= POLLPRI; - if(ufds[i].revents != 0) - r++; - } - -#endif /* HAVE_POLL_FINE */ - - return r; -} - -#ifdef TPF -/* - * This is a replacement for select() on the TPF platform. - * It is used whenever libcurl calls select(). - * The call below to tpf_process_signals() is required because - * TPF's select calls are not signal interruptible. - * - * Return values are the same as select's. - */ -int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, - fd_set* excepts, struct timeval* tv) -{ - int rc; - - rc = tpf_select_bsd(maxfds, reads, writes, excepts, tv); - tpf_process_signals(); - return rc; -} -#endif /* TPF */ diff --git a/Externals/curl/lib/select.h b/Externals/curl/lib/select.h deleted file mode 100644 index 695bb69cc8..0000000000 --- a/Externals/curl/lib/select.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef HEADER_CURL_SELECT_H -#define HEADER_CURL_SELECT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_SYS_POLL_H -#include -#elif defined(HAVE_POLL_H) -#include -#endif - -/* - * Definition of pollfd struct and constants for platforms lacking them. - */ - -#if !defined(HAVE_STRUCT_POLLFD) && \ - !defined(HAVE_SYS_POLL_H) && \ - !defined(HAVE_POLL_H) - -#define POLLIN 0x01 -#define POLLPRI 0x02 -#define POLLOUT 0x04 -#define POLLERR 0x08 -#define POLLHUP 0x10 -#define POLLNVAL 0x20 - -struct pollfd -{ - curl_socket_t fd; - short events; - short revents; -}; - -#endif - -#ifndef POLLRDNORM -#define POLLRDNORM POLLIN -#endif - -#ifndef POLLWRNORM -#define POLLWRNORM POLLOUT -#endif - -#ifndef POLLRDBAND -#define POLLRDBAND POLLPRI -#endif - -/* there are three CSELECT defines that are defined in the public header that - are exposed to users, but this *IN2 bit is only ever used internally and - therefore defined here */ -#define CURL_CSELECT_IN2 (CURL_CSELECT_ERR << 1) - -int Curl_socket_check(curl_socket_t readfd, curl_socket_t readfd2, - curl_socket_t writefd, - long timeout_ms); - -/* provide the former API internally */ -#define Curl_socket_ready(x,y,z) \ - Curl_socket_check(x, CURL_SOCKET_BAD, y, z) - -int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms); - -/* On non-DOS and non-Winsock platforms, when Curl_ack_eintr is set, - * EINTR condition is honored and function might exit early without - * awaiting full timeout. Otherwise EINTR will be ignored and full - * timeout will elapse. */ -extern int Curl_ack_eintr; - -int Curl_wait_ms(int timeout_ms); - -#ifdef TPF -int tpf_select_libcurl(int maxfds, fd_set* reads, fd_set* writes, - fd_set* excepts, struct timeval* tv); -#endif - -/* Winsock and TPF sockets are not in range [0..FD_SETSIZE-1], which - unfortunately makes it impossible for us to easily check if they're valid -*/ -#if defined(USE_WINSOCK) || defined(TPF) -#define VALID_SOCK(x) 1 -#define VERIFY_SOCK(x) Curl_nop_stmt -#else -#define VALID_SOCK(s) (((s) >= 0) && ((s) < FD_SETSIZE)) -#define VERIFY_SOCK(x) do { \ - if(!VALID_SOCK(x)) { \ - SET_SOCKERRNO(EINVAL); \ - return -1; \ - } \ -} WHILE_FALSE -#endif - -#endif /* HEADER_CURL_SELECT_H */ - diff --git a/Externals/curl/lib/sendf.c b/Externals/curl/lib/sendf.c deleted file mode 100644 index 22f3bf27cc..0000000000 --- a/Externals/curl/lib/sendf.c +++ /dev/null @@ -1,826 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "urldata.h" -#include "sendf.h" -#include "connect.h" -#include "vtls/vtls.h" -#include "ssh.h" -#include "multiif.h" -#include "non-ascii.h" -#include "strerror.h" -#include "select.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifdef CURL_DO_LINEEND_CONV -/* - * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF - * (\n), with special processing for CRLF sequences that are split between two - * blocks of data. Remaining, bare CRs are changed to LFs. The possibly new - * size of the data is returned. - */ -static size_t convert_lineends(struct SessionHandle *data, - char *startPtr, size_t size) -{ - char *inPtr, *outPtr; - - /* sanity check */ - if((startPtr == NULL) || (size < 1)) { - return size; - } - - if(data->state.prev_block_had_trailing_cr) { - /* The previous block of incoming data - had a trailing CR, which was turned into a LF. */ - if(*startPtr == '\n') { - /* This block of incoming data starts with the - previous block's LF so get rid of it */ - memmove(startPtr, startPtr+1, size-1); - size--; - /* and it wasn't a bare CR but a CRLF conversion instead */ - data->state.crlf_conversions++; - } - data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */ - } - - /* find 1st CR, if any */ - inPtr = outPtr = memchr(startPtr, '\r', size); - if(inPtr) { - /* at least one CR, now look for CRLF */ - while(inPtr < (startPtr+size-1)) { - /* note that it's size-1, so we'll never look past the last byte */ - if(memcmp(inPtr, "\r\n", 2) == 0) { - /* CRLF found, bump past the CR and copy the NL */ - inPtr++; - *outPtr = *inPtr; - /* keep track of how many CRLFs we converted */ - data->state.crlf_conversions++; - } - else { - if(*inPtr == '\r') { - /* lone CR, move LF instead */ - *outPtr = '\n'; - } - else { - /* not a CRLF nor a CR, just copy whatever it is */ - *outPtr = *inPtr; - } - } - outPtr++; - inPtr++; - } /* end of while loop */ - - if(inPtr < startPtr+size) { - /* handle last byte */ - if(*inPtr == '\r') { - /* deal with a CR at the end of the buffer */ - *outPtr = '\n'; /* copy a NL instead */ - /* note that a CRLF might be split across two blocks */ - data->state.prev_block_had_trailing_cr = TRUE; - } - else { - /* copy last byte */ - *outPtr = *inPtr; - } - outPtr++; - } - if(outPtr < startPtr+size) - /* tidy up by null terminating the now shorter data */ - *outPtr = '\0'; - - return (outPtr - startPtr); - } - return size; -} -#endif /* CURL_DO_LINEEND_CONV */ - -#ifdef USE_RECV_BEFORE_SEND_WORKAROUND -static void pre_receive_plain(struct connectdata *conn, int num) -{ - const curl_socket_t sockfd = conn->sock[num]; - struct postponed_data * const psnd = &(conn->postponed[num]); - size_t bytestorecv = psnd->allocated_size - psnd->recv_size; - /* WinSock will destroy unread received data if send() is - failed. - To avoid lossage of received data, recv() must be - performed before every send() if any incoming data is - available. However, skip this, if buffer is already full. */ - if((conn->handler->protocol&PROTO_FAMILY_HTTP) != 0 && - conn->recv[num] == Curl_recv_plain && - (!psnd->buffer || bytestorecv)) { - const int readymask = Curl_socket_check(sockfd, CURL_SOCKET_BAD, - CURL_SOCKET_BAD, 0); - if(readymask != -1 && (readymask & CURL_CSELECT_IN) != 0) { - /* Have some incoming data */ - if(!psnd->buffer) { - /* Use buffer double default size for intermediate buffer */ - psnd->allocated_size = 2 * BUFSIZE; - psnd->buffer = malloc(psnd->allocated_size); - psnd->recv_size = 0; - psnd->recv_processed = 0; -#ifdef DEBUGBUILD - psnd->bindsock = sockfd; /* Used only for DEBUGASSERT */ -#endif /* DEBUGBUILD */ - bytestorecv = psnd->allocated_size; - } - if(psnd->buffer) { - ssize_t recvedbytes; - DEBUGASSERT(psnd->bindsock == sockfd); - recvedbytes = sread(sockfd, psnd->buffer + psnd->recv_size, - bytestorecv); - if(recvedbytes > 0) - psnd->recv_size += recvedbytes; - } - else - psnd->allocated_size = 0; - } - } -} - -static ssize_t get_pre_recved(struct connectdata *conn, int num, char *buf, - size_t len) -{ - struct postponed_data * const psnd = &(conn->postponed[num]); - size_t copysize; - if(!psnd->buffer) - return 0; - - DEBUGASSERT(psnd->allocated_size > 0); - DEBUGASSERT(psnd->recv_size <= psnd->allocated_size); - DEBUGASSERT(psnd->recv_processed <= psnd->recv_size); - /* Check and process data that already received and storied in internal - intermediate buffer */ - if(psnd->recv_size > psnd->recv_processed) { - DEBUGASSERT(psnd->bindsock == conn->sock[num]); - copysize = CURLMIN(len, psnd->recv_size - psnd->recv_processed); - memcpy(buf, psnd->buffer + psnd->recv_processed, copysize); - psnd->recv_processed += copysize; - } - else - copysize = 0; /* buffer was allocated, but nothing was received */ - - /* Free intermediate buffer if it has no unprocessed data */ - if(psnd->recv_processed == psnd->recv_size) { - free(psnd->buffer); - psnd->buffer = NULL; - psnd->allocated_size = 0; - psnd->recv_size = 0; - psnd->recv_processed = 0; -#ifdef DEBUGBUILD - psnd->bindsock = CURL_SOCKET_BAD; -#endif /* DEBUGBUILD */ - } - return (ssize_t)copysize; -} -#else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ -/* Use "do-nothing" macros instead of functions when workaround not used */ -#define pre_receive_plain(c,n) do {} WHILE_FALSE -#define get_pre_recved(c,n,b,l) 0 -#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ - -/* Curl_infof() is for info message along the way */ - -void Curl_infof(struct SessionHandle *data, const char *fmt, ...) -{ - if(data && data->set.verbose) { - va_list ap; - size_t len; - char print_buffer[2048 + 1]; - va_start(ap, fmt); - vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap); - va_end(ap); - len = strlen(print_buffer); - Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL); - } -} - -/* Curl_failf() is for messages stating why we failed. - * The message SHALL NOT include any LF or CR. - */ - -void Curl_failf(struct SessionHandle *data, const char *fmt, ...) -{ - va_list ap; - size_t len; - va_start(ap, fmt); - - vsnprintf(data->state.buffer, BUFSIZE, fmt, ap); - - if(data->set.errorbuffer && !data->state.errorbuf) { - snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer); - data->state.errorbuf = TRUE; /* wrote error string */ - } - if(data->set.verbose) { - len = strlen(data->state.buffer); - if(len < BUFSIZE - 1) { - data->state.buffer[len] = '\n'; - data->state.buffer[++len] = '\0'; - } - Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL); - } - - va_end(ap); -} - -/* Curl_sendf() sends formated data to the server */ -CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn, - const char *fmt, ...) -{ - struct SessionHandle *data = conn->data; - ssize_t bytes_written; - size_t write_len; - CURLcode result = CURLE_OK; - char *s; - char *sptr; - va_list ap; - va_start(ap, fmt); - s = vaprintf(fmt, ap); /* returns an allocated string */ - va_end(ap); - if(!s) - return CURLE_OUT_OF_MEMORY; /* failure */ - - bytes_written=0; - write_len = strlen(s); - sptr = s; - - for(;;) { - /* Write the buffer to the socket */ - result = Curl_write(conn, sockfd, sptr, write_len, &bytes_written); - - if(result) - break; - - if(data->set.verbose) - Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn); - - if((size_t)bytes_written != write_len) { - /* if not all was written at once, we must advance the pointer, decrease - the size left and try again! */ - write_len -= bytes_written; - sptr += bytes_written; - } - else - break; - } - - free(s); /* free the output string */ - - return result; -} - -/* - * Curl_write() is an internal write function that sends data to the - * server. Works with plain sockets, SCP, SSL or kerberos. - * - * If the write would block (CURLE_AGAIN), we return CURLE_OK and - * (*written == 0). Otherwise we return regular CURLcode value. - */ -CURLcode Curl_write(struct connectdata *conn, - curl_socket_t sockfd, - const void *mem, - size_t len, - ssize_t *written) -{ - ssize_t bytes_written; - CURLcode result = CURLE_OK; - int num = (sockfd == conn->sock[SECONDARYSOCKET]); - - bytes_written = conn->send[num](conn, num, mem, len, &result); - - *written = bytes_written; - if(bytes_written >= 0) - /* we completely ignore the curlcode value when subzero is not returned */ - return CURLE_OK; - - /* handle CURLE_AGAIN or a send failure */ - switch(result) { - case CURLE_AGAIN: - *written = 0; - return CURLE_OK; - - case CURLE_OK: - /* general send failure */ - return CURLE_SEND_ERROR; - - default: - /* we got a specific curlcode, forward it */ - return result; - } -} - -ssize_t Curl_send_plain(struct connectdata *conn, int num, - const void *mem, size_t len, CURLcode *code) -{ - curl_socket_t sockfd = conn->sock[num]; - ssize_t bytes_written; - /* WinSock will destroy unread received data if send() is - failed. - To avoid lossage of received data, recv() must be - performed before every send() if any incoming data is - available. */ - pre_receive_plain(conn, num); - -#ifdef MSG_FASTOPEN /* Linux */ - if(conn->bits.tcp_fastopen) { - bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN, - conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen); - conn->bits.tcp_fastopen = FALSE; - } - else -#endif - bytes_written = swrite(sockfd, mem, len); - - *code = CURLE_OK; - if(-1 == bytes_written) { - int err = SOCKERRNO; - - if( -#ifdef WSAEWOULDBLOCK - /* This is how Windows does it */ - (WSAEWOULDBLOCK == err) -#else - /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We therefor - treat both error codes the same here */ - (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) || - (EINPROGRESS == err) -#endif - ) { - /* this is just a case of EWOULDBLOCK */ - bytes_written=0; - *code = CURLE_AGAIN; - } - else { - failf(conn->data, "Send failure: %s", - Curl_strerror(conn, err)); - conn->data->state.os_errno = err; - *code = CURLE_SEND_ERROR; - } - } - return bytes_written; -} - -/* - * Curl_write_plain() is an internal write function that sends data to the - * server using plain sockets only. Otherwise meant to have the exact same - * proto as Curl_write() - */ -CURLcode Curl_write_plain(struct connectdata *conn, - curl_socket_t sockfd, - const void *mem, - size_t len, - ssize_t *written) -{ - ssize_t bytes_written; - CURLcode result; - int num = (sockfd == conn->sock[SECONDARYSOCKET]); - - bytes_written = Curl_send_plain(conn, num, mem, len, &result); - - *written = bytes_written; - - return result; -} - -ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, - size_t len, CURLcode *code) -{ - curl_socket_t sockfd = conn->sock[num]; - ssize_t nread; - /* Check and return data that already received and storied in internal - intermediate buffer */ - nread = get_pre_recved(conn, num, buf, len); - if(nread > 0) { - *code = CURLE_OK; - return nread; - } - - nread = sread(sockfd, buf, len); - - *code = CURLE_OK; - if(-1 == nread) { - int err = SOCKERRNO; - - if( -#ifdef WSAEWOULDBLOCK - /* This is how Windows does it */ - (WSAEWOULDBLOCK == err) -#else - /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned - due to its inability to send off data without blocking. We therefor - treat both error codes the same here */ - (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err) -#endif - ) { - /* this is just a case of EWOULDBLOCK */ - *code = CURLE_AGAIN; - } - else { - failf(conn->data, "Recv failure: %s", - Curl_strerror(conn, err)); - conn->data->state.os_errno = err; - *code = CURLE_RECV_ERROR; - } - } - return nread; -} - -static CURLcode pausewrite(struct SessionHandle *data, - int type, /* what type of data */ - const char *ptr, - size_t len) -{ - /* signalled to pause sending on this connection, but since we have data - we want to send we need to dup it to save a copy for when the sending - is again enabled */ - struct SingleRequest *k = &data->req; - char *dupl = malloc(len); - if(!dupl) - return CURLE_OUT_OF_MEMORY; - - memcpy(dupl, ptr, len); - - /* store this information in the state struct for later use */ - data->state.tempwrite = dupl; - data->state.tempwritesize = len; - data->state.tempwritetype = type; - - /* mark the connection as RECV paused */ - k->keepon |= KEEP_RECV_PAUSE; - - DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n", - len, type)); - - return CURLE_OK; -} - - -/* Curl_client_chop_write() writes chunks of data not larger than - * CURL_MAX_WRITE_SIZE via client write callback(s) and - * takes care of pause requests from the callbacks. - */ -CURLcode Curl_client_chop_write(struct connectdata *conn, - int type, - char * ptr, - size_t len) -{ - struct SessionHandle *data = conn->data; - curl_write_callback writeheader = NULL; - curl_write_callback writebody = NULL; - - if(!len) - return CURLE_OK; - - /* If reading is actually paused, we're forced to append this chunk of data - to the already held data, but only if it is the same type as otherwise it - can't work and it'll return error instead. */ - if(data->req.keepon & KEEP_RECV_PAUSE) { - size_t newlen; - char *newptr; - if(type != data->state.tempwritetype) - /* major internal confusion */ - return CURLE_RECV_ERROR; - - DEBUGASSERT(data->state.tempwrite); - - /* figure out the new size of the data to save */ - newlen = len + data->state.tempwritesize; - /* allocate the new memory area */ - newptr = realloc(data->state.tempwrite, newlen); - if(!newptr) - return CURLE_OUT_OF_MEMORY; - /* copy the new data to the end of the new area */ - memcpy(newptr + data->state.tempwritesize, ptr, len); - /* update the pointer and the size */ - data->state.tempwrite = newptr; - data->state.tempwritesize = newlen; - return CURLE_OK; - } - - /* Determine the callback(s) to use. */ - if(type & CLIENTWRITE_BODY) - writebody = data->set.fwrite_func; - if((type & CLIENTWRITE_HEADER) && - (data->set.fwrite_header || data->set.writeheader)) { - /* - * Write headers to the same callback or to the especially setup - * header callback function (added after version 7.7.1). - */ - writeheader = - data->set.fwrite_header? data->set.fwrite_header: data->set.fwrite_func; - } - - /* Chop data, write chunks. */ - while(len) { - size_t chunklen = len <= CURL_MAX_WRITE_SIZE? len: CURL_MAX_WRITE_SIZE; - - if(writebody) { - size_t wrote = writebody(ptr, 1, chunklen, data->set.out); - - if(CURL_WRITEFUNC_PAUSE == wrote) { - if(conn->handler->flags & PROTOPT_NONETWORK) { - /* Protocols that work without network cannot be paused. This is - actually only FILE:// just now, and it can't pause since the - transfer isn't done using the "normal" procedure. */ - failf(data, "Write callback asked for PAUSE when not supported!"); - return CURLE_WRITE_ERROR; - } - else - return pausewrite(data, type, ptr, len); - } - else if(wrote != chunklen) { - failf(data, "Failed writing body (%zu != %zu)", wrote, chunklen); - return CURLE_WRITE_ERROR; - } - } - - if(writeheader) { - size_t wrote = writeheader(ptr, 1, chunklen, data->set.writeheader); - - if(CURL_WRITEFUNC_PAUSE == wrote) - /* here we pass in the HEADER bit only since if this was body as well - then it was passed already and clearly that didn't trigger the - pause, so this is saved for later with the HEADER bit only */ - return pausewrite(data, CLIENTWRITE_HEADER, ptr, len); - - if(wrote != chunklen) { - failf (data, "Failed writing header"); - return CURLE_WRITE_ERROR; - } - } - - ptr += chunklen; - len -= chunklen; - } - - return CURLE_OK; -} - - -/* Curl_client_write() sends data to the write callback(s) - - The bit pattern defines to what "streams" to write to. Body and/or header. - The defines are in sendf.h of course. - - If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the - local character encoding. This is a problem and should be changed in - the future to leave the original data alone. - */ -CURLcode Curl_client_write(struct connectdata *conn, - int type, - char *ptr, - size_t len) -{ - struct SessionHandle *data = conn->data; - - if(0 == len) - len = strlen(ptr); - - /* FTP data may need conversion. */ - if((type & CLIENTWRITE_BODY) && - (conn->handler->protocol & PROTO_FAMILY_FTP) && - conn->proto.ftpc.transfertype == 'A') { - /* convert from the network encoding */ - CURLcode result = Curl_convert_from_network(data, ptr, len); - /* Curl_convert_from_network calls failf if unsuccessful */ - if(result) - return result; - -#ifdef CURL_DO_LINEEND_CONV - /* convert end-of-line markers */ - len = convert_lineends(data, ptr, len); -#endif /* CURL_DO_LINEEND_CONV */ - } - - return Curl_client_chop_write(conn, type, ptr, len); -} - -CURLcode Curl_read_plain(curl_socket_t sockfd, - char *buf, - size_t bytesfromsocket, - ssize_t *n) -{ - ssize_t nread = sread(sockfd, buf, bytesfromsocket); - - if(-1 == nread) { - int err = SOCKERRNO; - int return_error; -#ifdef USE_WINSOCK - return_error = WSAEWOULDBLOCK == err; -#else - return_error = EWOULDBLOCK == err || EAGAIN == err || EINTR == err; -#endif - if(return_error) - return CURLE_AGAIN; - else - return CURLE_RECV_ERROR; - } - - /* we only return number of bytes read when we return OK */ - *n = nread; - return CURLE_OK; -} - -/* - * Internal read-from-socket function. This is meant to deal with plain - * sockets, SSL sockets and kerberos sockets. - * - * Returns a regular CURLcode value. - */ -CURLcode Curl_read(struct connectdata *conn, /* connection data */ - curl_socket_t sockfd, /* read from this socket */ - char *buf, /* store read data here */ - size_t sizerequested, /* max amount to read */ - ssize_t *n) /* amount bytes read */ -{ - CURLcode result = CURLE_RECV_ERROR; - ssize_t nread = 0; - size_t bytesfromsocket = 0; - char *buffertofill = NULL; - - /* if HTTP/1 pipelining is both wanted and possible */ - bool pipelining = Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1) && - (conn->bundle->multiuse == BUNDLE_PIPELINING); - - /* Set 'num' to 0 or 1, depending on which socket that has been sent here. - If it is the second socket, we set num to 1. Otherwise to 0. This lets - us use the correct ssl handle. */ - int num = (sockfd == conn->sock[SECONDARYSOCKET]); - - *n=0; /* reset amount to zero */ - - /* If session can pipeline, check connection buffer */ - if(pipelining) { - size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos, - sizerequested); - - /* Copy from our master buffer first if we have some unread data there*/ - if(bytestocopy > 0) { - memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy); - conn->read_pos += bytestocopy; - conn->bits.stream_was_rewound = FALSE; - - *n = (ssize_t)bytestocopy; - return CURLE_OK; - } - /* If we come here, it means that there is no data to read from the buffer, - * so we read from the socket */ - bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char)); - buffertofill = conn->master_buffer; - } - else { - bytesfromsocket = CURLMIN((long)sizerequested, - conn->data->set.buffer_size ? - conn->data->set.buffer_size : BUFSIZE); - buffertofill = buf; - } - - nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &result); - if(nread < 0) - return result; - - if(pipelining) { - memcpy(buf, conn->master_buffer, nread); - conn->buf_len = nread; - conn->read_pos = nread; - } - - *n += nread; - - return CURLE_OK; -} - -/* return 0 on success */ -static int showit(struct SessionHandle *data, curl_infotype type, - char *ptr, size_t size) -{ - static const char s_infotype[CURLINFO_END][3] = { - "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; - -#ifdef CURL_DOES_CONVERSIONS - char buf[BUFSIZE+1]; - size_t conv_size = 0; - - switch(type) { - case CURLINFO_HEADER_OUT: - /* assume output headers are ASCII */ - /* copy the data into my buffer so the original is unchanged */ - if(size > BUFSIZE) { - size = BUFSIZE; /* truncate if necessary */ - buf[BUFSIZE] = '\0'; - } - conv_size = size; - memcpy(buf, ptr, size); - /* Special processing is needed for this block if it - * contains both headers and data (separated by CRLFCRLF). - * We want to convert just the headers, leaving the data as-is. - */ - if(size > 4) { - size_t i; - for(i = 0; i < size-4; i++) { - if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) { - /* convert everything through this CRLFCRLF but no further */ - conv_size = i + 4; - break; - } - } - } - - Curl_convert_from_network(data, buf, conv_size); - /* Curl_convert_from_network calls failf if unsuccessful */ - /* we might as well continue even if it fails... */ - ptr = buf; /* switch pointer to use my buffer instead */ - break; - default: - /* leave everything else as-is */ - break; - } -#endif /* CURL_DOES_CONVERSIONS */ - - if(data->set.fdebug) - return (*data->set.fdebug)(data, type, ptr, size, - data->set.debugdata); - - switch(type) { - case CURLINFO_TEXT: - case CURLINFO_HEADER_OUT: - case CURLINFO_HEADER_IN: - fwrite(s_infotype[type], 2, 1, data->set.err); - fwrite(ptr, size, 1, data->set.err); -#ifdef CURL_DOES_CONVERSIONS - if(size != conv_size) { - /* we had untranslated data so we need an explicit newline */ - fwrite("\n", 1, 1, data->set.err); - } -#endif - break; - default: /* nada */ - break; - } - return 0; -} - -int Curl_debug(struct SessionHandle *data, curl_infotype type, - char *ptr, size_t size, - struct connectdata *conn) -{ - int rc; - if(data->set.printhost && conn && conn->host.dispname) { - char buffer[160]; - const char *t=NULL; - const char *w="Data"; - switch (type) { - case CURLINFO_HEADER_IN: - w = "Header"; - /* FALLTHROUGH */ - case CURLINFO_DATA_IN: - t = "from"; - break; - case CURLINFO_HEADER_OUT: - w = "Header"; - /* FALLTHROUGH */ - case CURLINFO_DATA_OUT: - t = "to"; - break; - default: - break; - } - - if(t) { - snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t, - conn->host.dispname); - rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer)); - if(rc) - return rc; - } - } - rc = showit(data, type, ptr, size); - return rc; -} diff --git a/Externals/curl/lib/sendf.h b/Externals/curl/lib/sendf.h deleted file mode 100644 index 48e9444c6d..0000000000 --- a/Externals/curl/lib/sendf.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef HEADER_CURL_SENDF_H -#define HEADER_CURL_SENDF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *, - const char *fmt, ...); -void Curl_infof(struct SessionHandle *, const char *fmt, ...); -void Curl_failf(struct SessionHandle *, const char *fmt, ...); - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - -#if defined(HAVE_VARIADIC_MACROS_C99) -#define infof(...) Curl_nop_stmt -#elif defined(HAVE_VARIADIC_MACROS_GCC) -#define infof(x...) Curl_nop_stmt -#else -#define infof (void) -#endif - -#else /* CURL_DISABLE_VERBOSE_STRINGS */ - -#define infof Curl_infof - -#endif /* CURL_DISABLE_VERBOSE_STRINGS */ - -#define failf Curl_failf - -#define CLIENTWRITE_BODY (1<<0) -#define CLIENTWRITE_HEADER (1<<1) -#define CLIENTWRITE_BOTH (CLIENTWRITE_BODY|CLIENTWRITE_HEADER) - -CURLcode Curl_client_chop_write(struct connectdata *conn, int type, char *ptr, - size_t len) WARN_UNUSED_RESULT; -CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, - size_t len) WARN_UNUSED_RESULT; - -/* internal read-function, does plain socket only */ -CURLcode Curl_read_plain(curl_socket_t sockfd, - char *buf, - size_t bytesfromsocket, - ssize_t *n); - -ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf, - size_t len, CURLcode *code); -ssize_t Curl_send_plain(struct connectdata *conn, int num, - const void *mem, size_t len, CURLcode *code); - -/* internal read-function, does plain socket, SSL and krb4 */ -CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd, - char *buf, size_t buffersize, - ssize_t *n); -/* internal write-function, does plain socket, SSL, SCP, SFTP and krb4 */ -CURLcode Curl_write(struct connectdata *conn, - curl_socket_t sockfd, - const void *mem, size_t len, - ssize_t *written); - -/* internal write-function, does plain sockets ONLY */ -CURLcode Curl_write_plain(struct connectdata *conn, - curl_socket_t sockfd, - const void *mem, size_t len, - ssize_t *written); - -/* the function used to output verbose information */ -int Curl_debug(struct SessionHandle *handle, curl_infotype type, - char *data, size_t size, - struct connectdata *conn); - - -#endif /* HEADER_CURL_SENDF_H */ diff --git a/Externals/curl/lib/setup-os400.h b/Externals/curl/lib/setup-os400.h deleted file mode 100644 index e32b72f21f..0000000000 --- a/Externals/curl/lib/setup-os400.h +++ /dev/null @@ -1,223 +0,0 @@ -#ifndef HEADER_CURL_SETUP_OS400_H -#define HEADER_CURL_SETUP_OS400_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - - -/* OS/400 netdb.h does not define NI_MAXHOST. */ -#define NI_MAXHOST 1025 - -/* OS/400 netdb.h does not define NI_MAXSERV. */ -#define NI_MAXSERV 32 - -/* No OS/400 header file defines u_int32_t. */ -typedef unsigned long u_int32_t; - - -/* System API wrapper prototypes & definitions to support ASCII parameters. */ - -#include -#include -#include -#include -#include - -extern int Curl_getaddrinfo_a(const char * nodename, - const char * servname, - const struct addrinfo * hints, - struct addrinfo * * res); -#define getaddrinfo Curl_getaddrinfo_a - - -extern int Curl_getnameinfo_a(const struct sockaddr * sa, - curl_socklen_t salen, - char * nodename, curl_socklen_t nodenamelen, - char * servname, curl_socklen_t servnamelen, - int flags); -#define getnameinfo Curl_getnameinfo_a - - -/* GSKit wrappers. */ - -extern int Curl_gsk_environment_open(gsk_handle * my_env_handle); -#define gsk_environment_open Curl_gsk_environment_open - -extern int Curl_gsk_secure_soc_open(gsk_handle my_env_handle, - gsk_handle * my_session_handle); -#define gsk_secure_soc_open Curl_gsk_secure_soc_open - -extern int Curl_gsk_environment_close(gsk_handle * my_env_handle); -#define gsk_environment_close Curl_gsk_environment_close - -extern int Curl_gsk_secure_soc_close(gsk_handle * my_session_handle); -#define gsk_secure_soc_close Curl_gsk_secure_soc_close - -extern int Curl_gsk_environment_init(gsk_handle my_env_handle); -#define gsk_environment_init Curl_gsk_environment_init - -extern int Curl_gsk_secure_soc_init(gsk_handle my_session_handle); -#define gsk_secure_soc_init Curl_gsk_secure_soc_init - -extern int Curl_gsk_attribute_set_buffer_a(gsk_handle my_gsk_handle, - GSK_BUF_ID bufID, - const char * buffer, - int bufSize); -#define gsk_attribute_set_buffer Curl_gsk_attribute_set_buffer_a - -extern int Curl_gsk_attribute_set_enum(gsk_handle my_gsk_handle, - GSK_ENUM_ID enumID, - GSK_ENUM_VALUE enumValue); -#define gsk_attribute_set_enum Curl_gsk_attribute_set_enum - -extern int Curl_gsk_attribute_set_numeric_value(gsk_handle my_gsk_handle, - GSK_NUM_ID numID, - int numValue); -#define gsk_attribute_set_numeric_value Curl_gsk_attribute_set_numeric_value - -extern int Curl_gsk_attribute_set_callback(gsk_handle my_gsk_handle, - GSK_CALLBACK_ID callBackID, - void * callBackAreaPtr); -#define gsk_attribute_set_callback Curl_gsk_attribute_set_callback - -extern int Curl_gsk_attribute_get_buffer_a(gsk_handle my_gsk_handle, - GSK_BUF_ID bufID, - const char * * buffer, - int * bufSize); -#define gsk_attribute_get_buffer Curl_gsk_attribute_get_buffer_a - -extern int Curl_gsk_attribute_get_enum(gsk_handle my_gsk_handle, - GSK_ENUM_ID enumID, - GSK_ENUM_VALUE * enumValue); -#define gsk_attribute_get_enum Curl_gsk_attribute_get_enum - -extern int Curl_gsk_attribute_get_numeric_value(gsk_handle my_gsk_handle, - GSK_NUM_ID numID, - int * numValue); -#define gsk_attribute_get_numeric_value Curl_gsk_attribute_get_numeric_value - -extern int Curl_gsk_attribute_get_cert_info(gsk_handle my_gsk_handle, - GSK_CERT_ID certID, - const gsk_cert_data_elem * * certDataElem, - int * certDataElementCount); -#define gsk_attribute_get_cert_info Curl_gsk_attribute_get_cert_info - -extern int Curl_gsk_secure_soc_misc(gsk_handle my_session_handle, - GSK_MISC_ID miscID); -#define gsk_secure_soc_misc Curl_gsk_secure_soc_misc - -extern int Curl_gsk_secure_soc_read(gsk_handle my_session_handle, - char * readBuffer, - int readBufSize, int * amtRead); -#define gsk_secure_soc_read Curl_gsk_secure_soc_read - -extern int Curl_gsk_secure_soc_write(gsk_handle my_session_handle, - char * writeBuffer, - int writeBufSize, int * amtWritten); -#define gsk_secure_soc_write Curl_gsk_secure_soc_write - -extern const char * Curl_gsk_strerror_a(int gsk_return_value); -#define gsk_strerror Curl_gsk_strerror_a - -extern int Curl_gsk_secure_soc_startInit(gsk_handle my_session_handle, - int IOCompletionPort, - Qso_OverlappedIO_t * communicationsArea); -#define gsk_secure_soc_startInit Curl_gsk_secure_soc_startInit - - -/* GSSAPI wrappers. */ - -extern OM_uint32 Curl_gss_import_name_a(OM_uint32 * minor_status, - gss_buffer_t in_name, - gss_OID in_name_type, - gss_name_t * out_name); -#define gss_import_name Curl_gss_import_name_a - - -extern OM_uint32 Curl_gss_display_status_a(OM_uint32 * minor_status, - OM_uint32 status_value, - int status_type, gss_OID mech_type, - gss_msg_ctx_t * message_context, - gss_buffer_t status_string); -#define gss_display_status Curl_gss_display_status_a - - -extern OM_uint32 Curl_gss_init_sec_context_a(OM_uint32 * minor_status, - gss_cred_id_t cred_handle, - gss_ctx_id_t * context_handle, - gss_name_t target_name, - gss_OID mech_type, - gss_flags_t req_flags, - OM_uint32 time_req, - gss_channel_bindings_t - input_chan_bindings, - gss_buffer_t input_token, - gss_OID * actual_mech_type, - gss_buffer_t output_token, - gss_flags_t * ret_flags, - OM_uint32 * time_rec); -#define gss_init_sec_context Curl_gss_init_sec_context_a - - -extern OM_uint32 Curl_gss_delete_sec_context_a(OM_uint32 * minor_status, - gss_ctx_id_t * context_handle, - gss_buffer_t output_token); -#define gss_delete_sec_context Curl_gss_delete_sec_context_a - - -/* LDAP wrappers. */ - -#define BerValue struct berval - -#define ldap_url_parse ldap_url_parse_utf8 -#define ldap_init Curl_ldap_init_a -#define ldap_simple_bind_s Curl_ldap_simple_bind_s_a -#define ldap_search_s Curl_ldap_search_s_a -#define ldap_get_values_len Curl_ldap_get_values_len_a -#define ldap_err2string Curl_ldap_err2string_a -#define ldap_get_dn Curl_ldap_get_dn_a -#define ldap_first_attribute Curl_ldap_first_attribute_a -#define ldap_next_attribute Curl_ldap_next_attribute_a - -/* Some socket functions must be wrapped to process textual addresses - like AF_UNIX. */ - -extern int Curl_os400_connect(int sd, struct sockaddr * destaddr, int addrlen); -extern int Curl_os400_bind(int sd, struct sockaddr * localaddr, int addrlen); -extern int Curl_os400_sendto(int sd, char * buffer, int buflen, int flags, - struct sockaddr * dstaddr, int addrlen); -extern int Curl_os400_recvfrom(int sd, char * buffer, int buflen, int flags, - struct sockaddr * fromaddr, int * addrlen); - -#define connect Curl_os400_connect -#define bind Curl_os400_bind -#define sendto Curl_os400_sendto -#define recvfrom Curl_os400_recvfrom - -#ifdef HAVE_LIBZ -#define zlibVersion Curl_os400_zlibVersion -#define inflateInit_ Curl_os400_inflateInit_ -#define inflateInit2_ Curl_os400_inflateInit2_ -#define inflate Curl_os400_inflate -#define inflateEnd Curl_os400_inflateEnd -#endif - -#endif /* HEADER_CURL_SETUP_OS400_H */ diff --git a/Externals/curl/lib/setup-vms.h b/Externals/curl/lib/setup-vms.h deleted file mode 100644 index 4b78e0bf04..0000000000 --- a/Externals/curl/lib/setup-vms.h +++ /dev/null @@ -1,442 +0,0 @@ -#ifndef HEADER_CURL_SETUP_VMS_H -#define HEADER_CURL_SETUP_VMS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* */ -/* JEM, 12/30/12, VMS now generates config.h, so only define wrappers for */ -/* getenv(), getpwuid() and provide is_vms_shell() */ -/* Also need upper case symbols for system services, and */ -/* OpenSSL, and some Kerberos image */ - -#ifdef __DECC -#pragma message save -#pragma message disable dollarid -#endif - -/* Hide the stuff we are overriding */ -#define getenv decc_getenv -#ifdef __DECC -# if __INITIAL_POINTER_SIZE != 64 -# define getpwuid decc_getpwuid -# endif -#endif -#include - char * decc$getenv(const char * __name); -#include - -#include -#include - -#undef getenv -#undef getpwuid -#define getenv vms_getenv -#define getpwuid vms_getpwuid - -/* VAX needs these in upper case when compiling exact case */ -#define sys$assign SYS$ASSIGN -#define sys$dassgn SYS$DASSGN -#define sys$qiow SYS$QIOW - -#ifdef __DECC -# if __INITIAL_POINTER_SIZE -# pragma __pointer_size __save -# endif -#endif - -#if __USE_LONG_GID_T -# define decc_getpwuid DECC$__LONG_GID_GETPWUID -#else -# if __INITIAL_POINTER_SIZE -# define decc_getpwuid decc$__32_getpwuid -# else -# define decc_getpwuid decc$getpwuid -# endif -#endif - - struct passwd * decc_getpwuid(uid_t uid); - -#ifdef __DECC -# if __INITIAL_POINTER_SIZE == 32 -/* Translate the path, but only if the path is a VMS file specification */ -/* The translation is usually only needed for older versions of VMS */ -static char * vms_translate_path(const char * path) { -char * unix_path; -char * test_str; - - /* See if the result is in VMS format, if not, we are done */ - /* Assume that this is a PATH, not just some data */ - test_str = strpbrk(path, ":[<^"); - if(test_str == NULL) { - return (char *)path; - } - - unix_path = decc$translate_vms(path); - - if((int)unix_path <= 0) { - /* We can not translate it, so return the original string */ - return (char *)path; - } -} -# else - /* VMS translate path is actually not needed on the current 64 bit */ - /* VMS platforms, so instead of figuring out the pointer settings */ - /* Change it to a noop */ -# define vms_translate_path(__path) __path -# endif -#endif - -#ifdef __DECC -# if __INITIAL_POINTER_SIZE -# pragma __pointer_size __restore -# endif -#endif - -static char * vms_getenv(const char * envvar) { - -char * result; -char * vms_path; - - /* first use the DECC getenv() function */ - result = decc$getenv(envvar); - if(result == NULL) { - return result; - } - - vms_path = result; - result = vms_translate_path(vms_path); - - /* note that if you backport this to use VAX C RTL, that the VAX C RTL */ - /* may do a malloc(2048) for each call to getenv(), so you will need */ - /* to add a free(vms_path) */ - /* Do not do a free() for DEC C RTL builds, which should be used for */ - /* VMS 5.5-2 and later, even if using GCC */ - - return result; -} - - -static struct passwd vms_passwd_cache; - -static struct passwd * vms_getpwuid(uid_t uid) { - -struct passwd * my_passwd; - -/* Hack needed to support 64 bit builds, decc_getpwnam is 32 bit only */ -#ifdef __DECC -# if __INITIAL_POINTER_SIZE -__char_ptr32 unix_path; -# else -char * unix_path; -# endif -#else -char * unix_path; -#endif - - my_passwd = decc_getpwuid(uid); - if(my_passwd == NULL) { - return my_passwd; - } - - unix_path = vms_translate_path(my_passwd->pw_dir); - - if((long)unix_path <= 0) { - /* We can not translate it, so return the original string */ - return my_passwd; - } - - /* If no changes needed just return it */ - if(unix_path == my_passwd->pw_dir) { - return my_passwd; - } - - /* Need to copy the structure returned */ - /* Since curl is only using pw_dir, no need to fix up * - /* the pw_shell when running under Bash */ - vms_passwd_cache.pw_name = my_passwd->pw_name; - vms_passwd_cache.pw_uid = my_passwd->pw_uid; - vms_passwd_cache.pw_gid = my_passwd->pw_uid; - vms_passwd_cache.pw_dir = unix_path; - vms_passwd_cache.pw_shell = my_passwd->pw_shell; - - return &vms_passwd_cache; -} - -#ifdef __DECC -#pragma message restore -#endif - -/* Bug - VMS OpenSSL and Kerberos universal symbols are in uppercase only */ -/* VMS libraries should have universal symbols in exact and uppercase */ - -#define ASN1_INTEGER_get ASN1_INTEGER_GET -#define ASN1_STRING_data ASN1_STRING_DATA -#define ASN1_STRING_length ASN1_STRING_LENGTH -#define ASN1_STRING_print ASN1_STRING_PRINT -#define ASN1_STRING_to_UTF8 ASN1_STRING_TO_UTF8 -#define ASN1_STRING_type ASN1_STRING_TYPE -#define BIO_ctrl BIO_CTRL -#define BIO_free BIO_FREE -#define BIO_new BIO_NEW -#define BIO_s_mem BIO_S_MEM -#define BN_bn2bin BN_BN2BIN -#define BN_num_bits BN_NUM_BITS -#define CRYPTO_cleanup_all_ex_data CRYPTO_CLEANUP_ALL_EX_DATA -#define CRYPTO_free CRYPTO_FREE -#define CRYPTO_malloc CRYPTO_MALLOC -#define CONF_modules_load_file CONF_MODULES_LOAD_FILE -#ifdef __VAX -# ifdef VMS_OLD_SSL - /* Ancient OpenSSL on VAX/VMS missing this constant */ -# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 -# undef CONF_modules_load_file - static int CONF_modules_load_file(const char *filename, - const char *appname, - unsigned long flags) { - return 1; - } -# endif -#endif -#define DES_ecb_encrypt DES_ECB_ENCRYPT -#define DES_set_key DES_SET_KEY -#define DES_set_odd_parity DES_SET_ODD_PARITY -#define ENGINE_ctrl ENGINE_CTRL -#define ENGINE_ctrl_cmd ENGINE_CTRL_CMD -#define ENGINE_finish ENGINE_FINISH -#define ENGINE_free ENGINE_FREE -#define ENGINE_get_first ENGINE_GET_FIRST -#define ENGINE_get_id ENGINE_GET_ID -#define ENGINE_get_next ENGINE_GET_NEXT -#define ENGINE_init ENGINE_INIT -#define ENGINE_load_builtin_engines ENGINE_LOAD_BUILTIN_ENGINES -#define ENGINE_load_private_key ENGINE_LOAD_PRIVATE_KEY -#define ENGINE_set_default ENGINE_SET_DEFAULT -#define ERR_clear_error ERR_CLEAR_ERROR -#define ERR_error_string ERR_ERROR_STRING -#define ERR_error_string_n ERR_ERROR_STRING_N -#define ERR_free_strings ERR_FREE_STRINGS -#define ERR_get_error ERR_GET_ERROR -#define ERR_peek_error ERR_PEEK_ERROR -#define ERR_remove_state ERR_REMOVE_STATE -#define EVP_PKEY_copy_parameters EVP_PKEY_COPY_PARAMETERS -#define EVP_PKEY_free EVP_PKEY_FREE -#define EVP_cleanup EVP_CLEANUP -#define GENERAL_NAMES_free GENERAL_NAMES_FREE -#define i2d_X509_PUBKEY I2D_X509_PUBKEY -#define MD4_Final MD4_FINAL -#define MD4_Init MD4_INIT -#define MD4_Update MD4_UPDATE -#define MD5_Final MD5_FINAL -#define MD5_Init MD5_INIT -#define MD5_Update MD5_UPDATE -#define OPENSSL_add_all_algo_noconf OPENSSL_ADD_ALL_ALGO_NOCONF -#ifndef __VAX -#define OPENSSL_load_builtin_modules OPENSSL_LOAD_BUILTIN_MODULES -#endif -#define PEM_read_X509 PEM_READ_X509 -#define PEM_write_bio_X509 PEM_WRITE_BIO_X509 -#define PKCS12_PBE_add PKCS12_PBE_ADD -#define PKCS12_free PKCS12_FREE -#define PKCS12_parse PKCS12_PARSE -#define RAND_add RAND_ADD -#define RAND_bytes RAND_BYTES -#define RAND_egd RAND_EGD -#define RAND_file_name RAND_FILE_NAME -#define RAND_load_file RAND_LOAD_FILE -#define RAND_status RAND_STATUS -#define SSL_CIPHER_get_name SSL_CIPHER_GET_NAME -#define SSL_CTX_add_client_CA SSL_CTX_ADD_CLIENT_CA -#define SSL_CTX_callback_ctrl SSL_CTX_CALLBACK_CTRL -#define SSL_CTX_check_private_key SSL_CTX_CHECK_PRIVATE_KEY -#define SSL_CTX_ctrl SSL_CTX_CTRL -#define SSL_CTX_free SSL_CTX_FREE -#define SSL_CTX_get_cert_store SSL_CTX_GET_CERT_STORE -#define SSL_CTX_load_verify_locations SSL_CTX_LOAD_VERIFY_LOCATIONS -#define SSL_CTX_new SSL_CTX_NEW -#define SSL_CTX_set_cipher_list SSL_CTX_SET_CIPHER_LIST -#define SSL_CTX_set_def_passwd_cb_ud SSL_CTX_SET_DEF_PASSWD_CB_UD -#define SSL_CTX_set_default_passwd_cb SSL_CTX_SET_DEFAULT_PASSWD_CB -#define SSL_CTX_set_msg_callback SSL_CTX_SET_MSG_CALLBACK -#define SSL_CTX_set_verify SSL_CTX_SET_VERIFY -#define SSL_CTX_use_PrivateKey SSL_CTX_USE_PRIVATEKEY -#define SSL_CTX_use_PrivateKey_file SSL_CTX_USE_PRIVATEKEY_FILE -#define SSL_CTX_use_cert_chain_file SSL_CTX_USE_CERT_CHAIN_FILE -#define SSL_CTX_use_certificate SSL_CTX_USE_CERTIFICATE -#define SSL_CTX_use_certificate_file SSL_CTX_USE_CERTIFICATE_FILE -#define SSL_SESSION_free SSL_SESSION_FREE -#define SSL_connect SSL_CONNECT -#define SSL_free SSL_FREE -#define SSL_get1_session SSL_GET1_SESSION -#define SSL_get_certificate SSL_GET_CERTIFICATE -#define SSL_get_current_cipher SSL_GET_CURRENT_CIPHER -#define SSL_get_error SSL_GET_ERROR -#define SSL_get_peer_cert_chain SSL_GET_PEER_CERT_CHAIN -#define SSL_get_peer_certificate SSL_GET_PEER_CERTIFICATE -#define SSL_get_privatekey SSL_GET_PRIVATEKEY -#define SSL_get_session SSL_GET_SESSION -#define SSL_get_shutdown SSL_GET_SHUTDOWN -#define SSL_get_verify_result SSL_GET_VERIFY_RESULT -#define SSL_library_init SSL_LIBRARY_INIT -#define SSL_load_error_strings SSL_LOAD_ERROR_STRINGS -#define SSL_new SSL_NEW -#define SSL_peek SSL_PEEK -#define SSL_pending SSL_PENDING -#define SSL_read SSL_READ -#define SSL_set_connect_state SSL_SET_CONNECT_STATE -#define SSL_set_fd SSL_SET_FD -#define SSL_set_session SSL_SET_SESSION -#define SSL_shutdown SSL_SHUTDOWN -#define SSL_version SSL_VERSION -#define SSL_write SSL_WRITE -#define SSLeay SSLEAY -#define SSLv23_client_method SSLV23_CLIENT_METHOD -#define SSLv3_client_method SSLV3_CLIENT_METHOD -#define TLSv1_client_method TLSV1_CLIENT_METHOD -#define UI_create_method UI_CREATE_METHOD -#define UI_destroy_method UI_DESTROY_METHOD -#define UI_get0_user_data UI_GET0_USER_DATA -#define UI_get_input_flags UI_GET_INPUT_FLAGS -#define UI_get_string_type UI_GET_STRING_TYPE -#define UI_create_method UI_CREATE_METHOD -#define UI_destroy_method UI_DESTROY_METHOD -#define UI_method_get_closer UI_METHOD_GET_CLOSER -#define UI_method_get_opener UI_METHOD_GET_OPENER -#define UI_method_get_reader UI_METHOD_GET_READER -#define UI_method_get_writer UI_METHOD_GET_WRITER -#define UI_method_set_closer UI_METHOD_SET_CLOSER -#define UI_method_set_opener UI_METHOD_SET_OPENER -#define UI_method_set_reader UI_METHOD_SET_READER -#define UI_method_set_writer UI_METHOD_SET_WRITER -#define UI_OpenSSL UI_OPENSSL -#define UI_set_result UI_SET_RESULT -#define X509V3_EXT_print X509V3_EXT_PRINT -#define X509_EXTENSION_get_critical X509_EXTENSION_GET_CRITICAL -#define X509_EXTENSION_get_data X509_EXTENSION_GET_DATA -#define X509_EXTENSION_get_object X509_EXTENSION_GET_OBJECT -#define X509_LOOKUP_file X509_LOOKUP_FILE -#define X509_NAME_ENTRY_get_data X509_NAME_ENTRY_GET_DATA -#define X509_NAME_get_entry X509_NAME_GET_ENTRY -#define X509_NAME_get_index_by_NID X509_NAME_GET_INDEX_BY_NID -#define X509_NAME_print_ex X509_NAME_PRINT_EX -#define X509_STORE_CTX_get_current_cert X509_STORE_CTX_GET_CURRENT_CERT -#define X509_STORE_add_lookup X509_STORE_ADD_LOOKUP -#define X509_STORE_set_flags X509_STORE_SET_FLAGS -#define X509_check_issued X509_CHECK_ISSUED -#define X509_free X509_FREE -#define X509_get_ext_d2i X509_GET_EXT_D2I -#define X509_get_issuer_name X509_GET_ISSUER_NAME -#define X509_get_pubkey X509_GET_PUBKEY -#define X509_get_serialNumber X509_GET_SERIALNUMBER -#define X509_get_subject_name X509_GET_SUBJECT_NAME -#define X509_load_crl_file X509_LOAD_CRL_FILE -#define X509_verify_cert_error_string X509_VERIFY_CERT_ERROR_STRING -#define d2i_PKCS12_fp D2I_PKCS12_FP -#define i2t_ASN1_OBJECT I2T_ASN1_OBJECT -#define sk_num SK_NUM -#define sk_pop SK_POP -#define sk_pop_free SK_POP_FREE -#define sk_value SK_VALUE -#ifdef __VAX -#define OPENSSL_NO_SHA256 -#endif -#define SHA256_Final SHA256_FINAL -#define SHA256_Init SHA256_INIT -#define SHA256_Update SHA256_UPDATE - -#define USE_UPPERCASE_GSSAPI 1 -#define gss_seal GSS_SEAL -#define gss_unseal GSS_UNSEAL - -#define USE_UPPERCASE_KRBAPI 1 - -/* AI_NUMERICHOST needed for IP V6 support in Curl */ -#ifdef HAVE_NETDB_H -#include -#ifndef AI_NUMERICHOST -#ifdef ENABLE_IPV6 -#undef ENABLE_IPV6 -#endif -#endif -#endif - -/* VAX symbols are always in uppercase */ -#ifdef __VAX -#define inflate INFLATE -#define inflateEnd INFLATEEND -#define inflateInit2_ INFLATEINIT2_ -#define inflateInit_ INFLATEINIT_ -#define zlibVersion ZLIBVERSION -#endif - -/* Older VAX OpenSSL port defines these as Macros */ -/* Need to include the headers first and then redefine */ -/* that way a newer port will also work if some one has one */ -#ifdef __VAX - -# if (OPENSSL_VERSION_NUMBER < 0x00907001L) -# define des_set_odd_parity DES_SET_ODD_PARITY -# define des_set_key DES_SET_KEY -# define des_ecb_encrypt DES_ECB_ENCRYPT - -# endif -# include -# ifndef OpenSSL_add_all_algorithms -# define OpenSSL_add_all_algorithms OPENSSL_ADD_ALL_ALGORITHMS - void OPENSSL_ADD_ALL_ALGORITHMS(void); -# endif - - /* Curl defines these to lower case and VAX needs them in upper case */ - /* So we need static routines */ -# if (OPENSSL_VERSION_NUMBER < 0x00907001L) - -# undef des_set_odd_parity -# undef DES_set_odd_parity -# undef des_set_key -# undef DES_set_key -# undef des_ecb_encrypt -# undef DES_ecb_encrypt - - static void des_set_odd_parity(des_cblock *key) { - DES_SET_ODD_PARITY(key); - } - - static int des_set_key(const_des_cblock *key, - des_key_schedule schedule) { - return DES_SET_KEY(key, schedule); - } - - static void des_ecb_encrypt(const_des_cblock *input, - des_cblock *output, - des_key_schedule ks, int enc) { - DES_ECB_ENCRYPT(input, output, ks, enc); - } -#endif -/* Need this to stop a macro redefinition error */ -#if OPENSSL_VERSION_NUMBER < 0x00907000L -# ifdef X509_STORE_set_flags -# undef X509_STORE_set_flags -# define X509_STORE_set_flags(x,y) Curl_nop_stmt -# endif -#endif -#endif - -#endif /* HEADER_CURL_SETUP_VMS_H */ diff --git a/Externals/curl/lib/share.c b/Externals/curl/lib/share.c deleted file mode 100644 index 58c5912319..0000000000 --- a/Externals/curl/lib/share.c +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include -#include "urldata.h" -#include "share.h" -#include "vtls/vtls.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -CURLSH * -curl_share_init(void) -{ - struct Curl_share *share = calloc(1, sizeof(struct Curl_share)); - if(share) { - share->specifier |= (1<hostcache)) { - free(share); - return NULL; - } - } - - return share; -} - -#undef curl_share_setopt -CURLSHcode -curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) -{ - struct Curl_share *share = (struct Curl_share *)sh; - va_list param; - int type; - curl_lock_function lockfunc; - curl_unlock_function unlockfunc; - void *ptr; - CURLSHcode res = CURLSHE_OK; - - if(share->dirty) - /* don't allow setting options while one or more handles are already - using this share */ - return CURLSHE_IN_USE; - - va_start(param, option); - - switch(option) { - case CURLSHOPT_SHARE: - /* this is a type this share will share */ - type = va_arg(param, int); - share->specifier |= (1<cookies) { - share->cookies = Curl_cookie_init(NULL, NULL, NULL, TRUE); - if(!share->cookies) - res = CURLSHE_NOMEM; - } -#else /* CURL_DISABLE_HTTP */ - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_SSL_SESSION: -#ifdef USE_SSL - if(!share->sslsession) { - share->max_ssl_sessions = 8; - share->sslsession = calloc(share->max_ssl_sessions, - sizeof(struct curl_ssl_session)); - share->sessionage = 0; - if(!share->sslsession) - res = CURLSHE_NOMEM; - } -#else - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_CONNECT: /* not supported (yet) */ - break; - - default: - res = CURLSHE_BAD_OPTION; - } - break; - - case CURLSHOPT_UNSHARE: - /* this is a type this share will no longer share */ - type = va_arg(param, int); - share->specifier &= ~(1<cookies) { - Curl_cookie_cleanup(share->cookies); - share->cookies = NULL; - } -#else /* CURL_DISABLE_HTTP */ - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_SSL_SESSION: -#ifdef USE_SSL - Curl_safefree(share->sslsession); -#else - res = CURLSHE_NOT_BUILT_IN; -#endif - break; - - case CURL_LOCK_DATA_CONNECT: - break; - - default: - res = CURLSHE_BAD_OPTION; - break; - } - break; - - case CURLSHOPT_LOCKFUNC: - lockfunc = va_arg(param, curl_lock_function); - share->lockfunc = lockfunc; - break; - - case CURLSHOPT_UNLOCKFUNC: - unlockfunc = va_arg(param, curl_unlock_function); - share->unlockfunc = unlockfunc; - break; - - case CURLSHOPT_USERDATA: - ptr = va_arg(param, void *); - share->clientdata = ptr; - break; - - default: - res = CURLSHE_BAD_OPTION; - break; - } - - va_end(param); - - return res; -} - -CURLSHcode -curl_share_cleanup(CURLSH *sh) -{ - struct Curl_share *share = (struct Curl_share *)sh; - - if(share == NULL) - return CURLSHE_INVALID; - - if(share->lockfunc) - share->lockfunc(NULL, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE, - share->clientdata); - - if(share->dirty) { - if(share->unlockfunc) - share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); - return CURLSHE_IN_USE; - } - - Curl_hash_destroy(&share->hostcache); - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - Curl_cookie_cleanup(share->cookies); -#endif - -#ifdef USE_SSL - if(share->sslsession) { - size_t i; - for(i = 0; i < share->max_ssl_sessions; i++) - Curl_ssl_kill_session(&(share->sslsession[i])); - free(share->sslsession); - } -#endif - - if(share->unlockfunc) - share->unlockfunc(NULL, CURL_LOCK_DATA_SHARE, share->clientdata); - free(share); - - return CURLSHE_OK; -} - - -CURLSHcode -Curl_share_lock(struct SessionHandle *data, curl_lock_data type, - curl_lock_access accesstype) -{ - struct Curl_share *share = data->share; - - if(share == NULL) - return CURLSHE_INVALID; - - if(share->specifier & (1<lockfunc) /* only call this if set! */ - share->lockfunc(data, type, accesstype, share->clientdata); - } - /* else if we don't share this, pretend successful lock */ - - return CURLSHE_OK; -} - -CURLSHcode -Curl_share_unlock(struct SessionHandle *data, curl_lock_data type) -{ - struct Curl_share *share = data->share; - - if(share == NULL) - return CURLSHE_INVALID; - - if(share->specifier & (1<unlockfunc) /* only call this if set! */ - share->unlockfunc (data, type, share->clientdata); - } - - return CURLSHE_OK; -} diff --git a/Externals/curl/lib/share.h b/Externals/curl/lib/share.h deleted file mode 100644 index d23d3a040d..0000000000 --- a/Externals/curl/lib/share.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef HEADER_CURL_SHARE_H -#define HEADER_CURL_SHARE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" -#include -#include "cookie.h" -#include "urldata.h" - -/* SalfordC says "A structure member may not be volatile". Hence: - */ -#ifdef __SALFORDC__ -#define CURL_VOLATILE -#else -#define CURL_VOLATILE volatile -#endif - -/* this struct is libcurl-private, don't export details */ -struct Curl_share { - unsigned int specifier; - CURL_VOLATILE unsigned int dirty; - - curl_lock_function lockfunc; - curl_unlock_function unlockfunc; - void *clientdata; - - struct curl_hash hostcache; -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - struct CookieInfo *cookies; -#endif - - struct curl_ssl_session *sslsession; - size_t max_ssl_sessions; - long sessionage; -}; - -CURLSHcode Curl_share_lock (struct SessionHandle *, curl_lock_data, - curl_lock_access); -CURLSHcode Curl_share_unlock (struct SessionHandle *, curl_lock_data); - -#endif /* HEADER_CURL_SHARE_H */ diff --git a/Externals/curl/lib/sigpipe.h b/Externals/curl/lib/sigpipe.h deleted file mode 100644 index 6559c74242..0000000000 --- a/Externals/curl/lib/sigpipe.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef HEADER_CURL_SIGPIPE_H -#define HEADER_CURL_SIGPIPE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#if defined(HAVE_SIGNAL_H) && defined(HAVE_SIGACTION) && defined(USE_OPENSSL) -#include - -struct sigpipe_ignore { - struct sigaction old_pipe_act; - bool no_signal; -}; - -#define SIGPIPE_VARIABLE(x) struct sigpipe_ignore x - -/* - * sigpipe_ignore() makes sure we ignore SIGPIPE while running libcurl - * internals, and then sigpipe_restore() will restore the situation when we - * return from libcurl again. - */ -static void sigpipe_ignore(struct SessionHandle *data, - struct sigpipe_ignore *ig) -{ - /* get a local copy of no_signal because the SessionHandle might not be - around when we restore */ - ig->no_signal = data->set.no_signal; - if(!data->set.no_signal) { - struct sigaction action; - /* first, extract the existing situation */ - memset(&ig->old_pipe_act, 0, sizeof(struct sigaction)); - sigaction(SIGPIPE, NULL, &ig->old_pipe_act); - action = ig->old_pipe_act; - /* ignore this signal */ - action.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &action, NULL); - } -} - -/* - * sigpipe_restore() puts back the outside world's opinion of signal handler - * and SIGPIPE handling. It MUST only be called after a corresponding - * sigpipe_ignore() was used. - */ -static void sigpipe_restore(struct sigpipe_ignore *ig) -{ - if(!ig->no_signal) - /* restore the outside state */ - sigaction(SIGPIPE, &ig->old_pipe_act, NULL); -} - -#else -/* for systems without sigaction */ -#define sigpipe_ignore(x,y) Curl_nop_stmt -#define sigpipe_restore(x) Curl_nop_stmt -#define SIGPIPE_VARIABLE(x) -#endif - -#endif /* HEADER_CURL_SIGPIPE_H */ diff --git a/Externals/curl/lib/slist.c b/Externals/curl/lib/slist.c deleted file mode 100644 index e5adc0e71a..0000000000 --- a/Externals/curl/lib/slist.c +++ /dev/null @@ -1,145 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "slist.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* returns last node in linked list */ -static struct curl_slist *slist_get_last(struct curl_slist *list) -{ - struct curl_slist *item; - - /* if caller passed us a NULL, return now */ - if(!list) - return NULL; - - /* loop through to find the last item */ - item = list; - while(item->next) { - item = item->next; - } - return item; -} - -/* - * Curl_slist_append_nodup() appends a string to the linked list. Rather than - * copying the string in dynamic storage, it takes its ownership. The string - * should have been malloc()ated. Curl_slist_append_nodup always returns - * the address of the first record, so that you can use this function as an - * initialization function as well as an append function. - * If an error occurs, NULL is returned and the string argument is NOT - * released. - */ -struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, char *data) -{ - struct curl_slist *last; - struct curl_slist *new_item; - - DEBUGASSERT(data); - - new_item = malloc(sizeof(struct curl_slist)); - if(!new_item) - return NULL; - - new_item->next = NULL; - new_item->data = data; - - /* if this is the first item, then new_item *is* the list */ - if(!list) - return new_item; - - last = slist_get_last(list); - last->next = new_item; - return list; -} - -/* - * curl_slist_append() appends a string to the linked list. It always returns - * the address of the first record, so that you can use this function as an - * initialization function as well as an append function. If you find this - * bothersome, then simply create a separate _init function and call it - * appropriately from within the program. - */ -struct curl_slist *curl_slist_append(struct curl_slist *list, - const char *data) -{ - char *dupdata = strdup(data); - - if(!dupdata) - return NULL; - - list = Curl_slist_append_nodup(list, dupdata); - if(!list) - free(dupdata); - - return list; -} - -/* - * Curl_slist_duplicate() duplicates a linked list. It always returns the - * address of the first record of the cloned list or NULL in case of an - * error (or if the input list was NULL). - */ -struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist) -{ - struct curl_slist *outlist = NULL; - struct curl_slist *tmp; - - while(inlist) { - tmp = curl_slist_append(outlist, inlist->data); - - if(!tmp) { - curl_slist_free_all(outlist); - return NULL; - } - - outlist = tmp; - inlist = inlist->next; - } - return outlist; -} - -/* be nice and clean up resources */ -void curl_slist_free_all(struct curl_slist *list) -{ - struct curl_slist *next; - struct curl_slist *item; - - if(!list) - return; - - item = list; - do { - next = item->next; - Curl_safefree(item->data); - free(item); - item = next; - } while(next); -} - diff --git a/Externals/curl/lib/slist.h b/Externals/curl/lib/slist.h deleted file mode 100644 index b3f498c35f..0000000000 --- a/Externals/curl/lib/slist.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HEADER_CURL_SLIST_H -#define HEADER_CURL_SLIST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Curl_slist_duplicate() duplicates a linked list. It always returns the - * address of the first record of the cloned list or NULL in case of an - * error (or if the input list was NULL). - */ -struct curl_slist *Curl_slist_duplicate(struct curl_slist *inlist); - -/* - * Curl_slist_append_nodup() takes ownership of the given string and appends - * it to the list. - */ -struct curl_slist *Curl_slist_append_nodup(struct curl_slist *list, - char *data); - -#endif /* HEADER_CURL_SLIST_H */ - diff --git a/Externals/curl/lib/smb.c b/Externals/curl/lib/smb.c deleted file mode 100644 index 2c33c11740..0000000000 --- a/Externals/curl/lib/smb.c +++ /dev/null @@ -1,978 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2014, Bill Nagel , Exacq Technologies - * Copyright (C) 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) - -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - -#define BUILDING_CURL_SMB_C - -#ifdef HAVE_PROCESS_H -#include -#define getpid _getpid -#endif - -#include "smb.h" -#include "urldata.h" -#include "sendf.h" -#include "multiif.h" -#include "connect.h" -#include "progress.h" -#include "transfer.h" -#include "vtls/vtls.h" -#include "curl_ntlm_core.h" -#include "escape.h" -#include "curl_endian.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* Local API functions */ -static CURLcode smb_setup_connection(struct connectdata *conn); -static CURLcode smb_connect(struct connectdata *conn, bool *done); -static CURLcode smb_connection_state(struct connectdata *conn, bool *done); -static CURLcode smb_request_state(struct connectdata *conn, bool *done); -static CURLcode smb_done(struct connectdata *conn, CURLcode status, - bool premature); -static CURLcode smb_disconnect(struct connectdata *conn, bool dead); -static int smb_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks); -static CURLcode smb_parse_url_path(struct connectdata *conn); - -/* - * SMB handler interface - */ -const struct Curl_handler Curl_handler_smb = { - "SMB", /* scheme */ - smb_setup_connection, /* setup_connection */ - ZERO_NULL, /* do_it */ - smb_done, /* done */ - ZERO_NULL, /* do_more */ - smb_connect, /* connect_it */ - smb_connection_state, /* connecting */ - smb_request_state, /* doing */ - smb_getsock, /* proto_getsock */ - smb_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - smb_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SMB, /* defport */ - CURLPROTO_SMB, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -#ifdef USE_SSL -/* - * SMBS handler interface - */ -const struct Curl_handler Curl_handler_smbs = { - "SMBS", /* scheme */ - smb_setup_connection, /* setup_connection */ - ZERO_NULL, /* do_it */ - smb_done, /* done */ - ZERO_NULL, /* do_more */ - smb_connect, /* connect_it */ - smb_connection_state, /* connecting */ - smb_request_state, /* doing */ - smb_getsock, /* proto_getsock */ - smb_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - smb_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SMBS, /* defport */ - CURLPROTO_SMBS, /* protocol */ - PROTOPT_SSL /* flags */ -}; -#endif - -#define MAX_PAYLOAD_SIZE 0x8000 -#define MAX_MESSAGE_SIZE (MAX_PAYLOAD_SIZE + 0x1000) -#define CLIENTNAME "curl" -#define SERVICENAME "?????" - -/* Append a string to an SMB message */ -#define MSGCAT(str) \ - strcpy(p, (str)); \ - p += strlen(str); - -/* Append a null-terminated string to an SMB message */ -#define MSGCATNULL(str) \ - strcpy(p, (str)); \ - p += strlen(str) + 1; - -/* SMB is mostly little endian */ -#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ - defined(__OS400__) -static unsigned short smb_swap16(unsigned short x) -{ - return (unsigned short) ((x << 8) | ((x >> 8) & 0xff)); -} - -static unsigned int smb_swap32(unsigned int x) -{ - return (x << 24) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) | - ((x >> 24) & 0xff); -} - -#ifdef HAVE_LONGLONG -static unsigned long long smb_swap64(unsigned long long x) -{ - return ((unsigned long long) smb_swap32((unsigned int) x) << 32) | - smb_swap32((unsigned int) (x >> 32)); -} -#else -static unsigned __int64 smb_swap64(unsigned __int64 x) -{ - return ((unsigned __int64) smb_swap32((unsigned int) x) << 32) | - smb_swap32((unsigned int) (x >> 32)); -} -#endif -#else -# define smb_swap16(x) (x) -# define smb_swap32(x) (x) -# define smb_swap64(x) (x) -#endif - -/* SMB request state */ -enum smb_req_state { - SMB_REQUESTING, - SMB_TREE_CONNECT, - SMB_OPEN, - SMB_DOWNLOAD, - SMB_UPLOAD, - SMB_CLOSE, - SMB_TREE_DISCONNECT, - SMB_DONE -}; - -/* SMB request data */ -struct smb_request { - enum smb_req_state state; - char *share; - char *path; - unsigned short tid; /* Even if we connect to the same tree as another */ - unsigned short fid; /* request, the tid will be different */ - CURLcode result; -}; - -static void conn_state(struct connectdata *conn, enum smb_conn_state newstate) -{ - struct smb_conn *smb = &conn->proto.smbc; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* For debug purposes */ - static const char * const names[] = { - "SMB_NOT_CONNECTED", - "SMB_CONNECTING", - "SMB_NEGOTIATE", - "SMB_SETUP", - "SMB_CONNECTED", - /* LAST */ - }; - - if(smb->state != newstate) - infof(conn->data, "SMB conn %p state change from %s to %s\n", - (void *)smb, names[smb->state], names[newstate]); -#endif - - smb->state = newstate; -} - -static void request_state(struct connectdata *conn, - enum smb_req_state newstate) -{ - struct smb_request *req = conn->data->req.protop; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* For debug purposes */ - static const char * const names[] = { - "SMB_REQUESTING", - "SMB_TREE_CONNECT", - "SMB_OPEN", - "SMB_DOWNLOAD", - "SMB_UPLOAD", - "SMB_CLOSE", - "SMB_TREE_DISCONNECT", - "SMB_DONE", - /* LAST */ - }; - - if(req->state != newstate) - infof(conn->data, "SMB request %p state change from %s to %s\n", - (void *)req, names[req->state], names[newstate]); -#endif - - req->state = newstate; -} - -static CURLcode smb_setup_connection(struct connectdata *conn) -{ - struct smb_request *req; - - /* Initialize the request state */ - conn->data->req.protop = req = calloc(1, sizeof(struct smb_request)); - if(!req) - return CURLE_OUT_OF_MEMORY; - - /* Parse the URL path */ - return smb_parse_url_path(conn); -} - -static CURLcode smb_connect(struct connectdata *conn, bool *done) -{ - struct smb_conn *smbc = &conn->proto.smbc; - char *slash; - - (void) done; - - /* Check we have a username and password to authenticate with */ - if(!conn->bits.user_passwd) - return CURLE_LOGIN_DENIED; - - /* Initialize the connection state */ - memset(smbc, 0, sizeof(*smbc)); - smbc->state = SMB_CONNECTING; - smbc->recv_buf = malloc(MAX_MESSAGE_SIZE); - if(!smbc->recv_buf) - return CURLE_OUT_OF_MEMORY; - - /* Multiple requests are allowed with this connection */ - connkeep(conn, "SMB default"); - - /* Parse the username, domain, and password */ - slash = strchr(conn->user, '/'); - if(!slash) - slash = strchr(conn->user, '\\'); - - if(slash) { - smbc->user = slash + 1; - smbc->domain = strdup(conn->user); - if(!smbc->domain) - return CURLE_OUT_OF_MEMORY; - smbc->domain[slash - conn->user] = 0; - } - else { - smbc->user = conn->user; - smbc->domain = strdup(conn->host.name); - if(!smbc->domain) - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - -static CURLcode smb_recv_message(struct connectdata *conn, void **msg) -{ - struct smb_conn *smbc = &conn->proto.smbc; - char *buf = smbc->recv_buf; - ssize_t bytes_read; - size_t nbt_size; - size_t msg_size; - size_t len = MAX_MESSAGE_SIZE - smbc->got; - CURLcode result; - - result = Curl_read(conn, FIRSTSOCKET, buf + smbc->got, len, &bytes_read); - if(result) - return result; - - if(!bytes_read) - return CURLE_OK; - - smbc->got += bytes_read; - - /* Check for a 32-bit nbt header */ - if(smbc->got < sizeof(unsigned int)) - return CURLE_OK; - - nbt_size = Curl_read16_be((unsigned char *)(buf + sizeof(unsigned short))) + - sizeof(unsigned int); - if(smbc->got < nbt_size) - return CURLE_OK; - - msg_size = sizeof(struct smb_header); - if(nbt_size >= msg_size + 1) { - /* Add the word count */ - msg_size += 1 + ((unsigned char) buf[msg_size]) * sizeof(unsigned short); - if(nbt_size >= msg_size + sizeof(unsigned short)) { - /* Add the byte count */ - msg_size += sizeof(unsigned short) + - Curl_read16_le((unsigned char *)&buf[msg_size]); - if(nbt_size < msg_size) - return CURLE_READ_ERROR; - } - } - - *msg = buf; - - return CURLE_OK; -} - -static void smb_pop_message(struct connectdata *conn) -{ - struct smb_conn *smbc = &conn->proto.smbc; - - smbc->got = 0; -} - -static void smb_format_message(struct connectdata *conn, struct smb_header *h, - unsigned char cmd, size_t len) -{ - struct smb_conn *smbc = &conn->proto.smbc; - struct smb_request *req = conn->data->req.protop; - unsigned int pid; - - memset(h, 0, sizeof(*h)); - h->nbt_length = htons((unsigned short) (sizeof(*h) - sizeof(unsigned int) + - len)); - memcpy((char *)h->magic, "\xffSMB", 4); - h->command = cmd; - h->flags = SMB_FLAGS_CANONICAL_PATHNAMES | SMB_FLAGS_CASELESS_PATHNAMES; - h->flags2 = smb_swap16(SMB_FLAGS2_IS_LONG_NAME | SMB_FLAGS2_KNOWS_LONG_NAME); - h->uid = smb_swap16(smbc->uid); - h->tid = smb_swap16(req->tid); - pid = getpid(); - h->pid_high = smb_swap16((unsigned short)(pid >> 16)); - h->pid = smb_swap16((unsigned short) pid); -} - -static CURLcode smb_send(struct connectdata *conn, ssize_t len, - size_t upload_size) -{ - struct smb_conn *smbc = &conn->proto.smbc; - ssize_t bytes_written; - CURLcode result; - - result = Curl_write(conn, FIRSTSOCKET, conn->data->state.uploadbuffer, - len, &bytes_written); - if(result) - return result; - - if(bytes_written != len) { - smbc->send_size = len; - smbc->sent = bytes_written; - } - - smbc->upload_size = upload_size; - - return CURLE_OK; -} - -static CURLcode smb_flush(struct connectdata *conn) -{ - struct smb_conn *smbc = &conn->proto.smbc; - ssize_t bytes_written; - ssize_t len = smbc->send_size - smbc->sent; - CURLcode result; - - if(!smbc->send_size) - return CURLE_OK; - - result = Curl_write(conn, FIRSTSOCKET, - conn->data->state.uploadbuffer + smbc->sent, - len, &bytes_written); - if(result) - return result; - - if(bytes_written != len) - smbc->sent += bytes_written; - else - smbc->send_size = 0; - - return CURLE_OK; -} - -static CURLcode smb_send_message(struct connectdata *conn, unsigned char cmd, - const void *msg, size_t msg_len) -{ - smb_format_message(conn, (struct smb_header *)conn->data->state.uploadbuffer, - cmd, msg_len); - memcpy(conn->data->state.uploadbuffer + sizeof(struct smb_header), - msg, msg_len); - - return smb_send(conn, sizeof(struct smb_header) + msg_len, 0); -} - -static CURLcode smb_send_negotiate(struct connectdata *conn) -{ - const char *msg = "\x00\x0c\x00\x02NT LM 0.12"; - - return smb_send_message(conn, SMB_COM_NEGOTIATE, msg, 15); -} - -static CURLcode smb_send_setup(struct connectdata *conn) -{ - struct smb_conn *smbc = &conn->proto.smbc; - struct smb_setup msg; - char *p = msg.bytes; - unsigned char lm_hash[21]; - unsigned char lm[24]; - unsigned char nt_hash[21]; - unsigned char nt[24]; - - size_t byte_count = sizeof(lm) + sizeof(nt); - byte_count += strlen(smbc->user) + strlen(smbc->domain); - byte_count += strlen(OS) + strlen(CLIENTNAME) + 4; /* 4 null chars */ - if(byte_count > sizeof(msg.bytes)) - return CURLE_FILESIZE_EXCEEDED; - - Curl_ntlm_core_mk_lm_hash(conn->data, conn->passwd, lm_hash); - Curl_ntlm_core_lm_resp(lm_hash, smbc->challenge, lm); -#if USE_NTRESPONSES - Curl_ntlm_core_mk_nt_hash(conn->data, conn->passwd, nt_hash); - Curl_ntlm_core_lm_resp(nt_hash, smbc->challenge, nt); -#else - memset(nt, 0, sizeof(nt)); -#endif - - memset(&msg, 0, sizeof(msg)); - msg.word_count = SMB_WC_SETUP_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - msg.max_buffer_size = smb_swap16(MAX_MESSAGE_SIZE); - msg.max_mpx_count = smb_swap16(1); - msg.vc_number = smb_swap16(1); - msg.session_key = smb_swap32(smbc->session_key); - msg.capabilities = smb_swap32(SMB_CAP_LARGE_FILES); - msg.lengths[0] = smb_swap16(sizeof(lm)); - msg.lengths[1] = smb_swap16(sizeof(nt)); - memcpy(p, lm, sizeof(lm)); - p += sizeof(lm); - memcpy(p, nt, sizeof(nt)); - p += sizeof(nt); - MSGCATNULL(smbc->user); - MSGCATNULL(smbc->domain); - MSGCATNULL(OS); - MSGCATNULL(CLIENTNAME); - byte_count = p - msg.bytes; - msg.byte_count = smb_swap16((unsigned short)byte_count); - - return smb_send_message(conn, SMB_COM_SETUP_ANDX, &msg, - sizeof(msg) - sizeof(msg.bytes) + byte_count); -} - -static CURLcode smb_send_tree_connect(struct connectdata *conn) -{ - struct smb_request *req = conn->data->req.protop; - struct smb_tree_connect msg; - char *p = msg.bytes; - - size_t byte_count = strlen(conn->host.name) + strlen(req->share); - byte_count += strlen(SERVICENAME) + 5; /* 2 nulls and 3 backslashes */ - if(byte_count > sizeof(msg.bytes)) - return CURLE_FILESIZE_EXCEEDED; - - memset(&msg, 0, sizeof(msg)); - msg.word_count = SMB_WC_TREE_CONNECT_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - msg.pw_len = 0; - MSGCAT("\\\\"); - MSGCAT(conn->host.name); - MSGCAT("\\"); - MSGCATNULL(req->share); - MSGCATNULL(SERVICENAME); /* Match any type of service */ - byte_count = p - msg.bytes; - msg.byte_count = smb_swap16((unsigned short)byte_count); - - return smb_send_message(conn, SMB_COM_TREE_CONNECT_ANDX, &msg, - sizeof(msg) - sizeof(msg.bytes) + byte_count); -} - -static CURLcode smb_send_open(struct connectdata *conn) -{ - struct smb_request *req = conn->data->req.protop; - struct smb_nt_create msg; - size_t byte_count; - - if((strlen(req->path) + 1) > sizeof(msg.bytes)) - return CURLE_FILESIZE_EXCEEDED; - - memset(&msg, 0, sizeof(msg)); - msg.word_count = SMB_WC_NT_CREATE_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - byte_count = strlen(req->path); - msg.name_length = smb_swap16((unsigned short)byte_count); - msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL); - if(conn->data->set.upload) { - msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE); - msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF); - } - else { - msg.access = smb_swap32(SMB_GENERIC_READ); - msg.create_disposition = smb_swap32(SMB_FILE_OPEN); - } - msg.byte_count = smb_swap16((unsigned short) ++byte_count); - strcpy(msg.bytes, req->path); - - return smb_send_message(conn, SMB_COM_NT_CREATE_ANDX, &msg, - sizeof(msg) - sizeof(msg.bytes) + byte_count); -} - -static CURLcode smb_send_close(struct connectdata *conn) -{ - struct smb_request *req = conn->data->req.protop; - struct smb_close msg; - - memset(&msg, 0, sizeof(msg)); - msg.word_count = SMB_WC_CLOSE; - msg.fid = smb_swap16(req->fid); - - return smb_send_message(conn, SMB_COM_CLOSE, &msg, sizeof(msg)); -} - -static CURLcode smb_send_tree_disconnect(struct connectdata *conn) -{ - struct smb_tree_disconnect msg; - - memset(&msg, 0, sizeof(msg)); - - return smb_send_message(conn, SMB_COM_TREE_DISCONNECT, &msg, sizeof(msg)); -} - -static CURLcode smb_send_read(struct connectdata *conn) -{ - struct smb_request *req = conn->data->req.protop; - curl_off_t offset = conn->data->req.offset; - struct smb_read msg; - - memset(&msg, 0, sizeof(msg)); - msg.word_count = SMB_WC_READ_ANDX; - msg.andx.command = SMB_COM_NO_ANDX_COMMAND; - msg.fid = smb_swap16(req->fid); - msg.offset = smb_swap32((unsigned int) offset); - msg.offset_high = smb_swap32((unsigned int) (offset >> 32)); - msg.min_bytes = smb_swap16(MAX_PAYLOAD_SIZE); - msg.max_bytes = smb_swap16(MAX_PAYLOAD_SIZE); - - return smb_send_message(conn, SMB_COM_READ_ANDX, &msg, sizeof(msg)); -} - -static CURLcode smb_send_write(struct connectdata *conn) -{ - struct smb_write *msg = (struct smb_write *)conn->data->state.uploadbuffer; - struct smb_request *req = conn->data->req.protop; - curl_off_t offset = conn->data->req.offset; - - curl_off_t upload_size = conn->data->req.size - conn->data->req.bytecount; - if(upload_size >= MAX_PAYLOAD_SIZE - 1) /* There is one byte of padding */ - upload_size = MAX_PAYLOAD_SIZE - 1; - - memset(msg, 0, sizeof(*msg)); - msg->word_count = SMB_WC_WRITE_ANDX; - msg->andx.command = SMB_COM_NO_ANDX_COMMAND; - msg->fid = smb_swap16(req->fid); - msg->offset = smb_swap32((unsigned int) offset); - msg->offset_high = smb_swap32((unsigned int) (offset >> 32)); - msg->data_length = smb_swap16((unsigned short) upload_size); - msg->data_offset = smb_swap16(sizeof(*msg) - sizeof(unsigned int)); - msg->byte_count = smb_swap16((unsigned short) (upload_size + 1)); - - smb_format_message(conn, &msg->h, SMB_COM_WRITE_ANDX, - sizeof(*msg) - sizeof(msg->h) + (size_t) upload_size); - - return smb_send(conn, sizeof(*msg), (size_t) upload_size); -} - -static CURLcode smb_send_and_recv(struct connectdata *conn, void **msg) -{ - struct smb_conn *smbc = &conn->proto.smbc; - CURLcode result; - - /* Check if there is data in the transfer buffer */ - if(!smbc->send_size && smbc->upload_size) { - int nread = smbc->upload_size > BUFSIZE ? BUFSIZE : - (int) smbc->upload_size; - conn->data->req.upload_fromhere = conn->data->state.uploadbuffer; - result = Curl_fillreadbuffer(conn, nread, &nread); - if(result && result != CURLE_AGAIN) - return result; - if(!nread) - return CURLE_OK; - - smbc->upload_size -= nread; - smbc->send_size = nread; - smbc->sent = 0; - } - - /* Check if there is data to send */ - if(smbc->send_size) { - result = smb_flush(conn); - if(result) - return result; - } - - /* Check if there is still data to be sent */ - if(smbc->send_size || smbc->upload_size) - return CURLE_AGAIN; - - return smb_recv_message(conn, msg); -} - -static CURLcode smb_connection_state(struct connectdata *conn, bool *done) -{ - struct smb_conn *smbc = &conn->proto.smbc; - struct smb_negotiate_response *nrsp; - struct smb_header *h; - CURLcode result; - void *msg = NULL; - - if(smbc->state == SMB_CONNECTING) { -#ifdef USE_SSL - if((conn->handler->flags & PROTOPT_SSL)) { - bool ssl_done; - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &ssl_done); - if(result && result != CURLE_AGAIN) - return result; - if(!ssl_done) - return CURLE_OK; - } -#endif - - result = smb_send_negotiate(conn); - if(result) { - connclose(conn, "SMB: failed to send negotiate message"); - return result; - } - - conn_state(conn, SMB_NEGOTIATE); - } - - /* Send the previous message and check for a response */ - result = smb_send_and_recv(conn, &msg); - if(result && result != CURLE_AGAIN) { - connclose(conn, "SMB: failed to communicate"); - return result; - } - - if(!msg) - return CURLE_OK; - - h = msg; - - switch(smbc->state) { - case SMB_NEGOTIATE: - if(h->status) { - connclose(conn, "SMB: negotiation failed"); - return CURLE_COULDNT_CONNECT; - } - nrsp = msg; - memcpy(smbc->challenge, nrsp->bytes, sizeof(smbc->challenge)); - smbc->session_key = smb_swap32(nrsp->session_key); - result = smb_send_setup(conn); - if(result) { - connclose(conn, "SMB: failed to send setup message"); - return result; - } - conn_state(conn, SMB_SETUP); - break; - - case SMB_SETUP: - if(h->status) { - connclose(conn, "SMB: authentication failed"); - return CURLE_LOGIN_DENIED; - } - smbc->uid = smb_swap16(h->uid); - conn_state(conn, SMB_CONNECTED); - *done = true; - break; - - default: - smb_pop_message(conn); - return CURLE_OK; /* ignore */ - } - - smb_pop_message(conn); - - return CURLE_OK; -} - -static CURLcode smb_request_state(struct connectdata *conn, bool *done) -{ - struct smb_request *req = conn->data->req.protop; - struct smb_header *h; - enum smb_req_state next_state = SMB_DONE; - unsigned short len; - unsigned short off; - CURLcode result; - void *msg = NULL; - - /* Start the request */ - if(req->state == SMB_REQUESTING) { - result = smb_send_tree_connect(conn); - if(result) { - connclose(conn, "SMB: failed to send tree connect message"); - return result; - } - - request_state(conn, SMB_TREE_CONNECT); - } - - /* Send the previous message and check for a response */ - result = smb_send_and_recv(conn, &msg); - if(result && result != CURLE_AGAIN) { - connclose(conn, "SMB: failed to communicate"); - return result; - } - - if(!msg) - return CURLE_OK; - - h = msg; - - switch(req->state) { - case SMB_TREE_CONNECT: - if(h->status) { - req->result = CURLE_REMOTE_FILE_NOT_FOUND; - if(h->status == smb_swap32(SMB_ERR_NOACCESS)) - req->result = CURLE_REMOTE_ACCESS_DENIED; - break; - } - req->tid = smb_swap16(h->tid); - next_state = SMB_OPEN; - break; - - case SMB_OPEN: - if(h->status) { - req->result = CURLE_REMOTE_FILE_NOT_FOUND; - next_state = SMB_TREE_DISCONNECT; - break; - } - req->fid = smb_swap16(((struct smb_nt_create_response *)msg)->fid); - conn->data->req.offset = 0; - if(conn->data->set.upload) { - conn->data->req.size = conn->data->state.infilesize; - Curl_pgrsSetUploadSize(conn->data, conn->data->req.size); - next_state = SMB_UPLOAD; - } - else { - conn->data->req.size = - smb_swap64(((struct smb_nt_create_response *)msg)->end_of_file); - Curl_pgrsSetDownloadSize(conn->data, conn->data->req.size); - next_state = SMB_DOWNLOAD; - } - break; - - case SMB_DOWNLOAD: - if(h->status) { - req->result = CURLE_RECV_ERROR; - next_state = SMB_CLOSE; - break; - } - len = Curl_read16_le(((unsigned char *) msg) + - sizeof(struct smb_header) + 11); - off = Curl_read16_le(((unsigned char *) msg) + - sizeof(struct smb_header) + 13); - if(len > 0) { - struct smb_conn *smbc = &conn->proto.smbc; - if(off + sizeof(unsigned int) + len > smbc->got) { - failf(conn->data, "Invalid input packet"); - result = CURLE_RECV_ERROR; - } - else - result = Curl_client_write(conn, CLIENTWRITE_BODY, - (char *)msg + off + sizeof(unsigned int), - len); - if(result) { - req->result = result; - next_state = SMB_CLOSE; - break; - } - } - conn->data->req.bytecount += len; - conn->data->req.offset += len; - Curl_pgrsSetDownloadCounter(conn->data, conn->data->req.bytecount); - next_state = (len < MAX_PAYLOAD_SIZE) ? SMB_CLOSE : SMB_DOWNLOAD; - break; - - case SMB_UPLOAD: - if(h->status) { - req->result = CURLE_UPLOAD_FAILED; - next_state = SMB_CLOSE; - break; - } - len = Curl_read16_le(((unsigned char *) msg) + - sizeof(struct smb_header) + 5); - conn->data->req.bytecount += len; - conn->data->req.offset += len; - Curl_pgrsSetUploadCounter(conn->data, conn->data->req.bytecount); - if(conn->data->req.bytecount >= conn->data->req.size) - next_state = SMB_CLOSE; - else - next_state = SMB_UPLOAD; - break; - - case SMB_CLOSE: - /* We don't care if the close failed, proceed to tree disconnect anyway */ - next_state = SMB_TREE_DISCONNECT; - break; - - case SMB_TREE_DISCONNECT: - next_state = SMB_DONE; - break; - - default: - smb_pop_message(conn); - return CURLE_OK; /* ignore */ - } - - smb_pop_message(conn); - - switch(next_state) { - case SMB_OPEN: - result = smb_send_open(conn); - break; - - case SMB_DOWNLOAD: - result = smb_send_read(conn); - break; - - case SMB_UPLOAD: - result = smb_send_write(conn); - break; - - case SMB_CLOSE: - result = smb_send_close(conn); - break; - - case SMB_TREE_DISCONNECT: - result = smb_send_tree_disconnect(conn); - break; - - case SMB_DONE: - result = req->result; - *done = true; - break; - - default: - break; - } - - if(result) { - connclose(conn, "SMB: failed to send message"); - return result; - } - - request_state(conn, next_state); - - return CURLE_OK; -} - -static CURLcode smb_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - struct smb_request *req = conn->data->req.protop; - - (void) premature; - - Curl_safefree(req->share); - Curl_safefree(conn->data->req.protop); - - return status; -} - -static CURLcode smb_disconnect(struct connectdata *conn, bool dead) -{ - struct smb_conn *smbc = &conn->proto.smbc; - struct smb_request *req = conn->data->req.protop; - - (void) dead; - - Curl_safefree(smbc->domain); - Curl_safefree(smbc->recv_buf); - - /* smb_done is not always called, so cleanup the request */ - if(req) { - Curl_safefree(req->share); - Curl_safefree(conn->data->req.protop); - } - - return CURLE_OK; -} - -static int smb_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks) -{ - struct smb_conn *smbc = &conn->proto.smbc; - - if(!numsocks) - return GETSOCK_BLANK; - - socks[0] = conn->sock[FIRSTSOCKET]; - - if(smbc->send_size || smbc->upload_size) - return GETSOCK_WRITESOCK(0); - - return GETSOCK_READSOCK(0); -} - -static CURLcode smb_parse_url_path(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct smb_request *req = data->req.protop; - char *path; - char *slash; - - /* URL decode the path */ - result = Curl_urldecode(data, data->state.path, 0, &path, NULL, TRUE); - if(result) - return result; - - /* Parse the path for the share */ - req->share = strdup((*path == '/' || *path == '\\') ? path + 1 : path); - if(!req->share) { - free(path); - - return CURLE_OUT_OF_MEMORY; - } - - slash = strchr(req->share, '/'); - if(!slash) - slash = strchr(req->share, '\\'); - - /* The share must be present */ - if(!slash) { - free(path); - - return CURLE_URL_MALFORMAT; - } - - /* Parse the path for the file path converting any forward slashes into - backslashes */ - *slash++ = 0; - req->path = slash; - for(; *slash; slash++) { - if(*slash == '/') - *slash = '\\'; - } - - free(path); - - return CURLE_OK; -} - -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */ diff --git a/Externals/curl/lib/smb.h b/Externals/curl/lib/smb.h deleted file mode 100644 index 1a4f66e5a8..0000000000 --- a/Externals/curl/lib/smb.h +++ /dev/null @@ -1,271 +0,0 @@ -#ifndef HEADER_CURL_SMB_H -#define HEADER_CURL_SMB_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2014, Bill Nagel , Exacq Technologies - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -enum smb_conn_state { - SMB_NOT_CONNECTED = 0, - SMB_CONNECTING, - SMB_NEGOTIATE, - SMB_SETUP, - SMB_CONNECTED -}; - -struct smb_conn { - enum smb_conn_state state; - char *user; - char *domain; - unsigned char challenge[8]; - unsigned int session_key; - unsigned short uid; - char *recv_buf; - size_t upload_size; - size_t send_size; - size_t sent; - size_t got; -}; - -/* - * Definitions for SMB protocol data structures - */ -#ifdef BUILDING_CURL_SMB_C - -#if defined(_MSC_VER) || defined(__ILEC400__) -# define PACK -# pragma pack(push) -# pragma pack(1) -#elif defined(__GNUC__) -# define PACK __attribute__((packed)) -#else -# define PACK -#endif - -#define SMB_COM_CLOSE 0x04 -#define SMB_COM_READ_ANDX 0x2e -#define SMB_COM_WRITE_ANDX 0x2f -#define SMB_COM_TREE_DISCONNECT 0x71 -#define SMB_COM_NEGOTIATE 0x72 -#define SMB_COM_SETUP_ANDX 0x73 -#define SMB_COM_TREE_CONNECT_ANDX 0x75 -#define SMB_COM_NT_CREATE_ANDX 0xa2 -#define SMB_COM_NO_ANDX_COMMAND 0xff - -#define SMB_WC_CLOSE 0x03 -#define SMB_WC_READ_ANDX 0x0c -#define SMB_WC_WRITE_ANDX 0x0e -#define SMB_WC_SETUP_ANDX 0x0d -#define SMB_WC_TREE_CONNECT_ANDX 0x04 -#define SMB_WC_NT_CREATE_ANDX 0x18 - -#define SMB_FLAGS_CANONICAL_PATHNAMES 0x10 -#define SMB_FLAGS_CASELESS_PATHNAMES 0x08 -#define SMB_FLAGS2_UNICODE_STRINGS 0x8000 -#define SMB_FLAGS2_IS_LONG_NAME 0x0040 -#define SMB_FLAGS2_KNOWS_LONG_NAME 0x0001 - -#define SMB_CAP_LARGE_FILES 0x08 -#define SMB_GENERIC_WRITE 0x40000000 -#define SMB_GENERIC_READ 0x80000000 -#define SMB_FILE_SHARE_ALL 0x07 -#define SMB_FILE_OPEN 0x01 -#define SMB_FILE_OVERWRITE_IF 0x05 - -#define SMB_ERR_NOACCESS 0x00050001 - -struct smb_header { - unsigned char nbt_type; - unsigned char nbt_flags; - unsigned short nbt_length; - unsigned char magic[4]; - unsigned char command; - unsigned int status; - unsigned char flags; - unsigned short flags2; - unsigned short pid_high; - unsigned char signature[8]; - unsigned short pad; - unsigned short tid; - unsigned short pid; - unsigned short uid; - unsigned short mid; -} PACK; - -struct smb_negotiate_response { - struct smb_header h; - unsigned char word_count; - unsigned short dialect_index; - unsigned char security_mode; - unsigned short max_mpx_count; - unsigned short max_number_vcs; - unsigned int max_buffer_size; - unsigned int max_raw_size; - unsigned int session_key; - unsigned int capabilities; - unsigned int system_time_low; - unsigned int system_time_high; - unsigned short server_time_zone; - unsigned char encryption_key_length; - unsigned short byte_count; - char bytes[1]; -} PACK; - -struct andx { - unsigned char command; - unsigned char pad; - unsigned short offset; -} PACK; - -struct smb_setup { - unsigned char word_count; - struct andx andx; - unsigned short max_buffer_size; - unsigned short max_mpx_count; - unsigned short vc_number; - unsigned int session_key; - unsigned short lengths[2]; - unsigned int pad; - unsigned int capabilities; - unsigned short byte_count; - char bytes[1024]; -} PACK; - -struct smb_tree_connect { - unsigned char word_count; - struct andx andx; - unsigned short flags; - unsigned short pw_len; - unsigned short byte_count; - char bytes[1024]; -} PACK; - -struct smb_nt_create { - unsigned char word_count; - struct andx andx; - unsigned char pad; - unsigned short name_length; - unsigned int flags; - unsigned int root_fid; - unsigned int access; -#ifdef HAVE_LONGLONG - unsigned long long allocation_size; -#else - unsigned __int64 allocation_size; -#endif - unsigned int ext_file_attributes; - unsigned int share_access; - unsigned int create_disposition; - unsigned int create_options; - unsigned int impersonation_level; - unsigned char security_flags; - unsigned short byte_count; - char bytes[1024]; -} PACK; - -struct smb_nt_create_response { - struct smb_header h; - unsigned char word_count; - struct andx andx; - unsigned char op_lock_level; - unsigned short fid; - unsigned int create_disposition; -#ifdef HAVE_LONGLONG - unsigned long long create_time; - unsigned long long last_access_time; - unsigned long long last_write_time; - unsigned long long last_change_time; -#else - unsigned __int64 create_time; - unsigned __int64 last_access_time; - unsigned __int64 last_write_time; - unsigned __int64 last_change_time; -#endif - unsigned int ext_file_attributes; -#ifdef HAVE_LONGLONG - unsigned long long allocation_size; - unsigned long long end_of_file; -#else - unsigned __int64 allocation_size; - unsigned __int64 end_of_file; -#endif -} PACK; - -struct smb_read { - unsigned char word_count; - struct andx andx; - unsigned short fid; - unsigned int offset; - unsigned short max_bytes; - unsigned short min_bytes; - unsigned int timeout; - unsigned short remaining; - unsigned int offset_high; - unsigned short byte_count; -} PACK; - -struct smb_write { - struct smb_header h; - unsigned char word_count; - struct andx andx; - unsigned short fid; - unsigned int offset; - unsigned int timeout; - unsigned short write_mode; - unsigned short remaining; - unsigned short pad; - unsigned short data_length; - unsigned short data_offset; - unsigned int offset_high; - unsigned short byte_count; - unsigned char pad2; -} PACK; - -struct smb_close { - unsigned char word_count; - unsigned short fid; - unsigned int last_mtime; - unsigned short byte_count; -} PACK; - -struct smb_tree_disconnect { - unsigned char word_count; - unsigned short byte_count; -} PACK; - -#if defined(_MSC_VER) || defined(__ILEC400__) -# pragma pack(pop) -#endif - -#endif /* BUILDING_CURL_SMB_C */ - -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) - -#if !defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO) - -extern const struct Curl_handler Curl_handler_smb; -extern const struct Curl_handler Curl_handler_smbs; - -#endif /* !USE_WINDOWS_SSPI || USE_WIN32_CRYPTO */ - -#endif /* CURL_DISABLE_SMB && USE_NTLM && CURL_SIZEOF_CURL_OFF_T > 4 */ - -#endif /* HEADER_CURL_SMB_H */ diff --git a/Externals/curl/lib/smtp.c b/Externals/curl/lib/smtp.c deleted file mode 100644 index 2a5b2bfee4..0000000000 --- a/Externals/curl/lib/smtp.c +++ /dev/null @@ -1,1674 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC1870 SMTP Service Extension for Message Size - * RFC2195 CRAM-MD5 authentication - * RFC2831 DIGEST-MD5 authentication - * RFC3207 SMTP over TLS - * RFC4422 Simple Authentication and Security Layer (SASL) - * RFC4616 PLAIN authentication - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * RFC4954 SMTP Authentication - * RFC5321 SMTP protocol - * RFC6749 OAuth 2.0 Authorization Framework - * Draft SMTP URL Interface - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_SMTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_UTSNAME_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "socks.h" -#include "smtp.h" - -#include "strtoofft.h" -#include "strequal.h" -#include "vtls/vtls.h" -#include "connect.h" -#include "strerror.h" -#include "select.h" -#include "multiif.h" -#include "url.h" -#include "rawstr.h" -#include "curl_gethostname.h" -#include "curl_sasl.h" -#include "warnless.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Local API functions */ -static CURLcode smtp_regular_transfer(struct connectdata *conn, bool *done); -static CURLcode smtp_do(struct connectdata *conn, bool *done); -static CURLcode smtp_done(struct connectdata *conn, CURLcode status, - bool premature); -static CURLcode smtp_connect(struct connectdata *conn, bool *done); -static CURLcode smtp_disconnect(struct connectdata *conn, bool dead); -static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done); -static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks); -static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done); -static CURLcode smtp_setup_connection(struct connectdata *conn); -static CURLcode smtp_parse_url_options(struct connectdata *conn); -static CURLcode smtp_parse_url_path(struct connectdata *conn); -static CURLcode smtp_parse_custom_request(struct connectdata *conn); -static CURLcode smtp_perform_auth(struct connectdata *conn, const char *mech, - const char *initresp); -static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp); -static void smtp_get_message(char *buffer, char** outptr); - -/* - * SMTP protocol handler. - */ - -const struct Curl_handler Curl_handler_smtp = { - "SMTP", /* scheme */ - smtp_setup_connection, /* setup_connection */ - smtp_do, /* do_it */ - smtp_done, /* done */ - ZERO_NULL, /* do_more */ - smtp_connect, /* connect_it */ - smtp_multi_statemach, /* connecting */ - smtp_doing, /* doing */ - smtp_getsock, /* proto_getsock */ - smtp_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - smtp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SMTP, /* defport */ - CURLPROTO_SMTP, /* protocol */ - PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY /* flags */ -}; - -#ifdef USE_SSL -/* - * SMTPS protocol handler. - */ - -const struct Curl_handler Curl_handler_smtps = { - "SMTPS", /* scheme */ - smtp_setup_connection, /* setup_connection */ - smtp_do, /* do_it */ - smtp_done, /* done */ - ZERO_NULL, /* do_more */ - smtp_connect, /* connect_it */ - smtp_multi_statemach, /* connecting */ - smtp_doing, /* doing */ - smtp_getsock, /* proto_getsock */ - smtp_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - smtp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SMTPS, /* defport */ - CURLPROTO_SMTPS, /* protocol */ - PROTOPT_CLOSEACTION | PROTOPT_SSL - | PROTOPT_NOURLQUERY /* flags */ -}; -#endif - -#ifndef CURL_DISABLE_HTTP -/* - * HTTP-proxyed SMTP protocol handler. - */ - -static const struct Curl_handler Curl_handler_smtp_proxy = { - "SMTP", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SMTP, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -#ifdef USE_SSL -/* - * HTTP-proxyed SMTPS protocol handler. - */ - -static const struct Curl_handler Curl_handler_smtps_proxy = { - "SMTPS", /* scheme */ - Curl_http_setup_conn, /* setup_connection */ - Curl_http, /* do_it */ - Curl_http_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SMTPS, /* defport */ - CURLPROTO_HTTP, /* protocol */ - PROTOPT_NONE /* flags */ -}; -#endif -#endif - -/* SASL parameters for the smtp protocol */ -static const struct SASLproto saslsmtp = { - "smtp", /* The service name */ - 334, /* Code received when continuation is expected */ - 235, /* Code to receive upon authentication success */ - 512 - 8, /* Maximum initial response length (no max) */ - smtp_perform_auth, /* Send authentication command */ - smtp_continue_auth, /* Send authentication continuation */ - smtp_get_message /* Get SASL response message */ -}; - -#ifdef USE_SSL -static void smtp_to_smtps(struct connectdata *conn) -{ - /* Change the connection handler */ - conn->handler = &Curl_handler_smtps; - - /* Set the connection's upgraded to TLS flag */ - conn->tls_upgraded = TRUE; -} -#else -#define smtp_to_smtps(x) Curl_nop_stmt -#endif - -/*********************************************************************** - * - * smtp_endofresp() - * - * Checks for an ending SMTP status code at the start of the given string, but - * also detects various capabilities from the EHLO response including the - * supported authentication mechanisms. - */ -static bool smtp_endofresp(struct connectdata *conn, char *line, size_t len, - int *resp) -{ - struct smtp_conn *smtpc = &conn->proto.smtpc; - bool result = FALSE; - - /* Nothing for us */ - if(len < 4 || !ISDIGIT(line[0]) || !ISDIGIT(line[1]) || !ISDIGIT(line[2])) - return FALSE; - - /* Do we have a command response? This should be the response code followed - by a space and optionally some text as per RFC-5321 and as outlined in - Section 4. Examples of RFC-4954 but some e-mail servers ignore this and - only send the response code instead as per Section 4.2. */ - if(line[3] == ' ' || len == 5) { - result = TRUE; - *resp = curlx_sltosi(strtol(line, NULL, 10)); - - /* Make sure real server never sends internal value */ - if(*resp == 1) - *resp = 0; - } - /* Do we have a multiline (continuation) response? */ - else if(line[3] == '-' && - (smtpc->state == SMTP_EHLO || smtpc->state == SMTP_COMMAND)) { - result = TRUE; - *resp = 1; /* Internal response code */ - } - - return result; -} - -/*********************************************************************** - * - * smtp_get_message() - * - * Gets the authentication message from the response buffer. - */ -static void smtp_get_message(char *buffer, char** outptr) -{ - size_t len = 0; - char* message = NULL; - - /* Find the start of the message */ - for(message = buffer + 4; *message == ' ' || *message == '\t'; message++) - ; - - /* Find the end of the message */ - for(len = strlen(message); len--;) - if(message[len] != '\r' && message[len] != '\n' && message[len] != ' ' && - message[len] != '\t') - break; - - /* Terminate the message */ - if(++len) { - message[len] = '\0'; - } - - *outptr = message; -} - -/*********************************************************************** - * - * state() - * - * This is the ONLY way to change SMTP state! - */ -static void state(struct connectdata *conn, smtpstate newstate) -{ - struct smtp_conn *smtpc = &conn->proto.smtpc; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char * const names[] = { - "STOP", - "SERVERGREET", - "EHLO", - "HELO", - "STARTTLS", - "UPGRADETLS", - "AUTH", - "COMMAND", - "MAIL", - "RCPT", - "DATA", - "POSTDATA", - "QUIT", - /* LAST */ - }; - - if(smtpc->state != newstate) - infof(conn->data, "SMTP %p state change from %s to %s\n", - (void *)smtpc, names[smtpc->state], names[newstate]); -#endif - - smtpc->state = newstate; -} - -/*********************************************************************** - * - * smtp_perform_ehlo() - * - * Sends the EHLO command to not only initialise communication with the ESMTP - * server but to also obtain a list of server side supported capabilities. - */ -static CURLcode smtp_perform_ehlo(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - - smtpc->sasl.authmechs = SASL_AUTH_NONE; /* No known auth. mechanism yet */ - smtpc->sasl.authused = SASL_AUTH_NONE; /* Clear the authentication mechanism - used for esmtp connections */ - smtpc->tls_supported = FALSE; /* Clear the TLS capability */ - smtpc->auth_supported = FALSE; /* Clear the AUTH capability */ - - /* Send the EHLO command */ - result = Curl_pp_sendf(&smtpc->pp, "EHLO %s", smtpc->domain); - - if(!result) - state(conn, SMTP_EHLO); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_helo() - * - * Sends the HELO command to initialise communication with the SMTP server. - */ -static CURLcode smtp_perform_helo(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - - smtpc->sasl.authused = SASL_AUTH_NONE; /* No authentication mechanism used - in smtp connections */ - - /* Send the HELO command */ - result = Curl_pp_sendf(&smtpc->pp, "HELO %s", smtpc->domain); - - if(!result) - state(conn, SMTP_HELO); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_starttls() - * - * Sends the STLS command to start the upgrade to TLS. - */ -static CURLcode smtp_perform_starttls(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* Send the STARTTLS command */ - result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "STARTTLS"); - - if(!result) - state(conn, SMTP_STARTTLS); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_upgrade_tls() - * - * Performs the upgrade to TLS. - */ -static CURLcode smtp_perform_upgrade_tls(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - - /* Start the SSL connection */ - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); - - if(!result) { - if(smtpc->state != SMTP_UPGRADETLS) - state(conn, SMTP_UPGRADETLS); - - if(smtpc->ssldone) { - smtp_to_smtps(conn); - result = smtp_perform_ehlo(conn); - } - } - - return result; -} - -/*********************************************************************** - * - * smtp_perform_auth() - * - * Sends an AUTH command allowing the client to login with the given SASL - * authentication mechanism. - */ -static CURLcode smtp_perform_auth(struct connectdata *conn, - const char *mech, - const char *initresp) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - - if(initresp) { /* AUTH ... */ - /* Send the AUTH command with the initial response */ - result = Curl_pp_sendf(&smtpc->pp, "AUTH %s %s", mech, initresp); - } - else { - /* Send the AUTH command */ - result = Curl_pp_sendf(&smtpc->pp, "AUTH %s", mech); - } - - return result; -} - -/*********************************************************************** - * - * smtp_continue_auth() - * - * Sends SASL continuation data or cancellation. - */ -static CURLcode smtp_continue_auth(struct connectdata *conn, const char *resp) -{ - struct smtp_conn *smtpc = &conn->proto.smtpc; - - return Curl_pp_sendf(&smtpc->pp, "%s", resp); -} - -/*********************************************************************** - * - * smtp_perform_authentication() - * - * Initiates the authentication sequence, with the appropriate SASL - * authentication mechanism. - */ -static CURLcode smtp_perform_authentication(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - saslprogress progress; - - /* Check we have enough data to authenticate with, and the - server supports authentiation, and end the connect phase if not */ - if(!smtpc->auth_supported || - !Curl_sasl_can_authenticate(&smtpc->sasl, conn)) { - state(conn, SMTP_STOP); - return result; - } - - /* Calculate the SASL login details */ - result = Curl_sasl_start(&smtpc->sasl, conn, FALSE, &progress); - - if(!result) { - if(progress == SASL_INPROGRESS) - state(conn, SMTP_AUTH); - else { - /* Other mechanisms not supported */ - infof(conn->data, "No known authentication mechanisms supported!\n"); - result = CURLE_LOGIN_DENIED; - } - } - - return result; -} - -/*********************************************************************** - * - * smtp_perform_command() - * - * Sends a SMTP based command. - */ -static CURLcode smtp_perform_command(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - - /* Send the command */ - if(smtp->rcpt) - result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s %s", - smtp->custom && smtp->custom[0] != '\0' ? - smtp->custom : "VRFY", - smtp->rcpt->data); - else - result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", - smtp->custom && smtp->custom[0] != '\0' ? - smtp->custom : "HELP"); - - if(!result) - state(conn, SMTP_COMMAND); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_mail() - * - * Sends an MAIL command to initiate the upload of a message. - */ -static CURLcode smtp_perform_mail(struct connectdata *conn) -{ - char *from = NULL; - char *auth = NULL; - char *size = NULL; - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - /* Calculate the FROM parameter */ - if(!data->set.str[STRING_MAIL_FROM]) - /* Null reverse-path, RFC-5321, sect. 3.6.3 */ - from = strdup("<>"); - else if(data->set.str[STRING_MAIL_FROM][0] == '<') - from = aprintf("%s", data->set.str[STRING_MAIL_FROM]); - else - from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]); - - if(!from) - return CURLE_OUT_OF_MEMORY; - - /* Calculate the optional AUTH parameter */ - if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) { - if(data->set.str[STRING_MAIL_AUTH][0] != '\0') - auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]); - else - /* Empty AUTH, RFC-2554, sect. 5 */ - auth = strdup("<>"); - - if(!auth) { - free(from); - - return CURLE_OUT_OF_MEMORY; - } - } - - /* Calculate the optional SIZE parameter */ - if(conn->proto.smtpc.size_supported && conn->data->state.infilesize > 0) { - size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize); - - if(!size) { - free(from); - free(auth); - - return CURLE_OUT_OF_MEMORY; - } - } - - /* Send the MAIL command */ - if(!auth && !size) - result = Curl_pp_sendf(&conn->proto.smtpc.pp, - "MAIL FROM:%s", from); - else if(auth && !size) - result = Curl_pp_sendf(&conn->proto.smtpc.pp, - "MAIL FROM:%s AUTH=%s", from, auth); - else if(auth && size) - result = Curl_pp_sendf(&conn->proto.smtpc.pp, - "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size); - else - result = Curl_pp_sendf(&conn->proto.smtpc.pp, - "MAIL FROM:%s SIZE=%s", from, size); - - free(from); - free(auth); - free(size); - - if(!result) - state(conn, SMTP_MAIL); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_rcpt_to() - * - * Sends a RCPT TO command for a given recipient as part of the message upload - * process. - */ -static CURLcode smtp_perform_rcpt_to(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - - /* Send the RCPT TO command */ - if(smtp->rcpt->data[0] == '<') - result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:%s", - smtp->rcpt->data); - else - result = Curl_pp_sendf(&conn->proto.smtpc.pp, "RCPT TO:<%s>", - smtp->rcpt->data); - if(!result) - state(conn, SMTP_RCPT); - - return result; -} - -/*********************************************************************** - * - * smtp_perform_quit() - * - * Performs the quit action prior to sclose() being called. - */ -static CURLcode smtp_perform_quit(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - - /* Send the QUIT command */ - result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "QUIT"); - - if(!result) - state(conn, SMTP_QUIT); - - return result; -} - -/* For the initial server greeting */ -static CURLcode smtp_state_servergreet_resp(struct connectdata *conn, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(smtpcode/100 != 2) { - failf(data, "Got unexpected smtp-server response: %d", smtpcode); - result = CURLE_FTP_WEIRD_SERVER_REPLY; - } - else - result = smtp_perform_ehlo(conn); - - return result; -} - -/* For STARTTLS responses */ -static CURLcode smtp_state_starttls_resp(struct connectdata *conn, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(smtpcode != 220) { - if(data->set.use_ssl != CURLUSESSL_TRY) { - failf(data, "STARTTLS denied. %c", smtpcode); - result = CURLE_USE_SSL_FAILED; - } - else - result = smtp_perform_authentication(conn); - } - else - result = smtp_perform_upgrade_tls(conn); - - return result; -} - -/* For EHLO responses */ -static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct smtp_conn *smtpc = &conn->proto.smtpc; - const char *line = data->state.buffer; - size_t len = strlen(line); - size_t wordlen; - - (void)instate; /* no use for this yet */ - - if(smtpcode/100 != 2 && smtpcode != 1) { - if(data->set.use_ssl <= CURLUSESSL_TRY || conn->ssl[FIRSTSOCKET].use) - result = smtp_perform_helo(conn); - else { - failf(data, "Remote access denied: %d", smtpcode); - result = CURLE_REMOTE_ACCESS_DENIED; - } - } - else { - line += 4; - len -= 4; - - /* Does the server support the STARTTLS capability? */ - if(len >= 8 && !memcmp(line, "STARTTLS", 8)) - smtpc->tls_supported = TRUE; - - /* Does the server support the SIZE capability? */ - else if(len >= 4 && !memcmp(line, "SIZE", 4)) - smtpc->size_supported = TRUE; - - /* Does the server support authentication? */ - else if(len >= 5 && !memcmp(line, "AUTH ", 5)) { - smtpc->auth_supported = TRUE; - - /* Advance past the AUTH keyword */ - line += 5; - len -= 5; - - /* Loop through the data line */ - for(;;) { - size_t llen; - unsigned int mechbit; - - while(len && - (*line == ' ' || *line == '\t' || - *line == '\r' || *line == '\n')) { - - line++; - len--; - } - - if(!len) - break; - - /* Extract the word */ - for(wordlen = 0; wordlen < len && line[wordlen] != ' ' && - line[wordlen] != '\t' && line[wordlen] != '\r' && - line[wordlen] != '\n';) - wordlen++; - - /* Test the word for a matching authentication mechanism */ - mechbit = Curl_sasl_decode_mech(line, wordlen, &llen); - if(mechbit && llen == wordlen) - smtpc->sasl.authmechs |= mechbit; - - line += wordlen; - len -= wordlen; - } - } - - if(smtpcode != 1) { - if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { - /* We don't have a SSL/TLS connection yet, but SSL is requested */ - if(smtpc->tls_supported) - /* Switch to TLS connection now */ - result = smtp_perform_starttls(conn); - else if(data->set.use_ssl == CURLUSESSL_TRY) - /* Fallback and carry on with authentication */ - result = smtp_perform_authentication(conn); - else { - failf(data, "STARTTLS not supported."); - result = CURLE_USE_SSL_FAILED; - } - } - else - result = smtp_perform_authentication(conn); - } - } - - return result; -} - -/* For HELO responses */ -static CURLcode smtp_state_helo_resp(struct connectdata *conn, int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(smtpcode/100 != 2) { - failf(data, "Remote access denied: %d", smtpcode); - result = CURLE_REMOTE_ACCESS_DENIED; - } - else - /* End of connect phase */ - state(conn, SMTP_STOP); - - return result; -} - -/* For SASL authentication responses */ -static CURLcode smtp_state_auth_resp(struct connectdata *conn, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct smtp_conn *smtpc = &conn->proto.smtpc; - saslprogress progress; - - (void)instate; /* no use for this yet */ - - result = Curl_sasl_continue(&smtpc->sasl, conn, smtpcode, &progress); - if(!result) - switch(progress) { - case SASL_DONE: - state(conn, SMTP_STOP); /* Authenticated */ - break; - case SASL_IDLE: /* No mechanism left after cancellation */ - failf(data, "Authentication cancelled"); - result = CURLE_LOGIN_DENIED; - break; - default: - break; - } - - return result; -} - -/* For command responses */ -static CURLcode smtp_state_command_resp(struct connectdata *conn, int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - char *line = data->state.buffer; - size_t len = strlen(line); - - (void)instate; /* no use for this yet */ - - if((smtp->rcpt && smtpcode/100 != 2 && smtpcode != 553 && smtpcode != 1) || - (!smtp->rcpt && smtpcode/100 != 2 && smtpcode != 1)) { - failf(data, "Command failed: %d", smtpcode); - result = CURLE_RECV_ERROR; - } - else { - /* Temporarily add the LF character back and send as body to the client */ - if(!data->set.opt_no_body) { - line[len] = '\n'; - result = Curl_client_write(conn, CLIENTWRITE_BODY, line, len + 1); - line[len] = '\0'; - } - - if(smtpcode != 1) { - if(smtp->rcpt) { - smtp->rcpt = smtp->rcpt->next; - - if(smtp->rcpt) { - /* Send the next command */ - result = smtp_perform_command(conn); - } - else - /* End of DO phase */ - state(conn, SMTP_STOP); - } - else - /* End of DO phase */ - state(conn, SMTP_STOP); - } - } - - return result; -} - -/* For MAIL responses */ -static CURLcode smtp_state_mail_resp(struct connectdata *conn, int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(smtpcode/100 != 2) { - failf(data, "MAIL failed: %d", smtpcode); - result = CURLE_SEND_ERROR; - } - else - /* Start the RCPT TO command */ - result = smtp_perform_rcpt_to(conn); - - return result; -} - -/* For RCPT responses */ -static CURLcode smtp_state_rcpt_resp(struct connectdata *conn, int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - - (void)instate; /* no use for this yet */ - - if(smtpcode/100 != 2) { - failf(data, "RCPT failed: %d", smtpcode); - result = CURLE_SEND_ERROR; - } - else { - smtp->rcpt = smtp->rcpt->next; - - if(smtp->rcpt) - /* Send the next RCPT TO command */ - result = smtp_perform_rcpt_to(conn); - else { - /* Send the DATA command */ - result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "DATA"); - - if(!result) - state(conn, SMTP_DATA); - } - } - - return result; -} - -/* For DATA response */ -static CURLcode smtp_state_data_resp(struct connectdata *conn, int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - (void)instate; /* no use for this yet */ - - if(smtpcode != 354) { - failf(data, "DATA failed: %d", smtpcode); - result = CURLE_SEND_ERROR; - } - else { - /* Set the progress upload size */ - Curl_pgrsSetUploadSize(data, data->state.infilesize); - - /* SMTP upload */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); - - /* End of DO phase */ - state(conn, SMTP_STOP); - } - - return result; -} - -/* For POSTDATA responses, which are received after the entire DATA - part has been sent to the server */ -static CURLcode smtp_state_postdata_resp(struct connectdata *conn, - int smtpcode, - smtpstate instate) -{ - CURLcode result = CURLE_OK; - - (void)instate; /* no use for this yet */ - - if(smtpcode != 250) - result = CURLE_RECV_ERROR; - - /* End of DONE phase */ - state(conn, SMTP_STOP); - - return result; -} - -static CURLcode smtp_statemach_act(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - struct SessionHandle *data = conn->data; - int smtpcode; - struct smtp_conn *smtpc = &conn->proto.smtpc; - struct pingpong *pp = &smtpc->pp; - size_t nread = 0; - - /* Busy upgrading the connection; right now all I/O is SSL/TLS, not SMTP */ - if(smtpc->state == SMTP_UPGRADETLS) - return smtp_perform_upgrade_tls(conn); - - /* Flush any data that needs to be sent */ - if(pp->sendleft) - return Curl_pp_flushsend(pp); - - do { - /* Read the response from the server */ - result = Curl_pp_readresp(sock, pp, &smtpcode, &nread); - if(result) - return result; - - /* Store the latest response for later retrieval if necessary */ - if(smtpc->state != SMTP_QUIT && smtpcode != 1) - data->info.httpcode = smtpcode; - - if(!smtpcode) - break; - - /* We have now received a full SMTP server response */ - switch(smtpc->state) { - case SMTP_SERVERGREET: - result = smtp_state_servergreet_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_EHLO: - result = smtp_state_ehlo_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_HELO: - result = smtp_state_helo_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_STARTTLS: - result = smtp_state_starttls_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_AUTH: - result = smtp_state_auth_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_COMMAND: - result = smtp_state_command_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_MAIL: - result = smtp_state_mail_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_RCPT: - result = smtp_state_rcpt_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_DATA: - result = smtp_state_data_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_POSTDATA: - result = smtp_state_postdata_resp(conn, smtpcode, smtpc->state); - break; - - case SMTP_QUIT: - /* fallthrough, just stop! */ - default: - /* internal error */ - state(conn, SMTP_STOP); - break; - } - } while(!result && smtpc->state != SMTP_STOP && Curl_pp_moredata(pp)); - - return result; -} - -/* Called repeatedly until done from multi.c */ -static CURLcode smtp_multi_statemach(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - - if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) { - result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, &smtpc->ssldone); - if(result || !smtpc->ssldone) - return result; - } - - result = Curl_pp_statemach(&smtpc->pp, FALSE); - *done = (smtpc->state == SMTP_STOP) ? TRUE : FALSE; - - return result; -} - -static CURLcode smtp_block_statemach(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - - while(smtpc->state != SMTP_STOP && !result) - result = Curl_pp_statemach(&smtpc->pp, TRUE); - - return result; -} - -/* Allocate and initialize the SMTP struct for the current SessionHandle if - required */ -static CURLcode smtp_init(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp; - - smtp = data->req.protop = calloc(sizeof(struct SMTP), 1); - if(!smtp) - result = CURLE_OUT_OF_MEMORY; - - return result; -} - -/* For the SMTP "protocol connect" and "doing" phases only */ -static int smtp_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks) -{ - return Curl_pp_getsock(&conn->proto.smtpc.pp, socks, numsocks); -} - -/*********************************************************************** - * - * smtp_connect() - * - * This function should do everything that is to be considered a part of - * the connection phase. - * - * The variable pointed to by 'done' will be TRUE if the protocol-layer - * connect phase is done when this function returns, or FALSE if not. - */ -static CURLcode smtp_connect(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - struct pingpong *pp = &smtpc->pp; - - *done = FALSE; /* default to not done yet */ - - /* We always support persistent connections in SMTP */ - connkeep(conn, "SMTP default"); - - /* Set the default response time-out */ - pp->response_time = RESP_TIMEOUT; - pp->statemach_act = smtp_statemach_act; - pp->endofresp = smtp_endofresp; - pp->conn = conn; - - /* Initialize the SASL storage */ - Curl_sasl_init(&smtpc->sasl, &saslsmtp); - - /* Initialise the pingpong layer */ - Curl_pp_init(pp); - - /* Parse the URL options */ - result = smtp_parse_url_options(conn); - if(result) - return result; - - /* Parse the URL path */ - result = smtp_parse_url_path(conn); - if(result) - return result; - - /* Start off waiting for the server greeting response */ - state(conn, SMTP_SERVERGREET); - - result = smtp_multi_statemach(conn, done); - - return result; -} - -/*********************************************************************** - * - * smtp_done() - * - * The DONE function. This does what needs to be done after a single DO has - * performed. - * - * Input argument is already checked for validity. - */ -static CURLcode smtp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - struct pingpong *pp = &conn->proto.smtpc.pp; - char *eob; - ssize_t len; - ssize_t bytes_written; - - (void)premature; - - if(!smtp || !pp->conn) - return CURLE_OK; - - if(status) { - connclose(conn, "SMTP done with bad status"); /* marked for closure */ - result = status; /* use the already set error code */ - } - else if(!data->set.connect_only && data->set.upload && data->set.mail_rcpt) { - /* Calculate the EOB taking into account any terminating CRLF from the - previous line of the email or the CRLF of the DATA command when there - is "no mail data". RFC-5321, sect. 4.1.1.4. - - Note: As some SSL backends, such as OpenSSL, will cause Curl_write() to - fail when using a different pointer following a previous write, that - returned CURLE_AGAIN, we duplicate the EOB now rather than when the - bytes written doesn't equal len. */ - if(smtp->trailing_crlf || !conn->data->state.infilesize) { - eob = strdup(SMTP_EOB + 2); - len = SMTP_EOB_LEN - 2; - } - else { - eob = strdup(SMTP_EOB); - len = SMTP_EOB_LEN; - } - - if(!eob) - return CURLE_OUT_OF_MEMORY; - - /* Send the end of block data */ - result = Curl_write(conn, conn->writesockfd, eob, len, &bytes_written); - if(result) { - free(eob); - return result; - } - - if(bytes_written != len) { - /* The whole chunk was not sent so keep it around and adjust the - pingpong structure accordingly */ - pp->sendthis = eob; - pp->sendsize = len; - pp->sendleft = len - bytes_written; - } - else { - /* Successfully sent so adjust the response timeout relative to now */ - pp->response = Curl_tvnow(); - - free(eob); - } - - state(conn, SMTP_POSTDATA); - - /* Run the state-machine - - TODO: when the multi interface is used, this _really_ should be using - the smtp_multi_statemach function but we have no general support for - non-blocking DONE operations! - */ - result = smtp_block_statemach(conn); - } - - /* Cleanup our per-request based variables */ - Curl_safefree(smtp->custom); - - /* Clear the transfer mode for the next request */ - smtp->transfer = FTPTRANSFER_BODY; - - return result; -} - -/*********************************************************************** - * - * smtp_perform() - * - * This is the actual DO function for SMTP. Transfer a mail, send a command - * or get some data according to the options previously setup. - */ -static CURLcode smtp_perform(struct connectdata *conn, bool *connected, - bool *dophase_done) -{ - /* This is SMTP and no proxy */ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - if(data->set.opt_no_body) { - /* Requested no body means no transfer */ - smtp->transfer = FTPTRANSFER_INFO; - } - - *dophase_done = FALSE; /* not done yet */ - - /* Store the first recipient (or NULL if not specified) */ - smtp->rcpt = data->set.mail_rcpt; - - /* Start the first command in the DO phase */ - if(data->set.upload && data->set.mail_rcpt) - /* MAIL transfer */ - result = smtp_perform_mail(conn); - else - /* SMTP based command (VRFY, EXPN, NOOP, RSET or HELP) */ - result = smtp_perform_command(conn); - - if(result) - return result; - - /* Run the state-machine */ - result = smtp_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) - DEBUGF(infof(conn->data, "DO phase is complete\n")); - - return result; -} - -/*********************************************************************** - * - * smtp_do() - * - * This function is registered as 'curl_do' function. It decodes the path - * parts etc as a wrapper to the actual DO function (smtp_perform). - * - * The input argument is already checked for validity. - */ -static CURLcode smtp_do(struct connectdata *conn, bool *done) -{ - CURLcode result = CURLE_OK; - - *done = FALSE; /* default to false */ - - /* Parse the custom request */ - result = smtp_parse_custom_request(conn); - if(result) - return result; - - result = smtp_regular_transfer(conn, done); - - return result; -} - -/*********************************************************************** - * - * smtp_disconnect() - * - * Disconnect from an SMTP server. Cleanup protocol-specific per-connection - * resources. BLOCKING. - */ -static CURLcode smtp_disconnect(struct connectdata *conn, bool dead_connection) -{ - struct smtp_conn *smtpc = &conn->proto.smtpc; - - /* We cannot send quit unconditionally. If this connection is stale or - bad in any way, sending quit and waiting around here will make the - disconnect wait in vain and cause more problems than we need to. */ - - /* The SMTP session may or may not have been allocated/setup at this - point! */ - if(!dead_connection && smtpc->pp.conn && smtpc->pp.conn->bits.protoconnstart) - if(!smtp_perform_quit(conn)) - (void)smtp_block_statemach(conn); /* ignore errors on QUIT */ - - /* Disconnect from the server */ - Curl_pp_disconnect(&smtpc->pp); - - /* Cleanup the SASL module */ - Curl_sasl_cleanup(conn, smtpc->sasl.authused); - - /* Cleanup our connection based variables */ - Curl_safefree(smtpc->domain); - - return CURLE_OK; -} - -/* Call this when the DO phase has completed */ -static CURLcode smtp_dophase_done(struct connectdata *conn, bool connected) -{ - struct SMTP *smtp = conn->data->req.protop; - - (void)connected; - - if(smtp->transfer != FTPTRANSFER_BODY) - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - - return CURLE_OK; -} - -/* Called from multi.c while DOing */ -static CURLcode smtp_doing(struct connectdata *conn, bool *dophase_done) -{ - CURLcode result = smtp_multi_statemach(conn, dophase_done); - - if(result) - DEBUGF(infof(conn->data, "DO phase failed\n")); - else if(*dophase_done) { - result = smtp_dophase_done(conn, FALSE /* not connected */); - - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/*********************************************************************** - * - * smtp_regular_transfer() - * - * The input argument is already checked for validity. - * - * Performs all commands done before a regular transfer between a local and a - * remote host. - */ -static CURLcode smtp_regular_transfer(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - bool connected = FALSE; - struct SessionHandle *data = conn->data; - - /* Make sure size is unknown at this point */ - data->req.size = -1; - - /* Set the progress data */ - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - - /* Carry out the perform */ - result = smtp_perform(conn, &connected, dophase_done); - - /* Perform post DO phase operations if necessary */ - if(!result && *dophase_done) - result = smtp_dophase_done(conn, connected); - - return result; -} - -static CURLcode smtp_setup_connection(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - CURLcode result; - - /* Clear the TLS upgraded flag */ - conn->tls_upgraded = FALSE; - - /* Set up the proxy if necessary */ - if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) { - /* Unless we have asked to tunnel SMTP operations through the proxy, we - switch and use HTTP operations only */ -#ifndef CURL_DISABLE_HTTP - if(conn->handler == &Curl_handler_smtp) - conn->handler = &Curl_handler_smtp_proxy; - else { -#ifdef USE_SSL - conn->handler = &Curl_handler_smtps_proxy; -#else - failf(data, "SMTPS not supported!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - /* set it up as a HTTP connection instead */ - return conn->handler->setup_connection(conn); - -#else - failf(data, "SMTP over http proxy requires HTTP support built-in!"); - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - } - - /* Initialise the SMTP layer */ - result = smtp_init(conn); - if(result) - return result; - - data->state.path++; /* don't include the initial slash */ - - return CURLE_OK; -} - -/*********************************************************************** - * - * smtp_parse_url_options() - * - * Parse the URL login options. - */ -static CURLcode smtp_parse_url_options(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct smtp_conn *smtpc = &conn->proto.smtpc; - const char *ptr = conn->options; - - smtpc->sasl.resetprefs = TRUE; - - while(!result && ptr && *ptr) { - const char *key = ptr; - const char *value; - - while(*ptr && *ptr != '=') - ptr++; - - value = ptr + 1; - - while(*ptr && *ptr != ';') - ptr++; - - if(strnequal(key, "AUTH=", 5)) - result = Curl_sasl_parse_url_auth_option(&smtpc->sasl, - value, ptr - value); - else - result = CURLE_URL_MALFORMAT; - - if(*ptr == ';') - ptr++; - } - - return result; -} - -/*********************************************************************** - * - * smtp_parse_url_path() - * - * Parse the URL path into separate path components. - */ -static CURLcode smtp_parse_url_path(struct connectdata *conn) -{ - /* The SMTP struct is already initialised in smtp_connect() */ - struct SessionHandle *data = conn->data; - struct smtp_conn *smtpc = &conn->proto.smtpc; - const char *path = data->state.path; - char localhost[HOSTNAME_MAX + 1]; - - /* Calculate the path if necessary */ - if(!*path) { - if(!Curl_gethostname(localhost, sizeof(localhost))) - path = localhost; - else - path = "localhost"; - } - - /* URL decode the path and use it as the domain in our EHLO */ - return Curl_urldecode(conn->data, path, 0, &smtpc->domain, NULL, TRUE); -} - -/*********************************************************************** - * - * smtp_parse_custom_request() - * - * Parse the custom request. - */ -static CURLcode smtp_parse_custom_request(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - const char *custom = data->set.str[STRING_CUSTOMREQUEST]; - - /* URL decode the custom request */ - if(custom) - result = Curl_urldecode(data, custom, 0, &smtp->custom, NULL, TRUE); - - return result; -} - -CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread) -{ - /* When sending a SMTP payload we must detect CRLF. sequences making sure - they are sent as CRLF.. instead, as a . on the beginning of a line will - be deleted by the server when not part of an EOB terminator and a - genuine CRLF.CRLF which isn't escaped will wrongly be detected as end of - data by the server - */ - ssize_t i; - ssize_t si; - struct SessionHandle *data = conn->data; - struct SMTP *smtp = data->req.protop; - char *scratch = data->state.scratch; - char *newscratch = NULL; - char *oldscratch = NULL; - size_t eob_sent; - - /* Do we need to allocate a scratch buffer? */ - if(!scratch || data->set.crlf) { - oldscratch = scratch; - - scratch = newscratch = malloc(2 * BUFSIZE); - if(!newscratch) { - failf(data, "Failed to alloc scratch buffer!"); - - return CURLE_OUT_OF_MEMORY; - } - } - - /* Have we already sent part of the EOB? */ - eob_sent = smtp->eob; - - /* This loop can be improved by some kind of Boyer-Moore style of - approach but that is saved for later... */ - for(i = 0, si = 0; i < nread; i++) { - if(SMTP_EOB[smtp->eob] == data->req.upload_fromhere[i]) { - smtp->eob++; - - /* Is the EOB potentially the terminating CRLF? */ - if(2 == smtp->eob || SMTP_EOB_LEN == smtp->eob) - smtp->trailing_crlf = TRUE; - else - smtp->trailing_crlf = FALSE; - } - else if(smtp->eob) { - /* A previous substring matched so output that first */ - memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent); - si += smtp->eob - eob_sent; - - /* Then compare the first byte */ - if(SMTP_EOB[0] == data->req.upload_fromhere[i]) - smtp->eob = 1; - else - smtp->eob = 0; - - eob_sent = 0; - - /* Reset the trailing CRLF flag as there was more data */ - smtp->trailing_crlf = FALSE; - } - - /* Do we have a match for CRLF. as per RFC-5321, sect. 4.5.2 */ - if(SMTP_EOB_FIND_LEN == smtp->eob) { - /* Copy the replacement data to the target buffer */ - memcpy(&scratch[si], &SMTP_EOB_REPL[eob_sent], - SMTP_EOB_REPL_LEN - eob_sent); - si += SMTP_EOB_REPL_LEN - eob_sent; - smtp->eob = 0; - eob_sent = 0; - } - else if(!smtp->eob) - scratch[si++] = data->req.upload_fromhere[i]; - } - - if(smtp->eob - eob_sent) { - /* A substring matched before processing ended so output that now */ - memcpy(&scratch[si], &SMTP_EOB[eob_sent], smtp->eob - eob_sent); - si += smtp->eob - eob_sent; - } - - /* Only use the new buffer if we replaced something */ - if(si != nread) { - /* Upload from the new (replaced) buffer instead */ - data->req.upload_fromhere = scratch; - - /* Save the buffer so it can be freed later */ - data->state.scratch = scratch; - - /* Free the old scratch buffer */ - free(oldscratch); - - /* Set the new amount too */ - data->req.upload_present = si; - } - else - free(newscratch); - - return CURLE_OK; -} - -#endif /* CURL_DISABLE_SMTP */ diff --git a/Externals/curl/lib/smtp.h b/Externals/curl/lib/smtp.h deleted file mode 100644 index 6ebec18392..0000000000 --- a/Externals/curl/lib/smtp.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef HEADER_CURL_SMTP_H -#define HEADER_CURL_SMTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2009 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "pingpong.h" -#include "curl_sasl.h" - -/**************************************************************************** - * SMTP unique setup - ***************************************************************************/ -typedef enum { - SMTP_STOP, /* do nothing state, stops the state machine */ - SMTP_SERVERGREET, /* waiting for the initial greeting immediately after - a connect */ - SMTP_EHLO, - SMTP_HELO, - SMTP_STARTTLS, - SMTP_UPGRADETLS, /* asynchronously upgrade the connection to SSL/TLS - (multi mode only) */ - SMTP_AUTH, - SMTP_COMMAND, /* VRFY, EXPN, NOOP, RSET and HELP */ - SMTP_MAIL, /* MAIL FROM */ - SMTP_RCPT, /* RCPT TO */ - SMTP_DATA, - SMTP_POSTDATA, - SMTP_QUIT, - SMTP_LAST /* never used */ -} smtpstate; - -/* This SMTP struct is used in the SessionHandle. All SMTP data that is - connection-oriented must be in smtp_conn to properly deal with the fact that - perhaps the SessionHandle is changed between the times the connection is - used. */ -struct SMTP { - curl_pp_transfer transfer; - char *custom; /* Custom Request */ - struct curl_slist *rcpt; /* Recipient list */ - size_t eob; /* Number of bytes of the EOB (End Of Body) that - have been received so far */ - bool trailing_crlf; /* Specifies if the tailing CRLF is present */ -}; - -/* smtp_conn is used for struct connection-oriented data in the connectdata - struct */ -struct smtp_conn { - struct pingpong pp; - smtpstate state; /* Always use smtp.c:state() to change state! */ - bool ssldone; /* Is connect() over SSL done? */ - char *domain; /* Client address/name to send in the EHLO */ - struct SASL sasl; /* SASL-related storage */ - bool tls_supported; /* StartTLS capability supported by server */ - bool size_supported; /* If server supports SIZE extension according to - RFC 1870 */ - bool auth_supported; /* AUTH capability supported by server */ -}; - -extern const struct Curl_handler Curl_handler_smtp; -extern const struct Curl_handler Curl_handler_smtps; - -/* this is the 5-bytes End-Of-Body marker for SMTP */ -#define SMTP_EOB "\x0d\x0a\x2e\x0d\x0a" -#define SMTP_EOB_LEN 5 -#define SMTP_EOB_FIND_LEN 3 - -/* if found in data, replace it with this string instead */ -#define SMTP_EOB_REPL "\x0d\x0a\x2e\x2e" -#define SMTP_EOB_REPL_LEN 4 - -CURLcode Curl_smtp_escape_eob(struct connectdata *conn, const ssize_t nread); - -#endif /* HEADER_CURL_SMTP_H */ diff --git a/Externals/curl/lib/sockaddr.h b/Externals/curl/lib/sockaddr.h deleted file mode 100644 index 95ba4c3c97..0000000000 --- a/Externals/curl/lib/sockaddr.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef HEADER_CURL_SOCKADDR_H -#define HEADER_CURL_SOCKADDR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -struct Curl_sockaddr_storage { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 sa_in6; -#endif -#ifdef HAVE_STRUCT_SOCKADDR_STORAGE - struct sockaddr_storage sa_stor; -#else - char cbuf[256]; /* this should be big enough to fit a lot */ -#endif - } buffer; -}; - -#endif /* HEADER_CURL_SOCKADDR_H */ - diff --git a/Externals/curl/lib/socks.c b/Externals/curl/lib/socks.c deleted file mode 100644 index 8c4129647e..0000000000 --- a/Externals/curl/lib/socks.c +++ /dev/null @@ -1,755 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_PROXY) - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "strequal.h" -#include "select.h" -#include "connect.h" -#include "timeval.h" -#include "socks.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -/* - * Helper read-from-socket functions. Does the same as Curl_read() but it - * blocks until all bytes amount of buffersize will be read. No more, no less. - * - * This is STUPID BLOCKING behaviour which we frown upon, but right now this - * is what we have... - */ -int Curl_blockread_all(struct connectdata *conn, /* connection data */ - curl_socket_t sockfd, /* read from this socket */ - char *buf, /* store read data here */ - ssize_t buffersize, /* max amount to read */ - ssize_t *n) /* amount bytes read */ -{ - ssize_t nread; - ssize_t allread = 0; - int result; - long timeleft; - *n = 0; - for(;;) { - timeleft = Curl_timeleft(conn->data, NULL, TRUE); - if(timeleft < 0) { - /* we already got the timeout */ - result = CURLE_OPERATION_TIMEDOUT; - break; - } - if(Curl_socket_ready(sockfd, CURL_SOCKET_BAD, timeleft) <= 0) { - result = ~CURLE_OK; - break; - } - result = Curl_read_plain(sockfd, buf, buffersize, &nread); - if(CURLE_AGAIN == result) - continue; - else if(result) - break; - - if(buffersize == nread) { - allread += nread; - *n = allread; - result = CURLE_OK; - break; - } - if(!nread) { - result = ~CURLE_OK; - break; - } - - buffersize -= nread; - buf += nread; - allread += nread; - } - return result; -} - -/* -* This function logs in to a SOCKS4 proxy and sends the specifics to the final -* destination server. -* -* Reference : -* http://socks.permeo.com/protocol/socks4.protocol -* -* Note : -* Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" -* Nonsupport "Identification Protocol (RFC1413)" -*/ -CURLcode Curl_SOCKS4(const char *proxy_name, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn, - bool protocol4a) -{ -#define SOCKS4REQLEN 262 - unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user - id */ - int result; - CURLcode code; - curl_socket_t sock = conn->sock[sockindex]; - struct SessionHandle *data = conn->data; - - if(Curl_timeleft(data, NULL, TRUE) < 0) { - /* time-out, bail out, go home */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - (void)curlx_nonblock(sock, FALSE); - - infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port); - - /* - * Compose socks4 request - * - * Request format - * - * +----+----+----+----+----+----+----+----+----+----+....+----+ - * | VN | CD | DSTPORT | DSTIP | USERID |NULL| - * +----+----+----+----+----+----+----+----+----+----+....+----+ - * # of bytes: 1 1 2 4 variable 1 - */ - - socksreq[0] = 4; /* version (SOCKS4) */ - socksreq[1] = 1; /* connect */ - socksreq[2] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */ - socksreq[3] = (unsigned char)(remote_port & 0xff); /* PORT LSB */ - - /* DNS resolve only for SOCKS4, not SOCKS4a */ - if(!protocol4a) { - struct Curl_dns_entry *dns; - Curl_addrinfo *hp=NULL; - int rc; - - rc = Curl_resolv(conn, hostname, remote_port, &dns); - - if(rc == CURLRESOLV_ERROR) - return CURLE_COULDNT_RESOLVE_PROXY; - - if(rc == CURLRESOLV_PENDING) - /* ignores the return code, but 'dns' remains NULL on failure */ - (void)Curl_resolver_wait_resolv(conn, &dns); - - /* - * We cannot use 'hostent' as a struct that Curl_resolv() returns. It - * returns a Curl_addrinfo pointer that may not always look the same. - */ - if(dns) - hp=dns->addr; - if(hp) { - char buf[64]; - unsigned short ip[4]; - Curl_printable_address(hp, buf, sizeof(buf)); - - if(4 == sscanf(buf, "%hu.%hu.%hu.%hu", - &ip[0], &ip[1], &ip[2], &ip[3])) { - /* Set DSTIP */ - socksreq[4] = (unsigned char)ip[0]; - socksreq[5] = (unsigned char)ip[1]; - socksreq[6] = (unsigned char)ip[2]; - socksreq[7] = (unsigned char)ip[3]; - } - else - hp = NULL; /* fail! */ - - infof(data, "SOCKS4 connect to %s (locally resolved)\n", buf); - - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ - - } - if(!hp) { - failf(data, "Failed to resolve \"%s\" for SOCKS4 connect.", - hostname); - return CURLE_COULDNT_RESOLVE_HOST; - } - } - - /* - * This is currently not supporting "Identification Protocol (RFC1413)". - */ - socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ - if(proxy_name) { - size_t plen = strlen(proxy_name); - if(plen >= sizeof(socksreq) - 8) { - failf(data, "Too long SOCKS proxy name, can't use!\n"); - return CURLE_COULDNT_CONNECT; - } - /* copy the proxy name WITH trailing zero */ - memcpy(socksreq + 8, proxy_name, plen+1); - } - - /* - * Make connection - */ - { - ssize_t actualread; - ssize_t written; - ssize_t hostnamelen = 0; - int packetsize = 9 + - (int)strlen((char*)socksreq + 8); /* size including NUL */ - - /* If SOCKS4a, set special invalid IP address 0.0.0.x */ - if(protocol4a) { - socksreq[4] = 0; - socksreq[5] = 0; - socksreq[6] = 0; - socksreq[7] = 1; - /* If still enough room in buffer, also append hostname */ - hostnamelen = (ssize_t)strlen(hostname) + 1; /* length including NUL */ - if(packetsize + hostnamelen <= SOCKS4REQLEN) - strcpy((char*)socksreq + packetsize, hostname); - else - hostnamelen = 0; /* Flag: hostname did not fit in buffer */ - } - - /* Send request */ - code = Curl_write_plain(conn, sock, (char *)socksreq, - packetsize + hostnamelen, - &written); - if(code || (written != packetsize + hostnamelen)) { - failf(data, "Failed to send SOCKS4 connect request."); - return CURLE_COULDNT_CONNECT; - } - if(protocol4a && hostnamelen == 0) { - /* SOCKS4a with very long hostname - send that name separately */ - hostnamelen = (ssize_t)strlen(hostname) + 1; - code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen, - &written); - if(code || (written != hostnamelen)) { - failf(data, "Failed to send SOCKS4 connect request."); - return CURLE_COULDNT_CONNECT; - } - } - - packetsize = 8; /* receive data size */ - - /* Receive response */ - result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize, - &actualread); - if(result || (actualread != packetsize)) { - failf(data, "Failed to receive SOCKS4 connect request ack."); - return CURLE_COULDNT_CONNECT; - } - - /* - * Response format - * - * +----+----+----+----+----+----+----+----+ - * | VN | CD | DSTPORT | DSTIP | - * +----+----+----+----+----+----+----+----+ - * # of bytes: 1 1 2 4 - * - * VN is the version of the reply code and should be 0. CD is the result - * code with one of the following values: - * - * 90: request granted - * 91: request rejected or failed - * 92: request rejected because SOCKS server cannot connect to - * identd on the client - * 93: request rejected because the client program and identd - * report different user-ids - */ - - /* wrong version ? */ - if(socksreq[0] != 0) { - failf(data, - "SOCKS4 reply has wrong version, version should be 4."); - return CURLE_COULDNT_CONNECT; - } - - /* Result */ - switch(socksreq[1]) { - case 90: - infof(data, "SOCKS4%s request granted.\n", protocol4a?"a":""); - break; - case 91: - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected or failed.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), - (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; - case 92: - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected because SOCKS server cannot connect to " - "identd on the client.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), - (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; - case 93: - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", request rejected because the client program and identd " - "report different user-ids.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), - (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; - default: - failf(data, - "Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)" - ", Unknown.", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), - (unsigned char)socksreq[1]); - return CURLE_COULDNT_CONNECT; - } - } - - (void)curlx_nonblock(sock, TRUE); - - return CURLE_OK; /* Proxy was successful! */ -} - -/* - * This function logs in to a SOCKS5 proxy and sends the specifics to the final - * destination server. - */ -CURLcode Curl_SOCKS5(const char *proxy_name, - const char *proxy_password, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn) -{ - /* - According to the RFC1928, section "6. Replies". This is what a SOCK5 - replies: - - +----+-----+-------+------+----------+----------+ - |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | - +----+-----+-------+------+----------+----------+ - | 1 | 1 | X'00' | 1 | Variable | 2 | - +----+-----+-------+------+----------+----------+ - - Where: - - o VER protocol version: X'05' - o REP Reply field: - o X'00' succeeded - */ - - unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ - ssize_t actualread; - ssize_t written; - int result; - CURLcode code; - curl_socket_t sock = conn->sock[sockindex]; - struct SessionHandle *data = conn->data; - long timeout; - bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE; - const size_t hostname_len = strlen(hostname); - ssize_t len = 0; - - /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */ - if(!socks5_resolve_local && hostname_len > 255) { - infof(conn->data, "SOCKS5: server resolving disabled for hostnames of " - "length > 255 [actual len=%zu]\n", hostname_len); - socks5_resolve_local = TRUE; - } - - /* get timeout */ - timeout = Curl_timeleft(data, NULL, TRUE); - - if(timeout < 0) { - /* time-out, bail out, go home */ - failf(data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - (void)curlx_nonblock(sock, TRUE); - - /* wait until socket gets connected */ - result = Curl_socket_ready(CURL_SOCKET_BAD, sock, timeout); - - if(-1 == result) { - failf(conn->data, "SOCKS5: no connection here"); - return CURLE_COULDNT_CONNECT; - } - else if(0 == result) { - failf(conn->data, "SOCKS5: connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - if(result & CURL_CSELECT_ERR) { - failf(conn->data, "SOCKS5: error occurred during connection"); - return CURLE_COULDNT_CONNECT; - } - - socksreq[0] = 5; /* version */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */ - socksreq[2] = 0; /* no authentication */ - socksreq[3] = 1; /* GSS-API */ - socksreq[4] = 2; /* username/password */ -#else - socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */ - socksreq[2] = 0; /* no authentication */ - socksreq[3] = 2; /* username/password */ -#endif - - (void)curlx_nonblock(sock, FALSE); - - code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]), - &written); - if(code || (written != (2 + (int)socksreq[1]))) { - failf(data, "Unable to send initial SOCKS5 request."); - return CURLE_COULDNT_CONNECT; - } - - (void)curlx_nonblock(sock, TRUE); - - result = Curl_socket_ready(sock, CURL_SOCKET_BAD, timeout); - - if(-1 == result) { - failf(conn->data, "SOCKS5 nothing to read"); - return CURLE_COULDNT_CONNECT; - } - else if(0 == result) { - failf(conn->data, "SOCKS5 read timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - if(result & CURL_CSELECT_ERR) { - failf(conn->data, "SOCKS5 read error occurred"); - return CURLE_RECV_ERROR; - } - - (void)curlx_nonblock(sock, FALSE); - - result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); - if(result || (actualread != 2)) { - failf(data, "Unable to receive initial SOCKS5 response."); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[0] != 5) { - failf(data, "Received invalid version in initial SOCKS5 response."); - return CURLE_COULDNT_CONNECT; - } - if(socksreq[1] == 0) { - /* Nothing to do, no authentication needed */ - ; - } -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - else if(socksreq[1] == 1) { - code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn); - if(code) { - failf(data, "Unable to negotiate SOCKS5 GSS-API context."); - return CURLE_COULDNT_CONNECT; - } - } -#endif - else if(socksreq[1] == 2) { - /* Needs user name and password */ - size_t proxy_name_len, proxy_password_len; - if(proxy_name && proxy_password) { - proxy_name_len = strlen(proxy_name); - proxy_password_len = strlen(proxy_password); - } - else { - proxy_name_len = 0; - proxy_password_len = 0; - } - - /* username/password request looks like - * +----+------+----------+------+----------+ - * |VER | ULEN | UNAME | PLEN | PASSWD | - * +----+------+----------+------+----------+ - * | 1 | 1 | 1 to 255 | 1 | 1 to 255 | - * +----+------+----------+------+----------+ - */ - len = 0; - socksreq[len++] = 1; /* username/pw subnegotiation version */ - socksreq[len++] = (unsigned char) proxy_name_len; - if(proxy_name && proxy_name_len) - memcpy(socksreq + len, proxy_name, proxy_name_len); - len += proxy_name_len; - socksreq[len++] = (unsigned char) proxy_password_len; - if(proxy_password && proxy_password_len) - memcpy(socksreq + len, proxy_password, proxy_password_len); - len += proxy_password_len; - - code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written); - if(code || (len != written)) { - failf(data, "Failed to send SOCKS5 sub-negotiation request."); - return CURLE_COULDNT_CONNECT; - } - - result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); - if(result || (actualread != 2)) { - failf(data, "Unable to receive SOCKS5 sub-negotiation response."); - return CURLE_COULDNT_CONNECT; - } - - /* ignore the first (VER) byte */ - if(socksreq[1] != 0) { /* status */ - failf(data, "User was rejected by the SOCKS5 server (%d %d).", - socksreq[0], socksreq[1]); - return CURLE_COULDNT_CONNECT; - } - - /* Everything is good so far, user was authenticated! */ - } - else { - /* error */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - if(socksreq[1] == 255) { -#else - if(socksreq[1] == 1) { - failf(data, - "SOCKS5 GSSAPI per-message authentication is not supported."); - return CURLE_COULDNT_CONNECT; - } - else if(socksreq[1] == 255) { -#endif - if(!proxy_name || !*proxy_name) { - failf(data, - "No authentication method was acceptable. (It is quite likely" - " that the SOCKS5 server wanted a username/password, since none" - " was supplied to the server on this connection.)"); - } - else { - failf(data, "No authentication method was acceptable."); - } - return CURLE_COULDNT_CONNECT; - } - else { - failf(data, - "Undocumented SOCKS5 mode attempted to be used by server."); - return CURLE_COULDNT_CONNECT; - } - } - - /* Authentication is complete, now specify destination to the proxy */ - len = 0; - socksreq[len++] = 5; /* version (SOCKS5) */ - socksreq[len++] = 1; /* connect */ - socksreq[len++] = 0; /* must be zero */ - - if(!socks5_resolve_local) { - socksreq[len++] = 3; /* ATYP: domain name = 3 */ - socksreq[len++] = (char) hostname_len; /* address length */ - memcpy(&socksreq[len], hostname, hostname_len); /* address str w/o NULL */ - len += hostname_len; - } - else { - struct Curl_dns_entry *dns; - Curl_addrinfo *hp = NULL; - int rc = Curl_resolv(conn, hostname, remote_port, &dns); - - if(rc == CURLRESOLV_ERROR) - return CURLE_COULDNT_RESOLVE_HOST; - - if(rc == CURLRESOLV_PENDING) { - /* this requires that we're in "wait for resolve" state */ - code = Curl_resolver_wait_resolv(conn, &dns); - if(code) - return code; - } - - /* - * We cannot use 'hostent' as a struct that Curl_resolv() returns. It - * returns a Curl_addrinfo pointer that may not always look the same. - */ - if(dns) - hp=dns->addr; - if(hp) { - struct sockaddr_in *saddr_in; -#ifdef ENABLE_IPV6 - struct sockaddr_in6 *saddr_in6; -#endif - int i; - - if(hp->ai_family == AF_INET) { - socksreq[len++] = 1; /* ATYP: IPv4 = 1 */ - - saddr_in = (struct sockaddr_in*)(void*)hp->ai_addr; - for(i = 0; i < 4; i++) { - socksreq[len++] = ((unsigned char*)&saddr_in->sin_addr.s_addr)[i]; - infof(data, "%d\n", socksreq[len-1]); - } - } -#ifdef ENABLE_IPV6 - else if(hp->ai_family == AF_INET6) { - socksreq[len++] = 4; /* ATYP: IPv6 = 4 */ - - saddr_in6 = (struct sockaddr_in6*)(void*)hp->ai_addr; - for(i = 0; i < 16; i++) { - socksreq[len++] = ((unsigned char*)&saddr_in6->sin6_addr.s6_addr)[i]; - } - } -#endif - else - hp = NULL; /* fail! */ - - Curl_resolv_unlock(data, dns); /* not used anymore from now on */ - } - if(!hp) { - failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.", - hostname); - return CURLE_COULDNT_RESOLVE_HOST; - } - } - - socksreq[len++] = (unsigned char)((remote_port >> 8) & 0xff); /* PORT MSB */ - socksreq[len++] = (unsigned char)(remote_port & 0xff); /* PORT LSB */ - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - if(conn->socks5_gssapi_enctype) { - failf(data, "SOCKS5 GSS-API protection not yet implemented."); - } - else -#endif - code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written); - - if(code || (len != written)) { - failf(data, "Failed to send SOCKS5 connect request."); - return CURLE_COULDNT_CONNECT; - } - - len = 10; /* minimum packet size is 10 */ - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - if(conn->socks5_gssapi_enctype) { - failf(data, "SOCKS5 GSS-API protection not yet implemented."); - } - else -#endif - result = Curl_blockread_all(conn, sock, (char *)socksreq, - len, &actualread); - - if(result || (len != actualread)) { - failf(data, "Failed to receive SOCKS5 connect request ack."); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[0] != 5) { /* version */ - failf(data, - "SOCKS5 reply has wrong version, version should be 5."); - return CURLE_COULDNT_CONNECT; - } - if(socksreq[1] != 0) { /* Anything besides 0 is an error */ - if(socksreq[3] == 1) { - failf(data, - "Can't complete SOCKS5 connection to %d.%d.%d.%d:%d. (%d)", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), - (unsigned char)socksreq[1]); - } - else if(socksreq[3] == 3) { - failf(data, - "Can't complete SOCKS5 connection to %s:%d. (%d)", - hostname, - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), - (unsigned char)socksreq[1]); - } - else if(socksreq[3] == 4) { - failf(data, - "Can't complete SOCKS5 connection to %02x%02x:%02x%02x:" - "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%d. (%d)", - (unsigned char)socksreq[4], (unsigned char)socksreq[5], - (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (unsigned char)socksreq[8], (unsigned char)socksreq[9], - (unsigned char)socksreq[10], (unsigned char)socksreq[11], - (unsigned char)socksreq[12], (unsigned char)socksreq[13], - (unsigned char)socksreq[14], (unsigned char)socksreq[15], - (unsigned char)socksreq[16], (unsigned char)socksreq[17], - (unsigned char)socksreq[18], (unsigned char)socksreq[19], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), - (unsigned char)socksreq[1]); - } - return CURLE_COULDNT_CONNECT; - } - - /* Fix: in general, returned BND.ADDR is variable length parameter by RFC - 1928, so the reply packet should be read until the end to avoid errors at - subsequent protocol level. - - +----+-----+-------+------+----------+----------+ - |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | - +----+-----+-------+------+----------+----------+ - | 1 | 1 | X'00' | 1 | Variable | 2 | - +----+-----+-------+------+----------+----------+ - - ATYP: - o IP v4 address: X'01', BND.ADDR = 4 byte - o domain name: X'03', BND.ADDR = [ 1 byte length, string ] - o IP v6 address: X'04', BND.ADDR = 16 byte - */ - - /* Calculate real packet size */ - if(socksreq[3] == 3) { - /* domain name */ - int addrlen = (int) socksreq[4]; - len = 5 + addrlen + 2; - } - else if(socksreq[3] == 4) { - /* IPv6 */ - len = 4 + 16 + 2; - } - - /* At this point we already read first 10 bytes */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - if(!conn->socks5_gssapi_enctype) { - /* decrypt_gssapi_blockread already read the whole packet */ -#endif - if(len > 10) { - len -= 10; - result = Curl_blockread_all(conn, sock, (char *)&socksreq[10], - len, &actualread); - if(result || (len != actualread)) { - failf(data, "Failed to receive SOCKS5 connect request ack."); - return CURLE_COULDNT_CONNECT; - } - } -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - } -#endif - - (void)curlx_nonblock(sock, TRUE); - return CURLE_OK; /* Proxy was successful! */ -} - -#endif /* CURL_DISABLE_PROXY */ - diff --git a/Externals/curl/lib/socks.h b/Externals/curl/lib/socks.h deleted file mode 100644 index a44ada6beb..0000000000 --- a/Externals/curl/lib/socks.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef HEADER_CURL_SOCKS_H -#define HEADER_CURL_SOCKS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef CURL_DISABLE_PROXY -#define Curl_SOCKS4(a,b,c,d,e,f) CURLE_NOT_BUILT_IN -#define Curl_SOCKS5(a,b,c,d,e,f) CURLE_NOT_BUILT_IN -#else -/* - * Helper read-from-socket functions. Does the same as Curl_read() but it - * blocks until all bytes amount of buffersize will be read. No more, no less. - * - * This is STUPID BLOCKING behaviour which we frown upon, but right now this - * is what we have... - */ -int Curl_blockread_all(struct connectdata *conn, - curl_socket_t sockfd, - char *buf, - ssize_t buffersize, - ssize_t *n); - -/* - * This function logs in to a SOCKS4(a) proxy and sends the specifics to the - * final destination server. - */ -CURLcode Curl_SOCKS4(const char *proxy_name, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn, - bool protocol4a); - -/* - * This function logs in to a SOCKS5 proxy and sends the specifics to the - * final destination server. - */ -CURLcode Curl_SOCKS5(const char *proxy_name, - const char *proxy_password, - const char *hostname, - int remote_port, - int sockindex, - struct connectdata *conn); - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) -/* - * This function handles the SOCKS5 GSS-API negotiation and initialisation - */ -CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, - struct connectdata *conn); -#endif - -#endif /* CURL_DISABLE_PROXY */ - -#endif /* HEADER_CURL_SOCKS_H */ - diff --git a/Externals/curl/lib/socks_gssapi.c b/Externals/curl/lib/socks_gssapi.c deleted file mode 100644 index 1214048bf1..0000000000 --- a/Externals/curl/lib/socks_gssapi.c +++ /dev/null @@ -1,524 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2009, 2011, Markus Moeller, - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(HAVE_GSSAPI) && !defined(CURL_DISABLE_PROXY) - -#include "curl_gssapi.h" -#include "urldata.h" -#include "sendf.h" -#include "connect.h" -#include "timeval.h" -#include "socks.h" -#include "warnless.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -static gss_ctx_id_t gss_context = GSS_C_NO_CONTEXT; - -/* - * Helper GSS-API error functions. - */ -static int check_gss_err(struct SessionHandle *data, - OM_uint32 major_status, - OM_uint32 minor_status, - const char* function) -{ - if(GSS_ERROR(major_status)) { - OM_uint32 maj_stat, min_stat; - OM_uint32 msg_ctx = 0; - gss_buffer_desc status_string; - char buf[1024]; - size_t len; - - len = 0; - msg_ctx = 0; - while(!msg_ctx) { - /* convert major status code (GSS-API error) to text */ - maj_stat = gss_display_status(&min_stat, major_status, - GSS_C_GSS_CODE, - GSS_C_NULL_OID, - &msg_ctx, &status_string); - if(maj_stat == GSS_S_COMPLETE) { - if(sizeof(buf) > len + status_string.length + 1) { - strcpy(buf+len, (char*) status_string.value); - len += status_string.length; - } - gss_release_buffer(&min_stat, &status_string); - break; - } - gss_release_buffer(&min_stat, &status_string); - } - if(sizeof(buf) > len + 3) { - strcpy(buf+len, ".\n"); - len += 2; - } - msg_ctx = 0; - while(!msg_ctx) { - /* convert minor status code (underlying routine error) to text */ - maj_stat = gss_display_status(&min_stat, minor_status, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, &status_string); - if(maj_stat == GSS_S_COMPLETE) { - if(sizeof(buf) > len + status_string.length) - strcpy(buf+len, (char*) status_string.value); - gss_release_buffer(&min_stat, &status_string); - break; - } - gss_release_buffer(&min_stat, &status_string); - } - failf(data, "GSS-API error: %s failed:\n%s", function, buf); - return 1; - } - - return 0; -} - -CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, - struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - curl_socket_t sock = conn->sock[sockindex]; - CURLcode code; - ssize_t actualread; - ssize_t written; - int result; - OM_uint32 gss_major_status, gss_minor_status, gss_status; - OM_uint32 gss_ret_flags; - int gss_conf_state, gss_enc; - gss_buffer_desc service = GSS_C_EMPTY_BUFFER; - gss_buffer_desc gss_send_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc gss_recv_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc gss_w_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc* gss_token = GSS_C_NO_BUFFER; - gss_name_t server = GSS_C_NO_NAME; - gss_name_t gss_client_name = GSS_C_NO_NAME; - unsigned short us_length; - char *user=NULL; - unsigned char socksreq[4]; /* room for GSS-API exchange header only */ - const char *serviceptr = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd"; - - /* GSS-API request looks like - * +----+------+-----+----------------+ - * |VER | MTYP | LEN | TOKEN | - * +----+------+----------------------+ - * | 1 | 1 | 2 | up to 2^16 - 1 | - * +----+------+-----+----------------+ - */ - - /* prepare service name */ - if(strchr(serviceptr, '/')) { - service.value = malloc(strlen(serviceptr)); - if(!service.value) - return CURLE_OUT_OF_MEMORY; - service.length = strlen(serviceptr); - memcpy(service.value, serviceptr, service.length); - - gss_major_status = gss_import_name(&gss_minor_status, &service, - (gss_OID) GSS_C_NULL_OID, &server); - } - else { - service.value = malloc(strlen(serviceptr) +strlen(conn->proxy.name)+2); - if(!service.value) - return CURLE_OUT_OF_MEMORY; - service.length = strlen(serviceptr) +strlen(conn->proxy.name)+1; - snprintf(service.value, service.length+1, "%s@%s", - serviceptr, conn->proxy.name); - - gss_major_status = gss_import_name(&gss_minor_status, &service, - GSS_C_NT_HOSTBASED_SERVICE, &server); - } - - gss_release_buffer(&gss_status, &service); /* clear allocated memory */ - - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_import_name()")) { - failf(data, "Failed to create service name."); - gss_release_name(&gss_status, &server); - return CURLE_COULDNT_CONNECT; - } - - /* As long as we need to keep sending some context info, and there's no */ - /* errors, keep sending it... */ - for(;;) { - gss_major_status = Curl_gss_init_sec_context(data, - &gss_minor_status, - &gss_context, - server, - &Curl_krb5_mech_oid, - NULL, - gss_token, - &gss_send_token, - TRUE, - &gss_ret_flags); - - if(gss_token != GSS_C_NO_BUFFER) - gss_release_buffer(&gss_status, &gss_recv_token); - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_init_sec_context")) { - gss_release_name(&gss_status, &server); - gss_release_buffer(&gss_status, &gss_recv_token); - gss_release_buffer(&gss_status, &gss_send_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - failf(data, "Failed to initial GSS-API token."); - return CURLE_COULDNT_CONNECT; - } - - if(gss_send_token.length != 0) { - socksreq[0] = 1; /* GSS-API subnegotiation version */ - socksreq[1] = 1; /* authentication message type */ - us_length = htons((short)gss_send_token.length); - memcpy(socksreq+2, &us_length, sizeof(short)); - - code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); - if(code || (4 != written)) { - failf(data, "Failed to send GSS-API authentication request."); - gss_release_name(&gss_status, &server); - gss_release_buffer(&gss_status, &gss_recv_token); - gss_release_buffer(&gss_status, &gss_send_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - code = Curl_write_plain(conn, sock, (char *)gss_send_token.value, - gss_send_token.length, &written); - - if(code || ((ssize_t)gss_send_token.length != written)) { - failf(data, "Failed to send GSS-API authentication token."); - gss_release_name(&gss_status, &server); - gss_release_buffer(&gss_status, &gss_recv_token); - gss_release_buffer(&gss_status, &gss_send_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - } - - gss_release_buffer(&gss_status, &gss_send_token); - gss_release_buffer(&gss_status, &gss_recv_token); - if(gss_major_status != GSS_S_CONTINUE_NEEDED) break; - - /* analyse response */ - - /* GSS-API response looks like - * +----+------+-----+----------------+ - * |VER | MTYP | LEN | TOKEN | - * +----+------+----------------------+ - * | 1 | 1 | 2 | up to 2^16 - 1 | - * +----+------+-----+----------------+ - */ - - result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive GSS-API authentication response."); - gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - /* ignore the first (VER) byte */ - if(socksreq[1] == 255) { /* status / message type */ - failf(data, "User was rejected by the SOCKS5 server (%d %d).", - socksreq[0], socksreq[1]); - gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 1) { /* status / messgae type */ - failf(data, "Invalid GSS-API authentication response type (%d %d).", - socksreq[0], socksreq[1]); - gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq+2, sizeof(short)); - us_length = ntohs(us_length); - - gss_recv_token.length=us_length; - gss_recv_token.value=malloc(us_length); - if(!gss_recv_token.value) { - failf(data, - "Could not allocate memory for GSS-API authentication " - "response token."); - gss_release_name(&gss_status, &server); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_OUT_OF_MEMORY; - } - - result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value, - gss_recv_token.length, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive GSS-API authentication token."); - gss_release_name(&gss_status, &server); - gss_release_buffer(&gss_status, &gss_recv_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - gss_token = &gss_recv_token; - } - - gss_release_name(&gss_status, &server); - - /* Everything is good so far, user was authenticated! */ - gss_major_status = gss_inquire_context (&gss_minor_status, gss_context, - &gss_client_name, NULL, NULL, NULL, - NULL, NULL, NULL); - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_inquire_context")) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); - gss_release_name(&gss_status, &gss_client_name); - failf(data, "Failed to determine user name."); - return CURLE_COULDNT_CONNECT; - } - gss_major_status = gss_display_name(&gss_minor_status, gss_client_name, - &gss_send_token, NULL); - if(check_gss_err(data, gss_major_status, - gss_minor_status, "gss_display_name")) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); - gss_release_name(&gss_status, &gss_client_name); - gss_release_buffer(&gss_status, &gss_send_token); - failf(data, "Failed to determine user name."); - return CURLE_COULDNT_CONNECT; - } - user=malloc(gss_send_token.length+1); - if(!user) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); - gss_release_name(&gss_status, &gss_client_name); - gss_release_buffer(&gss_status, &gss_send_token); - return CURLE_OUT_OF_MEMORY; - } - - memcpy(user, gss_send_token.value, gss_send_token.length); - user[gss_send_token.length] = '\0'; - gss_release_name(&gss_status, &gss_client_name); - gss_release_buffer(&gss_status, &gss_send_token); - infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n",user); - free(user); - user=NULL; - - /* Do encryption */ - socksreq[0] = 1; /* GSS-API subnegotiation version */ - socksreq[1] = 2; /* encryption message type */ - - gss_enc = 0; /* no data protection */ - /* do confidentiality protection if supported */ - if(gss_ret_flags & GSS_C_CONF_FLAG) - gss_enc = 2; - /* else do integrity protection */ - else if(gss_ret_flags & GSS_C_INTEG_FLAG) - gss_enc = 1; - - infof(data, "SOCKS5 server supports GSS-API %s data protection.\n", - (gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality")); - /* force for the moment to no data protection */ - gss_enc = 0; - /* - * Sending the encryption type in clear seems wrong. It should be - * protected with gss_seal()/gss_wrap(). See RFC1961 extract below - * The NEC reference implementations on which this is based is - * therefore at fault - * - * +------+------+------+.......................+ - * + ver | mtyp | len | token | - * +------+------+------+.......................+ - * + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets | - * +------+------+------+.......................+ - * - * Where: - * - * - "ver" is the protocol version number, here 1 to represent the - * first version of the SOCKS/GSS-API protocol - * - * - "mtyp" is the message type, here 2 to represent a protection - * -level negotiation message - * - * - "len" is the length of the "token" field in octets - * - * - "token" is the GSS-API encapsulated protection level - * - * The token is produced by encapsulating an octet containing the - * required protection level using gss_seal()/gss_wrap() with conf_req - * set to FALSE. The token is verified using gss_unseal()/ - * gss_unwrap(). - * - */ - if(data->set.socks5_gssapi_nec) { - us_length = htons((short)1); - memcpy(socksreq+2, &us_length, sizeof(short)); - } - else { - gss_send_token.length = 1; - gss_send_token.value = malloc(1); - if(!gss_send_token.value) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_OUT_OF_MEMORY; - } - memcpy(gss_send_token.value, &gss_enc, 1); - - gss_major_status = gss_wrap(&gss_minor_status, gss_context, 0, - GSS_C_QOP_DEFAULT, &gss_send_token, - &gss_conf_state, &gss_w_token); - - if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_wrap")) { - gss_release_buffer(&gss_status, &gss_send_token); - gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - failf(data, "Failed to wrap GSS-API encryption value into token."); - return CURLE_COULDNT_CONNECT; - } - gss_release_buffer(&gss_status, &gss_send_token); - - us_length = htons((short)gss_w_token.length); - memcpy(socksreq+2, &us_length, sizeof(short)); - } - - code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); - if(code || (4 != written)) { - failf(data, "Failed to send GSS-API encryption request."); - gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(data->set.socks5_gssapi_nec) { - memcpy(socksreq, &gss_enc, 1); - code = Curl_write_plain(conn, sock, socksreq, 1, &written); - if(code || ( 1 != written)) { - failf(data, "Failed to send GSS-API encryption type."); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - } - else { - code = Curl_write_plain(conn, sock, (char *)gss_w_token.value, - gss_w_token.length, &written); - if(code || ((ssize_t)gss_w_token.length != written)) { - failf(data, "Failed to send GSS-API encryption type."); - gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - gss_release_buffer(&gss_status, &gss_w_token); - } - - result=Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive GSS-API encryption response."); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - /* ignore the first (VER) byte */ - if(socksreq[1] == 255) { /* status / message type */ - failf(data, "User was rejected by the SOCKS5 server (%d %d).", - socksreq[0], socksreq[1]); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 2) { /* status / messgae type */ - failf(data, "Invalid GSS-API encryption response type (%d %d).", - socksreq[0], socksreq[1]); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq+2, sizeof(short)); - us_length = ntohs(us_length); - - gss_recv_token.length= us_length; - gss_recv_token.value=malloc(gss_recv_token.length); - if(!gss_recv_token.value) { - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_OUT_OF_MEMORY; - } - result=Curl_blockread_all(conn, sock, (char *)gss_recv_token.value, - gss_recv_token.length, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive GSS-API encryptrion type."); - gss_release_buffer(&gss_status, &gss_recv_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - if(!data->set.socks5_gssapi_nec) { - gss_major_status = gss_unwrap(&gss_minor_status, gss_context, - &gss_recv_token, &gss_w_token, - 0, GSS_C_QOP_DEFAULT); - - if(check_gss_err(data, gss_major_status, gss_minor_status, "gss_unwrap")) { - gss_release_buffer(&gss_status, &gss_recv_token); - gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - failf(data, "Failed to unwrap GSS-API encryption value into token."); - return CURLE_COULDNT_CONNECT; - } - gss_release_buffer(&gss_status, &gss_recv_token); - - if(gss_w_token.length != 1) { - failf(data, "Invalid GSS-API encryption response length (%d).", - gss_w_token.length); - gss_release_buffer(&gss_status, &gss_w_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(socksreq, gss_w_token.value, gss_w_token.length); - gss_release_buffer(&gss_status, &gss_w_token); - } - else { - if(gss_recv_token.length != 1) { - failf(data, "Invalid GSS-API encryption response length (%d).", - gss_recv_token.length); - gss_release_buffer(&gss_status, &gss_recv_token); - gss_delete_sec_context(&gss_status, &gss_context, NULL); - return CURLE_COULDNT_CONNECT; - } - - memcpy(socksreq, gss_recv_token.value, gss_recv_token.length); - gss_release_buffer(&gss_status, &gss_recv_token); - } - - infof(data, "SOCKS5 access with%s protection granted.\n", - (socksreq[0]==0)?"out GSS-API data": - ((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality")); - - conn->socks5_gssapi_enctype = socksreq[0]; - if(socksreq[0] == 0) - gss_delete_sec_context(&gss_status, &gss_context, NULL); - - return CURLE_OK; -} - -#endif /* HAVE_GSSAPI && !CURL_DISABLE_PROXY */ diff --git a/Externals/curl/lib/socks_sspi.c b/Externals/curl/lib/socks_sspi.c deleted file mode 100644 index ec564b4883..0000000000 --- a/Externals/curl/lib/socks_sspi.c +++ /dev/null @@ -1,602 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * Copyright (C) 2009, 2011, Markus Moeller, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_PROXY) - -#include "urldata.h" -#include "sendf.h" -#include "connect.h" -#include "strerror.h" -#include "timeval.h" -#include "socks.h" -#include "curl_sspi.h" -#include "curl_multibyte.h" -#include "warnless.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Helper sspi error functions. - */ -static int check_sspi_err(struct connectdata *conn, - SECURITY_STATUS status, - const char* function) -{ - if(status != SEC_E_OK && - status != SEC_I_COMPLETE_AND_CONTINUE && - status != SEC_I_COMPLETE_NEEDED && - status != SEC_I_CONTINUE_NEEDED) { - failf(conn->data, "SSPI error: %s failed: %s", function, - Curl_sspi_strerror(conn, status)); - return 1; - } - return 0; -} - -/* This is the SSPI-using version of this function */ -CURLcode Curl_SOCKS5_gssapi_negotiate(int sockindex, - struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - curl_socket_t sock = conn->sock[sockindex]; - CURLcode code; - ssize_t actualread; - ssize_t written; - int result; - /* Needs GSS-API authentication */ - SECURITY_STATUS status; - unsigned long sspi_ret_flags = 0; - unsigned char gss_enc; - SecBuffer sspi_send_token, sspi_recv_token, sspi_w_token[3]; - SecBufferDesc input_desc, output_desc, wrap_desc; - SecPkgContext_Sizes sspi_sizes; - CredHandle cred_handle; - CtxtHandle sspi_context; - PCtxtHandle context_handle = NULL; - SecPkgCredentials_Names names; - TimeStamp expiry; - char *service_name = NULL; - unsigned short us_length; - unsigned long qop; - unsigned char socksreq[4]; /* room for GSS-API exchange header only */ - const char *service = data->set.str[STRING_PROXY_SERVICE_NAME] ? - data->set.str[STRING_PROXY_SERVICE_NAME] : "rcmd"; - - /* GSS-API request looks like - * +----+------+-----+----------------+ - * |VER | MTYP | LEN | TOKEN | - * +----+------+----------------------+ - * | 1 | 1 | 2 | up to 2^16 - 1 | - * +----+------+-----+----------------+ - */ - - /* prepare service name */ - if(strchr(service, '/')) { - service_name = malloc(strlen(service)); - if(!service_name) - return CURLE_OUT_OF_MEMORY; - memcpy(service_name, service, strlen(service)); - } - else { - service_name = malloc(strlen(service) + strlen(conn->proxy.name) + 2); - if(!service_name) - return CURLE_OUT_OF_MEMORY; - snprintf(service_name, strlen(service) +strlen(conn->proxy.name)+2, - "%s/%s", service, conn->proxy.name); - } - - input_desc.cBuffers = 1; - input_desc.pBuffers = &sspi_recv_token; - input_desc.ulVersion = SECBUFFER_VERSION; - - sspi_recv_token.BufferType = SECBUFFER_TOKEN; - sspi_recv_token.cbBuffer = 0; - sspi_recv_token.pvBuffer = NULL; - - output_desc.cBuffers = 1; - output_desc.pBuffers = &sspi_send_token; - output_desc.ulVersion = SECBUFFER_VERSION; - - sspi_send_token.BufferType = SECBUFFER_TOKEN; - sspi_send_token.cbBuffer = 0; - sspi_send_token.pvBuffer = NULL; - - wrap_desc.cBuffers = 3; - wrap_desc.pBuffers = sspi_w_token; - wrap_desc.ulVersion = SECBUFFER_VERSION; - - cred_handle.dwLower = 0; - cred_handle.dwUpper = 0; - - status = s_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *) TEXT("Kerberos"), - SECPKG_CRED_OUTBOUND, - NULL, - NULL, - NULL, - NULL, - &cred_handle, - &expiry); - - if(check_sspi_err(conn, status, "AcquireCredentialsHandle")) { - failf(data, "Failed to acquire credentials."); - free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - return CURLE_COULDNT_CONNECT; - } - - /* As long as we need to keep sending some context info, and there's no */ - /* errors, keep sending it... */ - for(;;) { - TCHAR *sname; - - sname = Curl_convert_UTF8_to_tchar(service_name); - if(!sname) - return CURLE_OUT_OF_MEMORY; - - status = s_pSecFn->InitializeSecurityContext(&cred_handle, - context_handle, - sname, - ISC_REQ_MUTUAL_AUTH | - ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_CONFIDENTIALITY | - ISC_REQ_REPLAY_DETECT, - 0, - SECURITY_NATIVE_DREP, - &input_desc, - 0, - &sspi_context, - &output_desc, - &sspi_ret_flags, - &expiry); - - Curl_unicodefree(sname); - - if(sspi_recv_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - sspi_recv_token.pvBuffer = NULL; - sspi_recv_token.cbBuffer = 0; - } - - if(check_sspi_err(conn, status, "InitializeSecurityContext")) { - free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - failf(data, "Failed to initialise security context."); - return CURLE_COULDNT_CONNECT; - } - - if(sspi_send_token.cbBuffer != 0) { - socksreq[0] = 1; /* GSS-API subnegotiation version */ - socksreq[1] = 1; /* authentication message type */ - us_length = htons((short)sspi_send_token.cbBuffer); - memcpy(socksreq+2, &us_length, sizeof(short)); - - code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); - if(code || (4 != written)) { - failf(data, "Failed to send SSPI authentication request."); - free(service_name); - if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer, - sspi_send_token.cbBuffer, &written); - if(code || (sspi_send_token.cbBuffer != (size_t)written)) { - failf(data, "Failed to send SSPI authentication token."); - free(service_name); - if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - } - - if(sspi_send_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - sspi_send_token.pvBuffer = NULL; - } - sspi_send_token.cbBuffer = 0; - - if(sspi_recv_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - sspi_recv_token.pvBuffer = NULL; - } - sspi_recv_token.cbBuffer = 0; - - if(status != SEC_I_CONTINUE_NEEDED) - break; - - /* analyse response */ - - /* GSS-API response looks like - * +----+------+-----+----------------+ - * |VER | MTYP | LEN | TOKEN | - * +----+------+----------------------+ - * | 1 | 1 | 2 | up to 2^16 - 1 | - * +----+------+-----+----------------+ - */ - - result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive SSPI authentication response."); - free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - /* ignore the first (VER) byte */ - if(socksreq[1] == 255) { /* status / message type */ - failf(data, "User was rejected by the SOCKS5 server (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 1) { /* status / messgae type */ - failf(data, "Invalid SSPI authentication response type (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq+2, sizeof(short)); - us_length = ntohs(us_length); - - sspi_recv_token.cbBuffer = us_length; - sspi_recv_token.pvBuffer = malloc(us_length); - - if(!sspi_recv_token.pvBuffer) { - free(service_name); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_OUT_OF_MEMORY; - } - result = Curl_blockread_all(conn, sock, (char *)sspi_recv_token.pvBuffer, - sspi_recv_token.cbBuffer, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive SSPI authentication token."); - free(service_name); - if(sspi_recv_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_recv_token.pvBuffer); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - context_handle = &sspi_context; - } - - free(service_name); - - /* Everything is good so far, user was authenticated! */ - status = s_pSecFn->QueryCredentialsAttributes(&cred_handle, - SECPKG_CRED_ATTR_NAMES, - &names); - s_pSecFn->FreeCredentialsHandle(&cred_handle); - if(check_sspi_err(conn, status, "QueryCredentialAttributes")) { - s_pSecFn->DeleteSecurityContext(&sspi_context); - s_pSecFn->FreeContextBuffer(names.sUserName); - failf(data, "Failed to determine user name."); - return CURLE_COULDNT_CONNECT; - } - infof(data, "SOCKS5 server authencticated user %s with GSS-API.\n", - names.sUserName); - s_pSecFn->FreeContextBuffer(names.sUserName); - - /* Do encryption */ - socksreq[0] = 1; /* GSS-API subnegotiation version */ - socksreq[1] = 2; /* encryption message type */ - - gss_enc = 0; /* no data protection */ - /* do confidentiality protection if supported */ - if(sspi_ret_flags & ISC_REQ_CONFIDENTIALITY) - gss_enc = 2; - /* else do integrity protection */ - else if(sspi_ret_flags & ISC_REQ_INTEGRITY) - gss_enc = 1; - - infof(data, "SOCKS5 server supports GSS-API %s data protection.\n", - (gss_enc==0)?"no":((gss_enc==1)?"integrity":"confidentiality") ); - /* force to no data protection, avoid encryption/decryption for now */ - gss_enc = 0; - /* - * Sending the encryption type in clear seems wrong. It should be - * protected with gss_seal()/gss_wrap(). See RFC1961 extract below - * The NEC reference implementations on which this is based is - * therefore at fault - * - * +------+------+------+.......................+ - * + ver | mtyp | len | token | - * +------+------+------+.......................+ - * + 0x01 | 0x02 | 0x02 | up to 2^16 - 1 octets | - * +------+------+------+.......................+ - * - * Where: - * - * - "ver" is the protocol version number, here 1 to represent the - * first version of the SOCKS/GSS-API protocol - * - * - "mtyp" is the message type, here 2 to represent a protection - * -level negotiation message - * - * - "len" is the length of the "token" field in octets - * - * - "token" is the GSS-API encapsulated protection level - * - * The token is produced by encapsulating an octet containing the - * required protection level using gss_seal()/gss_wrap() with conf_req - * set to FALSE. The token is verified using gss_unseal()/ - * gss_unwrap(). - * - */ - - if(data->set.socks5_gssapi_nec) { - us_length = htons((short)1); - memcpy(socksreq+2, &us_length, sizeof(short)); - } - else { - status = s_pSecFn->QueryContextAttributes(&sspi_context, - SECPKG_ATTR_SIZES, - &sspi_sizes); - if(check_sspi_err(conn, status, "QueryContextAttributes")) { - s_pSecFn->DeleteSecurityContext(&sspi_context); - failf(data, "Failed to query security context attributes."); - return CURLE_COULDNT_CONNECT; - } - - sspi_w_token[0].cbBuffer = sspi_sizes.cbSecurityTrailer; - sspi_w_token[0].BufferType = SECBUFFER_TOKEN; - sspi_w_token[0].pvBuffer = malloc(sspi_sizes.cbSecurityTrailer); - - if(!sspi_w_token[0].pvBuffer) { - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_OUT_OF_MEMORY; - } - - sspi_w_token[1].cbBuffer = 1; - sspi_w_token[1].pvBuffer = malloc(1); - if(!sspi_w_token[1].pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_OUT_OF_MEMORY; - } - - memcpy(sspi_w_token[1].pvBuffer, &gss_enc, 1); - sspi_w_token[2].BufferType = SECBUFFER_PADDING; - sspi_w_token[2].cbBuffer = sspi_sizes.cbBlockSize; - sspi_w_token[2].pvBuffer = malloc(sspi_sizes.cbBlockSize); - if(!sspi_w_token[2].pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_OUT_OF_MEMORY; - } - status = s_pSecFn->EncryptMessage(&sspi_context, - KERB_WRAP_NO_ENCRYPT, - &wrap_desc, - 0); - if(check_sspi_err(conn, status, "EncryptMessage")) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - failf(data, "Failed to query security context attributes."); - return CURLE_COULDNT_CONNECT; - } - sspi_send_token.cbBuffer = sspi_w_token[0].cbBuffer - + sspi_w_token[1].cbBuffer - + sspi_w_token[2].cbBuffer; - sspi_send_token.pvBuffer = malloc(sspi_send_token.cbBuffer); - if(!sspi_send_token.pvBuffer) { - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_OUT_OF_MEMORY; - } - - memcpy(sspi_send_token.pvBuffer, sspi_w_token[0].pvBuffer, - sspi_w_token[0].cbBuffer); - memcpy((PUCHAR) sspi_send_token.pvBuffer +(int)sspi_w_token[0].cbBuffer, - sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer); - memcpy((PUCHAR) sspi_send_token.pvBuffer - +sspi_w_token[0].cbBuffer - +sspi_w_token[1].cbBuffer, - sspi_w_token[2].pvBuffer, sspi_w_token[2].cbBuffer); - - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - sspi_w_token[0].pvBuffer = NULL; - sspi_w_token[0].cbBuffer = 0; - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - sspi_w_token[1].pvBuffer = NULL; - sspi_w_token[1].cbBuffer = 0; - s_pSecFn->FreeContextBuffer(sspi_w_token[2].pvBuffer); - sspi_w_token[2].pvBuffer = NULL; - sspi_w_token[2].cbBuffer = 0; - - us_length = htons((short)sspi_send_token.cbBuffer); - memcpy(socksreq+2, &us_length, sizeof(short)); - } - - code = Curl_write_plain(conn, sock, (char *)socksreq, 4, &written); - if(code || (4 != written)) { - failf(data, "Failed to send SSPI encryption request."); - if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - if(data->set.socks5_gssapi_nec) { - memcpy(socksreq, &gss_enc, 1); - code = Curl_write_plain(conn, sock, (char *)socksreq, 1, &written); - if(code || (1 != written)) { - failf(data, "Failed to send SSPI encryption type."); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - } - else { - code = Curl_write_plain(conn, sock, (char *)sspi_send_token.pvBuffer, - sspi_send_token.cbBuffer, &written); - if(code || (sspi_send_token.cbBuffer != (size_t)written)) { - failf(data, "Failed to send SSPI encryption type."); - if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - if(sspi_send_token.pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_send_token.pvBuffer); - } - - result = Curl_blockread_all(conn, sock, (char *)socksreq, 4, &actualread); - if(result || (actualread != 4)) { - failf(data, "Failed to receive SSPI encryption response."); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - /* ignore the first (VER) byte */ - if(socksreq[1] == 255) { /* status / message type */ - failf(data, "User was rejected by the SOCKS5 server (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - if(socksreq[1] != 2) { /* status / message type */ - failf(data, "Invalid SSPI encryption response type (%u %u).", - (unsigned int)socksreq[0], (unsigned int)socksreq[1]); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - memcpy(&us_length, socksreq+2, sizeof(short)); - us_length = ntohs(us_length); - - sspi_w_token[0].cbBuffer = us_length; - sspi_w_token[0].pvBuffer = malloc(us_length); - if(!sspi_w_token[0].pvBuffer) { - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_OUT_OF_MEMORY; - } - - result = Curl_blockread_all(conn, sock, (char *)sspi_w_token[0].pvBuffer, - sspi_w_token[0].cbBuffer, &actualread); - - if(result || (actualread != us_length)) { - failf(data, "Failed to receive SSPI encryption type."); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - - if(!data->set.socks5_gssapi_nec) { - wrap_desc.cBuffers = 2; - sspi_w_token[0].BufferType = SECBUFFER_STREAM; - sspi_w_token[1].BufferType = SECBUFFER_DATA; - sspi_w_token[1].cbBuffer = 0; - sspi_w_token[1].pvBuffer = NULL; - - status = s_pSecFn->DecryptMessage(&sspi_context, - &wrap_desc, - 0, - &qop); - - if(check_sspi_err(conn, status, "DecryptMessage")) { - if(sspi_w_token[0].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - if(sspi_w_token[1].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - failf(data, "Failed to query security context attributes."); - return CURLE_COULDNT_CONNECT; - } - - if(sspi_w_token[1].cbBuffer != 1) { - failf(data, "Invalid SSPI encryption response length (%lu).", - (unsigned long)sspi_w_token[1].cbBuffer); - if(sspi_w_token[0].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - if(sspi_w_token[1].pvBuffer) - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - - memcpy(socksreq, sspi_w_token[1].pvBuffer, sspi_w_token[1].cbBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[1].pvBuffer); - } - else { - if(sspi_w_token[0].cbBuffer != 1) { - failf(data, "Invalid SSPI encryption response length (%lu).", - (unsigned long)sspi_w_token[0].cbBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - s_pSecFn->DeleteSecurityContext(&sspi_context); - return CURLE_COULDNT_CONNECT; - } - memcpy(socksreq, sspi_w_token[0].pvBuffer, sspi_w_token[0].cbBuffer); - s_pSecFn->FreeContextBuffer(sspi_w_token[0].pvBuffer); - } - - infof(data, "SOCKS5 access with%s protection granted.\n", - (socksreq[0]==0)?"out GSS-API data": - ((socksreq[0]==1)?" GSS-API integrity":" GSS-API confidentiality")); - - /* For later use if encryption is required - conn->socks5_gssapi_enctype = socksreq[0]; - if(socksreq[0] != 0) - conn->socks5_sspi_context = sspi_context; - else { - s_pSecFn->DeleteSecurityContext(&sspi_context); - conn->socks5_sspi_context = sspi_context; - } - */ - return CURLE_OK; -} -#endif diff --git a/Externals/curl/lib/speedcheck.c b/Externals/curl/lib/speedcheck.c deleted file mode 100644 index 4706d2dff4..0000000000 --- a/Externals/curl/lib/speedcheck.c +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include -#include "urldata.h" -#include "sendf.h" -#include "multiif.h" -#include "speedcheck.h" - -void Curl_speedinit(struct SessionHandle *data) -{ - memset(&data->state.keeps_speed, 0, sizeof(struct timeval)); -} - -CURLcode Curl_speedcheck(struct SessionHandle *data, - struct timeval now) -{ - if((data->progress.current_speed >= 0) && - data->set.low_speed_time && - (Curl_tvlong(data->state.keeps_speed) != 0) && - (data->progress.current_speed < data->set.low_speed_limit)) { - long howlong = Curl_tvdiff(now, data->state.keeps_speed); - long nextcheck = (data->set.low_speed_time * 1000) - howlong; - - /* We are now below the "low speed limit". If we are below it - for "low speed time" seconds we consider that enough reason - to abort the download. */ - if(nextcheck <= 0) { - /* we have been this slow for long enough, now die */ - failf(data, - "Operation too slow. " - "Less than %ld bytes/sec transferred the last %ld seconds", - data->set.low_speed_limit, - data->set.low_speed_time); - return CURLE_OPERATION_TIMEDOUT; - } - else { - /* wait complete low_speed_time */ - Curl_expire_latest(data, nextcheck); - } - } - else { - /* we keep up the required speed all right */ - data->state.keeps_speed = now; - - if(data->set.low_speed_limit) - /* if there is a low speed limit enabled, we set the expire timer to - make this connection's speed get checked again no later than when - this time is up */ - Curl_expire_latest(data, data->set.low_speed_time*1000); - } - return CURLE_OK; -} diff --git a/Externals/curl/lib/speedcheck.h b/Externals/curl/lib/speedcheck.h deleted file mode 100644 index e1921d66bf..0000000000 --- a/Externals/curl/lib/speedcheck.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef HEADER_CURL_SPEEDCHECK_H -#define HEADER_CURL_SPEEDCHECK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "timeval.h" - -void Curl_speedinit(struct SessionHandle *data); -CURLcode Curl_speedcheck(struct SessionHandle *data, - struct timeval now); - -#endif /* HEADER_CURL_SPEEDCHECK_H */ diff --git a/Externals/curl/lib/splay.c b/Externals/curl/lib/splay.c deleted file mode 100644 index 7aa2e4bac3..0000000000 --- a/Externals/curl/lib/splay.c +++ /dev/null @@ -1,288 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1997 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "splay.h" - -/* - * This macro compares two node keys i and j and returns: - * - * negative value: when i is smaller than j - * zero : when i is equal to j - * positive when : when i is larger than j - */ -#define compare(i,j) Curl_splaycomparekeys((i),(j)) - -/* - * Splay using the key i (which may or may not be in the tree.) The starting - * root is t. - */ -struct Curl_tree *Curl_splay(struct timeval i, - struct Curl_tree *t) -{ - struct Curl_tree N, *l, *r, *y; - long comp; - - if(t == NULL) - return t; - N.smaller = N.larger = NULL; - l = r = &N; - - for(;;) { - comp = compare(i, t->key); - if(comp < 0) { - if(t->smaller == NULL) - break; - if(compare(i, t->smaller->key) < 0) { - y = t->smaller; /* rotate smaller */ - t->smaller = y->larger; - y->larger = t; - t = y; - if(t->smaller == NULL) - break; - } - r->smaller = t; /* link smaller */ - r = t; - t = t->smaller; - } - else if(comp > 0) { - if(t->larger == NULL) - break; - if(compare(i, t->larger->key) > 0) { - y = t->larger; /* rotate larger */ - t->larger = y->smaller; - y->smaller = t; - t = y; - if(t->larger == NULL) - break; - } - l->larger = t; /* link larger */ - l = t; - t = t->larger; - } - else - break; - } - - l->larger = t->smaller; /* assemble */ - r->smaller = t->larger; - t->smaller = N.larger; - t->larger = N.smaller; - - return t; -} - -/* Insert key i into the tree t. Return a pointer to the resulting tree or - * NULL if something went wrong. - * - * @unittest: 1309 - */ -struct Curl_tree *Curl_splayinsert(struct timeval i, - struct Curl_tree *t, - struct Curl_tree *node) -{ - static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */ - - if(node == NULL) - return t; - - if(t != NULL) { - t = Curl_splay(i, t); - if(compare(i, t->key)==0) { - /* There already exists a node in the tree with the very same key. Build - a linked list of nodes. We make the new 'node' struct the new master - node and make the previous node the first one in the 'same' list. */ - - node->same = t; - node->key = i; - node->smaller = t->smaller; - node->larger = t->larger; - - t->smaller = node; /* in the sub node for this same key, we use the - smaller pointer to point back to the master - node */ - - t->key = KEY_NOTUSED; /* and we set the key in the sub node to NOTUSED - to quickly identify this node as a subnode */ - - return node; /* new root node */ - } - } - - if(t == NULL) { - node->smaller = node->larger = NULL; - } - else if(compare(i, t->key) < 0) { - node->smaller = t->smaller; - node->larger = t; - t->smaller = NULL; - - } - else { - node->larger = t->larger; - node->smaller = t; - t->larger = NULL; - } - node->key = i; - - node->same = NULL; /* no identical node (yet) */ - return node; -} - -/* Finds and deletes the best-fit node from the tree. Return a pointer to the - resulting tree. best-fit means the node with the given or lower key */ -struct Curl_tree *Curl_splaygetbest(struct timeval i, - struct Curl_tree *t, - struct Curl_tree **removed) -{ - struct Curl_tree *x; - - if(!t) { - *removed = NULL; /* none removed since there was no root */ - return NULL; - } - - t = Curl_splay(i, t); - if(compare(i, t->key) < 0) { - /* too big node, try the smaller chain */ - if(t->smaller) - t=Curl_splay(t->smaller->key, t); - else { - /* fail */ - *removed = NULL; - return t; - } - } - - if(compare(i, t->key) >= 0) { /* found it */ - /* FIRST! Check if there is a list with identical keys */ - x = t->same; - if(x) { - /* there is, pick one from the list */ - - /* 'x' is the new root node */ - - x->key = t->key; - x->larger = t->larger; - x->smaller = t->smaller; - - *removed = t; - return x; /* new root */ - } - - if(t->smaller == NULL) { - x = t->larger; - } - else { - x = Curl_splay(i, t->smaller); - x->larger = t->larger; - } - *removed = t; - - return x; - } - else { - *removed = NULL; /* no match */ - return t; /* It wasn't there */ - } -} - - -/* Deletes the very node we point out from the tree if it's there. Stores a - * pointer to the new resulting tree in 'newroot'. - * - * Returns zero on success and non-zero on errors! TODO: document error codes. - * When returning error, it does not touch the 'newroot' pointer. - * - * NOTE: when the last node of the tree is removed, there's no tree left so - * 'newroot' will be made to point to NULL. - * - * @unittest: 1309 - */ -int Curl_splayremovebyaddr(struct Curl_tree *t, - struct Curl_tree *removenode, - struct Curl_tree **newroot) -{ - static const struct timeval KEY_NOTUSED = {-1, -1}; /* will *NEVER* appear */ - struct Curl_tree *x; - - if(!t || !removenode) - return 1; - - if(compare(KEY_NOTUSED, removenode->key) == 0) { - /* Key set to NOTUSED means it is a subnode within a 'same' linked list - and thus we can unlink it easily. The 'smaller' link of a subnode - links to the parent node. */ - if(removenode->smaller == NULL) - return 3; - - removenode->smaller->same = removenode->same; - if(removenode->same) - removenode->same->smaller = removenode->smaller; - - /* Ensures that double-remove gets caught. */ - removenode->smaller = NULL; - - /* voila, we're done! */ - *newroot = t; /* return the same root */ - return 0; - } - - t = Curl_splay(removenode->key, t); - - /* First make sure that we got the same root node as the one we want - to remove, as otherwise we might be trying to remove a node that - isn't actually in the tree. - - We cannot just compare the keys here as a double remove in quick - succession of a node with key != KEY_NOTUSED && same != NULL - could return the same key but a different node. */ - if(t != removenode) - return 2; - - /* Check if there is a list with identical sizes, as then we're trying to - remove the root node of a list of nodes with identical keys. */ - x = t->same; - if(x) { - /* 'x' is the new root node, we just make it use the root node's - smaller/larger links */ - - x->key = t->key; - x->larger = t->larger; - x->smaller = t->smaller; - } - else { - /* Remove the root node */ - if(t->smaller == NULL) - x = t->larger; - else { - x = Curl_splay(removenode->key, t->smaller); - x->larger = t->larger; - } - } - - *newroot = x; /* store new root pointer */ - - return 0; -} - diff --git a/Externals/curl/lib/splay.h b/Externals/curl/lib/splay.h deleted file mode 100644 index 427bfc8eb4..0000000000 --- a/Externals/curl/lib/splay.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef HEADER_CURL_SPLAY_H -#define HEADER_CURL_SPLAY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1997 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -struct Curl_tree { - struct Curl_tree *smaller; /* smaller node */ - struct Curl_tree *larger; /* larger node */ - struct Curl_tree *same; /* points to a node with identical key */ - struct timeval key; /* this node's "sort" key */ - void *payload; /* data the splay code doesn't care about */ -}; - -struct Curl_tree *Curl_splay(struct timeval i, - struct Curl_tree *t); - -struct Curl_tree *Curl_splayinsert(struct timeval key, - struct Curl_tree *t, - struct Curl_tree *newnode); - -#if 0 -struct Curl_tree *Curl_splayremove(struct timeval key, - struct Curl_tree *t, - struct Curl_tree **removed); -#endif - -struct Curl_tree *Curl_splaygetbest(struct timeval key, - struct Curl_tree *t, - struct Curl_tree **removed); - -int Curl_splayremovebyaddr(struct Curl_tree *t, - struct Curl_tree *removenode, - struct Curl_tree **newroot); - -#define Curl_splaycomparekeys(i,j) ( ((i.tv_sec) < (j.tv_sec)) ? -1 : \ - ( ((i.tv_sec) > (j.tv_sec)) ? 1 : \ - ( ((i.tv_usec) < (j.tv_usec)) ? -1 : \ - ( ((i.tv_usec) > (j.tv_usec)) ? 1 : 0)))) - -#ifdef DEBUGBUILD -void Curl_splayprint(struct Curl_tree * t, int d, char output); -#else -#define Curl_splayprint(x,y,z) Curl_nop_stmt -#endif - -#endif /* HEADER_CURL_SPLAY_H */ diff --git a/Externals/curl/lib/ssh.c b/Externals/curl/lib/ssh.c deleted file mode 100644 index d5a1a2a8cf..0000000000 --- a/Externals/curl/lib/ssh.c +++ /dev/null @@ -1,3454 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* #define CURL_LIBSSH2_DEBUG */ - -#include "curl_setup.h" - -#ifdef USE_LIBSSH2 - -#ifdef HAVE_LIMITS_H -# include -#endif - -#include -#include - -#ifdef HAVE_FCNTL_H -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_UTSNAME_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef __VMS -#include -#include -#endif - -#if (defined(NETWARE) && defined(__NOVELL_LIBC__)) -#undef in_addr_t -#define in_addr_t unsigned long -#endif - -#include -#include "urldata.h" -#include "sendf.h" -#include "hostip.h" -#include "progress.h" -#include "transfer.h" -#include "escape.h" -#include "http.h" /* for HTTP proxy tunnel stuff */ -#include "ssh.h" -#include "url.h" -#include "speedcheck.h" -#include "getinfo.h" - -#include "strequal.h" -#include "vtls/vtls.h" -#include "connect.h" -#include "strerror.h" -#include "inet_ntop.h" -#include "parsedate.h" /* for the week day and month names */ -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "strtoofft.h" -#include "multiif.h" -#include "select.h" -#include "warnless.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#ifdef WIN32 -# undef PATH_MAX -# define PATH_MAX MAX_PATH -# ifndef R_OK -# define R_OK 4 -# endif -#endif - -#ifndef PATH_MAX -#define PATH_MAX 1024 /* just an extra precaution since there are systems that - have their definition hidden well */ -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010206 -/* libssh2_sftp_statvfs and friends were added in 1.2.6 */ -#define HAS_STATVFS_SUPPORT 1 -#endif - -#define sftp_libssh2_last_error(s) curlx_ultosi(libssh2_sftp_last_error(s)) - -#define sftp_libssh2_realpath(s,p,t,m) \ - libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \ - (t), (m), LIBSSH2_SFTP_REALPATH) - -/* Local functions: */ -static const char *sftp_libssh2_strerror(int err); -static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); -static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc); -static LIBSSH2_FREE_FUNC(my_libssh2_free); - -static CURLcode get_pathname(const char **cpp, char **path); - -static CURLcode ssh_connect(struct connectdata *conn, bool *done); -static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done); -static CURLcode ssh_do(struct connectdata *conn, bool *done); - -static CURLcode ssh_getworkingpath(struct connectdata *conn, - char *homedir, /* when SFTP is used */ - char **path); - -static CURLcode scp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode scp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection); - -static CURLcode sftp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode sftp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); -static -CURLcode sftp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done); - -static int ssh_getsock(struct connectdata *conn, - curl_socket_t *sock, /* points to numsocks number - of sockets */ - int numsocks); - -static int ssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock, /* points to numsocks - number of sockets */ - int numsocks); - -static CURLcode ssh_setup_connection(struct connectdata *conn); - -/* - * SCP protocol handler. - */ - -const struct Curl_handler Curl_handler_scp = { - "SCP", /* scheme */ - ssh_setup_connection, /* setup_connection */ - ssh_do, /* do_it */ - scp_done, /* done */ - ZERO_NULL, /* do_more */ - ssh_connect, /* connect_it */ - ssh_multi_statemach, /* connecting */ - scp_doing, /* doing */ - ssh_getsock, /* proto_getsock */ - ssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ssh_perform_getsock, /* perform_getsock */ - scp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SSH, /* defport */ - CURLPROTO_SCP, /* protocol */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION - | PROTOPT_NOURLQUERY /* flags */ -}; - - -/* - * SFTP protocol handler. - */ - -const struct Curl_handler Curl_handler_sftp = { - "SFTP", /* scheme */ - ssh_setup_connection, /* setup_connection */ - ssh_do, /* do_it */ - sftp_done, /* done */ - ZERO_NULL, /* do_more */ - ssh_connect, /* connect_it */ - ssh_multi_statemach, /* connecting */ - sftp_doing, /* doing */ - ssh_getsock, /* proto_getsock */ - ssh_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ssh_perform_getsock, /* perform_getsock */ - sftp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_SSH, /* defport */ - CURLPROTO_SFTP, /* protocol */ - PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION - | PROTOPT_NOURLQUERY /* flags */ -}; - -static void -kbd_callback(const char *name, int name_len, const char *instruction, - int instruction_len, int num_prompts, - const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, - LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, - void **abstract) -{ - struct connectdata *conn = (struct connectdata *)*abstract; - -#ifdef CURL_LIBSSH2_DEBUG - fprintf(stderr, "name=%s\n", name); - fprintf(stderr, "name_len=%d\n", name_len); - fprintf(stderr, "instruction=%s\n", instruction); - fprintf(stderr, "instruction_len=%d\n", instruction_len); - fprintf(stderr, "num_prompts=%d\n", num_prompts); -#else - (void)name; - (void)name_len; - (void)instruction; - (void)instruction_len; -#endif /* CURL_LIBSSH2_DEBUG */ - if(num_prompts == 1) { - responses[0].text = strdup(conn->passwd); - responses[0].length = curlx_uztoui(strlen(conn->passwd)); - } - (void)prompts; - (void)abstract; -} /* kbd_callback */ - -static CURLcode sftp_libssh2_error_to_CURLE(int err) -{ - switch (err) { - case LIBSSH2_FX_OK: - return CURLE_OK; - - case LIBSSH2_FX_NO_SUCH_FILE: - case LIBSSH2_FX_NO_SUCH_PATH: - return CURLE_REMOTE_FILE_NOT_FOUND; - - case LIBSSH2_FX_PERMISSION_DENIED: - case LIBSSH2_FX_WRITE_PROTECT: - case LIBSSH2_FX_LOCK_CONFlICT: - return CURLE_REMOTE_ACCESS_DENIED; - - case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: - case LIBSSH2_FX_QUOTA_EXCEEDED: - return CURLE_REMOTE_DISK_FULL; - - case LIBSSH2_FX_FILE_ALREADY_EXISTS: - return CURLE_REMOTE_FILE_EXISTS; - - case LIBSSH2_FX_DIR_NOT_EMPTY: - return CURLE_QUOTE_ERROR; - - default: - break; - } - - return CURLE_SSH; -} - -static CURLcode libssh2_session_error_to_CURLE(int err) -{ - switch (err) { - /* Ordered by order of appearance in libssh2.h */ - case LIBSSH2_ERROR_NONE: - return CURLE_OK; - - case LIBSSH2_ERROR_SOCKET_NONE: - return CURLE_COULDNT_CONNECT; - - case LIBSSH2_ERROR_ALLOC: - return CURLE_OUT_OF_MEMORY; - - case LIBSSH2_ERROR_SOCKET_SEND: - return CURLE_SEND_ERROR; - - case LIBSSH2_ERROR_HOSTKEY_INIT: - case LIBSSH2_ERROR_HOSTKEY_SIGN: - case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED: - case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: - return CURLE_PEER_FAILED_VERIFICATION; - - case LIBSSH2_ERROR_PASSWORD_EXPIRED: - return CURLE_LOGIN_DENIED; - - case LIBSSH2_ERROR_SOCKET_TIMEOUT: - case LIBSSH2_ERROR_TIMEOUT: - return CURLE_OPERATION_TIMEDOUT; - - case LIBSSH2_ERROR_EAGAIN: - return CURLE_AGAIN; - } - - /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode - error code, and possibly add a few new SSH-related one. We must however - not return or even depend on libssh2 errors in the public libcurl API */ - - return CURLE_SSH; -} - -static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc) -{ - (void)abstract; /* arg not used */ - return malloc(count); -} - -static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc) -{ - (void)abstract; /* arg not used */ - return realloc(ptr, count); -} - -static LIBSSH2_FREE_FUNC(my_libssh2_free) -{ - (void)abstract; /* arg not used */ - if(ptr) /* ssh2 agent sometimes call free with null ptr */ - free(ptr); -} - -/* - * SSH State machine related code - */ -/* This is the ONLY way to change SSH state! */ -static void state(struct connectdata *conn, sshstate nowstate) -{ - struct ssh_conn *sshc = &conn->proto.sshc; -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char * const names[] = { - "SSH_STOP", - "SSH_INIT", - "SSH_S_STARTUP", - "SSH_HOSTKEY", - "SSH_AUTHLIST", - "SSH_AUTH_PKEY_INIT", - "SSH_AUTH_PKEY", - "SSH_AUTH_PASS_INIT", - "SSH_AUTH_PASS", - "SSH_AUTH_AGENT_INIT", - "SSH_AUTH_AGENT_LIST", - "SSH_AUTH_AGENT", - "SSH_AUTH_HOST_INIT", - "SSH_AUTH_HOST", - "SSH_AUTH_KEY_INIT", - "SSH_AUTH_KEY", - "SSH_AUTH_DONE", - "SSH_SFTP_INIT", - "SSH_SFTP_REALPATH", - "SSH_SFTP_QUOTE_INIT", - "SSH_SFTP_POSTQUOTE_INIT", - "SSH_SFTP_QUOTE", - "SSH_SFTP_NEXT_QUOTE", - "SSH_SFTP_QUOTE_STAT", - "SSH_SFTP_QUOTE_SETSTAT", - "SSH_SFTP_QUOTE_SYMLINK", - "SSH_SFTP_QUOTE_MKDIR", - "SSH_SFTP_QUOTE_RENAME", - "SSH_SFTP_QUOTE_RMDIR", - "SSH_SFTP_QUOTE_UNLINK", - "SSH_SFTP_QUOTE_STATVFS", - "SSH_SFTP_GETINFO", - "SSH_SFTP_FILETIME", - "SSH_SFTP_TRANS_INIT", - "SSH_SFTP_UPLOAD_INIT", - "SSH_SFTP_CREATE_DIRS_INIT", - "SSH_SFTP_CREATE_DIRS", - "SSH_SFTP_CREATE_DIRS_MKDIR", - "SSH_SFTP_READDIR_INIT", - "SSH_SFTP_READDIR", - "SSH_SFTP_READDIR_LINK", - "SSH_SFTP_READDIR_BOTTOM", - "SSH_SFTP_READDIR_DONE", - "SSH_SFTP_DOWNLOAD_INIT", - "SSH_SFTP_DOWNLOAD_STAT", - "SSH_SFTP_CLOSE", - "SSH_SFTP_SHUTDOWN", - "SSH_SCP_TRANS_INIT", - "SSH_SCP_UPLOAD_INIT", - "SSH_SCP_DOWNLOAD_INIT", - "SSH_SCP_DONE", - "SSH_SCP_SEND_EOF", - "SSH_SCP_WAIT_EOF", - "SSH_SCP_WAIT_CLOSE", - "SSH_SCP_CHANNEL_FREE", - "SSH_SESSION_DISCONNECT", - "SSH_SESSION_FREE", - "QUIT" - }; - - if(sshc->state != nowstate) { - infof(conn->data, "SFTP %p state change from %s to %s\n", - (void *)sshc, names[sshc->state], names[nowstate]); - } -#endif - - sshc->state = nowstate; -} - -/* figure out the path to work with in this particular request */ -static CURLcode ssh_getworkingpath(struct connectdata *conn, - char *homedir, /* when SFTP is used */ - char **path) /* returns the allocated - real path to work with */ -{ - struct SessionHandle *data = conn->data; - char *real_path = NULL; - char *working_path; - int working_path_len; - - working_path = curl_easy_unescape(data, data->state.path, 0, - &working_path_len); - if(!working_path) - return CURLE_OUT_OF_MEMORY; - - /* Check for /~/, indicating relative to the user's home directory */ - if(conn->handler->protocol & CURLPROTO_SCP) { - real_path = malloc(working_path_len+1); - if(real_path == NULL) { - free(working_path); - return CURLE_OUT_OF_MEMORY; - } - if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) - /* It is referenced to the home directory, so strip the leading '/~/' */ - memcpy(real_path, working_path+3, 4 + working_path_len-3); - else - memcpy(real_path, working_path, 1 + working_path_len); - } - else if(conn->handler->protocol & CURLPROTO_SFTP) { - if((working_path_len > 1) && (working_path[1] == '~')) { - size_t homelen = strlen(homedir); - real_path = malloc(homelen + working_path_len + 1); - if(real_path == NULL) { - free(working_path); - return CURLE_OUT_OF_MEMORY; - } - /* It is referenced to the home directory, so strip the - leading '/' */ - memcpy(real_path, homedir, homelen); - real_path[homelen] = '/'; - real_path[homelen+1] = '\0'; - if(working_path_len > 3) { - memcpy(real_path+homelen+1, working_path + 3, - 1 + working_path_len -3); - } - } - else { - real_path = malloc(working_path_len+1); - if(real_path == NULL) { - free(working_path); - return CURLE_OUT_OF_MEMORY; - } - memcpy(real_path, working_path, 1+working_path_len); - } - } - - free(working_path); - - /* store the pointer for the caller to receive */ - *path = real_path; - - return CURLE_OK; -} - -#ifdef HAVE_LIBSSH2_KNOWNHOST_API -static int sshkeycallback(CURL *easy, - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch match, - void *clientp) -{ - (void)easy; - (void)knownkey; - (void)foundkey; - (void)clientp; - - /* we only allow perfect matches, and we reject everything else */ - return (match != CURLKHMATCH_OK)?CURLKHSTAT_REJECT:CURLKHSTAT_FINE; -} -#endif - -/* - * Earlier libssh2 versions didn't have the ability to seek to 64bit positions - * with 32bit size_t. - */ -#ifdef HAVE_LIBSSH2_SFTP_SEEK64 -#define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y) -#else -#define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y) -#endif - -/* - * Earlier libssh2 versions didn't do SCP properly beyond 32bit sizes on 32bit - * architectures so we check of the necessary function is present. - */ -#ifndef HAVE_LIBSSH2_SCP_SEND64 -#define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0) -#else -#define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \ - (libssh2_uint64_t)d, 0, 0) -#endif - -/* - * libssh2 1.2.8 fixed the problem with 32bit ints used for sockets on win64. - */ -#ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE -#define libssh2_session_startup(x,y) libssh2_session_handshake(x,y) -#endif - -static CURLcode ssh_knownhost(struct connectdata *conn) -{ - CURLcode result = CURLE_OK; - -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - struct SessionHandle *data = conn->data; - - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - /* we're asked to verify the host against a file */ - struct ssh_conn *sshc = &conn->proto.sshc; - int rc; - int keytype; - size_t keylen; - const char *remotekey = libssh2_session_hostkey(sshc->ssh_session, - &keylen, &keytype); - int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE; - int keybit = 0; - - if(remotekey) { - /* - * A subject to figure out is what host name we need to pass in here. - * What host name does OpenSSH store in its file if an IDN name is - * used? - */ - struct libssh2_knownhost *host; - enum curl_khmatch keymatch; - curl_sshkeycallback func = - data->set.ssh_keyfunc?data->set.ssh_keyfunc:sshkeycallback; - struct curl_khkey knownkey; - struct curl_khkey *knownkeyp = NULL; - struct curl_khkey foundkey; - - keybit = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - LIBSSH2_KNOWNHOST_KEY_SSHRSA:LIBSSH2_KNOWNHOST_KEY_SSHDSS; - -#ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP - keycheck = libssh2_knownhost_checkp(sshc->kh, - conn->host.name, - (conn->remote_port != PORT_SSH)? - conn->remote_port:-1, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); -#else - keycheck = libssh2_knownhost_check(sshc->kh, - conn->host.name, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, - &host); -#endif - - infof(data, "SSH host check: %d, key: %s\n", keycheck, - (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH)? - host->key:""); - - /* setup 'knownkey' */ - if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) { - knownkey.key = host->key; - knownkey.len = 0; - knownkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - CURLKHTYPE_RSA : CURLKHTYPE_DSS; - knownkeyp = &knownkey; - } - - /* setup 'foundkey' */ - foundkey.key = remotekey; - foundkey.len = keylen; - foundkey.keytype = (keytype == LIBSSH2_HOSTKEY_TYPE_RSA)? - CURLKHTYPE_RSA : CURLKHTYPE_DSS; - - /* - * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the - * curl_khmatch enum are ever modified, we need to introduce a - * translation table here! - */ - keymatch = (enum curl_khmatch)keycheck; - - /* Ask the callback how to behave */ - rc = func(data, knownkeyp, /* from the knownhosts file */ - &foundkey, /* from the remote host */ - keymatch, data->set.ssh_keyfunc_userp); - } - else - /* no remotekey means failure! */ - rc = CURLKHSTAT_REJECT; - - switch(rc) { - default: /* unknown return codes will equal reject */ - /* FALLTHROUGH */ - case CURLKHSTAT_REJECT: - state(conn, SSH_SESSION_FREE); - /* FALLTHROUGH */ - case CURLKHSTAT_DEFER: - /* DEFER means bail out but keep the SSH_HOSTKEY state */ - result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; - break; - case CURLKHSTAT_FINE: - case CURLKHSTAT_FINE_ADD_TO_FILE: - /* proceed */ - if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) { - /* the found host+key didn't match but has been told to be fine - anyway so we add it in memory */ - int addrc = libssh2_knownhost_add(sshc->kh, - conn->host.name, NULL, - remotekey, keylen, - LIBSSH2_KNOWNHOST_TYPE_PLAIN| - LIBSSH2_KNOWNHOST_KEYENC_RAW| - keybit, NULL); - if(addrc) - infof(data, "Warning adding the known host %s failed!\n", - conn->host.name); - else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE) { - /* now we write the entire in-memory list of known hosts to the - known_hosts file */ - int wrc = - libssh2_knownhost_writefile(sshc->kh, - data->set.str[STRING_SSH_KNOWNHOSTS], - LIBSSH2_KNOWNHOST_FILE_OPENSSH); - if(wrc) { - infof(data, "Warning, writing %s failed!\n", - data->set.str[STRING_SSH_KNOWNHOSTS]); - } - } - } - break; - } - } -#else /* HAVE_LIBSSH2_KNOWNHOST_API */ - (void)conn; -#endif - return result; -} - -static CURLcode ssh_check_fingerprint(struct connectdata *conn) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - struct SessionHandle *data = conn->data; - const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; - char md5buffer[33]; - int i; - - const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session, - LIBSSH2_HOSTKEY_HASH_MD5); - - if(fingerprint) { - /* The fingerprint points to static storage (!), don't free() it. */ - for(i = 0; i < 16; i++) - snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]); - infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); - } - - /* Before we authenticate we check the hostkey's MD5 fingerprint - * against a known fingerprint, if available. - */ - if(pubkey_md5 && strlen(pubkey_md5) == 32) { - if(!fingerprint || !strequal(md5buffer, pubkey_md5)) { - if(fingerprint) - failf(data, - "Denied establishing ssh session: mismatch md5 fingerprint. " - "Remote %s is not equal to %s", md5buffer, pubkey_md5); - else - failf(data, - "Denied establishing ssh session: md5 fingerprint not available"); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; - return sshc->actualcode; - } - else { - infof(data, "MD5 checksum match!\n"); - /* as we already matched, we skip the check for known hosts */ - return CURLE_OK; - } - } - else - return ssh_knownhost(conn); -} - -/* - * ssh_statemach_act() runs the SSH state machine as far as it can without - * blocking and without reaching the end. The data the pointer 'block' points - * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN - * meaning it wants to be called again when the socket is ready - */ - -static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct SSHPROTO *sftp_scp = data->req.protop; - struct ssh_conn *sshc = &conn->proto.sshc; - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - char *new_readdir_line; - int rc = LIBSSH2_ERROR_NONE; - int err; - int seekerr = CURL_SEEKFUNC_OK; - *block = 0; /* we're not blocking by default */ - - do { - - switch(sshc->state) { - case SSH_INIT: - sshc->secondCreateDirs = 0; - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_OK; - - /* Set libssh2 to non-blocking, since everything internally is - non-blocking */ - libssh2_session_set_blocking(sshc->ssh_session, 0); - - state(conn, SSH_S_STARTUP); - /* fall-through */ - - case SSH_S_STARTUP: - rc = libssh2_session_startup(sshc->ssh_session, (int)sock); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc) { - failf(data, "Failure establishing ssh session"); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_FAILED_INIT; - break; - } - - state(conn, SSH_HOSTKEY); - - /* fall-through */ - case SSH_HOSTKEY: - /* - * Before we authenticate we should check the hostkey's fingerprint - * against our known hosts. How that is handled (reading from file, - * whatever) is up to us. - */ - result = ssh_check_fingerprint(conn); - if(!result) - state(conn, SSH_AUTHLIST); - /* ssh_check_fingerprint sets state appropriately on error */ - break; - - case SSH_AUTHLIST: - /* - * Figure out authentication methods - * NB: As soon as we have provided a username to an openssh server we - * must never change it later. Thus, always specify the correct username - * here, even though the libssh2 docs kind of indicate that it should be - * possible to get a 'generic' list (not user-specific) of authentication - * methods, presumably with a blank username. That won't work in my - * experience. - * So always specify it here. - */ - sshc->authlist = libssh2_userauth_list(sshc->ssh_session, - conn->user, - curlx_uztoui(strlen(conn->user))); - - if(!sshc->authlist) { - if(libssh2_userauth_authenticated(sshc->ssh_session)) { - sshc->authed = TRUE; - infof(data, "SSH user accepted with no authentication\n"); - state(conn, SSH_AUTH_DONE); - break; - } - else if((err = libssh2_session_last_errno(sshc->ssh_session)) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - else { - state(conn, SSH_SESSION_FREE); - sshc->actualcode = libssh2_session_error_to_CURLE(err); - break; - } - } - infof(data, "SSH authentication methods available: %s\n", - sshc->authlist); - - state(conn, SSH_AUTH_PKEY_INIT); - break; - - case SSH_AUTH_PKEY_INIT: - /* - * Check the supported auth types in the order I feel is most secure - * with the requested type of authentication - */ - sshc->authed = FALSE; - - if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) && - (strstr(sshc->authlist, "publickey") != NULL)) { - char *home = NULL; - bool out_of_memory = FALSE; - - sshc->rsa_pub = sshc->rsa = NULL; - - /* To ponder about: should really the lib be messing about with the - HOME environment variable etc? */ - home = curl_getenv("HOME"); - - if(data->set.str[STRING_SSH_PRIVATE_KEY]) - sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]); - else { - /* If no private key file is specified, try some common paths. */ - if(home) { - /* Try ~/.ssh first. */ - sshc->rsa = aprintf("%s/.ssh/id_rsa", home); - if(!sshc->rsa) - out_of_memory = TRUE; - else if(access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - sshc->rsa = aprintf("%s/.ssh/id_dsa", home); - if(!sshc->rsa) - out_of_memory = TRUE; - else if(access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - } - } - } - if(!out_of_memory && !sshc->rsa) { - /* Nothing found; try the current dir. */ - sshc->rsa = strdup("id_rsa"); - if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - sshc->rsa = strdup("id_dsa"); - if(sshc->rsa && access(sshc->rsa, R_OK) != 0) { - Curl_safefree(sshc->rsa); - /* Out of guesses. Set to the empty string to avoid - * surprising info messages. */ - sshc->rsa = strdup(""); - } - } - } - } - - /* - * Unless the user explicitly specifies a public key file, let - * libssh2 extract the public key from the private key file. - * This is done by simply passing sshc->rsa_pub = NULL. - */ - if(data->set.str[STRING_SSH_PUBLIC_KEY] - /* treat empty string the same way as NULL */ - && data->set.str[STRING_SSH_PUBLIC_KEY][0]) { - sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]); - if(!sshc->rsa_pub) - out_of_memory = TRUE; - } - - if(out_of_memory || sshc->rsa == NULL) { - free(home); - Curl_safefree(sshc->rsa); - Curl_safefree(sshc->rsa_pub); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - sshc->passphrase = data->set.str[STRING_KEY_PASSWD]; - if(!sshc->passphrase) - sshc->passphrase = ""; - - free(home); - - if(sshc->rsa_pub) - infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub); - infof(data, "Using SSH private key file '%s'\n", sshc->rsa); - - state(conn, SSH_AUTH_PKEY); - } - else { - state(conn, SSH_AUTH_PASS_INIT); - } - break; - - case SSH_AUTH_PKEY: - /* The function below checks if the files exists, no need to stat() here. - */ - rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session, - conn->user, - curlx_uztoui( - strlen(conn->user)), - sshc->rsa_pub, - sshc->rsa, sshc->passphrase); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - - Curl_safefree(sshc->rsa_pub); - Curl_safefree(sshc->rsa); - - if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized SSH public key authentication\n"); - state(conn, SSH_AUTH_DONE); - } - else { - char *err_msg; - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - infof(data, "SSH public key authentication failed: %s\n", err_msg); - state(conn, SSH_AUTH_PASS_INIT); - } - break; - - case SSH_AUTH_PASS_INIT: - if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && - (strstr(sshc->authlist, "password") != NULL)) { - state(conn, SSH_AUTH_PASS); - } - else { - state(conn, SSH_AUTH_HOST_INIT); - } - break; - - case SSH_AUTH_PASS: - rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user, - curlx_uztoui(strlen(conn->user)), - conn->passwd, - curlx_uztoui(strlen(conn->passwd)), - NULL); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized password authentication\n"); - state(conn, SSH_AUTH_DONE); - } - else { - state(conn, SSH_AUTH_HOST_INIT); - rc = 0; /* clear rc and continue */ - } - break; - - case SSH_AUTH_HOST_INIT: - if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && - (strstr(sshc->authlist, "hostbased") != NULL)) { - state(conn, SSH_AUTH_HOST); - } - else { - state(conn, SSH_AUTH_AGENT_INIT); - } - break; - - case SSH_AUTH_HOST: - state(conn, SSH_AUTH_AGENT_INIT); - break; - - case SSH_AUTH_AGENT_INIT: -#ifdef HAVE_LIBSSH2_AGENT_API - if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT) - && (strstr(sshc->authlist, "publickey") != NULL)) { - - /* Connect to the ssh-agent */ - /* The agent could be shared by a curl thread i believe - but nothing obvious as keys can be added/removed at any time */ - if(!sshc->ssh_agent) { - sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session); - if(!sshc->ssh_agent) { - infof(data, "Could not create agent object\n"); - - state(conn, SSH_AUTH_KEY_INIT); - break; - } - } - - rc = libssh2_agent_connect(sshc->ssh_agent); - if(rc == LIBSSH2_ERROR_EAGAIN) - break; - if(rc < 0) { - infof(data, "Failure connecting to agent\n"); - state(conn, SSH_AUTH_KEY_INIT); - } - else { - state(conn, SSH_AUTH_AGENT_LIST); - } - } - else -#endif /* HAVE_LIBSSH2_AGENT_API */ - state(conn, SSH_AUTH_KEY_INIT); - break; - - case SSH_AUTH_AGENT_LIST: -#ifdef HAVE_LIBSSH2_AGENT_API - rc = libssh2_agent_list_identities(sshc->ssh_agent); - - if(rc == LIBSSH2_ERROR_EAGAIN) - break; - if(rc < 0) { - infof(data, "Failure requesting identities to agent\n"); - state(conn, SSH_AUTH_KEY_INIT); - } - else { - state(conn, SSH_AUTH_AGENT); - sshc->sshagent_prev_identity = NULL; - } -#endif - break; - - case SSH_AUTH_AGENT: -#ifdef HAVE_LIBSSH2_AGENT_API - /* as prev_identity evolves only after an identity user auth finished we - can safely request it again as long as EAGAIN is returned here or by - libssh2_agent_userauth */ - rc = libssh2_agent_get_identity(sshc->ssh_agent, - &sshc->sshagent_identity, - sshc->sshagent_prev_identity); - if(rc == LIBSSH2_ERROR_EAGAIN) - break; - - if(rc == 0) { - rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user, - sshc->sshagent_identity); - - if(rc < 0) { - if(rc != LIBSSH2_ERROR_EAGAIN) - /* tried and failed? go to next identity */ - sshc->sshagent_prev_identity = sshc->sshagent_identity; - else - break; - } - } - - if(rc < 0) - infof(data, "Failure requesting identities to agent\n"); - else if(rc == 1) - infof(data, "No identity would match\n"); - - if(rc == LIBSSH2_ERROR_NONE) { - sshc->authed = TRUE; - infof(data, "Agent based authentication successful\n"); - state(conn, SSH_AUTH_DONE); - } - else { - state(conn, SSH_AUTH_KEY_INIT); - rc = 0; /* clear rc and continue */ - } -#endif - break; - - case SSH_AUTH_KEY_INIT: - if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) - && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) { - state(conn, SSH_AUTH_KEY); - } - else { - state(conn, SSH_AUTH_DONE); - } - break; - - case SSH_AUTH_KEY: - /* Authentication failed. Continue with keyboard-interactive now. */ - rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session, - conn->user, - curlx_uztoui( - strlen(conn->user)), - &kbd_callback); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc == 0) { - sshc->authed = TRUE; - infof(data, "Initialized keyboard interactive authentication\n"); - } - state(conn, SSH_AUTH_DONE); - break; - - case SSH_AUTH_DONE: - if(!sshc->authed) { - failf(data, "Authentication failure"); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_LOGIN_DENIED; - break; - } - - /* - * At this point we have an authenticated ssh session. - */ - infof(data, "Authentication complete\n"); - - Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ - - conn->sockfd = sock; - conn->writesockfd = CURL_SOCKET_BAD; - - if(conn->handler->protocol == CURLPROTO_SFTP) { - state(conn, SSH_SFTP_INIT); - break; - } - infof(data, "SSH CONNECT phase done\n"); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_INIT: - /* - * Start the libssh2 sftp session - */ - sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session); - if(!sshc->sftp_session) { - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - else { - char *err_msg; - - (void)libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0); - failf(data, "Failure initializing sftp session: %s", err_msg); - state(conn, SSH_SESSION_FREE); - sshc->actualcode = CURLE_FAILED_INIT; - break; - } - } - state(conn, SSH_SFTP_REALPATH); - break; - - case SSH_SFTP_REALPATH: - { - char tempHome[PATH_MAX]; - - /* - * Get the "home" directory - */ - rc = sftp_libssh2_realpath(sshc->sftp_session, ".", - tempHome, PATH_MAX-1); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc > 0) { - /* It seems that this string is not always NULL terminated */ - tempHome[rc] = '\0'; - sshc->homedir = strdup(tempHome); - if(!sshc->homedir) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - conn->data->state.most_recent_ftp_entrypath = sshc->homedir; - } - else { - /* Return the error type */ - err = sftp_libssh2_last_error(sshc->sftp_session); - result = sftp_libssh2_error_to_CURLE(err); - sshc->actualcode = result?result:CURLE_SSH; - DEBUGF(infof(data, "error = %d makes libcurl = %d\n", - err, (int)result)); - state(conn, SSH_STOP); - break; - } - } - /* This is the last step in the SFTP connect phase. Do note that while - we get the homedir here, we get the "workingpath" in the DO action - since the homedir will remain the same between request but the - working path will not. */ - DEBUGF(infof(data, "SSH CONNECT phase done\n")); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_QUOTE_INIT: - - result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path); - if(result) { - sshc->actualcode = result; - state(conn, SSH_STOP); - break; - } - - if(data->set.quote) { - infof(data, "Sending quote commands\n"); - sshc->quote_item = data->set.quote; - state(conn, SSH_SFTP_QUOTE); - } - else { - state(conn, SSH_SFTP_GETINFO); - } - break; - - case SSH_SFTP_POSTQUOTE_INIT: - if(data->set.postquote) { - infof(data, "Sending quote commands\n"); - sshc->quote_item = data->set.postquote; - state(conn, SSH_SFTP_QUOTE); - } - else { - state(conn, SSH_STOP); - } - break; - - case SSH_SFTP_QUOTE: - /* Send any quote commands */ - { - const char *cp; - - /* - * Support some of the "FTP" commands - */ - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(curl_strequal("pwd", cmd)) { - /* output debug output if that is requested */ - char *tmp = aprintf("257 \"%s\" is current directory.\n", - sftp_scp->path); - if(!tmp) { - result = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - break; - } - if(data->set.verbose) { - Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn); - Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn); - } - /* this sends an FTP-like "header" to the header callback so that the - current directory can be read very similar to how it is read when - using ordinary FTP. */ - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - else - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - } - else if(cmd) { - /* - * the arguments following the command must be separated from the - * command with a space so we can check for it unconditionally - */ - cp = strchr(cmd, ' '); - if(cp == NULL) { - failf(data, "Syntax error in SFTP command. Supply parameter(s)!"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - - /* - * also, every command takes at least one argument so we get that - * first argument right now - */ - result = get_pathname(&cp, &sshc->quote_path1); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error: Bad first parameter"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - - /* - * SFTP is a binary protocol, so we don't send text commands - * to the server. Instead, we scan for commands used by - * OpenSSH's sftp program and call the appropriate libssh2 - * functions. - */ - if(curl_strnequal(cmd, "chgrp ", 6) || - curl_strnequal(cmd, "chmod ", 6) || - curl_strnequal(cmd, "chown ", 6) ) { - /* attribute change */ - - /* sshc->quote_path1 contains the mode to set */ - /* get the destination */ - result = get_pathname(&cp, &sshc->quote_path2); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in chgrp/chmod/chown: " - "Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - state(conn, SSH_SFTP_QUOTE_STAT); - break; - } - else if(curl_strnequal(cmd, "ln ", 3) || - curl_strnequal(cmd, "symlink ", 8)) { - /* symbolic linking */ - /* sshc->quote_path1 is the source */ - /* get the destination */ - result = get_pathname(&cp, &sshc->quote_path2); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, - "Syntax error in ln/symlink: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - state(conn, SSH_SFTP_QUOTE_SYMLINK); - break; - } - else if(curl_strnequal(cmd, "mkdir ", 6)) { - /* create dir */ - state(conn, SSH_SFTP_QUOTE_MKDIR); - break; - } - else if(curl_strnequal(cmd, "rename ", 7)) { - /* rename file */ - /* first param is the source path */ - /* second param is the dest. path */ - result = get_pathname(&cp, &sshc->quote_path2); - if(result) { - if(result == CURLE_OUT_OF_MEMORY) - failf(data, "Out of memory"); - else - failf(data, "Syntax error in rename: Bad second parameter"); - Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - break; - } - state(conn, SSH_SFTP_QUOTE_RENAME); - break; - } - else if(curl_strnequal(cmd, "rmdir ", 6)) { - /* delete dir */ - state(conn, SSH_SFTP_QUOTE_RMDIR); - break; - } - else if(curl_strnequal(cmd, "rm ", 3)) { - state(conn, SSH_SFTP_QUOTE_UNLINK); - break; - } -#ifdef HAS_STATVFS_SUPPORT - else if(curl_strnequal(cmd, "statvfs ", 8)) { - state(conn, SSH_SFTP_QUOTE_STATVFS); - break; - } -#endif - - failf(data, "Unknown SFTP command"); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - if(!sshc->quote_item) { - state(conn, SSH_SFTP_GETINFO); - } - break; - - case SSH_SFTP_NEXT_QUOTE: - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - - sshc->quote_item = sshc->quote_item->next; - - if(sshc->quote_item) { - state(conn, SSH_SFTP_QUOTE); - } - else { - if(sshc->nextstate != SSH_NO_STATE) { - state(conn, sshc->nextstate); - sshc->nextstate = SSH_NO_STATE; - } - else { - state(conn, SSH_SFTP_GETINFO); - } - } - break; - - case SSH_SFTP_QUOTE_STAT: - { - char *cmd = sshc->quote_item->data; - sshc->acceptfail = FALSE; - - /* if a command starts with an asterisk, which a legal SFTP command never - can, the command will be allowed to fail without it causing any - aborts or cancels etc. It will cause libcurl to act as if the command - is successful, whatever the server reponds. */ - - if(cmd[0] == '*') { - cmd++; - sshc->acceptfail = TRUE; - } - - if(!curl_strnequal(cmd, "chmod", 5)) { - /* Since chown and chgrp only set owner OR group but libssh2 wants to - * set them both at once, we need to obtain the current ownership - * first. This takes an extra protocol round trip. - */ - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_STAT, - &sshc->quote_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { /* get those attributes */ - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Attempt to get SFTP stats failed: %s", - sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - - /* Now set the new attributes... */ - if(curl_strnequal(cmd, "chgrp", 5)) { - sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chgrp gid not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - else if(curl_strnequal(cmd, "chmod", 5)) { - sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; - /* permissions are octal */ - if(sshc->quote_attrs.permissions == 0 && - !ISDIGIT(sshc->quote_path1[0])) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chmod permissions not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - else if(curl_strnequal(cmd, "chown", 5)) { - sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && - !sshc->acceptfail) { - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Syntax error: chown uid not a number"); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - } - - /* Now send the completed structure... */ - state(conn, SSH_SFTP_QUOTE_SETSTAT); - break; - } - - case SSH_SFTP_QUOTE_SETSTAT: - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_SETSTAT, - &sshc->quote_attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "Attempt to set SFTP stats failed: %s", - sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_SYMLINK: - rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_SYMLINK); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "symlink command failed: %s", - sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_MKDIR: - rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - data->set.new_directory_perms); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_RENAME: - rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - sshc->quote_path2, - curlx_uztoui(strlen(sshc->quote_path2)), - LIBSSH2_SFTP_RENAME_OVERWRITE | - LIBSSH2_SFTP_RENAME_ATOMIC | - LIBSSH2_SFTP_RENAME_NATIVE); - - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - failf(data, "rename command failed: %s", sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_RMDIR: - rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1))); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - - case SSH_SFTP_QUOTE_UNLINK: - rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1))); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - failf(data, "rm command failed: %s", sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - -#ifdef HAS_STATVFS_SUPPORT - case SSH_SFTP_QUOTE_STATVFS: - { - LIBSSH2_SFTP_STATVFS statvfs; - rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1, - curlx_uztoui(strlen(sshc->quote_path1)), - &statvfs); - - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc != 0 && !sshc->acceptfail) { - err = sftp_libssh2_last_error(sshc->sftp_session); - Curl_safefree(sshc->quote_path1); - failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = CURLE_QUOTE_ERROR; - break; - } - else if(rc == 0) { - char *tmp = aprintf("statvfs:\n" - "f_bsize: %llu\n" "f_frsize: %llu\n" - "f_blocks: %llu\n" "f_bfree: %llu\n" - "f_bavail: %llu\n" "f_files: %llu\n" - "f_ffree: %llu\n" "f_favail: %llu\n" - "f_fsid: %llu\n" "f_flag: %llu\n" - "f_namemax: %llu\n", - statvfs.f_bsize, statvfs.f_frsize, - statvfs.f_blocks, statvfs.f_bfree, - statvfs.f_bavail, statvfs.f_files, - statvfs.f_ffree, statvfs.f_favail, - statvfs.f_fsid, statvfs.f_flag, - statvfs.f_namemax); - if(!tmp) { - result = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - break; - } - - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); - free(tmp); - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->nextstate = SSH_NO_STATE; - sshc->actualcode = result; - } - } - state(conn, SSH_SFTP_NEXT_QUOTE); - break; - } -#endif - case SSH_SFTP_GETINFO: - { - if(data->set.get_filetime) { - state(conn, SSH_SFTP_FILETIME); - } - else { - state(conn, SSH_SFTP_TRANS_INIT); - } - break; - } - - case SSH_SFTP_FILETIME: - { - LIBSSH2_SFTP_ATTRIBUTES attrs; - - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc == 0) { - data->info.filetime = (long)attrs.mtime; - } - - state(conn, SSH_SFTP_TRANS_INIT); - break; - } - - case SSH_SFTP_TRANS_INIT: - if(data->set.upload) - state(conn, SSH_SFTP_UPLOAD_INIT); - else { - if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/') - state(conn, SSH_SFTP_READDIR_INIT); - else - state(conn, SSH_SFTP_DOWNLOAD_INIT); - } - break; - - case SSH_SFTP_UPLOAD_INIT: - { - unsigned long flags; - /* - * NOTE!!! libssh2 requires that the destination path is a full path - * that includes the destination file and name OR ends in a "/" - * If this is not done the destination file will be named the - * same name as the last directory in the path. - */ - - if(data->state.resume_from != 0) { - LIBSSH2_SFTP_ATTRIBUTES attrs; - if(data->state.resume_from < 0) { - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc) { - data->state.resume_from = 0; - } - else { - curl_off_t size = attrs.filesize; - if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - data->state.resume_from = attrs.filesize; - } - } - } - - if(data->set.ftp_append) - /* Try to open for append, but create if nonexisting */ - flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND; - else if(data->state.resume_from > 0) - /* If we have restart position then open for append */ - flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND; - else - /* Clear file before writing (normal behaviour) */ - flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC; - - sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - flags, data->set.new_file_perms, - LIBSSH2_SFTP_OPENFILE); - - if(!sshc->sftp_handle) { - rc = libssh2_session_last_errno(sshc->ssh_session); - - if(LIBSSH2_ERROR_EAGAIN == rc) - break; - else { - if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc) - /* only when there was an SFTP protocol error can we extract - the sftp error! */ - err = sftp_libssh2_last_error(sshc->sftp_session); - else - err = -1; /* not an sftp error at all */ - - if(sshc->secondCreateDirs) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = err>= LIBSSH2_FX_OK? - sftp_libssh2_error_to_CURLE(err):CURLE_SSH; - failf(data, "Creating the dir/file failed: %s", - sftp_libssh2_strerror(err)); - break; - } - else if(((err == LIBSSH2_FX_NO_SUCH_FILE) || - (err == LIBSSH2_FX_FAILURE) || - (err == LIBSSH2_FX_NO_SUCH_PATH)) && - (data->set.ftp_create_missing_dirs && - (strlen(sftp_scp->path) > 1))) { - /* try to create the path remotely */ - sshc->secondCreateDirs = 1; - state(conn, SSH_SFTP_CREATE_DIRS_INIT); - break; - } - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = err>= LIBSSH2_FX_OK? - sftp_libssh2_error_to_CURLE(err):CURLE_SSH; - if(!sshc->actualcode) { - /* Sometimes, for some reason libssh2_sftp_last_error() returns - zero even though libssh2_sftp_open() failed previously! We need - to work around that! */ - sshc->actualcode = CURLE_SSH; - err=-1; - } - failf(data, "Upload failed: %s (%d/%d)", - err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error", - err, rc); - break; - } - } - - /* If we have a restart point then we need to seek to the correct - position. */ - if(data->state.resume_from > 0) { - /* Let's read off the proper amount of bytes from the input. */ - if(conn->seek_func) { - seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, - SEEK_SET); - } - - if(seekerr != CURL_SEEKFUNC_OK) { - - if(seekerr != CURL_SEEKFUNC_CANTSEEK) { - failf(data, "Could not seek stream"); - return CURLE_FTP_COULDNT_USE_REST; - } - /* seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ - else { - curl_off_t passed=0; - do { - size_t readthisamountnow = - (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? - BUFSIZE : curlx_sotouz(data->state.resume_from - passed); - - size_t actuallyread = - data->state.fread_func(data->state.buffer, 1, - readthisamountnow, data->state.in); - - passed += actuallyread; - if((actuallyread == 0) || (actuallyread > readthisamountnow)) { - /* this checks for greater-than only to make sure that the - CURL_READFUNC_ABORT return code still aborts */ - failf(data, "Failed to read data"); - return CURLE_FTP_COULDNT_USE_REST; - } - } while(passed < data->state.resume_from); - } - } - - /* now, decrease the size of the read */ - if(data->state.infilesize > 0) { - data->state.infilesize -= data->state.resume_from; - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - - SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); - } - if(data->state.infilesize > 0) { - data->req.size = data->state.infilesize; - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - /* upload data */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->sockfd = conn->writesockfd; - - if(result) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = result; - } - else { - /* store this original bitmask setup to use later on if we can't - figure out a "real" bitmask */ - sshc->orig_waitfor = data->req.keepon; - - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh2 sftp send function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_OUT; - - /* since we don't really wait for anything at this point, we want the - state machine to move on as soon as possible so we set a very short - timeout here */ - Curl_expire(data, 1); - - state(conn, SSH_STOP); - } - break; - } - - case SSH_SFTP_CREATE_DIRS_INIT: - if(strlen(sftp_scp->path) > 1) { - sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */ - state(conn, SSH_SFTP_CREATE_DIRS); - } - else { - state(conn, SSH_SFTP_UPLOAD_INIT); - } - break; - - case SSH_SFTP_CREATE_DIRS: - sshc->slash_pos = strchr(sshc->slash_pos, '/'); - if(sshc->slash_pos) { - *sshc->slash_pos = 0; - - infof(data, "Creating directory '%s'\n", sftp_scp->path); - state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); - break; - } - else { - state(conn, SSH_SFTP_UPLOAD_INIT); - } - break; - - case SSH_SFTP_CREATE_DIRS_MKDIR: - /* 'mode' - parameter is preliminary - default to 0644 */ - rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - data->set.new_directory_perms); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - *sshc->slash_pos = '/'; - ++sshc->slash_pos; - if(rc == -1) { - /* - * Abort if failure wasn't that the dir already exists or the - * permission was denied (creation might succeed further down the - * path) - retry on unspecific FAILURE also - */ - err = sftp_libssh2_last_error(sshc->sftp_session); - if((err != LIBSSH2_FX_FILE_ALREADY_EXISTS) && - (err != LIBSSH2_FX_FAILURE) && - (err != LIBSSH2_FX_PERMISSION_DENIED)) { - result = sftp_libssh2_error_to_CURLE(err); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = result?result:CURLE_SSH; - break; - } - } - state(conn, SSH_SFTP_CREATE_DIRS); - break; - - case SSH_SFTP_READDIR_INIT: - Curl_pgrsSetDownloadSize(data, -1); - if(data->set.opt_no_body) { - state(conn, SSH_STOP); - break; - } - - /* - * This is a directory that we are trying to get, so produce a directory - * listing - */ - sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session, - sftp_scp->path, - curlx_uztoui( - strlen(sftp_scp->path)), - 0, 0, LIBSSH2_SFTP_OPENDIR); - if(!sshc->sftp_handle) { - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - else { - err = sftp_libssh2_last_error(sshc->sftp_session); - failf(data, "Could not open directory for reading: %s", - sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - result = sftp_libssh2_error_to_CURLE(err); - sshc->actualcode = result?result:CURLE_SSH; - break; - } - } - if((sshc->readdir_filename = malloc(PATH_MAX+1)) == NULL) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - if((sshc->readdir_longentry = malloc(PATH_MAX+1)) == NULL) { - Curl_safefree(sshc->readdir_filename); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - state(conn, SSH_SFTP_READDIR); - break; - - case SSH_SFTP_READDIR: - sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle, - sshc->readdir_filename, - PATH_MAX, - sshc->readdir_longentry, - PATH_MAX, - &sshc->readdir_attrs); - if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - if(sshc->readdir_len > 0) { - sshc->readdir_filename[sshc->readdir_len] = '\0'; - - if(data->set.ftp_list_only) { - char *tmpLine; - - tmpLine = aprintf("%s\n", sshc->readdir_filename); - if(tmpLine == NULL) { - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - result = Curl_client_write(conn, CLIENTWRITE_BODY, - tmpLine, sshc->readdir_len+1); - free(tmpLine); - - if(result) { - state(conn, SSH_STOP); - break; - } - /* since this counts what we send to the client, we include the - newline in this counter */ - data->req.bytecount += sshc->readdir_len+1; - - /* output debug output if that is requested */ - if(data->set.verbose) { - Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename, - sshc->readdir_len, conn); - } - } - else { - sshc->readdir_currLen = (int)strlen(sshc->readdir_longentry); - sshc->readdir_totalLen = 80 + sshc->readdir_currLen; - sshc->readdir_line = calloc(sshc->readdir_totalLen, 1); - if(!sshc->readdir_line) { - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - memcpy(sshc->readdir_line, sshc->readdir_longentry, - sshc->readdir_currLen); - if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) && - ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) == - LIBSSH2_SFTP_S_IFLNK)) { - sshc->readdir_linkPath = malloc(PATH_MAX + 1); - if(sshc->readdir_linkPath == NULL) { - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - - snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path, - sshc->readdir_filename); - state(conn, SSH_SFTP_READDIR_LINK); - break; - } - state(conn, SSH_SFTP_READDIR_BOTTOM); - break; - } - } - else if(sshc->readdir_len == 0) { - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_READDIR_DONE); - break; - } - else if(sshc->readdir_len <= 0) { - err = sftp_libssh2_last_error(sshc->sftp_session); - result = sftp_libssh2_error_to_CURLE(err); - sshc->actualcode = result?result:CURLE_SSH; - failf(data, "Could not open remote file for reading: %s :: %d", - sftp_libssh2_strerror(err), - libssh2_session_last_errno(sshc->ssh_session)); - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); - break; - } - break; - - case SSH_SFTP_READDIR_LINK: - sshc->readdir_len = - libssh2_sftp_symlink_ex(sshc->sftp_session, - sshc->readdir_linkPath, - curlx_uztoui(strlen(sshc->readdir_linkPath)), - sshc->readdir_filename, - PATH_MAX, LIBSSH2_SFTP_READLINK); - if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - Curl_safefree(sshc->readdir_linkPath); - - /* get room for the filename and extra output */ - sshc->readdir_totalLen += 4 + sshc->readdir_len; - new_readdir_line = realloc(sshc->readdir_line, sshc->readdir_totalLen); - if(!new_readdir_line) { - Curl_safefree(sshc->readdir_line); - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = CURLE_OUT_OF_MEMORY; - break; - } - sshc->readdir_line = new_readdir_line; - - sshc->readdir_currLen += snprintf(sshc->readdir_line + - sshc->readdir_currLen, - sshc->readdir_totalLen - - sshc->readdir_currLen, - " -> %s", - sshc->readdir_filename); - - state(conn, SSH_SFTP_READDIR_BOTTOM); - break; - - case SSH_SFTP_READDIR_BOTTOM: - sshc->readdir_currLen += snprintf(sshc->readdir_line + - sshc->readdir_currLen, - sshc->readdir_totalLen - - sshc->readdir_currLen, "\n"); - result = Curl_client_write(conn, CLIENTWRITE_BODY, - sshc->readdir_line, - sshc->readdir_currLen); - - if(!result) { - - /* output debug output if that is requested */ - if(data->set.verbose) { - Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line, - sshc->readdir_currLen, conn); - } - data->req.bytecount += sshc->readdir_currLen; - } - Curl_safefree(sshc->readdir_line); - if(result) { - state(conn, SSH_STOP); - } - else - state(conn, SSH_SFTP_READDIR); - break; - - case SSH_SFTP_READDIR_DONE: - if(libssh2_sftp_closedir(sshc->sftp_handle) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - sshc->sftp_handle = NULL; - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - state(conn, SSH_STOP); - break; - - case SSH_SFTP_DOWNLOAD_INIT: - /* - * Work on getting the specified file - */ - sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_FXF_READ, data->set.new_file_perms, - LIBSSH2_SFTP_OPENFILE); - if(!sshc->sftp_handle) { - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - else { - err = sftp_libssh2_last_error(sshc->sftp_session); - failf(data, "Could not open remote file for reading: %s", - sftp_libssh2_strerror(err)); - state(conn, SSH_SFTP_CLOSE); - result = sftp_libssh2_error_to_CURLE(err); - sshc->actualcode = result?result:CURLE_SSH; - break; - } - } - state(conn, SSH_SFTP_DOWNLOAD_STAT); - break; - - case SSH_SFTP_DOWNLOAD_STAT: - { - LIBSSH2_SFTP_ATTRIBUTES attrs; - - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), - LIBSSH2_SFTP_STAT, &attrs); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc || - !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) || - (attrs.filesize == 0)) { - /* - * libssh2_sftp_open() didn't return an error, so maybe the server - * just doesn't support stat() - * OR the server doesn't return a file size with a stat() - * OR file size is 0 - */ - data->req.size = -1; - data->req.maxdownload = -1; - Curl_pgrsSetDownloadSize(data, -1); - } - else { - curl_off_t size = attrs.filesize; - - if(size < 0) { - failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); - return CURLE_BAD_DOWNLOAD_RESUME; - } - if(conn->data->state.use_range) { - curl_off_t from, to; - char *ptr; - char *ptr2; - - from=curlx_strtoofft(conn->data->state.range, &ptr, 0); - while(*ptr && (ISSPACE(*ptr) || (*ptr=='-'))) - ptr++; - to=curlx_strtoofft(ptr, &ptr2, 0); - if((ptr == ptr2) /* no "to" value given */ - || (to >= size)) { - to = size - 1; - } - if(from < 0) { - /* from is relative to end of file */ - from += size; - } - if(from > size) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", from, attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - if(from > to) { - from = to; - size = 0; - } - else { - size = to - from + 1; - } - - SFTP_SEEK(conn->proto.sshc.sftp_handle, from); - } - data->req.size = size; - data->req.maxdownload = size; - Curl_pgrsSetDownloadSize(data, size); - } - - /* We can resume if we can seek to the resume position */ - if(data->state.resume_from) { - if(data->state.resume_from < 0) { - /* We're supposed to download the last abs(from) bytes */ - if((curl_off_t)attrs.filesize < -data->state.resume_from) { - failf(data, "Offset (%" - CURL_FORMAT_CURL_OFF_T ") was beyond file size (%" - CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - /* download from where? */ - data->state.resume_from += attrs.filesize; - } - else { - if((curl_off_t)attrs.filesize < data->state.resume_from) { - failf(data, "Offset (%" CURL_FORMAT_CURL_OFF_T - ") was beyond file size (%" CURL_FORMAT_CURL_OFF_T ")", - data->state.resume_from, attrs.filesize); - return CURLE_BAD_DOWNLOAD_RESUME; - } - } - /* Does a completed file need to be seeked and started or closed ? */ - /* Now store the number of bytes we are expected to download */ - data->req.size = attrs.filesize - data->state.resume_from; - data->req.maxdownload = attrs.filesize - data->state.resume_from; - Curl_pgrsSetDownloadSize(data, - attrs.filesize - data->state.resume_from); - SFTP_SEEK(sshc->sftp_handle, data->state.resume_from); - } - } - - /* Setup the actual download */ - if(data->req.size == 0) { - /* no data to transfer */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - infof(data, "File already completely downloaded\n"); - state(conn, SSH_STOP); - break; - } - else { - Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size, - FALSE, NULL, -1, NULL); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->writesockfd = conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh2 recv function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_IN; - } - if(result) { - /* this should never occur; the close state should be entered - at the time the error occurs */ - state(conn, SSH_SFTP_CLOSE); - sshc->actualcode = result; - } - else { - state(conn, SSH_STOP); - } - break; - - case SSH_SFTP_CLOSE: - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to close libssh2 file\n"); - } - sshc->sftp_handle = NULL; - } - if(sftp_scp) - Curl_safefree(sftp_scp->path); - - DEBUGF(infof(data, "SFTP DONE done\n")); - - /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT - After nextstate is executed, the control should come back to - SSH_SFTP_CLOSE to pass the correct result back */ - if(sshc->nextstate != SSH_NO_STATE && - sshc->nextstate != SSH_SFTP_CLOSE) { - state(conn, sshc->nextstate); - sshc->nextstate = SSH_SFTP_CLOSE; - } - else { - state(conn, SSH_STOP); - result = sshc->actualcode; - } - break; - - case SSH_SFTP_SHUTDOWN: - /* during times we get here due to a broken transfer and then the - sftp_handle might not have been taken down so make sure that is done - before we proceed */ - - if(sshc->sftp_handle) { - rc = libssh2_sftp_close(sshc->sftp_handle); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to close libssh2 file\n"); - } - sshc->sftp_handle = NULL; - } - if(sshc->sftp_session) { - rc = libssh2_sftp_shutdown(sshc->sftp_session); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to stop libssh2 sftp subsystem\n"); - } - sshc->sftp_session = NULL; - } - - Curl_safefree(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; - - state(conn, SSH_SESSION_DISCONNECT); - break; - - case SSH_SCP_TRANS_INIT: - result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path); - if(result) { - sshc->actualcode = result; - state(conn, SSH_STOP); - break; - } - - if(data->set.upload) { - if(data->state.infilesize < 0) { - failf(data, "SCP requires a known file size for upload"); - sshc->actualcode = CURLE_UPLOAD_FAILED; - state(conn, SSH_SCP_CHANNEL_FREE); - break; - } - state(conn, SSH_SCP_UPLOAD_INIT); - } - else { - state(conn, SSH_SCP_DOWNLOAD_INIT); - } - break; - - case SSH_SCP_UPLOAD_INIT: - /* - * libssh2 requires that the destination path is a full path that - * includes the destination file and name OR ends in a "/" . If this is - * not done the destination file will be named the same name as the last - * directory in the path. - */ - sshc->ssh_channel = - SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms, - data->state.infilesize); - if(!sshc->ssh_channel) { - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - else { - int ssh_err; - char *err_msg; - - ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0)); - failf(conn->data, "%s", err_msg); - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); - break; - } - } - - /* upload data */ - Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL, - FIRSTSOCKET, NULL); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->sockfd = conn->writesockfd; - - if(result) { - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = result; - } - else { - /* store this original bitmask setup to use later on if we can't - figure out a "real" bitmask */ - sshc->orig_waitfor = data->req.keepon; - - /* we want to use the _sending_ function even when the socket turns - out readable as the underlying libssh2 scp send function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_OUT; - - state(conn, SSH_STOP); - } - break; - - case SSH_SCP_DOWNLOAD_INIT: - { - curl_off_t bytecount; - - /* - * We must check the remote file; if it is a directory no values will - * be set in sb - */ - - /* - * If support for >2GB files exists, use it. - */ - - /* get a fresh new channel from the ssh layer */ -#if LIBSSH2_VERSION_NUM < 0x010700 - struct stat sb; - memset(&sb, 0, sizeof(struct stat)); - sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session, - sftp_scp->path, &sb); -#else - libssh2_struct_stat sb; - memset(&sb, 0, sizeof(libssh2_struct_stat)); - sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session, - sftp_scp->path, &sb); -#endif - - if(!sshc->ssh_channel) { - if(libssh2_session_last_errno(sshc->ssh_session) == - LIBSSH2_ERROR_EAGAIN) { - rc = LIBSSH2_ERROR_EAGAIN; - break; - } - else { - int ssh_err; - char *err_msg; - - ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, - &err_msg, NULL, 0)); - failf(conn->data, "%s", err_msg); - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); - break; - } - } - - /* download data */ - bytecount = (curl_off_t)sb.st_size; - data->req.maxdownload = (curl_off_t)sb.st_size; - Curl_setup_transfer(conn, FIRSTSOCKET, bytecount, FALSE, NULL, -1, NULL); - - /* not set by Curl_setup_transfer to preserve keepon bits */ - conn->writesockfd = conn->sockfd; - - /* we want to use the _receiving_ function even when the socket turns - out writableable as the underlying libssh2 recv function will deal - with both accordingly */ - conn->cselect_bits = CURL_CSELECT_IN; - - if(result) { - state(conn, SSH_SCP_CHANNEL_FREE); - sshc->actualcode = result; - } - else - state(conn, SSH_STOP); - } - break; - - case SSH_SCP_DONE: - if(data->set.upload) - state(conn, SSH_SCP_SEND_EOF); - else - state(conn, SSH_SCP_CHANNEL_FREE); - break; - - case SSH_SCP_SEND_EOF: - if(sshc->ssh_channel) { - rc = libssh2_channel_send_eof(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc) { - infof(data, "Failed to send libssh2 channel EOF\n"); - } - } - state(conn, SSH_SCP_WAIT_EOF); - break; - - case SSH_SCP_WAIT_EOF: - if(sshc->ssh_channel) { - rc = libssh2_channel_wait_eof(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc) { - infof(data, "Failed to get channel EOF: %d\n", rc); - } - } - state(conn, SSH_SCP_WAIT_CLOSE); - break; - - case SSH_SCP_WAIT_CLOSE: - if(sshc->ssh_channel) { - rc = libssh2_channel_wait_closed(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc) { - infof(data, "Channel failed to close: %d\n", rc); - } - } - state(conn, SSH_SCP_CHANNEL_FREE); - break; - - case SSH_SCP_CHANNEL_FREE: - if(sshc->ssh_channel) { - rc = libssh2_channel_free(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to free libssh2 scp subsystem\n"); - } - sshc->ssh_channel = NULL; - } - DEBUGF(infof(data, "SCP DONE phase complete\n")); -#if 0 /* PREV */ - state(conn, SSH_SESSION_DISCONNECT); -#endif - state(conn, SSH_STOP); - result = sshc->actualcode; - break; - - case SSH_SESSION_DISCONNECT: - /* during weird times when we've been prematurely aborted, the channel - is still alive when we reach this state and we MUST kill the channel - properly first */ - if(sshc->ssh_channel) { - rc = libssh2_channel_free(sshc->ssh_channel); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to free libssh2 scp subsystem\n"); - } - sshc->ssh_channel = NULL; - } - - if(sshc->ssh_session) { - rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown"); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to disconnect libssh2 session\n"); - } - } - - Curl_safefree(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; - - state(conn, SSH_SESSION_FREE); - break; - - case SSH_SESSION_FREE: -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - if(sshc->kh) { - libssh2_knownhost_free(sshc->kh); - sshc->kh = NULL; - } -#endif - -#ifdef HAVE_LIBSSH2_AGENT_API - if(sshc->ssh_agent) { - rc = libssh2_agent_disconnect(sshc->ssh_agent); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to disconnect from libssh2 agent\n"); - } - libssh2_agent_free (sshc->ssh_agent); - sshc->ssh_agent = NULL; - - /* NB: there is no need to free identities, they are part of internal - agent stuff */ - sshc->sshagent_identity = NULL; - sshc->sshagent_prev_identity = NULL; - } -#endif - - if(sshc->ssh_session) { - rc = libssh2_session_free(sshc->ssh_session); - if(rc == LIBSSH2_ERROR_EAGAIN) { - break; - } - else if(rc < 0) { - infof(data, "Failed to free libssh2 session\n"); - } - sshc->ssh_session = NULL; - } - - /* worst-case scenario cleanup */ - - DEBUGASSERT(sshc->ssh_session == NULL); - DEBUGASSERT(sshc->ssh_channel == NULL); - DEBUGASSERT(sshc->sftp_session == NULL); - DEBUGASSERT(sshc->sftp_handle == NULL); -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - DEBUGASSERT(sshc->kh == NULL); -#endif -#ifdef HAVE_LIBSSH2_AGENT_API - DEBUGASSERT(sshc->ssh_agent == NULL); -#endif - - Curl_safefree(sshc->rsa_pub); - Curl_safefree(sshc->rsa); - - Curl_safefree(sshc->quote_path1); - Curl_safefree(sshc->quote_path2); - - Curl_safefree(sshc->homedir); - - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - Curl_safefree(sshc->readdir_line); - Curl_safefree(sshc->readdir_linkPath); - - /* the code we are about to return */ - result = sshc->actualcode; - - memset(sshc, 0, sizeof(struct ssh_conn)); - - connclose(conn, "SSH session free"); - sshc->state = SSH_SESSION_FREE; /* current */ - sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); - break; - - case SSH_QUIT: - /* fallthrough, just stop! */ - default: - /* internal error */ - sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); - break; - } - - } while(!rc && (sshc->state != SSH_STOP)); - - if(rc == LIBSSH2_ERROR_EAGAIN) { - /* we would block, we need to wait for the socket to be ready (in the - right direction too)! */ - *block = TRUE; - } - - return result; -} - -/* called by the multi interface to figure out what socket(s) to wait for and - for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int ssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock, /* points to numsocks - number of sockets */ - int numsocks) -{ -#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION - int bitmap = GETSOCK_BLANK; - (void)numsocks; - - sock[0] = conn->sock[FIRSTSOCKET]; - - if(conn->waitfor & KEEP_RECV) - bitmap |= GETSOCK_READSOCK(FIRSTSOCKET); - - if(conn->waitfor & KEEP_SEND) - bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET); - - return bitmap; -#else - /* if we don't know the direction we can use the generic *_getsock() - function even for the protocol_connect and doing states */ - return Curl_single_getsock(conn, sock, numsocks); -#endif -} - -/* Generic function called by the multi interface to figure out what socket(s) - to wait for and for what actions during the DOING and PROTOCONNECT states*/ -static int ssh_getsock(struct connectdata *conn, - curl_socket_t *sock, /* points to numsocks number - of sockets */ - int numsocks) -{ -#ifndef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION - (void)conn; - (void)sock; - (void)numsocks; - /* if we don't know any direction we can just play along as we used to and - not provide any sensible info */ - return GETSOCK_BLANK; -#else - /* if we know the direction we can use the generic *_getsock() function even - for the protocol_connect and doing states */ - return ssh_perform_getsock(conn, sock, numsocks); -#endif -} - -#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION -/* - * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this - * function is used to figure out in what direction and stores this info so - * that the multi interface can take advantage of it. Make sure to call this - * function in all cases so that when it _doesn't_ return EAGAIN we can - * restore the default wait bits. - */ -static void ssh_block2waitfor(struct connectdata *conn, bool block) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - int dir; - if(block && (dir = libssh2_session_block_directions(sshc->ssh_session))) { - /* translate the libssh2 define bits into our own bit defines */ - conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND)?KEEP_RECV:0) | - ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND)?KEEP_SEND:0); - } - else - /* It didn't block or libssh2 didn't reveal in which direction, put back - the original set */ - conn->waitfor = sshc->orig_waitfor; -} -#else - /* no libssh2 directional support so we simply don't know */ -#define ssh_block2waitfor(x,y) Curl_nop_stmt -#endif - -/* called repeatedly until done from multi.c */ -static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - CURLcode result = CURLE_OK; - bool block; /* we store the status and use that to provide a ssh_getsock() - implementation */ - - result = ssh_statemach_act(conn, &block); - *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; - ssh_block2waitfor(conn, block); - - return result; -} - -static CURLcode ssh_block_statemach(struct connectdata *conn, - bool duringconnect) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - while((sshc->state != SSH_STOP) && !result) { - bool block; - long left; - - result = ssh_statemach_act(conn, &block); - if(result) - break; - - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; - else { - struct timeval now = Curl_tvnow(); - result = Curl_speedcheck(data, now); - if(result) - break; - } - - left = Curl_timeleft(data, NULL, duringconnect); - if(left < 0) { - failf(data, "Operation timed out"); - return CURLE_OPERATION_TIMEDOUT; - } - -#ifdef HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION - if(!result && block) { - int dir = libssh2_session_block_directions(sshc->ssh_session); - curl_socket_t sock = conn->sock[FIRSTSOCKET]; - curl_socket_t fd_read = CURL_SOCKET_BAD; - curl_socket_t fd_write = CURL_SOCKET_BAD; - if(LIBSSH2_SESSION_BLOCK_INBOUND & dir) - fd_read = sock; - if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir) - fd_write = sock; - /* wait for the socket to become ready */ - Curl_socket_ready(fd_read, fd_write, - left>1000?1000:left); /* ignore result */ - } -#endif - - } - - return result; -} - -/* - * SSH setup and connection - */ -static CURLcode ssh_setup_connection(struct connectdata *conn) -{ - struct SSHPROTO *ssh; - - conn->data->req.protop = ssh = calloc(1, sizeof(struct SSHPROTO)); - if(!ssh) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -static Curl_recv scp_recv, sftp_recv; -static Curl_send scp_send, sftp_send; - -/* - * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to - * do protocol-specific actions at connect-time. - */ -static CURLcode ssh_connect(struct connectdata *conn, bool *done) -{ -#ifdef CURL_LIBSSH2_DEBUG - curl_socket_t sock; -#endif - struct ssh_conn *ssh; - CURLcode result; - struct SessionHandle *data = conn->data; - - /* initialize per-handle data if not already */ - if(!data->req.protop) - ssh_setup_connection(conn); - - /* We default to persistent connections. We set this already in this connect - function to make the re-use checks properly be able to check this bit. */ - connkeep(conn, "SSH default"); - - if(conn->handler->protocol & CURLPROTO_SCP) { - conn->recv[FIRSTSOCKET] = scp_recv; - conn->send[FIRSTSOCKET] = scp_send; - } - else { - conn->recv[FIRSTSOCKET] = sftp_recv; - conn->send[FIRSTSOCKET] = sftp_send; - } - ssh = &conn->proto.sshc; - -#ifdef CURL_LIBSSH2_DEBUG - if(conn->user) { - infof(data, "User: %s\n", conn->user); - } - if(conn->passwd) { - infof(data, "Password: %s\n", conn->passwd); - } - sock = conn->sock[FIRSTSOCKET]; -#endif /* CURL_LIBSSH2_DEBUG */ - - ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, - my_libssh2_free, - my_libssh2_realloc, conn); - if(ssh->ssh_session == NULL) { - failf(data, "Failure initialising ssh session"); - return CURLE_FAILED_INIT; - } - -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { - int rc; - ssh->kh = libssh2_knownhost_init(ssh->ssh_session); - if(!ssh->kh) { - /* eeek. TODO: free the ssh_session! */ - return CURLE_FAILED_INIT; - } - - /* read all known hosts from there */ - rc = libssh2_knownhost_readfile(ssh->kh, - data->set.str[STRING_SSH_KNOWNHOSTS], - LIBSSH2_KNOWNHOST_FILE_OPENSSH); - if(rc < 0) - infof(data, "Failed to read known hosts from %s\n", - data->set.str[STRING_SSH_KNOWNHOSTS]); - } -#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ - -#ifdef CURL_LIBSSH2_DEBUG - libssh2_trace(ssh->ssh_session, ~0); - infof(data, "SSH socket: %d\n", (int)sock); -#endif /* CURL_LIBSSH2_DEBUG */ - - state(conn, SSH_INIT); - - result = ssh_multi_statemach(conn, done); - - return result; -} - -/* - *********************************************************************** - * - * scp_perform() - * - * This is the actual DO function for SCP. Get a file according to - * the options previously setup. - */ - -static -CURLcode scp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - state(conn, SSH_SCP_TRANS_INIT); - - /* run the state-machine */ - result = ssh_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode scp_doing(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result; - result = ssh_multi_statemach(conn, dophase_done); - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - return result; -} - -/* - * The DO function is generic for both protocols. There was previously two - * separate ones but this way means less duplicated code. - */ - -static CURLcode ssh_do(struct connectdata *conn, bool *done) -{ - CURLcode result; - bool connected = 0; - struct SessionHandle *data = conn->data; - struct ssh_conn *sshc = &conn->proto.sshc; - - *done = FALSE; /* default to false */ - - data->req.size = -1; /* make sure this is unknown at this point */ - - sshc->actualcode = CURLE_OK; /* reset error code */ - sshc->secondCreateDirs =0; /* reset the create dir attempt state - variable */ - - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - Curl_pgrsSetUploadSize(data, -1); - Curl_pgrsSetDownloadSize(data, -1); - - if(conn->handler->protocol & CURLPROTO_SCP) - result = scp_perform(conn, &connected, done); - else - result = sftp_perform(conn, &connected, done); - - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) -{ - CURLcode result = CURLE_OK; - struct ssh_conn *ssh = &conn->proto.sshc; - (void) dead_connection; - - Curl_safefree(conn->data->req.protop); - - if(ssh->ssh_session) { - /* only if there's a session still around to use! */ - - state(conn, SSH_SESSION_DISCONNECT); - - result = ssh_block_statemach(conn, FALSE); - } - - return result; -} - -/* generic done function for both SCP and SFTP called from their specific - done functions */ -static CURLcode ssh_done(struct connectdata *conn, CURLcode status) -{ - CURLcode result = CURLE_OK; - struct SSHPROTO *sftp_scp = conn->data->req.protop; - - if(!status) { - /* run the state-machine - - TODO: when the multi interface is used, this _really_ should be using - the ssh_multi_statemach function but we have no general support for - non-blocking DONE operations! - */ - result = ssh_block_statemach(conn, FALSE); - } - else - result = status; - - if(sftp_scp) - Curl_safefree(sftp_scp->path); - if(Curl_pgrsDone(conn)) - return CURLE_ABORTED_BY_CALLBACK; - - conn->data->req.keepon = 0; /* clear all bits */ - return result; -} - - -static CURLcode scp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - (void)premature; /* not used */ - - if(!status) - state(conn, SSH_SCP_DONE); - - return ssh_done(conn, status); - -} - -/* return number of received (decrypted) bytes */ -static ssize_t scp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *err) -{ - ssize_t nwrite; - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - - /* libssh2_channel_write() returns int! */ - nwrite = (ssize_t) - libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len); - - ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - - if(nwrite == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else if(nwrite < LIBSSH2_ERROR_NONE) { - *err = libssh2_session_error_to_CURLE((int)nwrite); - nwrite = -1; - } - - return nwrite; -} - -/* - * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return - * a regular CURLcode value. - */ -static ssize_t scp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - ssize_t nread; - (void)sockindex; /* we only support SCP on the fixed known primary socket */ - - /* libssh2_channel_read() returns int */ - nread = (ssize_t) - libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len); - - ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - if(nread == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nread = -1; - } - - return nread; -} - -/* - * =============== SFTP =============== - */ - -/* - *********************************************************************** - * - * sftp_perform() - * - * This is the actual DO function for SFTP. Get a file/directory according to - * the options previously setup. - */ - -static -CURLcode sftp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done) -{ - CURLcode result = CURLE_OK; - - DEBUGF(infof(conn->data, "DO phase starts\n")); - - *dophase_done = FALSE; /* not done yet */ - - /* start the first command in the DO phase */ - state(conn, SSH_SFTP_QUOTE_INIT); - - /* run the state-machine */ - result = ssh_multi_statemach(conn, dophase_done); - - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - - return result; -} - -/* called from multi.c while DOing */ -static CURLcode sftp_doing(struct connectdata *conn, - bool *dophase_done) -{ - CURLcode result = ssh_multi_statemach(conn, dophase_done); - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - return result; -} - -/* BLOCKING, but the function is using the state machine so the only reason - this is still blocking is that the multi interface code has no support for - disconnecting operations that takes a while */ -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) -{ - CURLcode result = CURLE_OK; - (void) dead_connection; - - DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); - - Curl_safefree(conn->data->req.protop); - - if(conn->proto.sshc.ssh_session) { - /* only if there's a session still around to use! */ - state(conn, SSH_SFTP_SHUTDOWN); - result = ssh_block_statemach(conn, FALSE); - } - - DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); - - return result; - -} - -static CURLcode sftp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - struct ssh_conn *sshc = &conn->proto.sshc; - - if(!status) { - /* Post quote commands are executed after the SFTP_CLOSE state to avoid - errors that could happen due to open file handles during POSTQUOTE - operation */ - if(!status && !premature && conn->data->set.postquote) { - sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - state(conn, SSH_SFTP_CLOSE); - } - else - state(conn, SSH_SFTP_CLOSE); - } - return ssh_done(conn, status); -} - -/* return number of sent bytes */ -static ssize_t sftp_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *err) -{ - ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14 - but is changed to ssize_t in 0.15. These days we don't - support libssh2 0.15*/ - (void)sockindex; - - nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len); - - ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - - if(nwrite == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nwrite = 0; - } - else if(nwrite < LIBSSH2_ERROR_NONE) { - *err = libssh2_session_error_to_CURLE((int)nwrite); - nwrite = -1; - } - - return nwrite; -} - -/* - * Return number of received (decrypted) bytes - * or <0 on error - */ -static ssize_t sftp_recv(struct connectdata *conn, int sockindex, - char *mem, size_t len, CURLcode *err) -{ - ssize_t nread; - (void)sockindex; - - nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len); - - ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); - - if(nread == LIBSSH2_ERROR_EAGAIN) { - *err = CURLE_AGAIN; - nread = -1; - - } - else if(nread < 0) { - *err = libssh2_session_error_to_CURLE((int)nread); - } - return nread; -} - -/* The get_pathname() function is being borrowed from OpenSSH sftp.c - version 4.6p1. */ -/* - * Copyright (c) 2001-2004 Damien Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -static CURLcode -get_pathname(const char **cpp, char **path) -{ - const char *cp = *cpp, *end; - char quot; - unsigned int i, j; - static const char WHITESPACE[] = " \t\r\n"; - - cp += strspn(cp, WHITESPACE); - if(!*cp) { - *cpp = cp; - *path = NULL; - return CURLE_QUOTE_ERROR; - } - - *path = malloc(strlen(cp) + 1); - if(*path == NULL) - return CURLE_OUT_OF_MEMORY; - - /* Check for quoted filenames */ - if(*cp == '\"' || *cp == '\'') { - quot = *cp++; - - /* Search for terminating quote, unescape some chars */ - for(i = j = 0; i <= strlen(cp); i++) { - if(cp[i] == quot) { /* Found quote */ - i++; - (*path)[j] = '\0'; - break; - } - if(cp[i] == '\0') { /* End of string */ - /*error("Unterminated quote");*/ - goto fail; - } - if(cp[i] == '\\') { /* Escaped characters */ - i++; - if(cp[i] != '\'' && cp[i] != '\"' && - cp[i] != '\\') { - /*error("Bad escaped character '\\%c'", - cp[i]);*/ - goto fail; - } - } - (*path)[j++] = cp[i]; - } - - if(j == 0) { - /*error("Empty quotes");*/ - goto fail; - } - *cpp = cp + i + strspn(cp + i, WHITESPACE); - } - else { - /* Read to end of filename */ - end = strpbrk(cp, WHITESPACE); - if(end == NULL) - end = strchr(cp, '\0'); - *cpp = end + strspn(end, WHITESPACE); - - memcpy(*path, cp, end - cp); - (*path)[end - cp] = '\0'; - } - return CURLE_OK; - - fail: - Curl_safefree(*path); - return CURLE_QUOTE_ERROR; -} - - -static const char *sftp_libssh2_strerror(int err) -{ - switch (err) { - case LIBSSH2_FX_NO_SUCH_FILE: - return "No such file or directory"; - - case LIBSSH2_FX_PERMISSION_DENIED: - return "Permission denied"; - - case LIBSSH2_FX_FAILURE: - return "Operation failed"; - - case LIBSSH2_FX_BAD_MESSAGE: - return "Bad message from SFTP server"; - - case LIBSSH2_FX_NO_CONNECTION: - return "Not connected to SFTP server"; - - case LIBSSH2_FX_CONNECTION_LOST: - return "Connection to SFTP server lost"; - - case LIBSSH2_FX_OP_UNSUPPORTED: - return "Operation not supported by SFTP server"; - - case LIBSSH2_FX_INVALID_HANDLE: - return "Invalid handle"; - - case LIBSSH2_FX_NO_SUCH_PATH: - return "No such file or directory"; - - case LIBSSH2_FX_FILE_ALREADY_EXISTS: - return "File already exists"; - - case LIBSSH2_FX_WRITE_PROTECT: - return "File is write protected"; - - case LIBSSH2_FX_NO_MEDIA: - return "No media"; - - case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: - return "Disk full"; - - case LIBSSH2_FX_QUOTA_EXCEEDED: - return "User quota exceeded"; - - case LIBSSH2_FX_UNKNOWN_PRINCIPLE: - return "Unknown principle"; - - case LIBSSH2_FX_LOCK_CONFlICT: - return "File lock conflict"; - - case LIBSSH2_FX_DIR_NOT_EMPTY: - return "Directory not empty"; - - case LIBSSH2_FX_NOT_A_DIRECTORY: - return "Not a directory"; - - case LIBSSH2_FX_INVALID_FILENAME: - return "Invalid filename"; - - case LIBSSH2_FX_LINK_LOOP: - return "Link points to itself"; - } - return "Unknown error in libssh2"; -} - -#endif /* USE_LIBSSH2 */ diff --git a/Externals/curl/lib/ssh.h b/Externals/curl/lib/ssh.h deleted file mode 100644 index 5b4b78ff42..0000000000 --- a/Externals/curl/lib/ssh.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef HEADER_CURL_SSH_H -#define HEADER_CURL_SSH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_LIBSSH2_H -#include -#include -#endif /* HAVE_LIBSSH2_H */ - -/**************************************************************************** - * SSH unique setup - ***************************************************************************/ -typedef enum { - SSH_NO_STATE = -1, /* Used for "nextState" so say there is none */ - SSH_STOP = 0, /* do nothing state, stops the state machine */ - - SSH_INIT, /* First state in SSH-CONNECT */ - SSH_S_STARTUP, /* Session startup */ - SSH_HOSTKEY, /* verify hostkey */ - SSH_AUTHLIST, - SSH_AUTH_PKEY_INIT, - SSH_AUTH_PKEY, - SSH_AUTH_PASS_INIT, - SSH_AUTH_PASS, - SSH_AUTH_AGENT_INIT, /* initialize then wait for connection to agent */ - SSH_AUTH_AGENT_LIST, /* ask for list then wait for entire list to come */ - SSH_AUTH_AGENT, /* attempt one key at a time */ - SSH_AUTH_HOST_INIT, - SSH_AUTH_HOST, - SSH_AUTH_KEY_INIT, - SSH_AUTH_KEY, - SSH_AUTH_DONE, - SSH_SFTP_INIT, - SSH_SFTP_REALPATH, /* Last state in SSH-CONNECT */ - - SSH_SFTP_QUOTE_INIT, /* First state in SFTP-DO */ - SSH_SFTP_POSTQUOTE_INIT, /* (Possibly) First state in SFTP-DONE */ - SSH_SFTP_QUOTE, - SSH_SFTP_NEXT_QUOTE, - SSH_SFTP_QUOTE_STAT, - SSH_SFTP_QUOTE_SETSTAT, - SSH_SFTP_QUOTE_SYMLINK, - SSH_SFTP_QUOTE_MKDIR, - SSH_SFTP_QUOTE_RENAME, - SSH_SFTP_QUOTE_RMDIR, - SSH_SFTP_QUOTE_UNLINK, - SSH_SFTP_QUOTE_STATVFS, - SSH_SFTP_GETINFO, - SSH_SFTP_FILETIME, - SSH_SFTP_TRANS_INIT, - SSH_SFTP_UPLOAD_INIT, - SSH_SFTP_CREATE_DIRS_INIT, - SSH_SFTP_CREATE_DIRS, - SSH_SFTP_CREATE_DIRS_MKDIR, - SSH_SFTP_READDIR_INIT, - SSH_SFTP_READDIR, - SSH_SFTP_READDIR_LINK, - SSH_SFTP_READDIR_BOTTOM, - SSH_SFTP_READDIR_DONE, - SSH_SFTP_DOWNLOAD_INIT, - SSH_SFTP_DOWNLOAD_STAT, /* Last state in SFTP-DO */ - SSH_SFTP_CLOSE, /* Last state in SFTP-DONE */ - SSH_SFTP_SHUTDOWN, /* First state in SFTP-DISCONNECT */ - SSH_SCP_TRANS_INIT, /* First state in SCP-DO */ - SSH_SCP_UPLOAD_INIT, - SSH_SCP_DOWNLOAD_INIT, - SSH_SCP_DONE, - SSH_SCP_SEND_EOF, - SSH_SCP_WAIT_EOF, - SSH_SCP_WAIT_CLOSE, - SSH_SCP_CHANNEL_FREE, /* Last state in SCP-DONE */ - SSH_SESSION_DISCONNECT, /* First state in SCP-DISCONNECT */ - SSH_SESSION_FREE, /* Last state in SCP/SFTP-DISCONNECT */ - SSH_QUIT, - SSH_LAST /* never used */ -} sshstate; - -/* this struct is used in the HandleData struct which is part of the - SessionHandle, which means this is used on a per-easy handle basis. - Everything that is strictly related to a connection is banned from this - struct. */ -struct SSHPROTO { - char *path; /* the path we operate on */ -}; - -/* ssh_conn is used for struct connection-oriented data in the connectdata - struct */ -struct ssh_conn { - const char *authlist; /* List of auth. methods, managed by libssh2 */ -#ifdef USE_LIBSSH2 - const char *passphrase; /* pass-phrase to use */ - char *rsa_pub; /* path name */ - char *rsa; /* path name */ - bool authed; /* the connection has been authenticated fine */ - sshstate state; /* always use ssh.c:state() to change state! */ - sshstate nextstate; /* the state to goto after stopping */ - CURLcode actualcode; /* the actual error code */ - struct curl_slist *quote_item; /* for the quote option */ - char *quote_path1; /* two generic pointers for the QUOTE stuff */ - char *quote_path2; - LIBSSH2_SFTP_ATTRIBUTES quote_attrs; /* used by the SFTP_QUOTE state */ - bool acceptfail; /* used by the SFTP_QUOTE (continue if - quote command fails) */ - char *homedir; /* when doing SFTP we figure out home dir in the - connect phase */ - - /* Here's a set of struct members used by the SFTP_READDIR state */ - LIBSSH2_SFTP_ATTRIBUTES readdir_attrs; - char *readdir_filename; - char *readdir_longentry; - int readdir_len, readdir_totalLen, readdir_currLen; - char *readdir_line; - char *readdir_linkPath; - /* end of READDIR stuff */ - - int secondCreateDirs; /* counter use by the code to see if the - second attempt has been made to change - to/create a directory */ - char *slash_pos; /* used by the SFTP_CREATE_DIRS state */ - LIBSSH2_SESSION *ssh_session; /* Secure Shell session */ - LIBSSH2_CHANNEL *ssh_channel; /* Secure Shell channel handle */ - LIBSSH2_SFTP *sftp_session; /* SFTP handle */ - LIBSSH2_SFTP_HANDLE *sftp_handle; - int orig_waitfor; /* default READ/WRITE bits wait for */ - -#ifdef HAVE_LIBSSH2_AGENT_API - LIBSSH2_AGENT *ssh_agent; /* proxy to ssh-agent/pageant */ - struct libssh2_agent_publickey *sshagent_identity, - *sshagent_prev_identity; -#endif - - /* note that HAVE_LIBSSH2_KNOWNHOST_API is a define set in the libssh2.h - header */ -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - LIBSSH2_KNOWNHOSTS *kh; -#endif -#endif /* USE_LIBSSH2 */ -}; - -#ifdef USE_LIBSSH2 - -/* Feature detection based on version numbers to better work with - non-configure platforms */ - -#if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000) -# error "SCP/SFTP protocols require libssh2 0.16 or later" -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010000 -#define HAVE_LIBSSH2_SFTP_SEEK64 1 -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010100 -#define HAVE_LIBSSH2_VERSION 1 -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010205 -#define HAVE_LIBSSH2_INIT 1 -#define HAVE_LIBSSH2_EXIT 1 -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010206 -#define HAVE_LIBSSH2_KNOWNHOST_CHECKP 1 -#define HAVE_LIBSSH2_SCP_SEND64 1 -#endif - -#if LIBSSH2_VERSION_NUM >= 0x010208 -#define HAVE_LIBSSH2_SESSION_HANDSHAKE 1 -#endif - -extern const struct Curl_handler Curl_handler_scp; -extern const struct Curl_handler Curl_handler_sftp; - -#endif /* USE_LIBSSH2 */ - -#endif /* HEADER_CURL_SSH_H */ diff --git a/Externals/curl/lib/strdup.c b/Externals/curl/lib/strdup.c deleted file mode 100644 index 23f554e518..0000000000 --- a/Externals/curl/lib/strdup.c +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "strdup.h" -#include "curl_memory.h" - -/* The last #include file should be: */ -#include "memdebug.h" - -#ifndef HAVE_STRDUP -char *curlx_strdup(const char *str) -{ - size_t len; - char *newstr; - - if(!str) - return (char *)NULL; - - len = strlen(str); - - if(len >= ((size_t)-1) / sizeof(char)) - return (char *)NULL; - - newstr = malloc((len+1)*sizeof(char)); - if(!newstr) - return (char *)NULL; - - memcpy(newstr, str, (len+1)*sizeof(char)); - - return newstr; - -} -#endif - -/*************************************************************************** - * - * Curl_memdup(source, length) - * - * Copies the 'source' data to a newly allocated buffer (that is - * returned). Copies 'length' bytes. - * - * Returns the new pointer or NULL on failure. - * - ***************************************************************************/ -char *Curl_memdup(const char *src, size_t length) -{ - char *buffer = malloc(length); - if(!buffer) - return NULL; /* fail */ - - memcpy(buffer, src, length); - - return buffer; -} diff --git a/Externals/curl/lib/strdup.h b/Externals/curl/lib/strdup.h deleted file mode 100644 index 4c48ca4127..0000000000 --- a/Externals/curl/lib/strdup.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_STRDUP_H -#define HEADER_CURL_STRDUP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifndef HAVE_STRDUP -extern char *curlx_strdup(const char *str); -#endif -char *Curl_memdup(const char *src, size_t buffer_length); - -#endif /* HEADER_CURL_STRDUP_H */ diff --git a/Externals/curl/lib/strequal.c b/Externals/curl/lib/strequal.c deleted file mode 100644 index 01c3784422..0000000000 --- a/Externals/curl/lib/strequal.c +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_STRINGS_H -#include -#endif - -#include "strequal.h" - -/* - * @unittest: 1301 - */ -int curl_strequal(const char *first, const char *second) -{ -#if defined(HAVE_STRCASECMP) - return !(strcasecmp)(first, second); -#elif defined(HAVE_STRCMPI) - return !(strcmpi)(first, second); -#elif defined(HAVE_STRICMP) - return !(stricmp)(first, second); -#else - while(*first && *second) { - if(toupper(*first) != toupper(*second)) { - break; - } - first++; - second++; - } - return toupper(*first) == toupper(*second); -#endif -} - -/* - * @unittest: 1301 - */ -int curl_strnequal(const char *first, const char *second, size_t max) -{ -#if defined(HAVE_STRNCASECMP) - return !strncasecmp(first, second, max); -#elif defined(HAVE_STRNCMPI) - return !strncmpi(first, second, max); -#elif defined(HAVE_STRNICMP) - return !strnicmp(first, second, max); -#else - while(*first && *second && max) { - if(toupper(*first) != toupper(*second)) { - break; - } - max--; - first++; - second++; - } - if(0 == max) - return 1; /* they are equal this far */ - - return toupper(*first) == toupper(*second); -#endif -} diff --git a/Externals/curl/lib/strequal.h b/Externals/curl/lib/strequal.h deleted file mode 100644 index ff56df51fd..0000000000 --- a/Externals/curl/lib/strequal.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef HEADER_CURL_STREQUAL_H -#define HEADER_CURL_STREQUAL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -#define strequal(a,b) curl_strequal(a,b) -#define strnequal(a,b,c) curl_strnequal(a,b,c) - -#endif /* HEADER_CURL_STREQUAL_H */ - diff --git a/Externals/curl/lib/strerror.c b/Externals/curl/lib/strerror.c deleted file mode 100644 index 0e268d5e3f..0000000000 --- a/Externals/curl/lib/strerror.c +++ /dev/null @@ -1,1145 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2004 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_STRERROR_R -# if (!defined(HAVE_POSIX_STRERROR_R) && \ - !defined(HAVE_GLIBC_STRERROR_R) && \ - !defined(HAVE_VXWORKS_STRERROR_R)) || \ - (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \ - (defined(HAVE_GLIBC_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R)) || \ - (defined(HAVE_POSIX_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R)) -# error "strerror_r MUST be either POSIX, glibc or vxworks-style" -# endif -#endif - -#include - -#ifdef USE_LIBIDN -#include -#endif - -#ifdef USE_WINDOWS_SSPI -#include "curl_sspi.h" -#endif - -#include "strerror.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -const char * -curl_easy_strerror(CURLcode error) -{ -#ifndef CURL_DISABLE_VERBOSE_STRINGS - switch (error) { - case CURLE_OK: - return "No error"; - - case CURLE_UNSUPPORTED_PROTOCOL: - return "Unsupported protocol"; - - case CURLE_FAILED_INIT: - return "Failed initialization"; - - case CURLE_URL_MALFORMAT: - return "URL using bad/illegal format or missing URL"; - - case CURLE_NOT_BUILT_IN: - return "A requested feature, protocol or option was not found built-in in" - " this libcurl due to a build-time decision."; - - case CURLE_COULDNT_RESOLVE_PROXY: - return "Couldn't resolve proxy name"; - - case CURLE_COULDNT_RESOLVE_HOST: - return "Couldn't resolve host name"; - - case CURLE_COULDNT_CONNECT: - return "Couldn't connect to server"; - - case CURLE_FTP_WEIRD_SERVER_REPLY: - return "FTP: weird server reply"; - - case CURLE_REMOTE_ACCESS_DENIED: - return "Access denied to remote resource"; - - case CURLE_FTP_ACCEPT_FAILED: - return "FTP: The server failed to connect to data port"; - - case CURLE_FTP_ACCEPT_TIMEOUT: - return "FTP: Accepting server connect has timed out"; - - case CURLE_FTP_PRET_FAILED: - return "FTP: The server did not accept the PRET command."; - - case CURLE_FTP_WEIRD_PASS_REPLY: - return "FTP: unknown PASS reply"; - - case CURLE_FTP_WEIRD_PASV_REPLY: - return "FTP: unknown PASV reply"; - - case CURLE_FTP_WEIRD_227_FORMAT: - return "FTP: unknown 227 response format"; - - case CURLE_FTP_CANT_GET_HOST: - return "FTP: can't figure out the host in the PASV response"; - - case CURLE_HTTP2: - return "Error in the HTTP2 framing layer"; - - case CURLE_FTP_COULDNT_SET_TYPE: - return "FTP: couldn't set file type"; - - case CURLE_PARTIAL_FILE: - return "Transferred a partial file"; - - case CURLE_FTP_COULDNT_RETR_FILE: - return "FTP: couldn't retrieve (RETR failed) the specified file"; - - case CURLE_QUOTE_ERROR: - return "Quote command returned error"; - - case CURLE_HTTP_RETURNED_ERROR: - return "HTTP response code said error"; - - case CURLE_WRITE_ERROR: - return "Failed writing received data to disk/application"; - - case CURLE_UPLOAD_FAILED: - return "Upload failed (at start/before it took off)"; - - case CURLE_READ_ERROR: - return "Failed to open/read local data from file/application"; - - case CURLE_OUT_OF_MEMORY: - return "Out of memory"; - - case CURLE_OPERATION_TIMEDOUT: - return "Timeout was reached"; - - case CURLE_FTP_PORT_FAILED: - return "FTP: command PORT failed"; - - case CURLE_FTP_COULDNT_USE_REST: - return "FTP: command REST failed"; - - case CURLE_RANGE_ERROR: - return "Requested range was not delivered by the server"; - - case CURLE_HTTP_POST_ERROR: - return "Internal problem setting up the POST"; - - case CURLE_SSL_CONNECT_ERROR: - return "SSL connect error"; - - case CURLE_BAD_DOWNLOAD_RESUME: - return "Couldn't resume download"; - - case CURLE_FILE_COULDNT_READ_FILE: - return "Couldn't read a file:// file"; - - case CURLE_LDAP_CANNOT_BIND: - return "LDAP: cannot bind"; - - case CURLE_LDAP_SEARCH_FAILED: - return "LDAP: search failed"; - - case CURLE_FUNCTION_NOT_FOUND: - return "A required function in the library was not found"; - - case CURLE_ABORTED_BY_CALLBACK: - return "Operation was aborted by an application callback"; - - case CURLE_BAD_FUNCTION_ARGUMENT: - return "A libcurl function was given a bad argument"; - - case CURLE_INTERFACE_FAILED: - return "Failed binding local connection end"; - - case CURLE_TOO_MANY_REDIRECTS : - return "Number of redirects hit maximum amount"; - - case CURLE_UNKNOWN_OPTION: - return "An unknown option was passed in to libcurl"; - - case CURLE_TELNET_OPTION_SYNTAX : - return "Malformed telnet option"; - - case CURLE_PEER_FAILED_VERIFICATION: - return "SSL peer certificate or SSH remote key was not OK"; - - case CURLE_GOT_NOTHING: - return "Server returned nothing (no headers, no data)"; - - case CURLE_SSL_ENGINE_NOTFOUND: - return "SSL crypto engine not found"; - - case CURLE_SSL_ENGINE_SETFAILED: - return "Can not set SSL crypto engine as default"; - - case CURLE_SSL_ENGINE_INITFAILED: - return "Failed to initialise SSL crypto engine"; - - case CURLE_SEND_ERROR: - return "Failed sending data to the peer"; - - case CURLE_RECV_ERROR: - return "Failure when receiving data from the peer"; - - case CURLE_SSL_CERTPROBLEM: - return "Problem with the local SSL certificate"; - - case CURLE_SSL_CIPHER: - return "Couldn't use specified SSL cipher"; - - case CURLE_SSL_CACERT: - return "Peer certificate cannot be authenticated with given CA " - "certificates"; - - case CURLE_SSL_CACERT_BADFILE: - return "Problem with the SSL CA cert (path? access rights?)"; - - case CURLE_BAD_CONTENT_ENCODING: - return "Unrecognized or bad HTTP Content or Transfer-Encoding"; - - case CURLE_LDAP_INVALID_URL: - return "Invalid LDAP URL"; - - case CURLE_FILESIZE_EXCEEDED: - return "Maximum file size exceeded"; - - case CURLE_USE_SSL_FAILED: - return "Requested SSL level failed"; - - case CURLE_SSL_SHUTDOWN_FAILED: - return "Failed to shut down the SSL connection"; - - case CURLE_SSL_CRL_BADFILE: - return "Failed to load CRL file (path? access rights?, format?)"; - - case CURLE_SSL_ISSUER_ERROR: - return "Issuer check against peer certificate failed"; - - case CURLE_SEND_FAIL_REWIND: - return "Send failed since rewinding of the data stream failed"; - - case CURLE_LOGIN_DENIED: - return "Login denied"; - - case CURLE_TFTP_NOTFOUND: - return "TFTP: File Not Found"; - - case CURLE_TFTP_PERM: - return "TFTP: Access Violation"; - - case CURLE_REMOTE_DISK_FULL: - return "Disk full or allocation exceeded"; - - case CURLE_TFTP_ILLEGAL: - return "TFTP: Illegal operation"; - - case CURLE_TFTP_UNKNOWNID: - return "TFTP: Unknown transfer ID"; - - case CURLE_REMOTE_FILE_EXISTS: - return "Remote file already exists"; - - case CURLE_TFTP_NOSUCHUSER: - return "TFTP: No such user"; - - case CURLE_CONV_FAILED: - return "Conversion failed"; - - case CURLE_CONV_REQD: - return "Caller must register CURLOPT_CONV_ callback options"; - - case CURLE_REMOTE_FILE_NOT_FOUND: - return "Remote file not found"; - - case CURLE_SSH: - return "Error in the SSH layer"; - - case CURLE_AGAIN: - return "Socket not ready for send/recv"; - - case CURLE_RTSP_CSEQ_ERROR: - return "RTSP CSeq mismatch or invalid CSeq"; - - case CURLE_RTSP_SESSION_ERROR: - return "RTSP session error"; - - case CURLE_FTP_BAD_FILE_LIST: - return "Unable to parse FTP file list"; - - case CURLE_CHUNK_FAILED: - return "Chunk callback failed"; - - case CURLE_NO_CONNECTION_AVAILABLE: - return "The max connection limit is reached"; - - case CURLE_SSL_PINNEDPUBKEYNOTMATCH: - return "SSL public key does not match pinned public key"; - - case CURLE_SSL_INVALIDCERTSTATUS: - return "SSL server certificate status verification FAILED"; - - case CURLE_HTTP2_STREAM: - return "Stream error in the HTTP/2 framing layer"; - - /* error codes not used by current libcurl */ - case CURLE_OBSOLETE20: - case CURLE_OBSOLETE24: - case CURLE_OBSOLETE29: - case CURLE_OBSOLETE32: - case CURLE_OBSOLETE40: - case CURLE_OBSOLETE44: - case CURLE_OBSOLETE46: - case CURLE_OBSOLETE50: - case CURLE_OBSOLETE57: - case CURL_LAST: - break; - } - /* - * By using a switch, gcc -Wall will complain about enum values - * which do not appear, helping keep this function up-to-date. - * By using gcc -Wall -Werror, you can't forget. - * - * A table would not have the same benefit. Most compilers will - * generate code very similar to a table in any case, so there - * is little performance gain from a table. And something is broken - * for the user's application, anyways, so does it matter how fast - * it _doesn't_ work? - * - * The line number for the error will be near this comment, which - * is why it is here, and not at the start of the switch. - */ - return "Unknown error"; -#else - if(!error) - return "No error"; - else - return "Error"; -#endif -} - -const char * -curl_multi_strerror(CURLMcode error) -{ -#ifndef CURL_DISABLE_VERBOSE_STRINGS - switch (error) { - case CURLM_CALL_MULTI_PERFORM: - return "Please call curl_multi_perform() soon"; - - case CURLM_OK: - return "No error"; - - case CURLM_BAD_HANDLE: - return "Invalid multi handle"; - - case CURLM_BAD_EASY_HANDLE: - return "Invalid easy handle"; - - case CURLM_OUT_OF_MEMORY: - return "Out of memory"; - - case CURLM_INTERNAL_ERROR: - return "Internal error"; - - case CURLM_BAD_SOCKET: - return "Invalid socket argument"; - - case CURLM_UNKNOWN_OPTION: - return "Unknown option"; - - case CURLM_ADDED_ALREADY: - return "The easy handle is already added to a multi handle"; - - case CURLM_LAST: - break; - } - - return "Unknown error"; -#else - if(error == CURLM_OK) - return "No error"; - else - return "Error"; -#endif -} - -const char * -curl_share_strerror(CURLSHcode error) -{ -#ifndef CURL_DISABLE_VERBOSE_STRINGS - switch (error) { - case CURLSHE_OK: - return "No error"; - - case CURLSHE_BAD_OPTION: - return "Unknown share option"; - - case CURLSHE_IN_USE: - return "Share currently in use"; - - case CURLSHE_INVALID: - return "Invalid share handle"; - - case CURLSHE_NOMEM: - return "Out of memory"; - - case CURLSHE_NOT_BUILT_IN: - return "Feature not enabled in this library"; - - case CURLSHE_LAST: - break; - } - - return "CURLSHcode unknown"; -#else - if(error == CURLSHE_OK) - return "No error"; - else - return "Error"; -#endif -} - -#ifdef USE_WINSOCK - -/* This function handles most / all (?) Winsock errors cURL is able to produce. - */ -static const char * -get_winsock_error (int err, char *buf, size_t len) -{ - const char *p; - -#ifndef CURL_DISABLE_VERBOSE_STRINGS - switch (err) { - case WSAEINTR: - p = "Call interrupted"; - break; - case WSAEBADF: - p = "Bad file"; - break; - case WSAEACCES: - p = "Bad access"; - break; - case WSAEFAULT: - p = "Bad argument"; - break; - case WSAEINVAL: - p = "Invalid arguments"; - break; - case WSAEMFILE: - p = "Out of file descriptors"; - break; - case WSAEWOULDBLOCK: - p = "Call would block"; - break; - case WSAEINPROGRESS: - case WSAEALREADY: - p = "Blocking call in progress"; - break; - case WSAENOTSOCK: - p = "Descriptor is not a socket"; - break; - case WSAEDESTADDRREQ: - p = "Need destination address"; - break; - case WSAEMSGSIZE: - p = "Bad message size"; - break; - case WSAEPROTOTYPE: - p = "Bad protocol"; - break; - case WSAENOPROTOOPT: - p = "Protocol option is unsupported"; - break; - case WSAEPROTONOSUPPORT: - p = "Protocol is unsupported"; - break; - case WSAESOCKTNOSUPPORT: - p = "Socket is unsupported"; - break; - case WSAEOPNOTSUPP: - p = "Operation not supported"; - break; - case WSAEAFNOSUPPORT: - p = "Address family not supported"; - break; - case WSAEPFNOSUPPORT: - p = "Protocol family not supported"; - break; - case WSAEADDRINUSE: - p = "Address already in use"; - break; - case WSAEADDRNOTAVAIL: - p = "Address not available"; - break; - case WSAENETDOWN: - p = "Network down"; - break; - case WSAENETUNREACH: - p = "Network unreachable"; - break; - case WSAENETRESET: - p = "Network has been reset"; - break; - case WSAECONNABORTED: - p = "Connection was aborted"; - break; - case WSAECONNRESET: - p = "Connection was reset"; - break; - case WSAENOBUFS: - p = "No buffer space"; - break; - case WSAEISCONN: - p = "Socket is already connected"; - break; - case WSAENOTCONN: - p = "Socket is not connected"; - break; - case WSAESHUTDOWN: - p = "Socket has been shut down"; - break; - case WSAETOOMANYREFS: - p = "Too many references"; - break; - case WSAETIMEDOUT: - p = "Timed out"; - break; - case WSAECONNREFUSED: - p = "Connection refused"; - break; - case WSAELOOP: - p = "Loop??"; - break; - case WSAENAMETOOLONG: - p = "Name too long"; - break; - case WSAEHOSTDOWN: - p = "Host down"; - break; - case WSAEHOSTUNREACH: - p = "Host unreachable"; - break; - case WSAENOTEMPTY: - p = "Not empty"; - break; - case WSAEPROCLIM: - p = "Process limit reached"; - break; - case WSAEUSERS: - p = "Too many users"; - break; - case WSAEDQUOT: - p = "Bad quota"; - break; - case WSAESTALE: - p = "Something is stale"; - break; - case WSAEREMOTE: - p = "Remote error"; - break; -#ifdef WSAEDISCON /* missing in SalfordC! */ - case WSAEDISCON: - p = "Disconnected"; - break; -#endif - /* Extended Winsock errors */ - case WSASYSNOTREADY: - p = "Winsock library is not ready"; - break; - case WSANOTINITIALISED: - p = "Winsock library not initialised"; - break; - case WSAVERNOTSUPPORTED: - p = "Winsock version not supported"; - break; - - /* getXbyY() errors (already handled in herrmsg): - * Authoritative Answer: Host not found */ - case WSAHOST_NOT_FOUND: - p = "Host not found"; - break; - - /* Non-Authoritative: Host not found, or SERVERFAIL */ - case WSATRY_AGAIN: - p = "Host not found, try again"; - break; - - /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ - case WSANO_RECOVERY: - p = "Unrecoverable error in call to nameserver"; - break; - - /* Valid name, no data record of requested type */ - case WSANO_DATA: - p = "No data record of requested type"; - break; - - default: - return NULL; - } -#else - if(!err) - return NULL; - else - p = "error"; -#endif - strncpy (buf, p, len); - buf [len-1] = '\0'; - return buf; -} -#endif /* USE_WINSOCK */ - -/* - * Our thread-safe and smart strerror() replacement. - * - * The 'err' argument passed in to this function MUST be a true errno number - * as reported on this system. We do no range checking on the number before - * we pass it to the "number-to-message" conversion function and there might - * be systems that don't do proper range checking in there themselves. - * - * We don't do range checking (on systems other than Windows) since there is - * no good reliable and portable way to do it. - */ -const char *Curl_strerror(struct connectdata *conn, int err) -{ - char *buf, *p; - size_t max; - int old_errno = ERRNO; - - DEBUGASSERT(conn); - DEBUGASSERT(err >= 0); - - buf = conn->syserr_buf; - max = sizeof(conn->syserr_buf)-1; - *buf = '\0'; - -#ifdef USE_WINSOCK - -#ifdef _WIN32_WCE - { - wchar_t wbuf[256]; - wbuf[0] = L'\0'; - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - LANG_NEUTRAL, wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL); - wcstombs(buf, wbuf, max); - } -#else - /* 'sys_nerr' is the maximum errno number, it is not widely portable */ - if(err >= 0 && err < sys_nerr) - strncpy(buf, strerror(err), max); - else { - if(!get_winsock_error(err, buf, max) && - !FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, - LANG_NEUTRAL, buf, (DWORD)max, NULL)) - snprintf(buf, max, "Unknown error %d (%#x)", err, err); - } -#endif - -#else /* not USE_WINSOCK coming up */ - -#if defined(HAVE_STRERROR_R) && defined(HAVE_POSIX_STRERROR_R) - /* - * The POSIX-style strerror_r() may set errno to ERANGE if insufficient - * storage is supplied via 'strerrbuf' and 'buflen' to hold the generated - * message string, or EINVAL if 'errnum' is not a valid error number. - */ - if(0 != strerror_r(err, buf, max)) { - if('\0' == buf[0]) - snprintf(buf, max, "Unknown error %d", err); - } -#elif defined(HAVE_STRERROR_R) && defined(HAVE_GLIBC_STRERROR_R) - /* - * The glibc-style strerror_r() only *might* use the buffer we pass to - * the function, but it always returns the error message as a pointer, - * so we must copy that string unconditionally (if non-NULL). - */ - { - char buffer[256]; - char *msg = strerror_r(err, buffer, sizeof(buffer)); - if(msg) - strncpy(buf, msg, max); - else - snprintf(buf, max, "Unknown error %d", err); - } -#elif defined(HAVE_STRERROR_R) && defined(HAVE_VXWORKS_STRERROR_R) - /* - * The vxworks-style strerror_r() does use the buffer we pass to the function. - * The buffer size should be at least NAME_MAX (256) - */ - { - char buffer[256]; - if(OK == strerror_r(err, buffer)) - strncpy(buf, buffer, max); - else - snprintf(buf, max, "Unknown error %d", err); - } -#else - { - char *msg = strerror(err); - if(msg) - strncpy(buf, msg, max); - else - snprintf(buf, max, "Unknown error %d", err); - } -#endif - -#endif /* end of ! USE_WINSOCK */ - - buf[max] = '\0'; /* make sure the string is zero terminated */ - - /* strip trailing '\r\n' or '\n'. */ - if((p = strrchr(buf, '\n')) != NULL && (p - buf) >= 2) - *p = '\0'; - if((p = strrchr(buf, '\r')) != NULL && (p - buf) >= 1) - *p = '\0'; - - if(old_errno != ERRNO) - SET_ERRNO(old_errno); - - return buf; -} - -#ifdef USE_LIBIDN -/* - * Return error-string for libidn status as returned from idna_to_ascii_lz(). - */ -const char *Curl_idn_strerror (struct connectdata *conn, int err) -{ -#ifdef HAVE_IDNA_STRERROR - (void)conn; - return idna_strerror((Idna_rc) err); -#else - const char *str; - char *buf; - size_t max; - - DEBUGASSERT(conn); - - buf = conn->syserr_buf; - max = sizeof(conn->syserr_buf)-1; - *buf = '\0'; - -#ifndef CURL_DISABLE_VERBOSE_STRINGS - switch ((Idna_rc)err) { - case IDNA_SUCCESS: - str = "No error"; - break; - case IDNA_STRINGPREP_ERROR: - str = "Error in string preparation"; - break; - case IDNA_PUNYCODE_ERROR: - str = "Error in Punycode operation"; - break; - case IDNA_CONTAINS_NON_LDH: - str = "Illegal ASCII characters"; - break; - case IDNA_CONTAINS_MINUS: - str = "Contains minus"; - break; - case IDNA_INVALID_LENGTH: - str = "Invalid output length"; - break; - case IDNA_NO_ACE_PREFIX: - str = "No ACE prefix (\"xn--\")"; - break; - case IDNA_ROUNDTRIP_VERIFY_ERROR: - str = "Round trip verify error"; - break; - case IDNA_CONTAINS_ACE_PREFIX: - str = "Already have ACE prefix (\"xn--\")"; - break; - case IDNA_ICONV_ERROR: - str = "Locale conversion failed"; - break; - case IDNA_MALLOC_ERROR: - str = "Allocation failed"; - break; - case IDNA_DLOPEN_ERROR: - str = "dlopen() error"; - break; - default: - snprintf(buf, max, "error %d", err); - str = NULL; - break; - } -#else - if((Idna_rc)err == IDNA_SUCCESS) - str = "No error"; - else - str = "Error"; -#endif - if(str) - strncpy(buf, str, max); - buf[max] = '\0'; - return (buf); -#endif -} -#endif /* USE_LIBIDN */ - -#ifdef USE_WINDOWS_SSPI -const char *Curl_sspi_strerror (struct connectdata *conn, int err) -{ -#ifndef CURL_DISABLE_VERBOSE_STRINGS - char txtbuf[80]; - char msgbuf[sizeof(conn->syserr_buf)]; - char *p, *str, *msg = NULL; - bool msg_formatted = FALSE; - int old_errno; -#endif - const char *txt; - char *outbuf; - size_t outmax; - - DEBUGASSERT(conn); - - outbuf = conn->syserr_buf; - outmax = sizeof(conn->syserr_buf)-1; - *outbuf = '\0'; - -#ifndef CURL_DISABLE_VERBOSE_STRINGS - - old_errno = ERRNO; - - switch (err) { - case SEC_E_OK: - txt = "No error"; - break; - case CRYPT_E_REVOKED: - txt = "CRYPT_E_REVOKED"; - break; - case SEC_E_ALGORITHM_MISMATCH: - txt = "SEC_E_ALGORITHM_MISMATCH"; - break; - case SEC_E_BAD_BINDINGS: - txt = "SEC_E_BAD_BINDINGS"; - break; - case SEC_E_BAD_PKGID: - txt = "SEC_E_BAD_PKGID"; - break; - case SEC_E_BUFFER_TOO_SMALL: - txt = "SEC_E_BUFFER_TOO_SMALL"; - break; - case SEC_E_CANNOT_INSTALL: - txt = "SEC_E_CANNOT_INSTALL"; - break; - case SEC_E_CANNOT_PACK: - txt = "SEC_E_CANNOT_PACK"; - break; - case SEC_E_CERT_EXPIRED: - txt = "SEC_E_CERT_EXPIRED"; - break; - case SEC_E_CERT_UNKNOWN: - txt = "SEC_E_CERT_UNKNOWN"; - break; - case SEC_E_CERT_WRONG_USAGE: - txt = "SEC_E_CERT_WRONG_USAGE"; - break; - case SEC_E_CONTEXT_EXPIRED: - txt = "SEC_E_CONTEXT_EXPIRED"; - break; - case SEC_E_CROSSREALM_DELEGATION_FAILURE: - txt = "SEC_E_CROSSREALM_DELEGATION_FAILURE"; - break; - case SEC_E_CRYPTO_SYSTEM_INVALID: - txt = "SEC_E_CRYPTO_SYSTEM_INVALID"; - break; - case SEC_E_DECRYPT_FAILURE: - txt = "SEC_E_DECRYPT_FAILURE"; - break; - case SEC_E_DELEGATION_POLICY: - txt = "SEC_E_DELEGATION_POLICY"; - break; - case SEC_E_DELEGATION_REQUIRED: - txt = "SEC_E_DELEGATION_REQUIRED"; - break; - case SEC_E_DOWNGRADE_DETECTED: - txt = "SEC_E_DOWNGRADE_DETECTED"; - break; - case SEC_E_ENCRYPT_FAILURE: - txt = "SEC_E_ENCRYPT_FAILURE"; - break; - case SEC_E_ILLEGAL_MESSAGE: - txt = "SEC_E_ILLEGAL_MESSAGE"; - break; - case SEC_E_INCOMPLETE_CREDENTIALS: - txt = "SEC_E_INCOMPLETE_CREDENTIALS"; - break; - case SEC_E_INCOMPLETE_MESSAGE: - txt = "SEC_E_INCOMPLETE_MESSAGE"; - break; - case SEC_E_INSUFFICIENT_MEMORY: - txt = "SEC_E_INSUFFICIENT_MEMORY"; - break; - case SEC_E_INTERNAL_ERROR: - txt = "SEC_E_INTERNAL_ERROR"; - break; - case SEC_E_INVALID_HANDLE: - txt = "SEC_E_INVALID_HANDLE"; - break; - case SEC_E_INVALID_PARAMETER: - txt = "SEC_E_INVALID_PARAMETER"; - break; - case SEC_E_INVALID_TOKEN: - txt = "SEC_E_INVALID_TOKEN"; - break; - case SEC_E_ISSUING_CA_UNTRUSTED: - txt = "SEC_E_ISSUING_CA_UNTRUSTED"; - break; - case SEC_E_ISSUING_CA_UNTRUSTED_KDC: - txt = "SEC_E_ISSUING_CA_UNTRUSTED_KDC"; - break; - case SEC_E_KDC_CERT_EXPIRED: - txt = "SEC_E_KDC_CERT_EXPIRED"; - break; - case SEC_E_KDC_CERT_REVOKED: - txt = "SEC_E_KDC_CERT_REVOKED"; - break; - case SEC_E_KDC_INVALID_REQUEST: - txt = "SEC_E_KDC_INVALID_REQUEST"; - break; - case SEC_E_KDC_UNABLE_TO_REFER: - txt = "SEC_E_KDC_UNABLE_TO_REFER"; - break; - case SEC_E_KDC_UNKNOWN_ETYPE: - txt = "SEC_E_KDC_UNKNOWN_ETYPE"; - break; - case SEC_E_LOGON_DENIED: - txt = "SEC_E_LOGON_DENIED"; - break; - case SEC_E_MAX_REFERRALS_EXCEEDED: - txt = "SEC_E_MAX_REFERRALS_EXCEEDED"; - break; - case SEC_E_MESSAGE_ALTERED: - txt = "SEC_E_MESSAGE_ALTERED"; - break; - case SEC_E_MULTIPLE_ACCOUNTS: - txt = "SEC_E_MULTIPLE_ACCOUNTS"; - break; - case SEC_E_MUST_BE_KDC: - txt = "SEC_E_MUST_BE_KDC"; - break; - case SEC_E_NOT_OWNER: - txt = "SEC_E_NOT_OWNER"; - break; - case SEC_E_NO_AUTHENTICATING_AUTHORITY: - txt = "SEC_E_NO_AUTHENTICATING_AUTHORITY"; - break; - case SEC_E_NO_CREDENTIALS: - txt = "SEC_E_NO_CREDENTIALS"; - break; - case SEC_E_NO_IMPERSONATION: - txt = "SEC_E_NO_IMPERSONATION"; - break; - case SEC_E_NO_IP_ADDRESSES: - txt = "SEC_E_NO_IP_ADDRESSES"; - break; - case SEC_E_NO_KERB_KEY: - txt = "SEC_E_NO_KERB_KEY"; - break; - case SEC_E_NO_PA_DATA: - txt = "SEC_E_NO_PA_DATA"; - break; - case SEC_E_NO_S4U_PROT_SUPPORT: - txt = "SEC_E_NO_S4U_PROT_SUPPORT"; - break; - case SEC_E_NO_TGT_REPLY: - txt = "SEC_E_NO_TGT_REPLY"; - break; - case SEC_E_OUT_OF_SEQUENCE: - txt = "SEC_E_OUT_OF_SEQUENCE"; - break; - case SEC_E_PKINIT_CLIENT_FAILURE: - txt = "SEC_E_PKINIT_CLIENT_FAILURE"; - break; - case SEC_E_PKINIT_NAME_MISMATCH: - txt = "SEC_E_PKINIT_NAME_MISMATCH"; - break; - case SEC_E_POLICY_NLTM_ONLY: - txt = "SEC_E_POLICY_NLTM_ONLY"; - break; - case SEC_E_QOP_NOT_SUPPORTED: - txt = "SEC_E_QOP_NOT_SUPPORTED"; - break; - case SEC_E_REVOCATION_OFFLINE_C: - txt = "SEC_E_REVOCATION_OFFLINE_C"; - break; - case SEC_E_REVOCATION_OFFLINE_KDC: - txt = "SEC_E_REVOCATION_OFFLINE_KDC"; - break; - case SEC_E_SECPKG_NOT_FOUND: - txt = "SEC_E_SECPKG_NOT_FOUND"; - break; - case SEC_E_SECURITY_QOS_FAILED: - txt = "SEC_E_SECURITY_QOS_FAILED"; - break; - case SEC_E_SHUTDOWN_IN_PROGRESS: - txt = "SEC_E_SHUTDOWN_IN_PROGRESS"; - break; - case SEC_E_SMARTCARD_CERT_EXPIRED: - txt = "SEC_E_SMARTCARD_CERT_EXPIRED"; - break; - case SEC_E_SMARTCARD_CERT_REVOKED: - txt = "SEC_E_SMARTCARD_CERT_REVOKED"; - break; - case SEC_E_SMARTCARD_LOGON_REQUIRED: - txt = "SEC_E_SMARTCARD_LOGON_REQUIRED"; - break; - case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED: - txt = "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED"; - break; - case SEC_E_TARGET_UNKNOWN: - txt = "SEC_E_TARGET_UNKNOWN"; - break; - case SEC_E_TIME_SKEW: - txt = "SEC_E_TIME_SKEW"; - break; - case SEC_E_TOO_MANY_PRINCIPALS: - txt = "SEC_E_TOO_MANY_PRINCIPALS"; - break; - case SEC_E_UNFINISHED_CONTEXT_DELETED: - txt = "SEC_E_UNFINISHED_CONTEXT_DELETED"; - break; - case SEC_E_UNKNOWN_CREDENTIALS: - txt = "SEC_E_UNKNOWN_CREDENTIALS"; - break; - case SEC_E_UNSUPPORTED_FUNCTION: - txt = "SEC_E_UNSUPPORTED_FUNCTION"; - break; - case SEC_E_UNSUPPORTED_PREAUTH: - txt = "SEC_E_UNSUPPORTED_PREAUTH"; - break; - case SEC_E_UNTRUSTED_ROOT: - txt = "SEC_E_UNTRUSTED_ROOT"; - break; - case SEC_E_WRONG_CREDENTIAL_HANDLE: - txt = "SEC_E_WRONG_CREDENTIAL_HANDLE"; - break; - case SEC_E_WRONG_PRINCIPAL: - txt = "SEC_E_WRONG_PRINCIPAL"; - break; - case SEC_I_COMPLETE_AND_CONTINUE: - txt = "SEC_I_COMPLETE_AND_CONTINUE"; - break; - case SEC_I_COMPLETE_NEEDED: - txt = "SEC_I_COMPLETE_NEEDED"; - break; - case SEC_I_CONTEXT_EXPIRED: - txt = "SEC_I_CONTEXT_EXPIRED"; - break; - case SEC_I_CONTINUE_NEEDED: - txt = "SEC_I_CONTINUE_NEEDED"; - break; - case SEC_I_INCOMPLETE_CREDENTIALS: - txt = "SEC_I_INCOMPLETE_CREDENTIALS"; - break; - case SEC_I_LOCAL_LOGON: - txt = "SEC_I_LOCAL_LOGON"; - break; - case SEC_I_NO_LSA_CONTEXT: - txt = "SEC_I_NO_LSA_CONTEXT"; - break; - case SEC_I_RENEGOTIATE: - txt = "SEC_I_RENEGOTIATE"; - break; - case SEC_I_SIGNATURE_NEEDED: - txt = "SEC_I_SIGNATURE_NEEDED"; - break; - default: - txt = "Unknown error"; - } - - if(err == SEC_E_OK) - strncpy(outbuf, txt, outmax); - else if(err == SEC_E_ILLEGAL_MESSAGE) - snprintf(outbuf, outmax, - "SEC_E_ILLEGAL_MESSAGE (0x%08X) - This error usually occurs " - "when a fatal SSL/TLS alert is received (e.g. handshake failed). " - "More detail may be available in the Windows System event log.", - err); - else { - str = txtbuf; - snprintf(txtbuf, sizeof(txtbuf), "%s (0x%08X)", txt, err); - txtbuf[sizeof(txtbuf)-1] = '\0'; - -#ifdef _WIN32_WCE - { - wchar_t wbuf[256]; - wbuf[0] = L'\0'; - - if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, LANG_NEUTRAL, - wbuf, sizeof(wbuf)/sizeof(wchar_t), NULL)) { - wcstombs(msgbuf, wbuf, sizeof(msgbuf)-1); - msg_formatted = TRUE; - } - } -#else - if(FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, err, LANG_NEUTRAL, - msgbuf, sizeof(msgbuf)-1, NULL)) { - msg_formatted = TRUE; - } -#endif - if(msg_formatted) { - msgbuf[sizeof(msgbuf)-1] = '\0'; - /* strip trailing '\r\n' or '\n' */ - if((p = strrchr(msgbuf, '\n')) != NULL && (p - msgbuf) >= 2) - *p = '\0'; - if((p = strrchr(msgbuf, '\r')) != NULL && (p - msgbuf) >= 1) - *p = '\0'; - msg = msgbuf; - } - if(msg) - snprintf(outbuf, outmax, "%s - %s", str, msg); - else - strncpy(outbuf, str, outmax); - } - - if(old_errno != ERRNO) - SET_ERRNO(old_errno); - -#else - - if(err == SEC_E_OK) - txt = "No error"; - else - txt = "Error"; - - strncpy(outbuf, txt, outmax); - -#endif - - outbuf[outmax] = '\0'; - - return outbuf; -} -#endif /* USE_WINDOWS_SSPI */ diff --git a/Externals/curl/lib/strerror.h b/Externals/curl/lib/strerror.h deleted file mode 100644 index ae8c96bd4a..0000000000 --- a/Externals/curl/lib/strerror.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef HEADER_CURL_STRERROR_H -#define HEADER_CURL_STRERROR_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "urldata.h" - -const char *Curl_strerror (struct connectdata *conn, int err); - -#ifdef USE_LIBIDN -const char *Curl_idn_strerror (struct connectdata *conn, int err); -#endif - -#ifdef USE_WINDOWS_SSPI -const char *Curl_sspi_strerror (struct connectdata *conn, int err); -#endif - -#endif /* HEADER_CURL_STRERROR_H */ diff --git a/Externals/curl/lib/strtok.c b/Externals/curl/lib/strtok.c deleted file mode 100644 index 460eb87e51..0000000000 --- a/Externals/curl/lib/strtok.c +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef HAVE_STRTOK_R -#include - -#include "strtok.h" - -char * -Curl_strtok_r(char *ptr, const char *sep, char **end) -{ - if(!ptr) - /* we got NULL input so then we get our last position instead */ - ptr = *end; - - /* pass all letters that are including in the separator string */ - while(*ptr && strchr(sep, *ptr)) - ++ptr; - - if(*ptr) { - /* so this is where the next piece of string starts */ - char *start = ptr; - - /* set the end pointer to the first byte after the start */ - *end = start + 1; - - /* scan through the string to find where it ends, it ends on a - null byte or a character that exists in the separator string */ - while(**end && !strchr(sep, **end)) - ++*end; - - if(**end) { - /* the end is not a null byte */ - **end = '\0'; /* zero terminate it! */ - ++*end; /* advance the last pointer to beyond the null byte */ - } - - return start; /* return the position where the string starts */ - } - - /* we ended up on a null byte, there are no more strings to find! */ - return NULL; -} - -#endif /* this was only compiled if strtok_r wasn't present */ diff --git a/Externals/curl/lib/strtok.h b/Externals/curl/lib/strtok.h deleted file mode 100644 index 90b831eb67..0000000000 --- a/Externals/curl/lib/strtok.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef HEADER_CURL_STRTOK_H -#define HEADER_CURL_STRTOK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" -#include - -#ifndef HAVE_STRTOK_R -char *Curl_strtok_r(char *s, const char *delim, char **last); -#define strtok_r Curl_strtok_r -#else -#include -#endif - -#endif /* HEADER_CURL_STRTOK_H */ diff --git a/Externals/curl/lib/strtoofft.c b/Externals/curl/lib/strtoofft.c deleted file mode 100644 index 6d5d2d5c52..0000000000 --- a/Externals/curl/lib/strtoofft.c +++ /dev/null @@ -1,188 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "strtoofft.h" - -/* - * NOTE: - * - * In the ISO C standard (IEEE Std 1003.1), there is a strtoimax() function we - * could use in case strtoll() doesn't exist... See - * http://www.opengroup.org/onlinepubs/009695399/functions/strtoimax.html - */ - -#ifdef NEED_CURL_STRTOLL - -/* Range tests can be used for alphanum decoding if characters are consecutive, - like in ASCII. Else an array is scanned. Determine this condition now. */ - -#if('9' - '0') != 9 || ('Z' - 'A') != 25 || ('z' - 'a') != 25 - -#define NO_RANGE_TEST - -static const char valchars[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; -#endif - -static int get_char(char c, int base); - -/** - * Emulated version of the strtoll function. This extracts a long long - * value from the given input string and returns it. - */ -curl_off_t -curlx_strtoll(const char *nptr, char **endptr, int base) -{ - char *end; - int is_negative = 0; - int overflow; - int i; - curl_off_t value = 0; - curl_off_t newval; - - /* Skip leading whitespace. */ - end = (char *)nptr; - while(ISSPACE(end[0])) { - end++; - } - - /* Handle the sign, if any. */ - if(end[0] == '-') { - is_negative = 1; - end++; - } - else if(end[0] == '+') { - end++; - } - else if(end[0] == '\0') { - /* We had nothing but perhaps some whitespace -- there was no number. */ - if(endptr) { - *endptr = end; - } - return 0; - } - - /* Handle special beginnings, if present and allowed. */ - if(end[0] == '0' && end[1] == 'x') { - if(base == 16 || base == 0) { - end += 2; - base = 16; - } - } - else if(end[0] == '0') { - if(base == 8 || base == 0) { - end++; - base = 8; - } - } - - /* Matching strtol, if the base is 0 and it doesn't look like - * the number is octal or hex, we assume it's base 10. - */ - if(base == 0) { - base = 10; - } - - /* Loop handling digits. */ - value = 0; - overflow = 0; - for(i = get_char(end[0], base); - i != -1; - end++, i = get_char(end[0], base)) { - newval = base * value + i; - if(newval < value) { - /* We've overflowed. */ - overflow = 1; - break; - } - else - value = newval; - } - - if(!overflow) { - if(is_negative) { - /* Fix the sign. */ - value *= -1; - } - } - else { - if(is_negative) - value = CURL_OFF_T_MIN; - else - value = CURL_OFF_T_MAX; - - SET_ERRNO(ERANGE); - } - - if(endptr) - *endptr = end; - - return value; -} - -/** - * Returns the value of c in the given base, or -1 if c cannot - * be interpreted properly in that base (i.e., is out of range, - * is a null, etc.). - * - * @param c the character to interpret according to base - * @param base the base in which to interpret c - * - * @return the value of c in base, or -1 if c isn't in range - */ -static int get_char(char c, int base) -{ -#ifndef NO_RANGE_TEST - int value = -1; - if(c <= '9' && c >= '0') { - value = c - '0'; - } - else if(c <= 'Z' && c >= 'A') { - value = c - 'A' + 10; - } - else if(c <= 'z' && c >= 'a') { - value = c - 'a' + 10; - } -#else - const char * cp; - int value; - - cp = memchr(valchars, c, 10 + 26 + 26); - - if(!cp) - return -1; - - value = cp - valchars; - - if(value >= 10 + 26) - value -= 26; /* Lowercase. */ -#endif - - if(value >= base) { - value = -1; - } - - return value; -} -#endif /* Only present if we need strtoll, but don't have it. */ diff --git a/Externals/curl/lib/strtoofft.h b/Externals/curl/lib/strtoofft.h deleted file mode 100644 index f4039f3a3b..0000000000 --- a/Externals/curl/lib/strtoofft.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef HEADER_CURL_STRTOOFFT_H -#define HEADER_CURL_STRTOOFFT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -/* - * Determine which string to integral data type conversion function we use - * to implement string conversion to our curl_off_t integral data type. - * - * Notice that curl_off_t might be 64 or 32 bit wide, and that it might use - * an underlying data type which might be 'long', 'int64_t', 'long long' or - * '__int64' and more remotely other data types. - * - * On systems where the size of curl_off_t is greater than the size of 'long' - * the conversion function to use is strtoll() if it is available, otherwise, - * we emulate its functionality with our own clone. - * - * On systems where the size of curl_off_t is smaller or equal than the size - * of 'long' the conversion function to use is strtol(). - */ - -#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG) -# ifdef HAVE_STRTOLL -# define curlx_strtoofft strtoll -# else -# if defined(_MSC_VER) && (_MSC_VER >= 1300) && (_INTEGRAL_MAX_BITS >= 64) -# if defined(_SAL_VERSION) - _Check_return_ _CRTIMP __int64 __cdecl _strtoi64( - _In_z_ const char *_String, - _Out_opt_ _Deref_post_z_ char **_EndPtr, _In_ int _Radix); -# else - _CRTIMP __int64 __cdecl _strtoi64(const char *_String, - char **_EndPtr, int _Radix); -# endif -# define curlx_strtoofft _strtoi64 -# else - curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base); -# define curlx_strtoofft curlx_strtoll -# define NEED_CURL_STRTOLL 1 -# endif -# endif -#else -# define curlx_strtoofft strtol -#endif - -#if (CURL_SIZEOF_CURL_OFF_T == 4) -# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFF) -#else - /* assume CURL_SIZEOF_CURL_OFF_T == 8 */ -# define CURL_OFF_T_MAX CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) -#endif -#define CURL_OFF_T_MIN (-CURL_OFF_T_MAX - CURL_OFF_T_C(1)) - -#endif /* HEADER_CURL_STRTOOFFT_H */ diff --git a/Externals/curl/lib/system_win32.c b/Externals/curl/lib/system_win32.c deleted file mode 100644 index 73d30b4219..0000000000 --- a/Externals/curl/lib/system_win32.c +++ /dev/null @@ -1,130 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2016, Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(WIN32) - -#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ - defined(USE_WINSOCK)) - -#include -#include "system_win32.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -#if !defined(LOAD_WITH_ALTERED_SEARCH_PATH) -#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 -#endif - -#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32) -#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 -#endif - -/* We use our own typedef here since some headers might lack these */ -typedef HMODULE (APIENTRY *LOADLIBRARYEX_FN)(LPCTSTR, HANDLE, DWORD); - -/* See function definitions in winbase.h */ -#ifdef UNICODE -# ifdef _WIN32_WCE -# define LOADLIBARYEX L"LoadLibraryExW" -# else -# define LOADLIBARYEX "LoadLibraryExW" -# endif -#else -# define LOADLIBARYEX "LoadLibraryExA" -#endif - -/* - * Curl_load_library() - * - * This is used to dynamically load DLLs using the most secure method available - * for the version of Windows that we are running on. - * - * Parameters: - * - * filename [in] - The filename or full path of the DLL to load. If only the - * filename is passed then the DLL will be loaded from the - * Windows system directory. - * - * Returns the handle of the module on success; otherwise NULL. - */ -HMODULE Curl_load_library(LPCTSTR filename) -{ - HMODULE hModule = NULL; - LOADLIBRARYEX_FN pLoadLibraryEx = NULL; - - /* Get a handle to kernel32 so we can access it's functions at runtime */ - HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32")); - if(!hKernel32) - return NULL; - - /* Attempt to find LoadLibraryEx() which is only available on Windows 2000 - and above */ - pLoadLibraryEx = (LOADLIBRARYEX_FN) GetProcAddress(hKernel32, LOADLIBARYEX); - - /* Detect if there's already a path in the filename and load the library if - there is. Note: Both back slashes and forward slashes have been supported - since the earlier days of DOS at an API level although they are not - supported by command prompt */ - if(_tcspbrk(filename, TEXT("\\/"))) - hModule = pLoadLibraryEx ? - pLoadLibraryEx(filename, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : - LoadLibrary(filename); - /* Detect if KB2533623 is installed, as LOAD_LIBARY_SEARCH_SYSTEM32 is only - supported on Windows Vista, Windows Server 2008, Windows 7 and Windows - Server 2008 R2 with this patch or natively on Windows 8 and above */ - else if(pLoadLibraryEx && GetProcAddress(hKernel32, "AddDllDirectory")) { - /* Load the DLL from the Windows system directory */ - hModule = pLoadLibraryEx(filename, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - } - else { - /* Attempt to get the Windows system path */ - UINT systemdirlen = GetSystemDirectory(NULL, 0); - if(systemdirlen) { - /* Allocate space for the full DLL path (Room for the null terminator - is included in systemdirlen) */ - size_t filenamelen = _tcslen(filename); - TCHAR *path = malloc(sizeof(TCHAR) * (systemdirlen + 1 + filenamelen)); - if(path && GetSystemDirectory(path, systemdirlen)) { - /* Calculate the full DLL path */ - _tcscpy(path + _tcslen(path), TEXT("\\")); - _tcscpy(path + _tcslen(path), filename); - - /* Load the DLL from the Windows system directory */ - hModule = pLoadLibraryEx ? - pLoadLibraryEx(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) : - LoadLibrary(path); - - free(path); - } - } - } - - return hModule; -} - -#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */ - -#endif /* WIN32 */ diff --git a/Externals/curl/lib/system_win32.h b/Externals/curl/lib/system_win32.h deleted file mode 100644 index dec18899ab..0000000000 --- a/Externals/curl/lib/system_win32.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef HEADER_CURL_SYSTEM_WIN32_H -#define HEADER_CURL_SYSTEM_WIN32_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2016, Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(WIN32) - -#if defined(USE_WINDOWS_SSPI) || (!defined(CURL_DISABLE_TELNET) && \ - defined(USE_WINSOCK)) - -/* This is used to dynamically load DLLs */ -HMODULE Curl_load_library(LPCTSTR filename); - -#endif /* USE_WINDOWS_SSPI || (!CURL_DISABLE_TELNET && USE_WINSOCK) */ - -#endif /* WIN32 */ - -#endif /* HEADER_CURL_SYSTEM_WIN32_H */ diff --git a/Externals/curl/lib/telnet.c b/Externals/curl/lib/telnet.c deleted file mode 100644 index 870a1b8256..0000000000 --- a/Externals/curl/lib/telnet.c +++ /dev/null @@ -1,1677 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_TELNET - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "urldata.h" -#include -#include "transfer.h" -#include "sendf.h" -#include "telnet.h" -#include "connect.h" -#include "progress.h" -#include "system_win32.h" - -#define TELOPTS -#define TELCMDS - -#include "arpa_telnet.h" -#include "select.h" -#include "strequal.h" -#include "rawstr.h" -#include "warnless.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -#define SUBBUFSIZE 512 - -#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer -#define CURL_SB_TERM(x) \ - do { \ - x->subend = x->subpointer; \ - CURL_SB_CLEAR(x); \ - } WHILE_FALSE -#define CURL_SB_ACCUM(x,c) \ - do { \ - if(x->subpointer < (x->subbuffer+sizeof x->subbuffer)) \ - *x->subpointer++ = (c); \ - } WHILE_FALSE - -#define CURL_SB_GET(x) ((*x->subpointer++)&0xff) -#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff) -#define CURL_SB_EOF(x) (x->subpointer >= x->subend) -#define CURL_SB_LEN(x) (x->subend - x->subpointer) - -#ifdef CURL_DISABLE_VERBOSE_STRINGS -#define printoption(a,b,c,d) Curl_nop_stmt -#endif - -#ifdef USE_WINSOCK -typedef FARPROC WSOCK2_FUNC; -static CURLcode check_wsock2 (struct SessionHandle *data); -#endif - -static -CURLcode telrcv(struct connectdata *, - const unsigned char *inbuf, /* Data received from socket */ - ssize_t count); /* Number of bytes received */ - -#ifndef CURL_DISABLE_VERBOSE_STRINGS -static void printoption(struct SessionHandle *data, - const char *direction, - int cmd, int option); -#endif - -static void negotiate(struct connectdata *); -static void send_negotiation(struct connectdata *, int cmd, int option); -static void set_local_option(struct connectdata *, int cmd, int option); -static void set_remote_option(struct connectdata *, int cmd, int option); - -static void printsub(struct SessionHandle *data, - int direction, unsigned char *pointer, - size_t length); -static void suboption(struct connectdata *); -static void sendsuboption(struct connectdata *conn, int option); - -static CURLcode telnet_do(struct connectdata *conn, bool *done); -static CURLcode telnet_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode send_telnet_data(struct connectdata *conn, - char *buffer, ssize_t nread); - -/* For negotiation compliant to RFC 1143 */ -#define CURL_NO 0 -#define CURL_YES 1 -#define CURL_WANTYES 2 -#define CURL_WANTNO 3 - -#define CURL_EMPTY 0 -#define CURL_OPPOSITE 1 - -/* - * Telnet receiver states for fsm - */ -typedef enum -{ - CURL_TS_DATA = 0, - CURL_TS_IAC, - CURL_TS_WILL, - CURL_TS_WONT, - CURL_TS_DO, - CURL_TS_DONT, - CURL_TS_CR, - CURL_TS_SB, /* sub-option collection */ - CURL_TS_SE /* looking for sub-option end */ -} TelnetReceive; - -struct TELNET { - int please_negotiate; - int already_negotiated; - int us[256]; - int usq[256]; - int us_preferred[256]; - int him[256]; - int himq[256]; - int him_preferred[256]; - int subnegotiation[256]; - char subopt_ttype[32]; /* Set with suboption TTYPE */ - char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */ - unsigned short subopt_wsx; /* Set with suboption NAWS */ - unsigned short subopt_wsy; /* Set with suboption NAWS */ - struct curl_slist *telnet_vars; /* Environment variables */ - - /* suboptions */ - unsigned char subbuffer[SUBBUFSIZE]; - unsigned char *subpointer, *subend; /* buffer for sub-options */ - - TelnetReceive telrcv_state; -}; - - -/* - * TELNET protocol handler. - */ - -const struct Curl_handler Curl_handler_telnet = { - "TELNET", /* scheme */ - ZERO_NULL, /* setup_connection */ - telnet_do, /* do_it */ - telnet_done, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_TELNET, /* defport */ - CURLPROTO_TELNET, /* protocol */ - PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ -}; - - -#ifdef USE_WINSOCK -static CURLcode -check_wsock2(struct SessionHandle *data) -{ - int err; - WORD wVersionRequested; - WSADATA wsaData; - - DEBUGASSERT(data); - - /* telnet requires at least WinSock 2.0 so ask for it. */ - wVersionRequested = MAKEWORD(2, 0); - - err = WSAStartup(wVersionRequested, &wsaData); - - /* We must've called this once already, so this call */ - /* should always succeed. But, just in case... */ - if(err != 0) { - failf(data,"WSAStartup failed (%d)",err); - return CURLE_FAILED_INIT; - } - - /* We have to have a WSACleanup call for every successful */ - /* WSAStartup call. */ - WSACleanup(); - - /* Check that our version is supported */ - if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) || - HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) { - /* Our version isn't supported */ - failf(data, "insufficient winsock version to support " - "telnet"); - return CURLE_FAILED_INIT; - } - - /* Our version is supported */ - return CURLE_OK; -} -#endif - -static -CURLcode init_telnet(struct connectdata *conn) -{ - struct TELNET *tn; - - tn = calloc(1, sizeof(struct TELNET)); - if(!tn) - return CURLE_OUT_OF_MEMORY; - - conn->data->req.protop = tn; /* make us known */ - - tn->telrcv_state = CURL_TS_DATA; - - /* Init suboptions */ - CURL_SB_CLEAR(tn); - - /* Set the options we want by default */ - tn->us_preferred[CURL_TELOPT_SGA] = CURL_YES; - tn->him_preferred[CURL_TELOPT_SGA] = CURL_YES; - - /* To be compliant with previous releases of libcurl - we enable this option by default. This behaviour - can be changed thanks to the "BINARY" option in - CURLOPT_TELNETOPTIONS - */ - tn->us_preferred[CURL_TELOPT_BINARY] = CURL_YES; - tn->him_preferred[CURL_TELOPT_BINARY] = CURL_YES; - - /* We must allow the server to echo what we sent - but it is not necessary to request the server - to do so (it might forces the server to close - the connection). Hence, we ignore ECHO in the - negotiate function - */ - tn->him_preferred[CURL_TELOPT_ECHO] = CURL_YES; - - /* Set the subnegotiation fields to send information - just after negotiation passed (do/will) - - Default values are (0,0) initialized by calloc. - According to the RFC1013 it is valid: - A value equal to zero is acceptable for the width (or height), - and means that no character width (or height) is being sent. - In this case, the width (or height) that will be assumed by the - Telnet server is operating system specific (it will probably be - based upon the terminal type information that may have been sent - using the TERMINAL TYPE Telnet option). */ - tn->subnegotiation[CURL_TELOPT_NAWS] = CURL_YES; - return CURLE_OK; -} - -static void negotiate(struct connectdata *conn) -{ - int i; - struct TELNET *tn = (struct TELNET *) conn->data->req.protop; - - for(i = 0;i < CURL_NTELOPTS;i++) { - if(i==CURL_TELOPT_ECHO) - continue; - - if(tn->us_preferred[i] == CURL_YES) - set_local_option(conn, i, CURL_YES); - - if(tn->him_preferred[i] == CURL_YES) - set_remote_option(conn, i, CURL_YES); - } -} - -#ifndef CURL_DISABLE_VERBOSE_STRINGS -static void printoption(struct SessionHandle *data, - const char *direction, int cmd, int option) -{ - const char *fmt; - const char *opt; - - if(data->set.verbose) { - if(cmd == CURL_IAC) { - if(CURL_TELCMD_OK(option)) - infof(data, "%s IAC %s\n", direction, CURL_TELCMD(option)); - else - infof(data, "%s IAC %d\n", direction, option); - } - else { - fmt = (cmd == CURL_WILL) ? "WILL" : (cmd == CURL_WONT) ? "WONT" : - (cmd == CURL_DO) ? "DO" : (cmd == CURL_DONT) ? "DONT" : 0; - if(fmt) { - if(CURL_TELOPT_OK(option)) - opt = CURL_TELOPT(option); - else if(option == CURL_TELOPT_EXOPL) - opt = "EXOPL"; - else - opt = NULL; - - if(opt) - infof(data, "%s %s %s\n", direction, fmt, opt); - else - infof(data, "%s %s %d\n", direction, fmt, option); - } - else - infof(data, "%s %d %d\n", direction, cmd, option); - } - } -} -#endif - -static void send_negotiation(struct connectdata *conn, int cmd, int option) -{ - unsigned char buf[3]; - ssize_t bytes_written; - int err; - struct SessionHandle *data = conn->data; - - buf[0] = CURL_IAC; - buf[1] = (unsigned char)cmd; - buf[2] = (unsigned char)option; - - bytes_written = swrite(conn->sock[FIRSTSOCKET], buf, 3); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data,"Sending data failed (%d)",err); - } - - printoption(conn->data, "SENT", cmd, option); -} - -static -void set_remote_option(struct connectdata *conn, int option, int newstate) -{ - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - if(newstate == CURL_YES) { - switch(tn->him[option]) { - case CURL_NO: - tn->him[option] = CURL_WANTYES; - send_negotiation(conn, CURL_DO, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Already negotiating for CURL_YES, queue the request */ - tn->himq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - /* Error: already queued an enable request */ - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Error: already negotiating for enable */ - break; - case CURL_OPPOSITE: - tn->himq[option] = CURL_EMPTY; - break; - } - break; - } - } - else { /* NO */ - switch(tn->him[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->him[option] = CURL_WANTNO; - send_negotiation(conn, CURL_DONT, option); - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Already negotiating for NO */ - break; - case CURL_OPPOSITE: - tn->himq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->himq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - break; - } - break; - } - } -} - -static -void rec_will(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - switch(tn->him[option]) { - case CURL_NO: - if(tn->him_preferred[option] == CURL_YES) { - tn->him[option] = CURL_YES; - send_negotiation(conn, CURL_DO, option); - } - else - send_negotiation(conn, CURL_DONT, option); - - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - /* Error: DONT answered by WILL */ - tn->him[option] = CURL_NO; - break; - case CURL_OPPOSITE: - /* Error: DONT answered by WILL */ - tn->him[option] = CURL_YES; - tn->himq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->him[option] = CURL_YES; - break; - case CURL_OPPOSITE: - tn->him[option] = CURL_WANTNO; - tn->himq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_DONT, option); - break; - } - break; - } -} - -static -void rec_wont(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - switch(tn->him[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->him[option] = CURL_NO; - send_negotiation(conn, CURL_DONT, option); - break; - - case CURL_WANTNO: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->him[option] = CURL_NO; - break; - - case CURL_OPPOSITE: - tn->him[option] = CURL_WANTYES; - tn->himq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_DO, option); - break; - } - break; - - case CURL_WANTYES: - switch(tn->himq[option]) { - case CURL_EMPTY: - tn->him[option] = CURL_NO; - break; - case CURL_OPPOSITE: - tn->him[option] = CURL_NO; - tn->himq[option] = CURL_EMPTY; - break; - } - break; - } -} - -static void -set_local_option(struct connectdata *conn, int option, int newstate) -{ - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - if(newstate == CURL_YES) { - switch(tn->us[option]) { - case CURL_NO: - tn->us[option] = CURL_WANTYES; - send_negotiation(conn, CURL_WILL, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Already negotiating for CURL_YES, queue the request */ - tn->usq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - /* Error: already queued an enable request */ - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Error: already negotiating for enable */ - break; - case CURL_OPPOSITE: - tn->usq[option] = CURL_EMPTY; - break; - } - break; - } - } - else { /* NO */ - switch(tn->us[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->us[option] = CURL_WANTNO; - send_negotiation(conn, CURL_WONT, option); - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Already negotiating for NO */ - break; - case CURL_OPPOSITE: - tn->usq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->usq[option] = CURL_OPPOSITE; - break; - case CURL_OPPOSITE: - break; - } - break; - } - } -} - -static -void rec_do(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - switch(tn->us[option]) { - case CURL_NO: - if(tn->us_preferred[option] == CURL_YES) { - tn->us[option] = CURL_YES; - send_negotiation(conn, CURL_WILL, option); - if(tn->subnegotiation[option] == CURL_YES) - /* transmission of data option */ - sendsuboption(conn, option); - } - else if(tn->subnegotiation[option] == CURL_YES) { - /* send information to achieve this option*/ - tn->us[option] = CURL_YES; - send_negotiation(conn, CURL_WILL, option); - sendsuboption(conn, option); - } - else - send_negotiation(conn, CURL_WONT, option); - break; - - case CURL_YES: - /* Already enabled */ - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - /* Error: DONT answered by WILL */ - tn->us[option] = CURL_NO; - break; - case CURL_OPPOSITE: - /* Error: DONT answered by WILL */ - tn->us[option] = CURL_YES; - tn->usq[option] = CURL_EMPTY; - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->us[option] = CURL_YES; - if(tn->subnegotiation[option] == CURL_YES) { - /* transmission of data option */ - sendsuboption(conn, option); - } - break; - case CURL_OPPOSITE: - tn->us[option] = CURL_WANTNO; - tn->himq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_WONT, option); - break; - } - break; - } -} - -static -void rec_dont(struct connectdata *conn, int option) -{ - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - switch(tn->us[option]) { - case CURL_NO: - /* Already disabled */ - break; - - case CURL_YES: - tn->us[option] = CURL_NO; - send_negotiation(conn, CURL_WONT, option); - break; - - case CURL_WANTNO: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->us[option] = CURL_NO; - break; - - case CURL_OPPOSITE: - tn->us[option] = CURL_WANTYES; - tn->usq[option] = CURL_EMPTY; - send_negotiation(conn, CURL_WILL, option); - break; - } - break; - - case CURL_WANTYES: - switch(tn->usq[option]) { - case CURL_EMPTY: - tn->us[option] = CURL_NO; - break; - case CURL_OPPOSITE: - tn->us[option] = CURL_NO; - tn->usq[option] = CURL_EMPTY; - break; - } - break; - } -} - - -static void printsub(struct SessionHandle *data, - int direction, /* '<' or '>' */ - unsigned char *pointer, /* where suboption data is */ - size_t length) /* length of suboption data */ -{ - unsigned int i = 0; - - if(data->set.verbose) { - if(direction) { - infof(data, "%s IAC SB ", (direction == '<')? "RCVD":"SENT"); - if(length >= 3) { - int j; - - i = pointer[length-2]; - j = pointer[length-1]; - - if(i != CURL_IAC || j != CURL_SE) { - infof(data, "(terminated by "); - if(CURL_TELOPT_OK(i)) - infof(data, "%s ", CURL_TELOPT(i)); - else if(CURL_TELCMD_OK(i)) - infof(data, "%s ", CURL_TELCMD(i)); - else - infof(data, "%u ", i); - if(CURL_TELOPT_OK(j)) - infof(data, "%s", CURL_TELOPT(j)); - else if(CURL_TELCMD_OK(j)) - infof(data, "%s", CURL_TELCMD(j)); - else - infof(data, "%d", j); - infof(data, ", not IAC SE!) "); - } - } - length -= 2; - } - if(length < 1) { - infof(data, "(Empty suboption?)"); - return; - } - - if(CURL_TELOPT_OK(pointer[0])) { - switch(pointer[0]) { - case CURL_TELOPT_TTYPE: - case CURL_TELOPT_XDISPLOC: - case CURL_TELOPT_NEW_ENVIRON: - case CURL_TELOPT_NAWS: - infof(data, "%s", CURL_TELOPT(pointer[0])); - break; - default: - infof(data, "%s (unsupported)", CURL_TELOPT(pointer[0])); - break; - } - } - else - infof(data, "%d (unknown)", pointer[i]); - - switch(pointer[0]) { - case CURL_TELOPT_NAWS: - if(length > 4) - infof(data, "Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2], - (pointer[3]<<8) | pointer[4]); - break; - default: - switch(pointer[1]) { - case CURL_TELQUAL_IS: - infof(data, " IS"); - break; - case CURL_TELQUAL_SEND: - infof(data, " SEND"); - break; - case CURL_TELQUAL_INFO: - infof(data, " INFO/REPLY"); - break; - case CURL_TELQUAL_NAME: - infof(data, " NAME"); - break; - } - - switch(pointer[0]) { - case CURL_TELOPT_TTYPE: - case CURL_TELOPT_XDISPLOC: - pointer[length] = 0; - infof(data, " \"%s\"", &pointer[2]); - break; - case CURL_TELOPT_NEW_ENVIRON: - if(pointer[1] == CURL_TELQUAL_IS) { - infof(data, " "); - for(i = 3;i < length;i++) { - switch(pointer[i]) { - case CURL_NEW_ENV_VAR: - infof(data, ", "); - break; - case CURL_NEW_ENV_VALUE: - infof(data, " = "); - break; - default: - infof(data, "%c", pointer[i]); - break; - } - } - } - break; - default: - for(i = 2; i < length; i++) - infof(data, " %.2x", pointer[i]); - break; - } - } - if(direction) - infof(data, "\n"); - } -} - -static CURLcode check_telnet_options(struct connectdata *conn) -{ - struct curl_slist *head; - struct curl_slist *beg; - char option_keyword[128] = ""; - char option_arg[256] = ""; - struct SessionHandle *data = conn->data; - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - CURLcode result = CURLE_OK; - int binary_option; - - /* Add the user name as an environment variable if it - was given on the command line */ - if(conn->bits.user_passwd) { - snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user); - beg = curl_slist_append(tn->telnet_vars, option_arg); - if(!beg) { - curl_slist_free_all(tn->telnet_vars); - tn->telnet_vars = NULL; - return CURLE_OUT_OF_MEMORY; - } - tn->telnet_vars = beg; - tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; - } - - for(head = data->set.telnet_options; head; head=head->next) { - if(sscanf(head->data, "%127[^= ]%*[ =]%255s", - option_keyword, option_arg) == 2) { - - /* Terminal type */ - if(Curl_raw_equal(option_keyword, "TTYPE")) { - strncpy(tn->subopt_ttype, option_arg, 31); - tn->subopt_ttype[31] = 0; /* String termination */ - tn->us_preferred[CURL_TELOPT_TTYPE] = CURL_YES; - continue; - } - - /* Display variable */ - if(Curl_raw_equal(option_keyword, "XDISPLOC")) { - strncpy(tn->subopt_xdisploc, option_arg, 127); - tn->subopt_xdisploc[127] = 0; /* String termination */ - tn->us_preferred[CURL_TELOPT_XDISPLOC] = CURL_YES; - continue; - } - - /* Environment variable */ - if(Curl_raw_equal(option_keyword, "NEW_ENV")) { - beg = curl_slist_append(tn->telnet_vars, option_arg); - if(!beg) { - result = CURLE_OUT_OF_MEMORY; - break; - } - tn->telnet_vars = beg; - tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES; - continue; - } - - /* Window Size */ - if(Curl_raw_equal(option_keyword, "WS")) { - if(sscanf(option_arg, "%hu%*[xX]%hu", - &tn->subopt_wsx, &tn->subopt_wsy) == 2) - tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES; - else { - failf(data, "Syntax error in telnet option: %s", head->data); - result = CURLE_TELNET_OPTION_SYNTAX; - break; - } - continue; - } - - /* To take care or not of the 8th bit in data exchange */ - if(Curl_raw_equal(option_keyword, "BINARY")) { - binary_option=atoi(option_arg); - if(binary_option!=1) { - tn->us_preferred[CURL_TELOPT_BINARY] = CURL_NO; - tn->him_preferred[CURL_TELOPT_BINARY] = CURL_NO; - } - continue; - } - - failf(data, "Unknown telnet option %s", head->data); - result = CURLE_UNKNOWN_TELNET_OPTION; - break; - } - else { - failf(data, "Syntax error in telnet option: %s", head->data); - result = CURLE_TELNET_OPTION_SYNTAX; - break; - } - } - - if(result) { - curl_slist_free_all(tn->telnet_vars); - tn->telnet_vars = NULL; - } - - return result; -} - -/* - * suboption() - * - * Look at the sub-option buffer, and try to be helpful to the other - * side. - */ - -static void suboption(struct connectdata *conn) -{ - struct curl_slist *v; - unsigned char temp[2048]; - ssize_t bytes_written; - size_t len; - size_t tmplen; - int err; - char varname[128] = ""; - char varval[128] = ""; - struct SessionHandle *data = conn->data; - struct TELNET *tn = (struct TELNET *)data->req.protop; - - printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2); - switch (CURL_SB_GET(tn)) { - case CURL_TELOPT_TTYPE: - len = strlen(tn->subopt_ttype) + 4 + 2; - snprintf((char *)temp, sizeof(temp), - "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE, - CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE); - bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data,"Sending data failed (%d)",err); - } - printsub(data, '>', &temp[2], len-2); - break; - case CURL_TELOPT_XDISPLOC: - len = strlen(tn->subopt_xdisploc) + 4 + 2; - snprintf((char *)temp, sizeof(temp), - "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC, - CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE); - bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data,"Sending data failed (%d)",err); - } - printsub(data, '>', &temp[2], len-2); - break; - case CURL_TELOPT_NEW_ENVIRON: - snprintf((char *)temp, sizeof(temp), - "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON, - CURL_TELQUAL_IS); - len = 4; - - for(v = tn->telnet_vars;v;v = v->next) { - tmplen = (strlen(v->data) + 1); - /* Add the variable only if it fits */ - if(len + tmplen < (int)sizeof(temp)-6) { - if(sscanf(v->data, "%127[^,],%127s", varname, varval)) { - snprintf((char *)&temp[len], sizeof(temp) - len, - "%c%s%c%s", CURL_NEW_ENV_VAR, varname, - CURL_NEW_ENV_VALUE, varval); - len += tmplen; - } - } - } - snprintf((char *)&temp[len], sizeof(temp) - len, - "%c%c", CURL_IAC, CURL_SE); - len += 2; - bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data,"Sending data failed (%d)",err); - } - printsub(data, '>', &temp[2], len-2); - break; - } - return; -} - - -/* - * sendsuboption() - * - * Send suboption information to the server side. - */ - -static void sendsuboption(struct connectdata *conn, int option) -{ - ssize_t bytes_written; - int err; - unsigned short x, y; - unsigned char*uc1, *uc2; - - struct SessionHandle *data = conn->data; - struct TELNET *tn = (struct TELNET *)data->req.protop; - - switch (option) { - case CURL_TELOPT_NAWS: - /* We prepare data to be sent */ - CURL_SB_CLEAR(tn); - CURL_SB_ACCUM(tn, CURL_IAC); - CURL_SB_ACCUM(tn, CURL_SB); - CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS); - /* We must deal either with litte or big endien processors */ - /* Window size must be sent according to the 'network order' */ - x=htons(tn->subopt_wsx); - y=htons(tn->subopt_wsy); - uc1 = (unsigned char*)&x; - uc2 = (unsigned char*)&y; - CURL_SB_ACCUM(tn, uc1[0]); - CURL_SB_ACCUM(tn, uc1[1]); - CURL_SB_ACCUM(tn, uc2[0]); - CURL_SB_ACCUM(tn, uc2[1]); - - CURL_SB_ACCUM(tn, CURL_IAC); - CURL_SB_ACCUM(tn, CURL_SE); - CURL_SB_TERM(tn); - /* data suboption is now ready */ - - printsub(data, '>', (unsigned char *)tn->subbuffer+2, - CURL_SB_LEN(tn)-2); - - /* we send the header of the suboption... */ - bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - } - /* ... then the window size with the send_telnet_data() function - to deal with 0xFF cases ... */ - send_telnet_data(conn, (char *)tn->subbuffer+3, 4); - /* ... and the footer */ - bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer+7, 2); - if(bytes_written < 0) { - err = SOCKERRNO; - failf(data, "Sending data failed (%d)", err); - } - break; - } -} - - -static -CURLcode telrcv(struct connectdata *conn, - const unsigned char *inbuf, /* Data received from socket */ - ssize_t count) /* Number of bytes received */ -{ - unsigned char c; - CURLcode result; - int in = 0; - int startwrite=-1; - struct SessionHandle *data = conn->data; - struct TELNET *tn = (struct TELNET *)data->req.protop; - -#define startskipping() \ - if(startwrite >= 0) { \ - result = Curl_client_write(conn, \ - CLIENTWRITE_BODY, \ - (char *)&inbuf[startwrite], \ - in-startwrite); \ - if(result) \ - return result; \ - } \ - startwrite = -1 - -#define writebyte() \ - if(startwrite < 0) \ - startwrite = in - -#define bufferflush() startskipping() - - while(count--) { - c = inbuf[in]; - - switch (tn->telrcv_state) { - case CURL_TS_CR: - tn->telrcv_state = CURL_TS_DATA; - if(c == '\0') { - startskipping(); - break; /* Ignore \0 after CR */ - } - writebyte(); - break; - - case CURL_TS_DATA: - if(c == CURL_IAC) { - tn->telrcv_state = CURL_TS_IAC; - startskipping(); - break; - } - else if(c == '\r') - tn->telrcv_state = CURL_TS_CR; - writebyte(); - break; - - case CURL_TS_IAC: - process_iac: - DEBUGASSERT(startwrite < 0); - switch (c) { - case CURL_WILL: - tn->telrcv_state = CURL_TS_WILL; - break; - case CURL_WONT: - tn->telrcv_state = CURL_TS_WONT; - break; - case CURL_DO: - tn->telrcv_state = CURL_TS_DO; - break; - case CURL_DONT: - tn->telrcv_state = CURL_TS_DONT; - break; - case CURL_SB: - CURL_SB_CLEAR(tn); - tn->telrcv_state = CURL_TS_SB; - break; - case CURL_IAC: - tn->telrcv_state = CURL_TS_DATA; - writebyte(); - break; - case CURL_DM: - case CURL_NOP: - case CURL_GA: - default: - tn->telrcv_state = CURL_TS_DATA; - printoption(data, "RCVD", CURL_IAC, c); - break; - } - break; - - case CURL_TS_WILL: - printoption(data, "RCVD", CURL_WILL, c); - tn->please_negotiate = 1; - rec_will(conn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_WONT: - printoption(data, "RCVD", CURL_WONT, c); - tn->please_negotiate = 1; - rec_wont(conn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_DO: - printoption(data, "RCVD", CURL_DO, c); - tn->please_negotiate = 1; - rec_do(conn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_DONT: - printoption(data, "RCVD", CURL_DONT, c); - tn->please_negotiate = 1; - rec_dont(conn, c); - tn->telrcv_state = CURL_TS_DATA; - break; - - case CURL_TS_SB: - if(c == CURL_IAC) - tn->telrcv_state = CURL_TS_SE; - else - CURL_SB_ACCUM(tn, c); - break; - - case CURL_TS_SE: - if(c != CURL_SE) { - if(c != CURL_IAC) { - /* - * This is an error. We only expect to get "IAC IAC" or "IAC SE". - * Several things may have happened. An IAC was not doubled, the - * IAC SE was left off, or another option got inserted into the - * suboption are all possibilities. If we assume that the IAC was - * not doubled, and really the IAC SE was left off, we could get - * into an infinate loop here. So, instead, we terminate the - * suboption, and process the partial suboption if we can. - */ - CURL_SB_ACCUM(tn, CURL_IAC); - CURL_SB_ACCUM(tn, c); - tn->subpointer -= 2; - CURL_SB_TERM(tn); - - printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c); - suboption(conn); /* handle sub-option */ - tn->telrcv_state = CURL_TS_IAC; - goto process_iac; - } - CURL_SB_ACCUM(tn, c); - tn->telrcv_state = CURL_TS_SB; - } - else - { - CURL_SB_ACCUM(tn, CURL_IAC); - CURL_SB_ACCUM(tn, CURL_SE); - tn->subpointer -= 2; - CURL_SB_TERM(tn); - suboption(conn); /* handle sub-option */ - tn->telrcv_state = CURL_TS_DATA; - } - break; - } - ++in; - } - bufferflush(); - return CURLE_OK; -} - -/* Escape and send a telnet data block */ -/* TODO: write large chunks of data instead of one byte at a time */ -static CURLcode send_telnet_data(struct connectdata *conn, - char *buffer, ssize_t nread) -{ - unsigned char outbuf[2]; - ssize_t bytes_written, total_written; - int out_count; - CURLcode result = CURLE_OK; - - while(!result && nread--) { - outbuf[0] = *buffer++; - out_count = 1; - if(outbuf[0] == CURL_IAC) - outbuf[out_count++] = CURL_IAC; - - total_written = 0; - do { - /* Make sure socket is writable to avoid EWOULDBLOCK condition */ - struct pollfd pfd[1]; - pfd[0].fd = conn->sock[FIRSTSOCKET]; - pfd[0].events = POLLOUT; - switch (Curl_poll(pfd, 1, -1)) { - case -1: /* error, abort writing */ - case 0: /* timeout (will never happen) */ - result = CURLE_SEND_ERROR; - break; - default: /* write! */ - bytes_written = 0; - result = Curl_write(conn, conn->sock[FIRSTSOCKET], - outbuf+total_written, out_count-total_written, - &bytes_written); - total_written += bytes_written; - break; - } - /* handle partial write */ - } while(!result && total_written < out_count); - } - return result; -} - -static CURLcode telnet_done(struct connectdata *conn, - CURLcode status, bool premature) -{ - struct TELNET *tn = (struct TELNET *)conn->data->req.protop; - (void)status; /* unused */ - (void)premature; /* not used */ - - if(!tn) - return CURLE_OK; - - curl_slist_free_all(tn->telnet_vars); - tn->telnet_vars = NULL; - - Curl_safefree(conn->data->req.protop); - - return CURLE_OK; -} - -static CURLcode telnet_do(struct connectdata *conn, bool *done) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; -#ifdef USE_WINSOCK - HMODULE wsock2; - WSOCK2_FUNC close_event_func; - WSOCK2_FUNC create_event_func; - WSOCK2_FUNC event_select_func; - WSOCK2_FUNC enum_netevents_func; - WSAEVENT event_handle; - WSANETWORKEVENTS events; - HANDLE stdin_handle; - HANDLE objs[2]; - DWORD obj_count; - DWORD wait_timeout; - DWORD waitret; - DWORD readfile_read; - int err; -#else - int interval_ms; - struct pollfd pfd[2]; - int poll_cnt; - curl_off_t total_dl = 0; - curl_off_t total_ul = 0; -#endif - ssize_t nread; - struct timeval now; - bool keepon = TRUE; - char *buf = data->state.buffer; - struct TELNET *tn; - - *done = TRUE; /* unconditionally */ - - result = init_telnet(conn); - if(result) - return result; - - tn = (struct TELNET *)data->req.protop; - - result = check_telnet_options(conn); - if(result) - return result; - -#ifdef USE_WINSOCK - /* - ** This functionality only works with WinSock >= 2.0. So, - ** make sure have it. - */ - result = check_wsock2(data); - if(result) - return result; - - /* OK, so we have WinSock 2.0. We need to dynamically */ - /* load ws2_32.dll and get the function pointers we need. */ - wsock2 = Curl_load_library(TEXT("WS2_32.DLL")); - if(wsock2 == NULL) { - failf(data, "failed to load WS2_32.DLL (%d)", ERRNO); - return CURLE_FAILED_INIT; - } - - /* Grab a pointer to WSACreateEvent */ - create_event_func = GetProcAddress(wsock2, "WSACreateEvent"); - if(create_event_func == NULL) { - failf(data, "failed to find WSACreateEvent function (%d)", ERRNO); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSACloseEvent */ - close_event_func = GetProcAddress(wsock2, "WSACloseEvent"); - if(close_event_func == NULL) { - failf(data, "failed to find WSACloseEvent function (%d)", ERRNO); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSAEventSelect */ - event_select_func = GetProcAddress(wsock2, "WSAEventSelect"); - if(event_select_func == NULL) { - failf(data, "failed to find WSAEventSelect function (%d)", ERRNO); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* And WSAEnumNetworkEvents */ - enum_netevents_func = GetProcAddress(wsock2, "WSAEnumNetworkEvents"); - if(enum_netevents_func == NULL) { - failf(data, "failed to find WSAEnumNetworkEvents function (%d)", ERRNO); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* We want to wait for both stdin and the socket. Since - ** the select() function in winsock only works on sockets - ** we have to use the WaitForMultipleObjects() call. - */ - - /* First, create a sockets event object */ - event_handle = (WSAEVENT)create_event_func(); - if(event_handle == WSA_INVALID_EVENT) { - failf(data, "WSACreateEvent failed (%d)", SOCKERRNO); - FreeLibrary(wsock2); - return CURLE_FAILED_INIT; - } - - /* Tell winsock what events we want to listen to */ - if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == - SOCKET_ERROR) { - close_event_func(event_handle); - FreeLibrary(wsock2); - return CURLE_OK; - } - - /* The get the Windows file handle for stdin */ - stdin_handle = GetStdHandle(STD_INPUT_HANDLE); - - /* Create the list of objects to wait for */ - objs[0] = event_handle; - objs[1] = stdin_handle; - - /* If stdin_handle is a pipe, use PeekNamedPipe() method to check it, - else use the old WaitForMultipleObjects() way */ - if(GetFileType(stdin_handle) == FILE_TYPE_PIPE || - data->set.is_fread_set) { - /* Don't wait for stdin_handle, just wait for event_handle */ - obj_count = 1; - /* Check stdin_handle per 100 milliseconds */ - wait_timeout = 100; - } - else { - obj_count = 2; - wait_timeout = 1000; - } - - /* Keep on listening and act on events */ - while(keepon) { - waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout); - switch(waitret) { - case WAIT_TIMEOUT: - { - for(;;) { - if(data->set.is_fread_set) { - /* read from user-supplied method */ - result = (int)data->state.fread_func(buf, 1, BUFSIZE - 1, - data->state.in); - if(result == CURL_READFUNC_ABORT) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - - if(result == CURL_READFUNC_PAUSE) - break; - - if(result == 0) /* no bytes */ - break; - - readfile_read = result; /* fall thru with number of bytes read */ - } - else { - /* read from stdin */ - if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, - &readfile_read, NULL)) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - - if(!readfile_read) - break; - - if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), - &readfile_read, NULL)) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - } - - result = send_telnet_data(conn, buf, readfile_read); - if(result) { - keepon = FALSE; - break; - } - } - } - break; - - case WAIT_OBJECT_0 + 1: - { - if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), - &readfile_read, NULL)) { - keepon = FALSE; - result = CURLE_READ_ERROR; - break; - } - - result = send_telnet_data(conn, buf, readfile_read); - if(result) { - keepon = FALSE; - break; - } - } - break; - - case WAIT_OBJECT_0: - - events.lNetworkEvents = 0; - if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) { - if((err = SOCKERRNO) != EINPROGRESS) { - infof(data, "WSAEnumNetworkEvents failed (%d)", err); - keepon = FALSE; - result = CURLE_READ_ERROR; - } - break; - } - if(events.lNetworkEvents & FD_READ) { - /* read data from network */ - result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); - /* read would've blocked. Loop again */ - if(result == CURLE_AGAIN) - break; - /* returned not-zero, this an error */ - else if(result) { - keepon = FALSE; - break; - } - /* returned zero but actually received 0 or less here, - the server closed the connection and we bail out */ - else if(nread <= 0) { - keepon = FALSE; - break; - } - - result = telrcv(conn, (unsigned char *) buf, nread); - if(result) { - keepon = FALSE; - break; - } - - /* Negotiate if the peer has started negotiating, - otherwise don't. We don't want to speak telnet with - non-telnet servers, like POP or SMTP. */ - if(tn->please_negotiate && !tn->already_negotiated) { - negotiate(conn); - tn->already_negotiated = 1; - } - } - if(events.lNetworkEvents & FD_CLOSE) { - keepon = FALSE; - } - break; - - } - - if(data->set.timeout) { - now = Curl_tvnow(); - if(Curl_tvdiff(now, conn->created) >= data->set.timeout) { - failf(data, "Time-out"); - result = CURLE_OPERATION_TIMEDOUT; - keepon = FALSE; - } - } - } - - /* We called WSACreateEvent, so call WSACloseEvent */ - if(!close_event_func(event_handle)) { - infof(data, "WSACloseEvent failed (%d)", SOCKERRNO); - } - - /* "Forget" pointers into the library we're about to free */ - create_event_func = NULL; - close_event_func = NULL; - event_select_func = NULL; - enum_netevents_func = NULL; - - /* We called LoadLibrary, so call FreeLibrary */ - if(!FreeLibrary(wsock2)) - infof(data, "FreeLibrary(wsock2) failed (%d)", ERRNO); -#else - pfd[0].fd = sockfd; - pfd[0].events = POLLIN; - - if(data->set.is_fread_set) { - poll_cnt = 1; - interval_ms = 100; /* poll user-supplied read function */ - } - else { - /* really using fread, so infile is a FILE* */ - pfd[1].fd = fileno((FILE *)data->state.in); - pfd[1].events = POLLIN; - poll_cnt = 2; - interval_ms = 1 * 1000; - } - - while(keepon) { - switch (Curl_poll(pfd, poll_cnt, interval_ms)) { - case -1: /* error, stop reading */ - keepon = FALSE; - continue; - case 0: /* timeout */ - pfd[0].revents = 0; - pfd[1].revents = 0; - /* fall through */ - default: /* read! */ - if(pfd[0].revents & POLLIN) { - /* read data from network */ - result = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); - /* read would've blocked. Loop again */ - if(result == CURLE_AGAIN) - break; - /* returned not-zero, this an error */ - else if(result) { - keepon = FALSE; - break; - } - /* returned zero but actually received 0 or less here, - the server closed the connection and we bail out */ - else if(nread <= 0) { - keepon = FALSE; - break; - } - - total_dl += nread; - Curl_pgrsSetDownloadCounter(data, total_dl); - result = telrcv(conn, (unsigned char *)buf, nread); - if(result) { - keepon = FALSE; - break; - } - - /* Negotiate if the peer has started negotiating, - otherwise don't. We don't want to speak telnet with - non-telnet servers, like POP or SMTP. */ - if(tn->please_negotiate && !tn->already_negotiated) { - negotiate(conn); - tn->already_negotiated = 1; - } - } - - nread = 0; - if(poll_cnt == 2) { - if(pfd[1].revents & POLLIN) { /* read from in file */ - nread = read(pfd[1].fd, buf, BUFSIZE - 1); - } - } - else { - /* read from user-supplied method */ - nread = (int)data->state.fread_func(buf, 1, BUFSIZE - 1, - data->state.in); - if(nread == CURL_READFUNC_ABORT) { - keepon = FALSE; - break; - } - if(nread == CURL_READFUNC_PAUSE) - break; - } - - if(nread > 0) { - result = send_telnet_data(conn, buf, nread); - if(result) { - keepon = FALSE; - break; - } - total_ul += nread; - Curl_pgrsSetUploadCounter(data, total_ul); - } - else if(nread < 0) - keepon = FALSE; - - break; - } /* poll switch statement */ - - if(data->set.timeout) { - now = Curl_tvnow(); - if(Curl_tvdiff(now, conn->created) >= data->set.timeout) { - failf(data, "Time-out"); - result = CURLE_OPERATION_TIMEDOUT; - keepon = FALSE; - } - } - - if(Curl_pgrsUpdate(conn)) { - result = CURLE_ABORTED_BY_CALLBACK; - break; - } - } -#endif - /* mark this as "no further transfer wanted" */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - - return result; -} -#endif diff --git a/Externals/curl/lib/telnet.h b/Externals/curl/lib/telnet.h deleted file mode 100644 index 419a399b7b..0000000000 --- a/Externals/curl/lib/telnet.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HEADER_CURL_TELNET_H -#define HEADER_CURL_TELNET_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifndef CURL_DISABLE_TELNET -extern const struct Curl_handler Curl_handler_telnet; -#endif - -#endif /* HEADER_CURL_TELNET_H */ - diff --git a/Externals/curl/lib/tftp.c b/Externals/curl/lib/tftp.c deleted file mode 100644 index 3c3eb5e11d..0000000000 --- a/Externals/curl/lib/tftp.c +++ /dev/null @@ -1,1379 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifndef CURL_DISABLE_TFTP - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#include "urldata.h" -#include -#include "transfer.h" -#include "sendf.h" -#include "tftp.h" -#include "progress.h" -#include "connect.h" -#include "strerror.h" -#include "sockaddr.h" /* required for Curl_sockaddr_storage */ -#include "multiif.h" -#include "url.h" -#include "rawstr.h" -#include "speedcheck.h" -#include "select.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* RFC2348 allows the block size to be negotiated */ -#define TFTP_BLKSIZE_DEFAULT 512 -#define TFTP_BLKSIZE_MIN 8 -#define TFTP_BLKSIZE_MAX 65464 -#define TFTP_OPTION_BLKSIZE "blksize" - -/* from RFC2349: */ -#define TFTP_OPTION_TSIZE "tsize" -#define TFTP_OPTION_INTERVAL "timeout" - -typedef enum { - TFTP_MODE_NETASCII=0, - TFTP_MODE_OCTET -} tftp_mode_t; - -typedef enum { - TFTP_STATE_START=0, - TFTP_STATE_RX, - TFTP_STATE_TX, - TFTP_STATE_FIN -} tftp_state_t; - -typedef enum { - TFTP_EVENT_NONE = -1, - TFTP_EVENT_INIT = 0, - TFTP_EVENT_RRQ = 1, - TFTP_EVENT_WRQ = 2, - TFTP_EVENT_DATA = 3, - TFTP_EVENT_ACK = 4, - TFTP_EVENT_ERROR = 5, - TFTP_EVENT_OACK = 6, - TFTP_EVENT_TIMEOUT -} tftp_event_t; - -typedef enum { - TFTP_ERR_UNDEF=0, - TFTP_ERR_NOTFOUND, - TFTP_ERR_PERM, - TFTP_ERR_DISKFULL, - TFTP_ERR_ILLEGAL, - TFTP_ERR_UNKNOWNID, - TFTP_ERR_EXISTS, - TFTP_ERR_NOSUCHUSER, /* This will never be triggered by this code */ - - /* The remaining error codes are internal to curl */ - TFTP_ERR_NONE = -100, - TFTP_ERR_TIMEOUT, - TFTP_ERR_NORESPONSE -} tftp_error_t; - -typedef struct tftp_packet { - unsigned char *data; -} tftp_packet_t; - -typedef struct tftp_state_data { - tftp_state_t state; - tftp_mode_t mode; - tftp_error_t error; - tftp_event_t event; - struct connectdata *conn; - curl_socket_t sockfd; - int retries; - int retry_time; - int retry_max; - time_t start_time; - time_t max_time; - time_t rx_time; - unsigned short block; - struct Curl_sockaddr_storage local_addr; - struct Curl_sockaddr_storage remote_addr; - curl_socklen_t remote_addrlen; - int rbytes; - int sbytes; - int blksize; - int requested_blksize; - tftp_packet_t rpacket; - tftp_packet_t spacket; -} tftp_state_data_t; - - -/* Forward declarations */ -static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event); -static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event); -static CURLcode tftp_connect(struct connectdata *conn, bool *done); -static CURLcode tftp_disconnect(struct connectdata *conn, - bool dead_connection); -static CURLcode tftp_do(struct connectdata *conn, bool *done); -static CURLcode tftp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode tftp_setup_connection(struct connectdata * conn); -static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done); -static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done); -static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks); -static CURLcode tftp_translate_code(tftp_error_t error); - - -/* - * TFTP protocol handler. - */ - -const struct Curl_handler Curl_handler_tftp = { - "TFTP", /* scheme */ - tftp_setup_connection, /* setup_connection */ - tftp_do, /* do_it */ - tftp_done, /* done */ - ZERO_NULL, /* do_more */ - tftp_connect, /* connect_it */ - tftp_multi_statemach, /* connecting */ - tftp_doing, /* doing */ - tftp_getsock, /* proto_getsock */ - tftp_getsock, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - tftp_disconnect, /* disconnect */ - ZERO_NULL, /* readwrite */ - PORT_TFTP, /* defport */ - CURLPROTO_TFTP, /* protocol */ - PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */ -}; - -/********************************************************** - * - * tftp_set_timeouts - - * - * Set timeouts based on state machine state. - * Use user provided connect timeouts until DATA or ACK - * packet is received, then use user-provided transfer timeouts - * - * - **********************************************************/ -static CURLcode tftp_set_timeouts(tftp_state_data_t *state) -{ - time_t maxtime, timeout; - long timeout_ms; - bool start = (state->state == TFTP_STATE_START) ? TRUE : FALSE; - - time(&state->start_time); - - /* Compute drop-dead time */ - timeout_ms = Curl_timeleft(state->conn->data, NULL, start); - - if(timeout_ms < 0) { - /* time-out, bail out, go home */ - failf(state->conn->data, "Connection time-out"); - return CURLE_OPERATION_TIMEDOUT; - } - - if(start) { - - maxtime = (time_t)(timeout_ms + 500) / 1000; - state->max_time = state->start_time+maxtime; - - /* Set per-block timeout to total */ - timeout = maxtime; - - /* Average restart after 5 seconds */ - state->retry_max = (int)timeout/5; - - if(state->retry_max < 1) - /* avoid division by zero below */ - state->retry_max = 1; - - /* Compute the re-start interval to suit the timeout */ - state->retry_time = (int)timeout/state->retry_max; - if(state->retry_time<1) - state->retry_time=1; - - } - else { - if(timeout_ms > 0) - maxtime = (time_t)(timeout_ms + 500) / 1000; - else - maxtime = 3600; - - state->max_time = state->start_time+maxtime; - - /* Set per-block timeout to total */ - timeout = maxtime; - - /* Average reposting an ACK after 5 seconds */ - state->retry_max = (int)timeout/5; - } - /* But bound the total number */ - if(state->retry_max<3) - state->retry_max=3; - - if(state->retry_max>50) - state->retry_max=50; - - /* Compute the re-ACK interval to suit the timeout */ - state->retry_time = (int)(timeout/state->retry_max); - if(state->retry_time<1) - state->retry_time=1; - - infof(state->conn->data, - "set timeouts for state %d; Total %ld, retry %d maxtry %d\n", - (int)state->state, (long)(state->max_time-state->start_time), - state->retry_time, state->retry_max); - - /* init RX time */ - time(&state->rx_time); - - return CURLE_OK; -} - -/********************************************************** - * - * tftp_set_send_first - * - * Event handler for the START state - * - **********************************************************/ - -static void setpacketevent(tftp_packet_t *packet, unsigned short num) -{ - packet->data[0] = (unsigned char)(num >> 8); - packet->data[1] = (unsigned char)(num & 0xff); -} - - -static void setpacketblock(tftp_packet_t *packet, unsigned short num) -{ - packet->data[2] = (unsigned char)(num >> 8); - packet->data[3] = (unsigned char)(num & 0xff); -} - -static unsigned short getrpacketevent(const tftp_packet_t *packet) -{ - return (unsigned short)((packet->data[0] << 8) | packet->data[1]); -} - -static unsigned short getrpacketblock(const tftp_packet_t *packet) -{ - return (unsigned short)((packet->data[2] << 8) | packet->data[3]); -} - -static size_t Curl_strnlen(const char *string, size_t maxlen) -{ - const char *end = memchr (string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} - -static const char *tftp_option_get(const char *buf, size_t len, - const char **option, const char **value) -{ - size_t loc; - - loc = Curl_strnlen(buf, len); - loc++; /* NULL term */ - - if(loc >= len) - return NULL; - *option = buf; - - loc += Curl_strnlen(buf+loc, len-loc); - loc++; /* NULL term */ - - if(loc > len) - return NULL; - *value = &buf[strlen(*option) + 1]; - - return &buf[loc]; -} - -static CURLcode tftp_parse_option_ack(tftp_state_data_t *state, - const char *ptr, int len) -{ - const char *tmp = ptr; - struct SessionHandle *data = state->conn->data; - - /* if OACK doesn't contain blksize option, the default (512) must be used */ - state->blksize = TFTP_BLKSIZE_DEFAULT; - - while(tmp < ptr + len) { - const char *option, *value; - - tmp = tftp_option_get(tmp, ptr + len - tmp, &option, &value); - if(tmp == NULL) { - failf(data, "Malformed ACK packet, rejecting"); - return CURLE_TFTP_ILLEGAL; - } - - infof(data, "got option=(%s) value=(%s)\n", option, value); - - if(checkprefix(option, TFTP_OPTION_BLKSIZE)) { - long blksize; - - blksize = strtol(value, NULL, 10); - - if(!blksize) { - failf(data, "invalid blocksize value in OACK packet"); - return CURLE_TFTP_ILLEGAL; - } - else if(blksize > TFTP_BLKSIZE_MAX) { - failf(data, "%s (%d)", "blksize is larger than max supported", - TFTP_BLKSIZE_MAX); - return CURLE_TFTP_ILLEGAL; - } - else if(blksize < TFTP_BLKSIZE_MIN) { - failf(data, "%s (%d)", "blksize is smaller than min supported", - TFTP_BLKSIZE_MIN); - return CURLE_TFTP_ILLEGAL; - } - else if(blksize > state->requested_blksize) { - /* could realloc pkt buffers here, but the spec doesn't call out - * support for the server requesting a bigger blksize than the client - * requests */ - failf(data, "%s (%ld)", - "server requested blksize larger than allocated", blksize); - return CURLE_TFTP_ILLEGAL; - } - - state->blksize = (int)blksize; - infof(data, "%s (%d) %s (%d)\n", "blksize parsed from OACK", - state->blksize, "requested", state->requested_blksize); - } - else if(checkprefix(option, TFTP_OPTION_TSIZE)) { - long tsize = 0; - - tsize = strtol(value, NULL, 10); - infof(data, "%s (%ld)\n", "tsize parsed from OACK", tsize); - - /* tsize should be ignored on upload: Who cares about the size of the - remote file? */ - if(!data->set.upload) { - if(!tsize) { - failf(data, "invalid tsize -:%s:- value in OACK packet", value); - return CURLE_TFTP_ILLEGAL; - } - Curl_pgrsSetDownloadSize(data, tsize); - } - } - } - - return CURLE_OK; -} - -static size_t tftp_option_add(tftp_state_data_t *state, size_t csize, - char *buf, const char *option) -{ - if(( strlen(option) + csize + 1) > (size_t)state->blksize) - return 0; - strcpy(buf, option); - return strlen(option) + 1; -} - -static CURLcode tftp_connect_for_tx(tftp_state_data_t *state, - tftp_event_t event) -{ - CURLcode result; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - struct SessionHandle *data = state->conn->data; - - infof(data, "%s\n", "Connected for transmit"); -#endif - state->state = TFTP_STATE_TX; - result = tftp_set_timeouts(state); - if(result) - return result; - return tftp_tx(state, event); -} - -static CURLcode tftp_connect_for_rx(tftp_state_data_t *state, - tftp_event_t event) -{ - CURLcode result; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - struct SessionHandle *data = state->conn->data; - - infof(data, "%s\n", "Connected for receive"); -#endif - state->state = TFTP_STATE_RX; - result = tftp_set_timeouts(state); - if(result) - return result; - return tftp_rx(state, event); -} - -static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event) -{ - size_t sbytes; - ssize_t senddata; - const char *mode = "octet"; - char *filename; - char buf[64]; - struct SessionHandle *data = state->conn->data; - CURLcode result = CURLE_OK; - - /* Set ascii mode if -B flag was used */ - if(data->set.prefer_ascii) - mode = "netascii"; - - switch(event) { - - case TFTP_EVENT_INIT: /* Send the first packet out */ - case TFTP_EVENT_TIMEOUT: /* Resend the first packet out */ - /* Increment the retry counter, quit if over the limit */ - state->retries++; - if(state->retries>state->retry_max) { - state->error = TFTP_ERR_NORESPONSE; - state->state = TFTP_STATE_FIN; - return result; - } - - if(data->set.upload) { - /* If we are uploading, send an WRQ */ - setpacketevent(&state->spacket, TFTP_EVENT_WRQ); - state->conn->data->req.upload_fromhere = - (char *)state->spacket.data+4; - if(data->state.infilesize != -1) - Curl_pgrsSetUploadSize(data, data->state.infilesize); - } - else { - /* If we are downloading, send an RRQ */ - setpacketevent(&state->spacket, TFTP_EVENT_RRQ); - } - /* As RFC3617 describes the separator slash is not actually part of the - file name so we skip the always-present first letter of the path - string. */ - filename = curl_easy_unescape(data, &state->conn->data->state.path[1], 0, - NULL); - if(!filename) - return CURLE_OUT_OF_MEMORY; - - snprintf((char *)state->spacket.data+2, - state->blksize, - "%s%c%s%c", filename, '\0', mode, '\0'); - sbytes = 4 + strlen(filename) + strlen(mode); - - /* optional addition of TFTP options */ - if(!data->set.tftp_no_options) { - /* add tsize option */ - if(data->set.upload && (data->state.infilesize != -1)) - snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T, - data->state.infilesize); - else - strcpy(buf, "0"); /* the destination is large enough */ - - sbytes += tftp_option_add(state, sbytes, - (char *)state->spacket.data+sbytes, - TFTP_OPTION_TSIZE); - sbytes += tftp_option_add(state, sbytes, - (char *)state->spacket.data+sbytes, buf); - /* add blksize option */ - snprintf(buf, sizeof(buf), "%d", state->requested_blksize); - sbytes += tftp_option_add(state, sbytes, - (char *)state->spacket.data+sbytes, - TFTP_OPTION_BLKSIZE); - sbytes += tftp_option_add(state, sbytes, - (char *)state->spacket.data+sbytes, buf); - - /* add timeout option */ - snprintf(buf, sizeof(buf), "%d", state->retry_time); - sbytes += tftp_option_add(state, sbytes, - (char *)state->spacket.data+sbytes, - TFTP_OPTION_INTERVAL); - sbytes += tftp_option_add(state, sbytes, - (char *)state->spacket.data+sbytes, buf); - } - - /* the typecase for the 3rd argument is mostly for systems that do - not have a size_t argument, like older unixes that want an 'int' */ - senddata = sendto(state->sockfd, (void *)state->spacket.data, - (SEND_TYPE_ARG3)sbytes, 0, - state->conn->ip_addr->ai_addr, - state->conn->ip_addr->ai_addrlen); - if(senddata != (ssize_t)sbytes) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); - } - free(filename); - break; - - case TFTP_EVENT_OACK: - if(data->set.upload) { - result = tftp_connect_for_tx(state, event); - } - else { - result = tftp_connect_for_rx(state, event); - } - break; - - case TFTP_EVENT_ACK: /* Connected for transmit */ - result = tftp_connect_for_tx(state, event); - break; - - case TFTP_EVENT_DATA: /* Connected for receive */ - result = tftp_connect_for_rx(state, event); - break; - - case TFTP_EVENT_ERROR: - state->state = TFTP_STATE_FIN; - break; - - default: - failf(state->conn->data, "tftp_send_first: internal error"); - break; - } - - return result; -} - -/* the next blocknum is x + 1 but it needs to wrap at an unsigned 16bit - boundary */ -#define NEXT_BLOCKNUM(x) (((x)+1)&0xffff) - -/********************************************************** - * - * tftp_rx - * - * Event handler for the RX state - * - **********************************************************/ -static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) -{ - ssize_t sbytes; - int rblock; - struct SessionHandle *data = state->conn->data; - - switch(event) { - - case TFTP_EVENT_DATA: - /* Is this the block we expect? */ - rblock = getrpacketblock(&state->rpacket); - if(NEXT_BLOCKNUM(state->block) == rblock) { - /* This is the expected block. Reset counters and ACK it. */ - state->retries = 0; - } - else if(state->block == rblock) { - /* This is the last recently received block again. Log it and ACK it - again. */ - infof(data, "Received last DATA packet block %d again.\n", rblock); - } - else { - /* totally unexpected, just log it */ - infof(data, - "Received unexpected DATA packet block %d, expecting block %d\n", - rblock, NEXT_BLOCKNUM(state->block)); - break; - } - - /* ACK this block. */ - state->block = (unsigned short)rblock; - setpacketevent(&state->spacket, TFTP_EVENT_ACK); - setpacketblock(&state->spacket, state->block); - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - if(sbytes < 0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); - return CURLE_SEND_ERROR; - } - - /* Check if completed (That is, a less than full packet is received) */ - if(state->rbytes < (ssize_t)state->blksize+4) { - state->state = TFTP_STATE_FIN; - } - else { - state->state = TFTP_STATE_RX; - } - time(&state->rx_time); - break; - - case TFTP_EVENT_OACK: - /* ACK option acknowledgement so we can move on to data */ - state->block = 0; - state->retries = 0; - setpacketevent(&state->spacket, TFTP_EVENT_ACK); - setpacketblock(&state->spacket, state->block); - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - if(sbytes < 0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); - return CURLE_SEND_ERROR; - } - - /* we're ready to RX data */ - state->state = TFTP_STATE_RX; - time(&state->rx_time); - break; - - case TFTP_EVENT_TIMEOUT: - /* Increment the retry count and fail if over the limit */ - state->retries++; - infof(data, - "Timeout waiting for block %d ACK. Retries = %d\n", - NEXT_BLOCKNUM(state->block), state->retries); - if(state->retries > state->retry_max) { - state->error = TFTP_ERR_TIMEOUT; - state->state = TFTP_STATE_FIN; - } - else { - /* Resend the previous ACK */ - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); - return CURLE_SEND_ERROR; - } - } - break; - - case TFTP_EVENT_ERROR: - setpacketevent(&state->spacket, TFTP_EVENT_ERROR); - setpacketblock(&state->spacket, state->block); - (void)sendto(state->sockfd, (void *)state->spacket.data, - 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* don't bother with the return code, but if the socket is still up we - * should be a good TFTP client and let the server know we're done */ - state->state = TFTP_STATE_FIN; - break; - - default: - failf(data, "%s", "tftp_rx: internal error"); - return CURLE_TFTP_ILLEGAL; /* not really the perfect return code for - this */ - } - return CURLE_OK; -} - -/********************************************************** - * - * tftp_tx - * - * Event handler for the TX state - * - **********************************************************/ -static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) -{ - struct SessionHandle *data = state->conn->data; - ssize_t sbytes; - int rblock; - CURLcode result = CURLE_OK; - struct SingleRequest *k = &data->req; - - switch(event) { - - case TFTP_EVENT_ACK: - case TFTP_EVENT_OACK: - if(event == TFTP_EVENT_ACK) { - /* Ack the packet */ - rblock = getrpacketblock(&state->rpacket); - - if(rblock != state->block && - /* There's a bug in tftpd-hpa that causes it to send us an ack for - * 65535 when the block number wraps to 0. So when we're expecting - * 0, also accept 65535. See - * http://syslinux.zytor.com/archives/2010-September/015253.html - * */ - !(state->block == 0 && rblock == 65535)) { - /* This isn't the expected block. Log it and up the retry counter */ - infof(data, "Received ACK for block %d, expecting %d\n", - rblock, state->block); - state->retries++; - /* Bail out if over the maximum */ - if(state->retries>state->retry_max) { - failf(data, "tftp_tx: giving up waiting for block %d ack", - state->block); - result = CURLE_SEND_ERROR; - } - else { - /* Re-send the data packet */ - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4+state->sbytes, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* Check all sbytes were sent */ - if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); - result = CURLE_SEND_ERROR; - } - } - - return result; - } - /* This is the expected packet. Reset the counters and send the next - block */ - time(&state->rx_time); - state->block++; - } - else - state->block = 1; /* first data block is 1 when using OACK */ - - state->retries = 0; - setpacketevent(&state->spacket, TFTP_EVENT_DATA); - setpacketblock(&state->spacket, state->block); - if(state->block > 1 && state->sbytes < (int)state->blksize) { - state->state = TFTP_STATE_FIN; - return CURLE_OK; - } - - result = Curl_fillreadbuffer(state->conn, state->blksize, &state->sbytes); - if(result) - return result; - - sbytes = sendto(state->sockfd, (void *) state->spacket.data, - 4 + state->sbytes, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* Check all sbytes were sent */ - if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); - return CURLE_SEND_ERROR; - } - /* Update the progress meter */ - k->writebytecount += state->sbytes; - Curl_pgrsSetUploadCounter(data, k->writebytecount); - break; - - case TFTP_EVENT_TIMEOUT: - /* Increment the retry counter and log the timeout */ - state->retries++; - infof(data, "Timeout waiting for block %d ACK. " - " Retries = %d\n", NEXT_BLOCKNUM(state->block), state->retries); - /* Decide if we've had enough */ - if(state->retries > state->retry_max) { - state->error = TFTP_ERR_TIMEOUT; - state->state = TFTP_STATE_FIN; - } - else { - /* Re-send the data packet */ - sbytes = sendto(state->sockfd, (void *)state->spacket.data, - 4+state->sbytes, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* Check all sbytes were sent */ - if(sbytes<0) { - failf(data, "%s", Curl_strerror(state->conn, SOCKERRNO)); - return CURLE_SEND_ERROR; - } - /* since this was a re-send, we remain at the still byte position */ - Curl_pgrsSetUploadCounter(data, k->writebytecount); - } - break; - - case TFTP_EVENT_ERROR: - state->state = TFTP_STATE_FIN; - setpacketevent(&state->spacket, TFTP_EVENT_ERROR); - setpacketblock(&state->spacket, state->block); - (void)sendto(state->sockfd, (void *)state->spacket.data, 4, SEND_4TH_ARG, - (struct sockaddr *)&state->remote_addr, - state->remote_addrlen); - /* don't bother with the return code, but if the socket is still up we - * should be a good TFTP client and let the server know we're done */ - state->state = TFTP_STATE_FIN; - break; - - default: - failf(data, "tftp_tx: internal error, event: %i", (int)(event)); - break; - } - - return result; -} - -/********************************************************** - * - * tftp_translate_code - * - * Translate internal error codes to CURL error codes - * - **********************************************************/ -static CURLcode tftp_translate_code(tftp_error_t error) -{ - CURLcode result = CURLE_OK; - - if(error != TFTP_ERR_NONE) { - switch(error) { - case TFTP_ERR_NOTFOUND: - result = CURLE_TFTP_NOTFOUND; - break; - case TFTP_ERR_PERM: - result = CURLE_TFTP_PERM; - break; - case TFTP_ERR_DISKFULL: - result = CURLE_REMOTE_DISK_FULL; - break; - case TFTP_ERR_UNDEF: - case TFTP_ERR_ILLEGAL: - result = CURLE_TFTP_ILLEGAL; - break; - case TFTP_ERR_UNKNOWNID: - result = CURLE_TFTP_UNKNOWNID; - break; - case TFTP_ERR_EXISTS: - result = CURLE_REMOTE_FILE_EXISTS; - break; - case TFTP_ERR_NOSUCHUSER: - result = CURLE_TFTP_NOSUCHUSER; - break; - case TFTP_ERR_TIMEOUT: - result = CURLE_OPERATION_TIMEDOUT; - break; - case TFTP_ERR_NORESPONSE: - result = CURLE_COULDNT_CONNECT; - break; - default: - result = CURLE_ABORTED_BY_CALLBACK; - break; - } - } - else - result = CURLE_OK; - - return result; -} - -/********************************************************** - * - * tftp_state_machine - * - * The tftp state machine event dispatcher - * - **********************************************************/ -static CURLcode tftp_state_machine(tftp_state_data_t *state, - tftp_event_t event) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = state->conn->data; - - switch(state->state) { - case TFTP_STATE_START: - DEBUGF(infof(data, "TFTP_STATE_START\n")); - result = tftp_send_first(state, event); - break; - case TFTP_STATE_RX: - DEBUGF(infof(data, "TFTP_STATE_RX\n")); - result = tftp_rx(state, event); - break; - case TFTP_STATE_TX: - DEBUGF(infof(data, "TFTP_STATE_TX\n")); - result = tftp_tx(state, event); - break; - case TFTP_STATE_FIN: - infof(data, "%s\n", "TFTP finished"); - break; - default: - DEBUGF(infof(data, "STATE: %d\n", state->state)); - failf(data, "%s", "Internal state machine error"); - result = CURLE_TFTP_ILLEGAL; - break; - } - - return result; -} - -/********************************************************** - * - * tftp_disconnect - * - * The disconnect callback - * - **********************************************************/ -static CURLcode tftp_disconnect(struct connectdata *conn, bool dead_connection) -{ - tftp_state_data_t *state = conn->proto.tftpc; - (void) dead_connection; - - /* done, free dynamically allocated pkt buffers */ - if(state) { - Curl_safefree(state->rpacket.data); - Curl_safefree(state->spacket.data); - free(state); - } - - return CURLE_OK; -} - -/********************************************************** - * - * tftp_connect - * - * The connect callback - * - **********************************************************/ -static CURLcode tftp_connect(struct connectdata *conn, bool *done) -{ - tftp_state_data_t *state; - int blksize, rc; - - blksize = TFTP_BLKSIZE_DEFAULT; - - state = conn->proto.tftpc = calloc(1, sizeof(tftp_state_data_t)); - if(!state) - return CURLE_OUT_OF_MEMORY; - - /* alloc pkt buffers based on specified blksize */ - if(conn->data->set.tftp_blksize) { - blksize = (int)conn->data->set.tftp_blksize; - if(blksize > TFTP_BLKSIZE_MAX || blksize < TFTP_BLKSIZE_MIN) - return CURLE_TFTP_ILLEGAL; - } - - if(!state->rpacket.data) { - state->rpacket.data = calloc(1, blksize + 2 + 2); - - if(!state->rpacket.data) - return CURLE_OUT_OF_MEMORY; - } - - if(!state->spacket.data) { - state->spacket.data = calloc(1, blksize + 2 + 2); - - if(!state->spacket.data) - return CURLE_OUT_OF_MEMORY; - } - - /* we don't keep TFTP connections up basically because there's none or very - * little gain for UDP */ - connclose(conn, "TFTP"); - - state->conn = conn; - state->sockfd = state->conn->sock[FIRSTSOCKET]; - state->state = TFTP_STATE_START; - state->error = TFTP_ERR_NONE; - state->blksize = TFTP_BLKSIZE_DEFAULT; - state->requested_blksize = blksize; - - ((struct sockaddr *)&state->local_addr)->sa_family = - (unsigned short)(conn->ip_addr->ai_family); - - tftp_set_timeouts(state); - - if(!conn->bits.bound) { - /* If not already bound, bind to any interface, random UDP port. If it is - * reused or a custom local port was desired, this has already been done! - * - * We once used the size of the local_addr struct as the third argument - * for bind() to better work with IPv6 or whatever size the struct could - * have, but we learned that at least Tru64, AIX and IRIX *requires* the - * size of that argument to match the exact size of a 'sockaddr_in' struct - * when running IPv4-only. - * - * Therefore we use the size from the address we connected to, which we - * assume uses the same IP version and thus hopefully this works for both - * IPv4 and IPv6... - */ - rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr, - conn->ip_addr->ai_addrlen); - if(rc) { - failf(conn->data, "bind() failed; %s", - Curl_strerror(conn, SOCKERRNO)); - return CURLE_COULDNT_CONNECT; - } - conn->bits.bound = TRUE; - } - - Curl_pgrsStartNow(conn->data); - - *done = TRUE; - - return CURLE_OK; -} - -/********************************************************** - * - * tftp_done - * - * The done callback - * - **********************************************************/ -static CURLcode tftp_done(struct connectdata *conn, CURLcode status, - bool premature) -{ - CURLcode result = CURLE_OK; - tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; - - (void)status; /* unused */ - (void)premature; /* not used */ - - if(Curl_pgrsDone(conn)) - return CURLE_ABORTED_BY_CALLBACK; - - /* If we have encountered an error */ - if(state) - result = tftp_translate_code(state->error); - - return result; -} - -/********************************************************** - * - * tftp_getsock - * - * The getsock callback - * - **********************************************************/ -static int tftp_getsock(struct connectdata *conn, curl_socket_t *socks, - int numsocks) -{ - if(!numsocks) - return GETSOCK_BLANK; - - socks[0] = conn->sock[FIRSTSOCKET]; - - return GETSOCK_READSOCK(0); -} - -/********************************************************** - * - * tftp_receive_packet - * - * Called once select fires and data is ready on the socket - * - **********************************************************/ -static CURLcode tftp_receive_packet(struct connectdata *conn) -{ - struct Curl_sockaddr_storage fromaddr; - curl_socklen_t fromlen; - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; - struct SingleRequest *k = &data->req; - - /* Receive the packet */ - fromlen = sizeof(fromaddr); - state->rbytes = (int)recvfrom(state->sockfd, - (void *)state->rpacket.data, - state->blksize+4, - 0, - (struct sockaddr *)&fromaddr, - &fromlen); - if(state->remote_addrlen==0) { - memcpy(&state->remote_addr, &fromaddr, fromlen); - state->remote_addrlen = fromlen; - } - - /* Sanity check packet length */ - if(state->rbytes < 4) { - failf(data, "Received too short packet"); - /* Not a timeout, but how best to handle it? */ - state->event = TFTP_EVENT_TIMEOUT; - } - else { - /* The event is given by the TFTP packet time */ - state->event = (tftp_event_t)getrpacketevent(&state->rpacket); - - switch(state->event) { - case TFTP_EVENT_DATA: - /* Don't pass to the client empty or retransmitted packets */ - if(state->rbytes > 4 && - (NEXT_BLOCKNUM(state->block) == getrpacketblock(&state->rpacket))) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, - (char *)state->rpacket.data+4, - state->rbytes-4); - if(result) { - tftp_state_machine(state, TFTP_EVENT_ERROR); - return result; - } - k->bytecount += state->rbytes-4; - Curl_pgrsSetDownloadCounter(data, (curl_off_t) k->bytecount); - } - break; - case TFTP_EVENT_ERROR: - state->error = (tftp_error_t)getrpacketblock(&state->rpacket); - infof(data, "%s\n", (const char *)state->rpacket.data+4); - break; - case TFTP_EVENT_ACK: - break; - case TFTP_EVENT_OACK: - result = tftp_parse_option_ack(state, - (const char *)state->rpacket.data+2, - state->rbytes-2); - if(result) - return result; - break; - case TFTP_EVENT_RRQ: - case TFTP_EVENT_WRQ: - default: - failf(data, "%s", "Internal error: Unexpected packet"); - break; - } - - /* Update the progress meter */ - if(Curl_pgrsUpdate(conn)) { - tftp_state_machine(state, TFTP_EVENT_ERROR); - return CURLE_ABORTED_BY_CALLBACK; - } - } - return result; -} - -/********************************************************** - * - * tftp_state_timeout - * - * Check if timeouts have been reached - * - **********************************************************/ -static long tftp_state_timeout(struct connectdata *conn, tftp_event_t *event) -{ - time_t current; - tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; - - if(event) - *event = TFTP_EVENT_NONE; - - time(¤t); - if(current > state->max_time) { - DEBUGF(infof(conn->data, "timeout: %ld > %ld\n", - (long)current, (long)state->max_time)); - state->error = TFTP_ERR_TIMEOUT; - state->state = TFTP_STATE_FIN; - return 0; - } - else if(current > state->rx_time+state->retry_time) { - if(event) - *event = TFTP_EVENT_TIMEOUT; - time(&state->rx_time); /* update even though we received nothing */ - } - - /* there's a typecast below here since 'time_t' may in fact be larger than - 'long', but we estimate that a 'long' will still be able to hold number - of seconds even if "only" 32 bit */ - return (long)(state->max_time - current); -} - -/********************************************************** - * - * tftp_multi_statemach - * - * Handle single RX socket event and return - * - **********************************************************/ -static CURLcode tftp_multi_statemach(struct connectdata *conn, bool *done) -{ - int rc; - tftp_event_t event; - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; - long timeout_ms = tftp_state_timeout(conn, &event); - - *done = FALSE; - - if(timeout_ms <= 0) { - failf(data, "TFTP response timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - else if(event != TFTP_EVENT_NONE) { - result = tftp_state_machine(state, event); - if(result) - return result; - *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; - if(*done) - /* Tell curl we're done */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - } - else { - /* no timeouts to handle, check our socket */ - rc = Curl_socket_ready(state->sockfd, CURL_SOCKET_BAD, 0); - - if(rc == -1) { - /* bail out */ - int error = SOCKERRNO; - failf(data, "%s", Curl_strerror(conn, error)); - state->event = TFTP_EVENT_ERROR; - } - else if(rc != 0) { - result = tftp_receive_packet(conn); - if(result) - return result; - result = tftp_state_machine(state, state->event); - if(result) - return result; - *done = (state->state == TFTP_STATE_FIN) ? TRUE : FALSE; - if(*done) - /* Tell curl we're done */ - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL); - } - /* if rc == 0, then select() timed out */ - } - - return result; -} - -/********************************************************** - * - * tftp_doing - * - * Called from multi.c while DOing - * - **********************************************************/ -static CURLcode tftp_doing(struct connectdata *conn, bool *dophase_done) -{ - CURLcode result; - result = tftp_multi_statemach(conn, dophase_done); - - if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); - } - else if(!result) { - /* The multi code doesn't have this logic for the DOING state so we - provide it for TFTP since it may do the entire transfer in this - state. */ - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - else - result = Curl_speedcheck(conn->data, Curl_tvnow()); - } - return result; -} - -/********************************************************** - * - * tftp_peform - * - * Entry point for transfer from tftp_do, sarts state mach - * - **********************************************************/ -static CURLcode tftp_perform(struct connectdata *conn, bool *dophase_done) -{ - CURLcode result = CURLE_OK; - tftp_state_data_t *state = (tftp_state_data_t *)conn->proto.tftpc; - - *dophase_done = FALSE; - - result = tftp_state_machine(state, TFTP_EVENT_INIT); - - if((state->state == TFTP_STATE_FIN) || result) - return result; - - tftp_multi_statemach(conn, dophase_done); - - if(*dophase_done) - DEBUGF(infof(conn->data, "DO phase is complete\n")); - - return result; -} - - -/********************************************************** - * - * tftp_do - * - * The do callback - * - * This callback initiates the TFTP transfer - * - **********************************************************/ - -static CURLcode tftp_do(struct connectdata *conn, bool *done) -{ - tftp_state_data_t *state; - CURLcode result; - - *done = FALSE; - - if(!conn->proto.tftpc) { - result = tftp_connect(conn, done); - if(result) - return result; - } - - state = (tftp_state_data_t *)conn->proto.tftpc; - if(!state) - return CURLE_BAD_CALLING_ORDER; - - result = tftp_perform(conn, done); - - /* If tftp_perform() returned an error, use that for return code. If it - was OK, see if tftp_translate_code() has an error. */ - if(!result) - /* If we have encountered an internal tftp error, translate it. */ - result = tftp_translate_code(state->error); - - return result; -} - -static CURLcode tftp_setup_connection(struct connectdata * conn) -{ - struct SessionHandle *data = conn->data; - char * type; - char command; - - conn->socktype = SOCK_DGRAM; /* UDP datagram based */ - - /* TFTP URLs support an extension like ";mode=" that - * we'll try to get now! */ - type = strstr(data->state.path, ";mode="); - - if(!type) - type = strstr(conn->host.rawalloc, ";mode="); - - if(type) { - *type = 0; /* it was in the middle of the hostname */ - command = Curl_raw_toupper(type[6]); - - switch (command) { - case 'A': /* ASCII mode */ - case 'N': /* NETASCII mode */ - data->set.prefer_ascii = TRUE; - break; - - case 'O': /* octet mode */ - case 'I': /* binary mode */ - default: - /* switch off ASCII */ - data->set.prefer_ascii = FALSE; - break; - } - } - - return CURLE_OK; -} -#endif diff --git a/Externals/curl/lib/tftp.h b/Externals/curl/lib/tftp.h deleted file mode 100644 index c2325b2327..0000000000 --- a/Externals/curl/lib/tftp.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef HEADER_CURL_TFTP_H -#define HEADER_CURL_TFTP_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifndef CURL_DISABLE_TFTP -extern const struct Curl_handler Curl_handler_tftp; -#endif - -#endif /* HEADER_CURL_TFTP_H */ - diff --git a/Externals/curl/lib/timeval.c b/Externals/curl/lib/timeval.c deleted file mode 100644 index 629f1c8f07..0000000000 --- a/Externals/curl/lib/timeval.c +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "timeval.h" - -#if defined(WIN32) && !defined(MSDOS) - -struct timeval curlx_tvnow(void) -{ - /* - ** GetTickCount() is available on _all_ Windows versions from W95 up - ** to nowadays. Returns milliseconds elapsed since last system boot, - ** increases monotonically and wraps once 49.7 days have elapsed. - */ - struct timeval now; -#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_VISTA) || \ - (_WIN32_WINNT < _WIN32_WINNT_VISTA) - DWORD milliseconds = GetTickCount(); - now.tv_sec = milliseconds / 1000; - now.tv_usec = (milliseconds % 1000) * 1000; -#else - ULONGLONG milliseconds = GetTickCount64(); - now.tv_sec = (long) (milliseconds / 1000); - now.tv_usec = (long) (milliseconds % 1000) * 1000; -#endif - - return now; -} - -#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) - -struct timeval curlx_tvnow(void) -{ - /* - ** clock_gettime() is granted to be increased monotonically when the - ** monotonic clock is queried. Time starting point is unspecified, it - ** could be the system start-up time, the Epoch, or something else, - ** in any case the time starting point does not change once that the - ** system has started up. - */ - struct timeval now; - struct timespec tsnow; - if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { - now.tv_sec = tsnow.tv_sec; - now.tv_usec = tsnow.tv_nsec / 1000; - } - /* - ** Even when the configure process has truly detected monotonic clock - ** availability, it might happen that it is not actually available at - ** run-time. When this occurs simply fallback to other time source. - */ -#ifdef HAVE_GETTIMEOFDAY - else - (void)gettimeofday(&now, NULL); -#else - else { - now.tv_sec = (long)time(NULL); - now.tv_usec = 0; - } -#endif - return now; -} - -#elif defined(HAVE_GETTIMEOFDAY) - -struct timeval curlx_tvnow(void) -{ - /* - ** gettimeofday() is not granted to be increased monotonically, due to - ** clock drifting and external source time synchronization it can jump - ** forward or backward in time. - */ - struct timeval now; - (void)gettimeofday(&now, NULL); - return now; -} - -#else - -struct timeval curlx_tvnow(void) -{ - /* - ** time() returns the value of time in seconds since the Epoch. - */ - struct timeval now; - now.tv_sec = (long)time(NULL); - now.tv_usec = 0; - return now; -} - -#endif - -/* - * Make sure that the first argument is the more recent time, as otherwise - * we'll get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds. For large diffs it - * returns 0x7fffffff on 32bit time_t systems. - */ -long curlx_tvdiff(struct timeval newer, struct timeval older) -{ -#if SIZEOF_TIME_T < 8 - /* for 32bit time_t systems, add a precaution to avoid overflow for really - big time differences */ - time_t diff = newer.tv_sec-older.tv_sec; - if(diff >= (0x7fffffff/1000)) - return 0x7fffffff; -#endif - return (newer.tv_sec-older.tv_sec)*1000+ - (long)(newer.tv_usec-older.tv_usec)/1000; -} - -/* - * Same as curlx_tvdiff but with full usec resolution. - * - * Returns: the time difference in seconds with subsecond resolution. - */ -double curlx_tvdiff_secs(struct timeval newer, struct timeval older) -{ - if(newer.tv_sec != older.tv_sec) - return (double)(newer.tv_sec-older.tv_sec)+ - (double)(newer.tv_usec-older.tv_usec)/1000000.0; - else - return (double)(newer.tv_usec-older.tv_usec)/1000000.0; -} - -/* return the number of seconds in the given input timeval struct */ -long Curl_tvlong(struct timeval t1) -{ - return t1.tv_sec; -} diff --git a/Externals/curl/lib/timeval.h b/Externals/curl/lib/timeval.h deleted file mode 100644 index 50c31a252c..0000000000 --- a/Externals/curl/lib/timeval.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef HEADER_CURL_TIMEVAL_H -#define HEADER_CURL_TIMEVAL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * CAUTION: this header is designed to work when included by the app-side - * as well as the library. Do not mix with library internals! - */ - -#include "curl_setup.h" - -struct timeval curlx_tvnow(void); - -/* - * Make sure that the first argument (t1) is the more recent time and t2 is - * the older time, as otherwise you get a weird negative time-diff back... - * - * Returns: the time difference in number of milliseconds. - */ -long curlx_tvdiff(struct timeval t1, struct timeval t2); - -/* - * Same as curlx_tvdiff but with full usec resolution. - * - * Returns: the time difference in seconds with subsecond resolution. - */ -double curlx_tvdiff_secs(struct timeval t1, struct timeval t2); - -long Curl_tvlong(struct timeval t1); - -/* These two defines below exist to provide the older API for library - internals only. */ -#define Curl_tvnow() curlx_tvnow() -#define Curl_tvdiff(x,y) curlx_tvdiff(x,y) -#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y) - -#endif /* HEADER_CURL_TIMEVAL_H */ - diff --git a/Externals/curl/lib/transfer.c b/Externals/curl/lib/transfer.c deleted file mode 100644 index 4a12ee9a3f..0000000000 --- a/Externals/curl/lib/transfer.c +++ /dev/null @@ -1,1993 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "strtoofft.h" -#include "strequal.h" -#include "rawstr.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_SIGNAL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -#ifndef HAVE_SOCKET -#error "We can't compile without socket() support!" -#endif - -#include "urldata.h" -#include -#include "netrc.h" - -#include "content_encoding.h" -#include "hostip.h" -#include "transfer.h" -#include "sendf.h" -#include "speedcheck.h" -#include "progress.h" -#include "http.h" -#include "url.h" -#include "getinfo.h" -#include "vtls/vtls.h" -#include "select.h" -#include "multiif.h" -#include "connect.h" -#include "non-ascii.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* - * This function will call the read callback to fill our buffer with data - * to upload. - */ -CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp) -{ - struct SessionHandle *data = conn->data; - size_t buffersize = (size_t)bytes; - int nread; -#ifdef CURL_DOES_CONVERSIONS - bool sending_http_headers = FALSE; - - if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) { - const struct HTTP *http = data->req.protop; - - if(http->sending == HTTPSEND_REQUEST) - /* We're sending the HTTP request headers, not the data. - Remember that so we don't re-translate them into garbage. */ - sending_http_headers = TRUE; - } -#endif - - if(data->req.upload_chunky) { - /* if chunked Transfer-Encoding */ - buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */ - data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */ - } - - /* this function returns a size_t, so we typecast to int to prevent warnings - with picky compilers */ - nread = (int)data->state.fread_func(data->req.upload_fromhere, 1, - buffersize, data->state.in); - - if(nread == CURL_READFUNC_ABORT) { - failf(data, "operation aborted by callback"); - *nreadp = 0; - return CURLE_ABORTED_BY_CALLBACK; - } - else if(nread == CURL_READFUNC_PAUSE) { - - if(conn->handler->flags & PROTOPT_NONETWORK) { - /* protocols that work without network cannot be paused. This is - actually only FILE:// just now, and it can't pause since the transfer - isn't done using the "normal" procedure. */ - failf(data, "Read callback asked for PAUSE when not supported!"); - return CURLE_READ_ERROR; - } - else { - struct SingleRequest *k = &data->req; - /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ - k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ - if(data->req.upload_chunky) { - /* Back out the preallocation done above */ - data->req.upload_fromhere -= (8 + 2); - } - *nreadp = 0; - } - return CURLE_OK; /* nothing was read */ - } - else if((size_t)nread > buffersize) { - /* the read function returned a too large value */ - *nreadp = 0; - failf(data, "read function returned funny value"); - return CURLE_READ_ERROR; - } - - if(!data->req.forbidchunk && data->req.upload_chunky) { - /* if chunked Transfer-Encoding - * build chunk: - * - * CRLF - * CRLF - */ - /* On non-ASCII platforms the may or may not be - translated based on set.prefer_ascii while the protocol - portion must always be translated to the network encoding. - To further complicate matters, line end conversion might be - done later on, so we need to prevent CRLFs from becoming - CRCRLFs if that's the case. To do this we use bare LFs - here, knowing they'll become CRLFs later on. - */ - - char hexbuffer[11]; - const char *endofline_native; - const char *endofline_network; - int hexlen; - - if( -#ifdef CURL_DO_LINEEND_CONV - (data->set.prefer_ascii) || -#endif - (data->set.crlf)) { - /* \n will become \r\n later on */ - endofline_native = "\n"; - endofline_network = "\x0a"; - } - else { - endofline_native = "\r\n"; - endofline_network = "\x0d\x0a"; - } - hexlen = snprintf(hexbuffer, sizeof(hexbuffer), - "%x%s", nread, endofline_native); - - /* move buffer pointer */ - data->req.upload_fromhere -= hexlen; - nread += hexlen; - - /* copy the prefix to the buffer, leaving out the NUL */ - memcpy(data->req.upload_fromhere, hexbuffer, hexlen); - - /* always append ASCII CRLF to the data */ - memcpy(data->req.upload_fromhere + nread, - endofline_network, - strlen(endofline_network)); - -#ifdef CURL_DOES_CONVERSIONS - CURLcode result; - int length; - if(data->set.prefer_ascii) { - /* translate the protocol and data */ - length = nread; - } - else { - /* just translate the protocol portion */ - length = strlen(hexbuffer); - } - result = Curl_convert_to_network(data, data->req.upload_fromhere, length); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) - return result; -#endif /* CURL_DOES_CONVERSIONS */ - - if((nread - hexlen) == 0) - /* mark this as done once this chunk is transferred */ - data->req.upload_done = TRUE; - - nread+=(int)strlen(endofline_native); /* for the added end of line */ - } -#ifdef CURL_DOES_CONVERSIONS - else if((data->set.prefer_ascii) && (!sending_http_headers)) { - CURLcode result; - result = Curl_convert_to_network(data, data->req.upload_fromhere, nread); - /* Curl_convert_to_network calls failf if unsuccessful */ - if(result) - return result; - } -#endif /* CURL_DOES_CONVERSIONS */ - - *nreadp = nread; - - return CURLE_OK; -} - - -/* - * Curl_readrewind() rewinds the read stream. This is typically used for HTTP - * POST/PUT with multi-pass authentication when a sending was denied and a - * resend is necessary. - */ -CURLcode Curl_readrewind(struct connectdata *conn) -{ - struct SessionHandle *data = conn->data; - - conn->bits.rewindaftersend = FALSE; /* we rewind now */ - - /* explicitly switch off sending data on this connection now since we are - about to restart a new transfer and thus we want to avoid inadvertently - sending more data on the existing connection until the next transfer - starts */ - data->req.keepon &= ~KEEP_SEND; - - /* We have sent away data. If not using CURLOPT_POSTFIELDS or - CURLOPT_HTTPPOST, call app to rewind - */ - if(data->set.postfields || - (data->set.httpreq == HTTPREQ_POST_FORM)) - ; /* do nothing */ - else { - if(data->set.seek_func) { - int err; - - err = (data->set.seek_func)(data->set.seek_client, 0, SEEK_SET); - if(err) { - failf(data, "seek callback returned error %d", (int)err); - return CURLE_SEND_FAIL_REWIND; - } - } - else if(data->set.ioctl_func) { - curlioerr err; - - err = (data->set.ioctl_func)(data, CURLIOCMD_RESTARTREAD, - data->set.ioctl_client); - infof(data, "the ioctl callback returned %d\n", (int)err); - - if(err) { - /* FIXME: convert to a human readable error message */ - failf(data, "ioctl callback returned error %d", (int)err); - return CURLE_SEND_FAIL_REWIND; - } - } - else { - /* If no CURLOPT_READFUNCTION is used, we know that we operate on a - given FILE * stream and we can actually attempt to rewind that - ourselves with fseek() */ - if(data->state.fread_func == (curl_read_callback)fread) { - if(-1 != fseek(data->state.in, 0, SEEK_SET)) - /* successful rewind */ - return CURLE_OK; - } - - /* no callback set or failure above, makes us fail at once */ - failf(data, "necessary data rewind wasn't possible"); - return CURLE_SEND_FAIL_REWIND; - } - } - return CURLE_OK; -} - -static int data_pending(const struct connectdata *conn) -{ - /* in the case of libssh2, we can never be really sure that we have emptied - its internal buffers so we MUST always try until we get EAGAIN back */ - return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || -#if defined(USE_NGHTTP2) - Curl_ssl_data_pending(conn, FIRSTSOCKET) || - /* For HTTP/2, we may read up everything including responde body - with header fields in Curl_http_readwrite_headers. If no - content-length is provided, curl waits for the connection - close, which we emulate it using conn->proto.httpc.closed = - TRUE. The thing is if we read everything, then http2_recv won't - be called and we cannot signal the HTTP/2 stream has closed. As - a workaround, we return nonzero here to call http2_recv. */ - ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion == 20); -#else - Curl_ssl_data_pending(conn, FIRSTSOCKET); -#endif -} - -static void read_rewind(struct connectdata *conn, - size_t thismuch) -{ - DEBUGASSERT(conn->read_pos >= thismuch); - - conn->read_pos -= thismuch; - conn->bits.stream_was_rewound = TRUE; - -#ifdef DEBUGBUILD - { - char buf[512 + 1]; - size_t show; - - show = CURLMIN(conn->buf_len - conn->read_pos, sizeof(buf)-1); - if(conn->master_buffer) { - memcpy(buf, conn->master_buffer + conn->read_pos, show); - buf[show] = '\0'; - } - else { - buf[0] = '\0'; - } - - DEBUGF(infof(conn->data, - "Buffer after stream rewind (read_pos = %zu): [%s]\n", - conn->read_pos, buf)); - } -#endif -} - -/* - * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the - * remote document with the time provided by CURLOPT_TIMEVAL - */ -bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc) -{ - if((timeofdoc == 0) || (data->set.timevalue == 0)) - return TRUE; - - switch(data->set.timecondition) { - case CURL_TIMECOND_IFMODSINCE: - default: - if(timeofdoc <= data->set.timevalue) { - infof(data, - "The requested document is not new enough\n"); - data->info.timecond = TRUE; - return FALSE; - } - break; - case CURL_TIMECOND_IFUNMODSINCE: - if(timeofdoc >= data->set.timevalue) { - infof(data, - "The requested document is not old enough\n"); - data->info.timecond = TRUE; - return FALSE; - } - break; - } - - return TRUE; -} - -/* - * Go ahead and do a read if we have a readable socket or if - * the stream was rewound (in which case we have data in a - * buffer) - */ -static CURLcode readwrite_data(struct SessionHandle *data, - struct connectdata *conn, - struct SingleRequest *k, - int *didwhat, bool *done) -{ - CURLcode result = CURLE_OK; - ssize_t nread; /* number of bytes read */ - size_t excess = 0; /* excess bytes read */ - bool is_empty_data = FALSE; - bool readmore = FALSE; /* used by RTP to signal for more data */ - int maxloops = 100; - - *done = FALSE; - - /* This is where we loop until we have read everything there is to - read or we get a CURLE_AGAIN */ - do { - size_t buffersize = data->set.buffer_size? - data->set.buffer_size : BUFSIZE; - size_t bytestoread = buffersize; - - if( -#if defined(USE_NGHTTP2) - /* For HTTP/2, read data without caring about the content - length. This is safe because body in HTTP/2 is always - segmented thanks to its framing layer. Meanwhile, we have to - call Curl_read to ensure that http2_handle_stream_close is - called when we read all incoming bytes for a particular - stream. */ - !((conn->handler->protocol & PROTO_FAMILY_HTTP) && - conn->httpversion == 20) && -#endif - k->size != -1 && !k->header) { - /* make sure we don't read "too much" if we can help it since we - might be pipelining and then someone else might want to read what - follows! */ - curl_off_t totalleft = k->size - k->bytecount; - if(totalleft < (curl_off_t)bytestoread) - bytestoread = (size_t)totalleft; - } - - if(bytestoread) { - /* receive data from the network! */ - result = Curl_read(conn, conn->sockfd, k->buf, bytestoread, &nread); - - /* read would've blocked */ - if(CURLE_AGAIN == result) - break; /* get out of loop */ - - if(result>0) - return result; - } - else { - /* read nothing but since we wanted nothing we consider this an OK - situation to proceed from */ - DEBUGF(infof(data, "readwrite_data: we're done!\n")); - nread = 0; - } - - if((k->bytecount == 0) && (k->writebytecount == 0)) { - Curl_pgrsTime(data, TIMER_STARTTRANSFER); - if(k->exp100 > EXP100_SEND_DATA) - /* set time stamp to compare with when waiting for the 100 */ - k->start100 = Curl_tvnow(); - } - - *didwhat |= KEEP_RECV; - /* indicates data of zero size, i.e. empty file */ - is_empty_data = ((nread == 0) && (k->bodywrites == 0)) ? TRUE : FALSE; - - /* NUL terminate, allowing string ops to be used */ - if(0 < nread || is_empty_data) { - k->buf[nread] = 0; - } - else if(0 >= nread) { - /* if we receive 0 or less here, the server closed the connection - and we bail out from this! */ - DEBUGF(infof(data, "nread <= 0, server closed connection, bailing\n")); - k->keepon &= ~KEEP_RECV; - break; - } - - /* Default buffer to use when we write the buffer, it may be changed - in the flow below before the actual storing is done. */ - k->str = k->buf; - - if(conn->handler->readwrite) { - result = conn->handler->readwrite(data, conn, &nread, &readmore); - if(result) - return result; - if(readmore) - break; - } - -#ifndef CURL_DISABLE_HTTP - /* Since this is a two-state thing, we check if we are parsing - headers at the moment or not. */ - if(k->header) { - /* we are in parse-the-header-mode */ - bool stop_reading = FALSE; - result = Curl_http_readwrite_headers(data, conn, &nread, &stop_reading); - if(result) - return result; - - if(conn->handler->readwrite && - (k->maxdownload <= 0 && nread > 0)) { - result = conn->handler->readwrite(data, conn, &nread, &readmore); - if(result) - return result; - if(readmore) - break; - } - - if(stop_reading) { - /* We've stopped dealing with input, get out of the do-while loop */ - - if(nread > 0) { - if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) { - infof(data, - "Rewinding stream by : %zd" - " bytes on url %s (zero-length body)\n", - nread, data->state.path); - read_rewind(conn, (size_t)nread); - } - else { - infof(data, - "Excess found in a non pipelined read:" - " excess = %zd" - " url = %s (zero-length body)\n", - nread, data->state.path); - } - } - - break; - } - } -#endif /* CURL_DISABLE_HTTP */ - - - /* This is not an 'else if' since it may be a rest from the header - parsing, where the beginning of the buffer is headers and the end - is non-headers. */ - if(k->str && !k->header && (nread > 0 || is_empty_data)) { - -#ifndef CURL_DISABLE_HTTP - if(0 == k->bodywrites && !is_empty_data) { - /* These checks are only made the first time we are about to - write a piece of the body */ - if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) { - /* HTTP-only checks */ - - if(data->req.newurl) { - if(conn->bits.close) { - /* Abort after the headers if "follow Location" is set - and we're set to close anyway. */ - k->keepon &= ~KEEP_RECV; - *done = TRUE; - return CURLE_OK; - } - /* We have a new url to load, but since we want to be able - to re-use this connection properly, we read the full - response in "ignore more" */ - k->ignorebody = TRUE; - infof(data, "Ignoring the response-body\n"); - } - if(data->state.resume_from && !k->content_range && - (data->set.httpreq==HTTPREQ_GET) && - !k->ignorebody) { - - if(k->size == data->state.resume_from) { - /* The resume point is at the end of file, consider this fine - even if it doesn't allow resume from here. */ - infof(data, "The entire document is already downloaded"); - connclose(conn, "already downloaded"); - /* Abort download */ - k->keepon &= ~KEEP_RECV; - *done = TRUE; - return CURLE_OK; - } - - /* we wanted to resume a download, although the server doesn't - * seem to support this and we did this with a GET (if it - * wasn't a GET we did a POST or PUT resume) */ - failf(data, "HTTP server doesn't seem to support " - "byte ranges. Cannot resume."); - return CURLE_RANGE_ERROR; - } - - if(data->set.timecondition && !data->state.range) { - /* A time condition has been set AND no ranges have been - requested. This seems to be what chapter 13.3.4 of - RFC 2616 defines to be the correct action for a - HTTP/1.1 client */ - - if(!Curl_meets_timecondition(data, k->timeofdoc)) { - *done = TRUE; - /* We're simulating a http 304 from server so we return - what should have been returned from the server */ - data->info.httpcode = 304; - infof(data, "Simulate a HTTP 304 response!\n"); - /* we abort the transfer before it is completed == we ruin the - re-use ability. Close the connection */ - connclose(conn, "Simulated 304 handling"); - return CURLE_OK; - } - } /* we have a time condition */ - - } /* this is HTTP or RTSP */ - } /* this is the first time we write a body part */ -#endif /* CURL_DISABLE_HTTP */ - - k->bodywrites++; - - /* pass data to the debug function before it gets "dechunked" */ - if(data->set.verbose) { - if(k->badheader) { - Curl_debug(data, CURLINFO_DATA_IN, data->state.headerbuff, - (size_t)k->hbuflen, conn); - if(k->badheader == HEADER_PARTHEADER) - Curl_debug(data, CURLINFO_DATA_IN, - k->str, (size_t)nread, conn); - } - else - Curl_debug(data, CURLINFO_DATA_IN, - k->str, (size_t)nread, conn); - } - -#ifndef CURL_DISABLE_HTTP - if(k->chunk) { - /* - * Here comes a chunked transfer flying and we need to decode this - * properly. While the name says read, this function both reads - * and writes away the data. The returned 'nread' holds the number - * of actual data it wrote to the client. - */ - - CHUNKcode res = - Curl_httpchunk_read(conn, k->str, nread, &nread); - - if(CHUNKE_OK < res) { - if(CHUNKE_WRITE_ERROR == res) { - failf(data, "Failed writing data"); - return CURLE_WRITE_ERROR; - } - failf(data, "%s in chunked-encoding", Curl_chunked_strerror(res)); - return CURLE_RECV_ERROR; - } - else if(CHUNKE_STOP == res) { - size_t dataleft; - /* we're done reading chunks! */ - k->keepon &= ~KEEP_RECV; /* read no more */ - - /* There are now possibly N number of bytes at the end of the - str buffer that weren't written to the client. - - We DO care about this data if we are pipelining. - Push it back to be read on the next pass. */ - - dataleft = conn->chunk.dataleft; - if(dataleft != 0) { - infof(conn->data, "Leftovers after chunking: %zu bytes\n", - dataleft); - if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) { - /* only attempt the rewind if we truly are pipelining */ - infof(conn->data, "Rewinding %zu bytes\n",dataleft); - read_rewind(conn, dataleft); - } - } - } - /* If it returned OK, we just keep going */ - } -#endif /* CURL_DISABLE_HTTP */ - - /* Account for body content stored in the header buffer */ - if(k->badheader && !k->ignorebody) { - DEBUGF(infof(data, "Increasing bytecount by %zu from hbuflen\n", - k->hbuflen)); - k->bytecount += k->hbuflen; - } - - if((-1 != k->maxdownload) && - (k->bytecount + nread >= k->maxdownload)) { - - excess = (size_t)(k->bytecount + nread - k->maxdownload); - if(excess > 0 && !k->ignorebody) { - if(Curl_pipeline_wanted(conn->data->multi, CURLPIPE_HTTP1)) { - /* The 'excess' amount below can't be more than BUFSIZE which - always will fit in a size_t */ - infof(data, - "Rewinding stream by : %zu" - " bytes on url %s (size = %" CURL_FORMAT_CURL_OFF_T - ", maxdownload = %" CURL_FORMAT_CURL_OFF_T - ", bytecount = %" CURL_FORMAT_CURL_OFF_T ", nread = %zd)\n", - excess, data->state.path, - k->size, k->maxdownload, k->bytecount, nread); - read_rewind(conn, excess); - } - else { - infof(data, - "Excess found in a non pipelined read:" - " excess = %zu" - ", size = %" CURL_FORMAT_CURL_OFF_T - ", maxdownload = %" CURL_FORMAT_CURL_OFF_T - ", bytecount = %" CURL_FORMAT_CURL_OFF_T "\n", - excess, k->size, k->maxdownload, k->bytecount); - } - } - - nread = (ssize_t) (k->maxdownload - k->bytecount); - if(nread < 0) /* this should be unusual */ - nread = 0; - - k->keepon &= ~KEEP_RECV; /* we're done reading */ - } - - k->bytecount += nread; - - Curl_pgrsSetDownloadCounter(data, k->bytecount); - - if(!k->chunk && (nread || k->badheader || is_empty_data)) { - /* If this is chunky transfer, it was already written */ - - if(k->badheader && !k->ignorebody) { - /* we parsed a piece of data wrongly assuming it was a header - and now we output it as body instead */ - - /* Don't let excess data pollute body writes */ - if(k->maxdownload == -1 || (curl_off_t)k->hbuflen <= k->maxdownload) - result = Curl_client_write(conn, CLIENTWRITE_BODY, - data->state.headerbuff, - k->hbuflen); - else - result = Curl_client_write(conn, CLIENTWRITE_BODY, - data->state.headerbuff, - (size_t)k->maxdownload); - - if(result) - return result; - } - if(k->badheader < HEADER_ALLBAD) { - /* This switch handles various content encodings. If there's an - error here, be sure to check over the almost identical code - in http_chunks.c. - Make sure that ALL_CONTENT_ENCODINGS contains all the - encodings handled here. */ -#ifdef HAVE_LIBZ - switch (conn->data->set.http_ce_skip ? - IDENTITY : k->auto_decoding) { - case IDENTITY: -#endif - /* This is the default when the server sends no - Content-Encoding header. See Curl_readwrite_init; the - memset() call initializes k->auto_decoding to zero. */ - if(!k->ignorebody) { - -#ifndef CURL_DISABLE_POP3 - if(conn->handler->protocol&PROTO_FAMILY_POP3) - result = Curl_pop3_write(conn, k->str, nread); - else -#endif /* CURL_DISABLE_POP3 */ - - result = Curl_client_write(conn, CLIENTWRITE_BODY, k->str, - nread); - } -#ifdef HAVE_LIBZ - break; - - case DEFLATE: - /* Assume CLIENTWRITE_BODY; headers are not encoded. */ - if(!k->ignorebody) - result = Curl_unencode_deflate_write(conn, k, nread); - break; - - case GZIP: - /* Assume CLIENTWRITE_BODY; headers are not encoded. */ - if(!k->ignorebody) - result = Curl_unencode_gzip_write(conn, k, nread); - break; - - default: - failf (data, "Unrecognized content encoding type. " - "libcurl understands `identity', `deflate' and `gzip' " - "content encodings."); - result = CURLE_BAD_CONTENT_ENCODING; - break; - } -#endif - } - k->badheader = HEADER_NORMAL; /* taken care of now */ - - if(result) - return result; - } - - } /* if(!header and data to read) */ - - if(conn->handler->readwrite && - (excess > 0 && !conn->bits.stream_was_rewound)) { - /* Parse the excess data */ - k->str += nread; - nread = (ssize_t)excess; - - result = conn->handler->readwrite(data, conn, &nread, &readmore); - if(result) - return result; - - if(readmore) - k->keepon |= KEEP_RECV; /* we're not done reading */ - break; - } - - if(is_empty_data) { - /* if we received nothing, the server closed the connection and we - are done */ - k->keepon &= ~KEEP_RECV; - } - - } while(data_pending(conn) && maxloops--); - - if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) && - conn->bits.close) { - /* When we've read the entire thing and the close bit is set, the server - may now close the connection. If there's now any kind of sending going - on from our side, we need to stop that immediately. */ - infof(data, "we are done reading and this is set to close, stop send\n"); - k->keepon &= ~KEEP_SEND; /* no writing anymore either */ - } - - return CURLE_OK; -} - -static CURLcode done_sending(struct connectdata *conn, - struct SingleRequest *k) -{ - k->keepon &= ~KEEP_SEND; /* we're done writing */ - - if(conn->bits.rewindaftersend) { - CURLcode result = Curl_readrewind(conn); - if(result) - return result; - } - return CURLE_OK; -} - - -/* - * Send data to upload to the server, when the socket is writable. - */ -static CURLcode readwrite_upload(struct SessionHandle *data, - struct connectdata *conn, - struct SingleRequest *k, - int *didwhat) -{ - ssize_t i, si; - ssize_t bytes_written; - CURLcode result; - ssize_t nread; /* number of bytes read */ - bool sending_http_headers = FALSE; - - if((k->bytecount == 0) && (k->writebytecount == 0)) - Curl_pgrsTime(data, TIMER_STARTTRANSFER); - - *didwhat |= KEEP_SEND; - - do { - - /* only read more data if there's no upload data already - present in the upload buffer */ - if(0 == data->req.upload_present) { - /* init the "upload from here" pointer */ - data->req.upload_fromhere = k->uploadbuf; - - if(!k->upload_done) { - /* HTTP pollution, this should be written nicer to become more - protocol agnostic. */ - int fillcount; - struct HTTP *http = data->req.protop; - - if((k->exp100 == EXP100_SENDING_REQUEST) && - (http->sending == HTTPSEND_BODY)) { - /* If this call is to send body data, we must take some action: - We have sent off the full HTTP 1.1 request, and we shall now - go into the Expect: 100 state and await such a header */ - k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */ - k->keepon &= ~KEEP_SEND; /* disable writing */ - k->start100 = Curl_tvnow(); /* timeout count starts now */ - *didwhat &= ~KEEP_SEND; /* we didn't write anything actually */ - - /* set a timeout for the multi interface */ - Curl_expire(data, data->set.expect_100_timeout); - break; - } - - if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) { - if(http->sending == HTTPSEND_REQUEST) - /* We're sending the HTTP request headers, not the data. - Remember that so we don't change the line endings. */ - sending_http_headers = TRUE; - else - sending_http_headers = FALSE; - } - - result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount); - if(result) - return result; - - nread = (ssize_t)fillcount; - } - else - nread = 0; /* we're done uploading/reading */ - - if(!nread && (k->keepon & KEEP_SEND_PAUSE)) { - /* this is a paused transfer */ - break; - } - else if(nread<=0) { - result = done_sending(conn, k); - if(result) - return result; - break; - } - - /* store number of bytes available for upload */ - data->req.upload_present = nread; - - /* convert LF to CRLF if so asked */ - if((!sending_http_headers) && ( -#ifdef CURL_DO_LINEEND_CONV - /* always convert if we're FTPing in ASCII mode */ - (data->set.prefer_ascii) || -#endif - (data->set.crlf))) { - /* Do we need to allocate a scratch buffer? */ - if(!data->state.scratch) { - data->state.scratch = malloc(2 * BUFSIZE); - if(!data->state.scratch) { - failf(data, "Failed to alloc scratch buffer!"); - - return CURLE_OUT_OF_MEMORY; - } - } - - /* - * ASCII/EBCDIC Note: This is presumably a text (not binary) - * transfer so the data should already be in ASCII. - * That means the hex values for ASCII CR (0x0d) & LF (0x0a) - * must be used instead of the escape sequences \r & \n. - */ - for(i = 0, si = 0; i < nread; i++, si++) { - if(data->req.upload_fromhere[i] == 0x0a) { - data->state.scratch[si++] = 0x0d; - data->state.scratch[si] = 0x0a; - if(!data->set.crlf) { - /* we're here only because FTP is in ASCII mode... - bump infilesize for the LF we just added */ - if(data->state.infilesize != -1) - data->state.infilesize++; - } - } - else - data->state.scratch[si] = data->req.upload_fromhere[i]; - } - - if(si != nread) { - /* only perform the special operation if we really did replace - anything */ - nread = si; - - /* upload from the new (replaced) buffer instead */ - data->req.upload_fromhere = data->state.scratch; - - /* set the new amount too */ - data->req.upload_present = nread; - } - } - -#ifndef CURL_DISABLE_SMTP - if(conn->handler->protocol & PROTO_FAMILY_SMTP) { - result = Curl_smtp_escape_eob(conn, nread); - if(result) - return result; - } -#endif /* CURL_DISABLE_SMTP */ - } /* if 0 == data->req.upload_present */ - else { - /* We have a partial buffer left from a previous "round". Use - that instead of reading more data */ - } - - /* write to socket (send away data) */ - result = Curl_write(conn, - conn->writesockfd, /* socket to send to */ - data->req.upload_fromhere, /* buffer pointer */ - data->req.upload_present, /* buffer size */ - &bytes_written); /* actually sent */ - - if(result) - return result; - - if(data->set.verbose) - /* show the data before we change the pointer upload_fromhere */ - Curl_debug(data, CURLINFO_DATA_OUT, data->req.upload_fromhere, - (size_t)bytes_written, conn); - - k->writebytecount += bytes_written; - - if(k->writebytecount == data->state.infilesize) { - /* we have sent all data we were supposed to */ - k->upload_done = TRUE; - infof(data, "We are completely uploaded and fine\n"); - } - - if(data->req.upload_present != bytes_written) { - /* we only wrote a part of the buffer (if anything), deal with it! */ - - /* store the amount of bytes left in the buffer to write */ - data->req.upload_present -= bytes_written; - - /* advance the pointer where to find the buffer when the next send - is to happen */ - data->req.upload_fromhere += bytes_written; - } - else { - /* we've uploaded that buffer now */ - data->req.upload_fromhere = k->uploadbuf; - data->req.upload_present = 0; /* no more bytes left */ - - if(k->upload_done) { - result = done_sending(conn, k); - if(result) - return result; - } - } - - Curl_pgrsSetUploadCounter(data, k->writebytecount); - - } WHILE_FALSE; /* just to break out from! */ - - return CURLE_OK; -} - -/* - * Curl_readwrite() is the low-level function to be called when data is to - * be read and written to/from the connection. - */ -CURLcode Curl_readwrite(struct connectdata *conn, - struct SessionHandle *data, - bool *done) -{ - struct SingleRequest *k = &data->req; - CURLcode result; - int didwhat=0; - - curl_socket_t fd_read; - curl_socket_t fd_write; - int select_res = conn->cselect_bits; - - conn->cselect_bits = 0; - - /* only use the proper socket if the *_HOLD bit is not set simultaneously as - then we are in rate limiting state in that transfer direction */ - - if((k->keepon & KEEP_RECVBITS) == KEEP_RECV) - fd_read = conn->sockfd; - else - fd_read = CURL_SOCKET_BAD; - - if((k->keepon & KEEP_SENDBITS) == KEEP_SEND) - fd_write = conn->writesockfd; - else - fd_write = CURL_SOCKET_BAD; - - if(conn->data->state.drain) { - select_res |= CURL_CSELECT_IN; - DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data\n")); - } - - if(!select_res) /* Call for select()/poll() only, if read/write/error - status is not known. */ - select_res = Curl_socket_ready(fd_read, fd_write, 0); - - if(select_res == CURL_CSELECT_ERR) { - failf(data, "select/poll returned error"); - return CURLE_SEND_ERROR; - } - - /* We go ahead and do a read if we have a readable socket or if - the stream was rewound (in which case we have data in a - buffer) */ - if((k->keepon & KEEP_RECV) && - ((select_res & CURL_CSELECT_IN) || conn->bits.stream_was_rewound)) { - - result = readwrite_data(data, conn, k, &didwhat, done); - if(result || *done) - return result; - } - - /* If we still have writing to do, we check if we have a writable socket. */ - if((k->keepon & KEEP_SEND) && (select_res & CURL_CSELECT_OUT)) { - /* write */ - - result = readwrite_upload(data, conn, k, &didwhat); - if(result) - return result; - } - - k->now = Curl_tvnow(); - if(didwhat) { - /* Update read/write counters */ - if(k->bytecountp) - *k->bytecountp = k->bytecount; /* read count */ - if(k->writebytecountp) - *k->writebytecountp = k->writebytecount; /* write count */ - } - else { - /* no read no write, this is a timeout? */ - if(k->exp100 == EXP100_AWAITING_CONTINUE) { - /* This should allow some time for the header to arrive, but only a - very short time as otherwise it'll be too much wasted time too - often. */ - - /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status": - - Therefore, when a client sends this header field to an origin server - (possibly via a proxy) from which it has never seen a 100 (Continue) - status, the client SHOULD NOT wait for an indefinite period before - sending the request body. - - */ - - long ms = Curl_tvdiff(k->now, k->start100); - if(ms >= data->set.expect_100_timeout) { - /* we've waited long enough, continue anyway */ - k->exp100 = EXP100_SEND_DATA; - k->keepon |= KEEP_SEND; - infof(data, "Done waiting for 100-continue\n"); - } - } - } - - if(Curl_pgrsUpdate(conn)) - result = CURLE_ABORTED_BY_CALLBACK; - else - result = Curl_speedcheck(data, k->now); - if(result) - return result; - - if(k->keepon) { - if(0 > Curl_timeleft(data, &k->now, FALSE)) { - if(k->size != -1) { - failf(data, "Operation timed out after %ld milliseconds with %" - CURL_FORMAT_CURL_OFF_T " out of %" - CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount, - k->size); - } - else { - failf(data, "Operation timed out after %ld milliseconds with %" - CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_tvdiff(k->now, data->progress.t_startsingle), k->bytecount); - } - return CURLE_OPERATION_TIMEDOUT; - } - } - else { - /* - * The transfer has been performed. Just make some general checks before - * returning. - */ - - if(!(data->set.opt_no_body) && (k->size != -1) && - (k->bytecount != k->size) && -#ifdef CURL_DO_LINEEND_CONV - /* Most FTP servers don't adjust their file SIZE response for CRLFs, - so we'll check to see if the discrepancy can be explained - by the number of CRLFs we've changed to LFs. - */ - (k->bytecount != (k->size + data->state.crlf_conversions)) && -#endif /* CURL_DO_LINEEND_CONV */ - !data->req.newurl) { - failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T - " bytes remaining to read", - k->size - k->bytecount); - return CURLE_PARTIAL_FILE; - } - else if(!(data->set.opt_no_body) && - k->chunk && - (conn->chunk.state != CHUNK_STOP)) { - /* - * In chunked mode, return an error if the connection is closed prior to - * the empty (terminating) chunk is read. - * - * The condition above used to check for - * conn->proto.http->chunk.datasize != 0 which is true after reading - * *any* chunk, not just the empty chunk. - * - */ - failf(data, "transfer closed with outstanding read data remaining"); - return CURLE_PARTIAL_FILE; - } - if(Curl_pgrsUpdate(conn)) - return CURLE_ABORTED_BY_CALLBACK; - } - - /* Now update the "done" boolean we return */ - *done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND| - KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE; - - return CURLE_OK; -} - -/* - * Curl_single_getsock() gets called by the multi interface code when the app - * has requested to get the sockets for the current connection. This function - * will then be called once for every connection that the multi interface - * keeps track of. This function will only be called for connections that are - * in the proper state to have this information available. - */ -int Curl_single_getsock(const struct connectdata *conn, - curl_socket_t *sock, /* points to numsocks number - of sockets */ - int numsocks) -{ - const struct SessionHandle *data = conn->data; - int bitmap = GETSOCK_BLANK; - unsigned sockindex = 0; - - if(conn->handler->perform_getsock) - return conn->handler->perform_getsock(conn, sock, numsocks); - - if(numsocks < 2) - /* simple check but we might need two slots */ - return GETSOCK_BLANK; - - /* don't include HOLD and PAUSE connections */ - if((data->req.keepon & KEEP_RECVBITS) == KEEP_RECV) { - - DEBUGASSERT(conn->sockfd != CURL_SOCKET_BAD); - - bitmap |= GETSOCK_READSOCK(sockindex); - sock[sockindex] = conn->sockfd; - } - - /* don't include HOLD and PAUSE connections */ - if((data->req.keepon & KEEP_SENDBITS) == KEEP_SEND) { - - if((conn->sockfd != conn->writesockfd) || - bitmap == GETSOCK_BLANK) { - /* only if they are not the same socket and we have a readable - one, we increase index */ - if(bitmap != GETSOCK_BLANK) - sockindex++; /* increase index if we need two entries */ - - DEBUGASSERT(conn->writesockfd != CURL_SOCKET_BAD); - - sock[sockindex] = conn->writesockfd; - } - - bitmap |= GETSOCK_WRITESOCK(sockindex); - } - - return bitmap; -} - -/* - * Determine optimum sleep time based on configured rate, current rate, - * and packet size. - * Returns value in milliseconds. - * - * The basic idea is to adjust the desired rate up/down in this method - * based on whether we are running too slow or too fast. Then, calculate - * how many milliseconds to wait for the next packet to achieve this new - * rate. - */ -long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps, - int pkt_size) -{ - curl_off_t min_sleep = 0; - curl_off_t rv = 0; - - if(rate_bps == 0) - return 0; - - /* If running faster than about .1% of the desired speed, slow - * us down a bit. Use shift instead of division as the 0.1% - * cutoff is arbitrary anyway. - */ - if(cur_rate_bps > (rate_bps + (rate_bps >> 10))) { - /* running too fast, decrease target rate by 1/64th of rate */ - rate_bps -= rate_bps >> 6; - min_sleep = 1; - } - else if(cur_rate_bps < (rate_bps - (rate_bps >> 10))) { - /* running too slow, increase target rate by 1/64th of rate */ - rate_bps += rate_bps >> 6; - } - - /* Determine number of milliseconds to wait until we do - * the next packet at the adjusted rate. We should wait - * longer when using larger packets, for instance. - */ - rv = ((curl_off_t)(pkt_size * 1000) / rate_bps); - - /* Catch rounding errors and always slow down at least 1ms if - * we are running too fast. - */ - if(rv < min_sleep) - rv = min_sleep; - - /* Bound value to fit in 'long' on 32-bit platform. That's - * plenty long enough anyway! - */ - if(rv > 0x7fffffff) - rv = 0x7fffffff; - - return (long)rv; -} - -/* Curl_init_CONNECT() gets called each time the handle switches to CONNECT - which means this gets called once for each subsequent redirect etc */ -void Curl_init_CONNECT(struct SessionHandle *data) -{ - data->state.fread_func = data->set.fread_func_set; - data->state.in = data->set.in_set; -} - -/* - * Curl_pretransfer() is called immediately before a transfer starts, and only - * once for one transfer no matter if it has redirects or do multi-pass - * authentication etc. - */ -CURLcode Curl_pretransfer(struct SessionHandle *data) -{ - CURLcode result; - if(!data->change.url) { - /* we can't do anything without URL */ - failf(data, "No URL set!"); - return CURLE_URL_MALFORMAT; - } - - /* Init the SSL session ID cache here. We do it here since we want to do it - after the *_setopt() calls (that could specify the size of the cache) but - before any transfer takes place. */ - result = Curl_ssl_initsessions(data, data->set.ssl.max_ssl_sessions); - if(result) - return result; - - data->set.followlocation=0; /* reset the location-follow counter */ - data->state.this_is_a_follow = FALSE; /* reset this */ - data->state.errorbuf = FALSE; /* no error has occurred */ - data->state.httpversion = 0; /* don't assume any particular server version */ - - data->state.authproblem = FALSE; - data->state.authhost.want = data->set.httpauth; - data->state.authproxy.want = data->set.proxyauth; - Curl_safefree(data->info.wouldredirect); - data->info.wouldredirect = NULL; - - if(data->set.httpreq == HTTPREQ_PUT) - data->state.infilesize = data->set.filesize; - else - data->state.infilesize = data->set.postfieldsize; - - /* If there is a list of cookie files to read, do it now! */ - if(data->change.cookielist) - Curl_cookie_loadfiles(data); - - /* If there is a list of host pairs to deal with */ - if(data->change.resolve) - result = Curl_loadhostpairs(data); - - if(!result) { - /* Allow data->set.use_port to set which port to use. This needs to be - * disabled for example when we follow Location: headers to URLs using - * different ports! */ - data->state.allow_port = TRUE; - -#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) - /************************************************************* - * Tell signal handler to ignore SIGPIPE - *************************************************************/ - if(!data->set.no_signal) - data->state.prev_signal = signal(SIGPIPE, SIG_IGN); -#endif - - Curl_initinfo(data); /* reset session-specific information "variables" */ - Curl_pgrsResetTimesSizes(data); - Curl_pgrsStartNow(data); - - if(data->set.timeout) - Curl_expire(data, data->set.timeout); - - if(data->set.connecttimeout) - Curl_expire(data, data->set.connecttimeout); - - /* In case the handle is re-used and an authentication method was picked - in the session we need to make sure we only use the one(s) we now - consider to be fine */ - data->state.authhost.picked &= data->state.authhost.want; - data->state.authproxy.picked &= data->state.authproxy.want; - - if(data->set.wildcardmatch) { - struct WildcardData *wc = &data->wildcard; - if(!wc->filelist) { - result = Curl_wildcard_init(wc); /* init wildcard structures */ - if(result) - return CURLE_OUT_OF_MEMORY; - } - } - - } - - return result; -} - -/* - * Curl_posttransfer() is called immediately after a transfer ends - */ -CURLcode Curl_posttransfer(struct SessionHandle *data) -{ -#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) - /* restore the signal handler for SIGPIPE before we get back */ - if(!data->set.no_signal) - signal(SIGPIPE, data->state.prev_signal); -#else - (void)data; /* unused parameter */ -#endif - - return CURLE_OK; -} - -#ifndef CURL_DISABLE_HTTP -/* - * strlen_url() returns the length of the given URL if the spaces within the - * URL were properly URL encoded. - */ -static size_t strlen_url(const char *url) -{ - const unsigned char *ptr; - size_t newlen=0; - bool left=TRUE; /* left side of the ? */ - - for(ptr=(unsigned char *)url; *ptr; ptr++) { - switch(*ptr) { - case '?': - left=FALSE; - /* fall through */ - default: - if(*ptr >= 0x80) - newlen += 2; - newlen++; - break; - case ' ': - if(left) - newlen+=3; - else - newlen++; - break; - } - } - return newlen; -} - -/* strcpy_url() copies a url to a output buffer and URL-encodes the spaces in - * the source URL accordingly. - */ -static void strcpy_url(char *output, const char *url) -{ - /* we must add this with whitespace-replacing */ - bool left=TRUE; - const unsigned char *iptr; - char *optr = output; - for(iptr = (unsigned char *)url; /* read from here */ - *iptr; /* until zero byte */ - iptr++) { - switch(*iptr) { - case '?': - left=FALSE; - /* fall through */ - default: - if(*iptr >= 0x80) { - snprintf(optr, 4, "%%%02x", *iptr); - optr += 3; - } - else - *optr++=*iptr; - break; - case ' ': - if(left) { - *optr++='%'; /* add a '%' */ - *optr++='2'; /* add a '2' */ - *optr++='0'; /* add a '0' */ - } - else - *optr++='+'; /* add a '+' here */ - break; - } - } - *optr=0; /* zero terminate output buffer */ - -} - -/* - * Returns true if the given URL is absolute (as opposed to relative) - */ -static bool is_absolute_url(const char *url) -{ - char prot[16]; /* URL protocol string storage */ - char letter; /* used for a silly sscanf */ - - return (2 == sscanf(url, "%15[^?&/:]://%c", prot, &letter)) ? TRUE : FALSE; -} - -/* - * Concatenate a relative URL to a base URL making it absolute. - * URL-encodes any spaces. - * The returned pointer must be freed by the caller unless NULL - * (returns NULL on out of memory). - */ -static char *concat_url(const char *base, const char *relurl) -{ - /*** - TRY to append this new path to the old URL - to the right of the host part. Oh crap, this is doomed to cause - problems in the future... - */ - char *newest; - char *protsep; - char *pathsep; - size_t newlen; - - const char *useurl = relurl; - size_t urllen; - - /* we must make our own copy of the URL to play with, as it may - point to read-only data */ - char *url_clone=strdup(base); - - if(!url_clone) - return NULL; /* skip out of this NOW */ - - /* protsep points to the start of the host name */ - protsep=strstr(url_clone, "//"); - if(!protsep) - protsep=url_clone; - else - protsep+=2; /* pass the slashes */ - - if('/' != relurl[0]) { - int level=0; - - /* First we need to find out if there's a ?-letter in the URL, - and cut it and the right-side of that off */ - pathsep = strchr(protsep, '?'); - if(pathsep) - *pathsep=0; - - /* we have a relative path to append to the last slash if there's one - available, or if the new URL is just a query string (starts with a - '?') we append the new one at the end of the entire currently worked - out URL */ - if(useurl[0] != '?') { - pathsep = strrchr(protsep, '/'); - if(pathsep) - *pathsep=0; - } - - /* Check if there's any slash after the host name, and if so, remember - that position instead */ - pathsep = strchr(protsep, '/'); - if(pathsep) - protsep = pathsep+1; - else - protsep = NULL; - - /* now deal with one "./" or any amount of "../" in the newurl - and act accordingly */ - - if((useurl[0] == '.') && (useurl[1] == '/')) - useurl+=2; /* just skip the "./" */ - - while((useurl[0] == '.') && - (useurl[1] == '.') && - (useurl[2] == '/')) { - level++; - useurl+=3; /* pass the "../" */ - } - - if(protsep) { - while(level--) { - /* cut off one more level from the right of the original URL */ - pathsep = strrchr(protsep, '/'); - if(pathsep) - *pathsep=0; - else { - *protsep=0; - break; - } - } - } - } - else { - /* We got a new absolute path for this server */ - - if((relurl[0] == '/') && (relurl[1] == '/')) { - /* the new URL starts with //, just keep the protocol part from the - original one */ - *protsep=0; - useurl = &relurl[2]; /* we keep the slashes from the original, so we - skip the new ones */ - } - else { - /* cut off the original URL from the first slash, or deal with URLs - without slash */ - pathsep = strchr(protsep, '/'); - if(pathsep) { - /* When people use badly formatted URLs, such as - "http://www.url.com?dir=/home/daniel" we must not use the first - slash, if there's a ?-letter before it! */ - char *sep = strchr(protsep, '?'); - if(sep && (sep < pathsep)) - pathsep = sep; - *pathsep=0; - } - else { - /* There was no slash. Now, since we might be operating on a badly - formatted URL, such as "http://www.url.com?id=2380" which doesn't - use a slash separator as it is supposed to, we need to check for a - ?-letter as well! */ - pathsep = strchr(protsep, '?'); - if(pathsep) - *pathsep=0; - } - } - } - - /* If the new part contains a space, this is a mighty stupid redirect - but we still make an effort to do "right". To the left of a '?' - letter we replace each space with %20 while it is replaced with '+' - on the right side of the '?' letter. - */ - newlen = strlen_url(useurl); - - urllen = strlen(url_clone); - - newest = malloc(urllen + 1 + /* possible slash */ - newlen + 1 /* zero byte */); - - if(!newest) { - free(url_clone); /* don't leak this */ - return NULL; - } - - /* copy over the root url part */ - memcpy(newest, url_clone, urllen); - - /* check if we need to append a slash */ - if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) - ; - else - newest[urllen++]='/'; - - /* then append the new piece on the right side */ - strcpy_url(&newest[urllen], useurl); - - free(url_clone); - - return newest; -} -#endif /* CURL_DISABLE_HTTP */ - -/* - * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string - * as given by the remote server and set up the new URL to request. - */ -CURLcode Curl_follow(struct SessionHandle *data, - char *newurl, /* this 'newurl' is the Location: string, - and it must be malloc()ed before passed - here */ - followtype type) /* see transfer.h */ -{ -#ifdef CURL_DISABLE_HTTP - (void)data; - (void)newurl; - (void)type; - /* Location: following will not happen when HTTP is disabled */ - return CURLE_TOO_MANY_REDIRECTS; -#else - - /* Location: redirect */ - bool disallowport = FALSE; - - if(type == FOLLOW_REDIR) { - if((data->set.maxredirs != -1) && - (data->set.followlocation >= data->set.maxredirs)) { - failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs); - return CURLE_TOO_MANY_REDIRECTS; - } - - /* mark the next request as a followed location: */ - data->state.this_is_a_follow = TRUE; - - data->set.followlocation++; /* count location-followers */ - - if(data->set.http_auto_referer) { - /* We are asked to automatically set the previous URL as the referer - when we get the next URL. We pick the ->url field, which may or may - not be 100% correct */ - - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; - } - - data->change.referer = strdup(data->change.url); - if(!data->change.referer) - return CURLE_OUT_OF_MEMORY; - data->change.referer_alloc = TRUE; /* yes, free this later */ - } - } - - if(!is_absolute_url(newurl)) { - /*** - *DANG* this is an RFC 2068 violation. The URL is supposed - to be absolute and this doesn't seem to be that! - */ - char *absolute = concat_url(data->change.url, newurl); - if(!absolute) - return CURLE_OUT_OF_MEMORY; - free(newurl); - newurl = absolute; - } - else { - /* The new URL MAY contain space or high byte values, that means a mighty - stupid redirect URL but we still make an effort to do "right". */ - char *newest; - size_t newlen = strlen_url(newurl); - - /* This is an absolute URL, don't allow the custom port number */ - disallowport = TRUE; - - newest = malloc(newlen+1); /* get memory for this */ - if(!newest) - return CURLE_OUT_OF_MEMORY; - strcpy_url(newest, newurl); /* create a space-free URL */ - - free(newurl); /* that was no good */ - newurl = newest; /* use this instead now */ - - } - - if(type == FOLLOW_FAKE) { - /* we're only figuring out the new url if we would've followed locations - but now we're done so we can get out! */ - data->info.wouldredirect = newurl; - return CURLE_OK; - } - - if(disallowport) - data->state.allow_port = FALSE; - - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - - data->change.url = newurl; - data->change.url_alloc = TRUE; - newurl = NULL; /* don't free! */ - - infof(data, "Issue another request to this URL: '%s'\n", data->change.url); - - /* - * We get here when the HTTP code is 300-399 (and 401). We need to perform - * differently based on exactly what return code there was. - * - * News from 7.10.6: we can also get here on a 401 or 407, in case we act on - * a HTTP (proxy-) authentication scheme other than Basic. - */ - switch(data->info.httpcode) { - /* 401 - Act on a WWW-Authenticate, we keep on moving and do the - Authorization: XXXX header in the HTTP request code snippet */ - /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the - Proxy-Authorization: XXXX header in the HTTP request code snippet */ - /* 300 - Multiple Choices */ - /* 306 - Not used */ - /* 307 - Temporary Redirect */ - default: /* for all above (and the unknown ones) */ - /* Some codes are explicitly mentioned since I've checked RFC2616 and they - * seem to be OK to POST to. - */ - break; - case 301: /* Moved Permanently */ - /* (quote from RFC7231, section 6.4.2) - * - * Note: For historical reasons, a user agent MAY change the request - * method from POST to GET for the subsequent request. If this - * behavior is undesired, the 307 (Temporary Redirect) status code - * can be used instead. - * - * ---- - * - * Many webservers expect this, so these servers often answers to a POST - * request with an error page. To be sure that libcurl gets the page that - * most user agents would get, libcurl has to force GET. - * - * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and - * can be overridden with CURLOPT_POSTREDIR. - */ - if((data->set.httpreq == HTTPREQ_POST - || data->set.httpreq == HTTPREQ_POST_FORM) - && !(data->set.keep_post & CURL_REDIR_POST_301)) { - infof(data, "Switch from POST to GET\n"); - data->set.httpreq = HTTPREQ_GET; - } - break; - case 302: /* Found */ - /* (quote from RFC7231, section 6.4.3) - * - * Note: For historical reasons, a user agent MAY change the request - * method from POST to GET for the subsequent request. If this - * behavior is undesired, the 307 (Temporary Redirect) status code - * can be used instead. - * - * ---- - * - * Many webservers expect this, so these servers often answers to a POST - * request with an error page. To be sure that libcurl gets the page that - * most user agents would get, libcurl has to force GET. - * - * This behaviour is forbidden by RFC1945 and the obsolete RFC2616, and - * can be overridden with CURLOPT_POSTREDIR. - */ - if((data->set.httpreq == HTTPREQ_POST - || data->set.httpreq == HTTPREQ_POST_FORM) - && !(data->set.keep_post & CURL_REDIR_POST_302)) { - infof(data, "Switch from POST to GET\n"); - data->set.httpreq = HTTPREQ_GET; - } - break; - - case 303: /* See Other */ - /* Disable both types of POSTs, unless the user explicitely - asks for POST after POST */ - if(data->set.httpreq != HTTPREQ_GET - && !(data->set.keep_post & CURL_REDIR_POST_303)) { - data->set.httpreq = HTTPREQ_GET; /* enforce GET request */ - infof(data, "Disables POST, goes with %s\n", - data->set.opt_no_body?"HEAD":"GET"); - } - break; - case 304: /* Not Modified */ - /* 304 means we did a conditional request and it was "Not modified". - * We shouldn't get any Location: header in this response! - */ - break; - case 305: /* Use Proxy */ - /* (quote from RFC2616, section 10.3.6): - * "The requested resource MUST be accessed through the proxy given - * by the Location field. The Location field gives the URI of the - * proxy. The recipient is expected to repeat this single request - * via the proxy. 305 responses MUST only be generated by origin - * servers." - */ - break; - } - Curl_pgrsTime(data, TIMER_REDIRECT); - Curl_pgrsResetTimesSizes(data); - - return CURLE_OK; -#endif /* CURL_DISABLE_HTTP */ -} - -/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted. - - NOTE: that the *url is malloc()ed. */ -CURLcode Curl_retry_request(struct connectdata *conn, - char **url) -{ - struct SessionHandle *data = conn->data; - - *url = NULL; - - /* if we're talking upload, we can't do the checks below, unless the protocol - is HTTP as when uploading over HTTP we will still get a response */ - if(data->set.upload && - !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP))) - return CURLE_OK; - - if((data->req.bytecount + data->req.headerbytecount == 0) && - conn->bits.reuse && - !data->set.opt_no_body && - (data->set.rtspreq != RTSPREQ_RECEIVE)) { - /* We got no data, we attempted to re-use a connection and yet we want a - "body". This might happen if the connection was left alive when we were - done using it before, but that was closed when we wanted to read from - it again. Bad luck. Retry the same request on a fresh connect! */ - infof(conn->data, "Connection died, retrying a fresh connect\n"); - *url = strdup(conn->data->change.url); - if(!*url) - return CURLE_OUT_OF_MEMORY; - - connclose(conn, "retry"); /* close this connection */ - conn->bits.retry = TRUE; /* mark this as a connection we're about - to retry. Marking it this way should - prevent i.e HTTP transfers to return - error just because nothing has been - transferred! */ - - - if(conn->handler->protocol&PROTO_FAMILY_HTTP) { - struct HTTP *http = data->req.protop; - if(http->writebytecount) - return Curl_readrewind(conn); - } - } - return CURLE_OK; -} - -/* - * Curl_setup_transfer() is called to setup some basic properties for the - * upcoming transfer. - */ -void -Curl_setup_transfer( - struct connectdata *conn, /* connection data */ - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - curl_off_t *bytecountp, /* return number of bytes read or NULL */ - int writesockindex, /* socket index to write to, it may very well be - the same we read from. -1 disables */ - curl_off_t *writecountp /* return number of bytes written or NULL */ - ) -{ - struct SessionHandle *data; - struct SingleRequest *k; - - DEBUGASSERT(conn != NULL); - - data = conn->data; - k = &data->req; - - DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); - - /* now copy all input parameters */ - conn->sockfd = sockindex == -1 ? - CURL_SOCKET_BAD : conn->sock[sockindex]; - conn->writesockfd = writesockindex == -1 ? - CURL_SOCKET_BAD:conn->sock[writesockindex]; - k->getheader = getheader; - - k->size = size; - k->bytecountp = bytecountp; - k->writebytecountp = writecountp; - - /* The code sequence below is placed in this function just because all - necessary input is not always known in do_complete() as this function may - be called after that */ - - if(!k->getheader) { - k->header = FALSE; - if(size > 0) - Curl_pgrsSetDownloadSize(data, size); - } - /* we want header and/or body, if neither then don't do this! */ - if(k->getheader || !data->set.opt_no_body) { - - if(conn->sockfd != CURL_SOCKET_BAD) - k->keepon |= KEEP_RECV; - - if(conn->writesockfd != CURL_SOCKET_BAD) { - struct HTTP *http = data->req.protop; - /* HTTP 1.1 magic: - - Even if we require a 100-return code before uploading data, we might - need to write data before that since the REQUEST may not have been - finished sent off just yet. - - Thus, we must check if the request has been sent before we set the - state info where we wait for the 100-return code - */ - if((data->state.expect100header) && - (conn->handler->protocol&PROTO_FAMILY_HTTP) && - (http->sending == HTTPSEND_BODY)) { - /* wait with write until we either got 100-continue or a timeout */ - k->exp100 = EXP100_AWAITING_CONTINUE; - k->start100 = Curl_tvnow(); - - /* Set a timeout for the multi interface. Add the inaccuracy margin so - that we don't fire slightly too early and get denied to run. */ - Curl_expire(data, data->set.expect_100_timeout); - } - else { - if(data->state.expect100header) - /* when we've sent off the rest of the headers, we must await a - 100-continue but first finish sending the request */ - k->exp100 = EXP100_SENDING_REQUEST; - - /* enable the write bit when we're not waiting for continue */ - k->keepon |= KEEP_SEND; - } - } /* if(conn->writesockfd != CURL_SOCKET_BAD) */ - } /* if(k->getheader || !data->set.opt_no_body) */ - -} diff --git a/Externals/curl/lib/transfer.h b/Externals/curl/lib/transfer.h deleted file mode 100644 index 802344f23d..0000000000 --- a/Externals/curl/lib/transfer.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef HEADER_CURL_TRANSFER_H -#define HEADER_CURL_TRANSFER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -void Curl_init_CONNECT(struct SessionHandle *data); - -CURLcode Curl_pretransfer(struct SessionHandle *data); -CURLcode Curl_second_connect(struct connectdata *conn); -CURLcode Curl_posttransfer(struct SessionHandle *data); - -typedef enum { - FOLLOW_NONE, /* not used within the function, just a placeholder to - allow initing to this */ - FOLLOW_FAKE, /* only records stuff, not actually following */ - FOLLOW_RETRY, /* set if this is a request retry as opposed to a real - redirect following */ - FOLLOW_REDIR, /* a full true redirect */ - FOLLOW_LAST /* never used */ -} followtype; - -CURLcode Curl_follow(struct SessionHandle *data, char *newurl, - followtype type); - - -CURLcode Curl_readwrite(struct connectdata *conn, - struct SessionHandle *data, bool *done); -int Curl_single_getsock(const struct connectdata *conn, - curl_socket_t *socks, - int numsocks); -CURLcode Curl_readrewind(struct connectdata *conn); -CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp); -CURLcode Curl_retry_request(struct connectdata *conn, char **url); -bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc); - -/* This sets up a forthcoming transfer */ -void -Curl_setup_transfer (struct connectdata *data, - int sockindex, /* socket index to read from or -1 */ - curl_off_t size, /* -1 if unknown at this point */ - bool getheader, /* TRUE if header parsing is wanted */ - curl_off_t *bytecountp, /* return number of bytes read */ - int writesockindex, /* socket index to write to, it may - very well be the same we read from. - -1 disables */ - curl_off_t *writecountp /* return number of bytes written */ -); - -long Curl_sleep_time(curl_off_t rate_bps, curl_off_t cur_rate_bps, - int pkt_size); - -#endif /* HEADER_CURL_TRANSFER_H */ - diff --git a/Externals/curl/lib/url.c b/Externals/curl/lib/url.c deleted file mode 100644 index 2a30266507..0000000000 --- a/Externals/curl/lib/url.c +++ /dev/null @@ -1,6588 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NETDB_H -#include -#endif -#ifdef HAVE_ARPA_INET_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#ifdef HAVE_SYS_PARAM_H -#include -#endif - -#ifdef __VMS -#include -#include -#endif - -#ifdef HAVE_SYS_UN_H -#include -#endif - -#ifndef HAVE_SOCKET -#error "We can't compile without socket() support!" -#endif - -#ifdef HAVE_LIMITS_H -#include -#endif - -#ifdef USE_LIBIDN -#include -#include -#include -#ifdef HAVE_IDN_FREE_H -#include -#else -/* prototype from idn-free.h, not provided by libidn 0.4.5's make install! */ -void idn_free (void *ptr); -#endif -#ifndef HAVE_IDN_FREE -/* if idn_free() was not found in this version of libidn use free() instead */ -#define idn_free(x) (free)(x) -#endif -#elif defined(USE_WIN32_IDN) -/* prototype for curl_win32_idn_to_ascii() */ -bool curl_win32_idn_to_ascii(const char *in, char **out); -#endif /* USE_LIBIDN */ - -#include "urldata.h" -#include "netrc.h" - -#include "formdata.h" -#include "vtls/vtls.h" -#include "hostip.h" -#include "transfer.h" -#include "sendf.h" -#include "progress.h" -#include "cookie.h" -#include "strequal.h" -#include "strerror.h" -#include "escape.h" -#include "strtok.h" -#include "share.h" -#include "content_encoding.h" -#include "http_digest.h" -#include "http_negotiate.h" -#include "select.h" -#include "multiif.h" -#include "easyif.h" -#include "speedcheck.h" -#include "rawstr.h" -#include "warnless.h" -#include "non-ascii.h" -#include "inet_pton.h" - -/* And now for the protocols */ -#include "ftp.h" -#include "dict.h" -#include "telnet.h" -#include "tftp.h" -#include "http.h" -#include "http2.h" -#include "file.h" -#include "curl_ldap.h" -#include "ssh.h" -#include "imap.h" -#include "url.h" -#include "connect.h" -#include "inet_ntop.h" -#include "http_ntlm.h" -#include "curl_ntlm_wb.h" -#include "socks.h" -#include "curl_rtmp.h" -#include "gopher.h" -#include "http_proxy.h" -#include "conncache.h" -#include "multihandle.h" -#include "pipeline.h" -#include "dotdot.h" -#include "strdup.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* Local static prototypes */ -static struct connectdata * -find_oldest_idle_connection_in_bundle(struct SessionHandle *data, - struct connectbundle *bundle); -static void conn_free(struct connectdata *conn); -static void free_fixed_hostname(struct hostname *host); -static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke); -static CURLcode parse_url_login(struct SessionHandle *data, - struct connectdata *conn, - char **userptr, char **passwdptr, - char **optionsptr); -static CURLcode parse_login_details(const char *login, const size_t len, - char **userptr, char **passwdptr, - char **optionsptr); -static unsigned int get_protocol_family(unsigned int protocol); - -/* - * Protocol table. - */ - -static const struct Curl_handler * const protocols[] = { - -#ifndef CURL_DISABLE_HTTP - &Curl_handler_http, -#endif - -#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) - &Curl_handler_https, -#endif - -#ifndef CURL_DISABLE_FTP - &Curl_handler_ftp, -#endif - -#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) - &Curl_handler_ftps, -#endif - -#ifndef CURL_DISABLE_TELNET - &Curl_handler_telnet, -#endif - -#ifndef CURL_DISABLE_DICT - &Curl_handler_dict, -#endif - -#ifndef CURL_DISABLE_LDAP - &Curl_handler_ldap, -#if !defined(CURL_DISABLE_LDAPS) && \ - ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ - (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) - &Curl_handler_ldaps, -#endif -#endif - -#ifndef CURL_DISABLE_FILE - &Curl_handler_file, -#endif - -#ifndef CURL_DISABLE_TFTP - &Curl_handler_tftp, -#endif - -#ifdef USE_LIBSSH2 - &Curl_handler_scp, - &Curl_handler_sftp, -#endif - -#ifndef CURL_DISABLE_IMAP - &Curl_handler_imap, -#ifdef USE_SSL - &Curl_handler_imaps, -#endif -#endif - -#ifndef CURL_DISABLE_POP3 - &Curl_handler_pop3, -#ifdef USE_SSL - &Curl_handler_pop3s, -#endif -#endif - -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) && \ - (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) - &Curl_handler_smb, -#ifdef USE_SSL - &Curl_handler_smbs, -#endif -#endif - -#ifndef CURL_DISABLE_SMTP - &Curl_handler_smtp, -#ifdef USE_SSL - &Curl_handler_smtps, -#endif -#endif - -#ifndef CURL_DISABLE_RTSP - &Curl_handler_rtsp, -#endif - -#ifndef CURL_DISABLE_GOPHER - &Curl_handler_gopher, -#endif - -#ifdef USE_LIBRTMP - &Curl_handler_rtmp, - &Curl_handler_rtmpt, - &Curl_handler_rtmpe, - &Curl_handler_rtmpte, - &Curl_handler_rtmps, - &Curl_handler_rtmpts, -#endif - - (struct Curl_handler *) NULL -}; - -/* - * Dummy handler for undefined protocol schemes. - */ - -static const struct Curl_handler Curl_handler_dummy = { - "", /* scheme */ - ZERO_NULL, /* setup_connection */ - ZERO_NULL, /* do_it */ - ZERO_NULL, /* done */ - ZERO_NULL, /* do_more */ - ZERO_NULL, /* connect_it */ - ZERO_NULL, /* connecting */ - ZERO_NULL, /* doing */ - ZERO_NULL, /* proto_getsock */ - ZERO_NULL, /* doing_getsock */ - ZERO_NULL, /* domore_getsock */ - ZERO_NULL, /* perform_getsock */ - ZERO_NULL, /* disconnect */ - ZERO_NULL, /* readwrite */ - 0, /* defport */ - 0, /* protocol */ - PROTOPT_NONE /* flags */ -}; - -void Curl_freeset(struct SessionHandle *data) -{ - /* Free all dynamic strings stored in the data->set substructure. */ - enum dupstring i; - for(i=(enum dupstring)0; i < STRING_LAST; i++) { - Curl_safefree(data->set.str[i]); - } - - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; - } - data->change.referer = NULL; - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - data->change.url = NULL; -} - -static CURLcode setstropt(char **charp, const char *s) -{ - /* Release the previous storage at `charp' and replace by a dynamic storage - copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */ - - Curl_safefree(*charp); - - if(s) { - char *str = strdup(s); - - if(!str) - return CURLE_OUT_OF_MEMORY; - - *charp = str; - } - - return CURLE_OK; -} - -static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) -{ - CURLcode result = CURLE_OK; - char *user = NULL; - char *passwd = NULL; - - /* Parse the login details if specified. It not then we treat NULL as a hint - to clear the existing data */ - if(option) { - result = parse_login_details(option, strlen(option), - (userp ? &user : NULL), - (passwdp ? &passwd : NULL), - NULL); - } - - if(!result) { - /* Store the username part of option if required */ - if(userp) { - if(!user && option && option[0] == ':') { - /* Allocate an empty string instead of returning NULL as user name */ - user = strdup(""); - if(!user) - result = CURLE_OUT_OF_MEMORY; - } - - Curl_safefree(*userp); - *userp = user; - } - - /* Store the password part of option if required */ - if(passwdp) { - Curl_safefree(*passwdp); - *passwdp = passwd; - } - } - - return result; -} - -CURLcode Curl_dupset(struct SessionHandle *dst, struct SessionHandle *src) -{ - CURLcode result = CURLE_OK; - enum dupstring i; - - /* Copy src->set into dst->set first, then deal with the strings - afterwards */ - dst->set = src->set; - - /* clear all string pointers first */ - memset(dst->set.str, 0, STRING_LAST * sizeof(char *)); - - /* duplicate all strings */ - for(i=(enum dupstring)0; i< STRING_LASTZEROTERMINATED; i++) { - result = setstropt(&dst->set.str[i], src->set.str[i]); - if(result) - return result; - } - - /* duplicate memory areas pointed to */ - i = STRING_COPYPOSTFIELDS; - if(src->set.postfieldsize && src->set.str[i]) { - /* postfieldsize is curl_off_t, Curl_memdup() takes a size_t ... */ - dst->set.str[i] = Curl_memdup(src->set.str[i], - curlx_sotouz(src->set.postfieldsize)); - if(!dst->set.str[i]) - return CURLE_OUT_OF_MEMORY; - /* point to the new copy */ - dst->set.postfields = dst->set.str[i]; - } - - return CURLE_OK; -} - -/* - * This is the internal function curl_easy_cleanup() calls. This should - * cleanup and free all resources associated with this sessionhandle. - * - * NOTE: if we ever add something that attempts to write to a socket or - * similar here, we must ignore SIGPIPE first. It is currently only done - * when curl_easy_perform() is invoked. - */ - -CURLcode Curl_close(struct SessionHandle *data) -{ - struct Curl_multi *m; - - if(!data) - return CURLE_OK; - - Curl_expire(data, 0); /* shut off timers */ - - m = data->multi; - - if(m) - /* This handle is still part of a multi handle, take care of this first - and detach this handle from there. */ - curl_multi_remove_handle(data->multi, data); - - if(data->multi_easy) - /* when curl_easy_perform() is used, it creates its own multi handle to - use and this is the one */ - curl_multi_cleanup(data->multi_easy); - - /* Destroy the timeout list that is held in the easy handle. It is - /normally/ done by curl_multi_remove_handle() but this is "just in - case" */ - if(data->state.timeoutlist) { - Curl_llist_destroy(data->state.timeoutlist, NULL); - data->state.timeoutlist = NULL; - } - - data->magic = 0; /* force a clear AFTER the possibly enforced removal from - the multi handle, since that function uses the magic - field! */ - - if(data->state.rangestringalloc) - free(data->state.range); - - /* Free the pathbuffer */ - Curl_safefree(data->state.pathbuffer); - data->state.path = NULL; - - /* freed here just in case DONE wasn't called */ - Curl_free_request_state(data); - - /* Close down all open SSL info and sessions */ - Curl_ssl_close_all(data); - Curl_safefree(data->state.first_host); - Curl_safefree(data->state.scratch); - Curl_ssl_free_certinfo(data); - - /* Cleanup possible redirect junk */ - free(data->req.newurl); - data->req.newurl = NULL; - - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; - } - data->change.referer = NULL; - - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - data->change.url = NULL; - - Curl_safefree(data->state.headerbuff); - - Curl_flush_cookies(data, 1); - - Curl_digest_cleanup(data); - - Curl_safefree(data->info.contenttype); - Curl_safefree(data->info.wouldredirect); - - /* this destroys the channel and we cannot use it anymore after this */ - Curl_resolver_cleanup(data->state.resolver); - - Curl_convert_close(data); - - /* No longer a dirty share, if it exists */ - if(data->share) { - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - data->share->dirty--; - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - } - - if(data->set.wildcardmatch) { - /* destruct wildcard structures if it is needed */ - struct WildcardData *wc = &data->wildcard; - Curl_wildcard_dtor(wc); - } - - Curl_freeset(data); - free(data); - return CURLE_OK; -} - -/* - * Initialize the UserDefined fields within a SessionHandle. - * This may be safely called on a new or existing SessionHandle. - */ -CURLcode Curl_init_userdefined(struct UserDefined *set) -{ - CURLcode result = CURLE_OK; - - set->out = stdout; /* default output to stdout */ - set->in_set = stdin; /* default input from stdin */ - set->err = stderr; /* default stderr to stderr */ - - /* use fwrite as default function to store output */ - set->fwrite_func = (curl_write_callback)fwrite; - - /* use fread as default function to read input */ - set->fread_func_set = (curl_read_callback)fread; - set->is_fread_set = 0; - set->is_fwrite_set = 0; - - set->seek_func = ZERO_NULL; - set->seek_client = ZERO_NULL; - - /* conversion callbacks for non-ASCII hosts */ - set->convfromnetwork = ZERO_NULL; - set->convtonetwork = ZERO_NULL; - set->convfromutf8 = ZERO_NULL; - - set->filesize = -1; /* we don't know the size */ - set->postfieldsize = -1; /* unknown size */ - set->maxredirs = -1; /* allow any amount by default */ - - set->httpreq = HTTPREQ_GET; /* Default HTTP request */ - set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ - set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ - set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */ - set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */ - set->ftp_filemethod = FTPFILE_MULTICWD; - - set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */ - - /* Set the default size of the SSL session ID cache */ - set->ssl.max_ssl_sessions = 5; - - set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */ - set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */ - set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ - set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ - - /* make libcurl quiet by default: */ - set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ - - /* - * libcurl 7.10 introduced SSL verification *by default*! This needs to be - * switched off unless wanted. - */ - set->ssl.verifypeer = TRUE; - set->ssl.verifyhost = TRUE; -#ifdef USE_TLS_SRP - set->ssl.authtype = CURL_TLSAUTH_NONE; -#endif - set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth - type */ - set->ssl.sessionid = TRUE; /* session ID caching enabled by default */ - - set->new_file_perms = 0644; /* Default permissions */ - set->new_directory_perms = 0755; /* Default permissions */ - - /* for the *protocols fields we don't use the CURLPROTO_ALL convenience - define since we internally only use the lower 16 bits for the passed - in bitmask to not conflict with the private bits */ - set->allowed_protocols = CURLPROTO_ALL; - set->redir_protocols = CURLPROTO_ALL & /* All except FILE, SCP and SMB */ - ~(CURLPROTO_FILE | CURLPROTO_SCP | CURLPROTO_SMB | - CURLPROTO_SMBS); - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - /* - * disallow unprotected protection negotiation NEC reference implementation - * seem not to follow rfc1961 section 4.3/4.4 - */ - set->socks5_gssapi_nec = FALSE; -#endif - - /* This is our preferred CA cert bundle/path since install time */ -#if defined(CURL_CA_BUNDLE) - result = setstropt(&set->str[STRING_SSL_CAFILE], CURL_CA_BUNDLE); - if(result) - return result; -#endif -#if defined(CURL_CA_PATH) - result = setstropt(&set->str[STRING_SSL_CAPATH], CURL_CA_PATH); - if(result) - return result; -#endif - - set->wildcardmatch = FALSE; - set->chunk_bgn = ZERO_NULL; - set->chunk_end = ZERO_NULL; - - /* tcp keepalives are disabled by default, but provide reasonable values for - * the interval and idle times. - */ - set->tcp_keepalive = FALSE; - set->tcp_keepintvl = 60; - set->tcp_keepidle = 60; - set->tcp_fastopen = FALSE; - - set->ssl_enable_npn = TRUE; - set->ssl_enable_alpn = TRUE; - - set->expect_100_timeout = 1000L; /* Wait for a second by default. */ - set->sep_headers = TRUE; /* separated header lists by default */ - - Curl_http2_init_userset(set); - return result; -} - -/** - * Curl_open() - * - * @param curl is a pointer to a sessionhandle pointer that gets set by this - * function. - * @return CURLcode - */ - -CURLcode Curl_open(struct SessionHandle **curl) -{ - CURLcode result; - struct SessionHandle *data; - - /* Very simple start-up: alloc the struct, init it with zeroes and return */ - data = calloc(1, sizeof(struct SessionHandle)); - if(!data) { - /* this is a very serious error */ - DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n")); - return CURLE_OUT_OF_MEMORY; - } - - data->magic = CURLEASY_MAGIC_NUMBER; - - result = Curl_resolver_init(&data->state.resolver); - if(result) { - DEBUGF(fprintf(stderr, "Error: resolver_init failed\n")); - free(data); - return result; - } - - /* We do some initial setup here, all those fields that can't be just 0 */ - - data->state.headerbuff = malloc(HEADERSIZE); - if(!data->state.headerbuff) { - DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); - result = CURLE_OUT_OF_MEMORY; - } - else { - result = Curl_init_userdefined(&data->set); - - data->state.headersize=HEADERSIZE; - - Curl_convert_init(data); - - /* most recent connection is not yet defined */ - data->state.lastconnect = NULL; - - data->progress.flags |= PGRS_HIDE; - data->state.current_speed = -1; /* init to negative == impossible */ - - data->wildcard.state = CURLWC_INIT; - data->wildcard.filelist = NULL; - data->set.fnmatch = ZERO_NULL; - data->set.maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */ - - Curl_http2_init_state(&data->state); - } - - if(result) { - Curl_resolver_cleanup(data->state.resolver); - free(data->state.headerbuff); - Curl_freeset(data); - free(data); - data = NULL; - } - else - *curl = data; - - return result; -} - -CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, - va_list param) -{ - char *argptr; - CURLcode result = CURLE_OK; - long arg; -#ifndef CURL_DISABLE_HTTP - curl_off_t bigsize; -#endif - - switch(option) { - case CURLOPT_DNS_CACHE_TIMEOUT: - data->set.dns_cache_timeout = va_arg(param, long); - break; - case CURLOPT_DNS_USE_GLOBAL_CACHE: - /* remember we want this enabled */ - arg = va_arg(param, long); - data->set.global_dns_cache = (0 != arg) ? TRUE : FALSE; - break; - case CURLOPT_SSL_CIPHER_LIST: - /* set a list of cipher we want to use in the SSL connection */ - result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST], - va_arg(param, char *)); - break; - - case CURLOPT_RANDOM_FILE: - /* - * This is the path name to a file that contains random data to seed - * the random SSL stuff with. The file is only used for reading. - */ - result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE], - va_arg(param, char *)); - break; - case CURLOPT_EGDSOCKET: - /* - * The Entropy Gathering Daemon socket pathname - */ - result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET], - va_arg(param, char *)); - break; - case CURLOPT_MAXCONNECTS: - /* - * Set the absolute number of maximum simultaneous alive connection that - * libcurl is allowed to have. - */ - data->set.maxconnects = va_arg(param, long); - break; - case CURLOPT_FORBID_REUSE: - /* - * When this transfer is done, it must not be left to be reused by a - * subsequent transfer but shall be closed immediately. - */ - data->set.reuse_forbid = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_FRESH_CONNECT: - /* - * This transfer shall not use a previously cached connection but - * should be made with a fresh new connect! - */ - data->set.reuse_fresh = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_VERBOSE: - /* - * Verbose means infof() calls that give a lot of information about - * the connection and transfer procedures as well as internal choices. - */ - data->set.verbose = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_HEADER: - /* - * Set to include the header in the general data output stream. - */ - data->set.include_header = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_NOPROGRESS: - /* - * Shut off the internal supported progress meter - */ - data->set.hide_progress = (0 != va_arg(param, long)) ? TRUE : FALSE; - if(data->set.hide_progress) - data->progress.flags |= PGRS_HIDE; - else - data->progress.flags &= ~PGRS_HIDE; - break; - case CURLOPT_NOBODY: - /* - * Do not include the body part in the output data stream. - */ - data->set.opt_no_body = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_FAILONERROR: - /* - * Don't output the >=400 error code HTML-page, but instead only - * return error. - */ - data->set.http_fail_on_error = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_UPLOAD: - case CURLOPT_PUT: - /* - * We want to sent data to the remote host. If this is HTTP, that equals - * using the PUT request. - */ - data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE; - if(data->set.upload) { - /* If this is HTTP, PUT is what's needed to "upload" */ - data->set.httpreq = HTTPREQ_PUT; - data->set.opt_no_body = FALSE; /* this is implied */ - } - else - /* In HTTP, the opposite of upload is GET (unless NOBODY is true as - then this can be changed to HEAD later on) */ - data->set.httpreq = HTTPREQ_GET; - break; - case CURLOPT_FILETIME: - /* - * Try to get the file time of the remote document. The time will - * later (possibly) become available using curl_easy_getinfo(). - */ - data->set.get_filetime = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_FTP_CREATE_MISSING_DIRS: - /* - * An FTP option that modifies an upload to create missing directories on - * the server. - */ - switch(va_arg(param, long)) { - case 0: - data->set.ftp_create_missing_dirs = 0; - break; - case 1: - data->set.ftp_create_missing_dirs = 1; - break; - case 2: - data->set.ftp_create_missing_dirs = 2; - break; - default: - /* reserve other values for future use */ - result = CURLE_UNKNOWN_OPTION; - break; - } - break; - case CURLOPT_SERVER_RESPONSE_TIMEOUT: - /* - * Option that specifies how quickly an server response must be obtained - * before it is considered failure. For pingpong protocols. - */ - data->set.server_response_timeout = va_arg(param, long) * 1000; - break; - case CURLOPT_TFTP_NO_OPTIONS: - /* - * Option that prevents libcurl from sending TFTP option requests to the - * server. - */ - data->set.tftp_no_options = va_arg(param, long) != 0; - break; - case CURLOPT_TFTP_BLKSIZE: - /* - * TFTP option that specifies the block size to use for data transmission. - */ - data->set.tftp_blksize = va_arg(param, long); - break; - case CURLOPT_DIRLISTONLY: - /* - * An option that changes the command to one that asks for a list - * only, no file info details. - */ - data->set.ftp_list_only = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_APPEND: - /* - * We want to upload and append to an existing file. - */ - data->set.ftp_append = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_FTP_FILEMETHOD: - /* - * How do access files over FTP. - */ - data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long); - break; - case CURLOPT_NETRC: - /* - * Parse the $HOME/.netrc file - */ - data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long); - break; - case CURLOPT_NETRC_FILE: - /* - * Use this file instead of the $HOME/.netrc file - */ - result = setstropt(&data->set.str[STRING_NETRC_FILE], - va_arg(param, char *)); - break; - case CURLOPT_TRANSFERTEXT: - /* - * This option was previously named 'FTPASCII'. Renamed to work with - * more protocols than merely FTP. - * - * Transfer using ASCII (instead of BINARY). - */ - data->set.prefer_ascii = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_TIMECONDITION: - /* - * Set HTTP time condition. This must be one of the defines in the - * curl/curl.h header file. - */ - data->set.timecondition = (curl_TimeCond)va_arg(param, long); - break; - case CURLOPT_TIMEVALUE: - /* - * This is the value to compare with the remote document with the - * method set with CURLOPT_TIMECONDITION - */ - data->set.timevalue = (time_t)va_arg(param, long); - break; - case CURLOPT_SSLVERSION: - /* - * Set explicit SSL version to try to connect with, as some SSL - * implementations are lame. - */ -#ifdef USE_SSL - data->set.ssl.version = va_arg(param, long); -#else - result = CURLE_UNKNOWN_OPTION; -#endif - break; - -#ifndef CURL_DISABLE_HTTP - case CURLOPT_AUTOREFERER: - /* - * Switch on automatic referer that gets set if curl follows locations. - */ - data->set.http_auto_referer = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_ACCEPT_ENCODING: - /* - * String to use at the value of Accept-Encoding header. - * - * If the encoding is set to "" we use an Accept-Encoding header that - * encompasses all the encodings we support. - * If the encoding is set to NULL we don't send an Accept-Encoding header - * and ignore an received Content-Encoding header. - * - */ - argptr = va_arg(param, char *); - result = setstropt(&data->set.str[STRING_ENCODING], - (argptr && !*argptr)? - ALL_CONTENT_ENCODINGS: argptr); - break; - - case CURLOPT_TRANSFER_ENCODING: - data->set.http_transfer_encoding = (0 != va_arg(param, long)) ? - TRUE : FALSE; - break; - - case CURLOPT_FOLLOWLOCATION: - /* - * Follow Location: header hints on a HTTP-server. - */ - data->set.http_follow_location = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_UNRESTRICTED_AUTH: - /* - * Send authentication (user+password) when following locations, even when - * hostname changed. - */ - data->set.http_disable_hostname_check_before_authentication = - (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_MAXREDIRS: - /* - * The maximum amount of hops you allow curl to follow Location: - * headers. This should mostly be used to detect never-ending loops. - */ - data->set.maxredirs = va_arg(param, long); - break; - - case CURLOPT_POSTREDIR: - { - /* - * Set the behaviour of POST when redirecting - * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302 - * CURL_REDIR_POST_301 - POST is kept as POST after 301 - * CURL_REDIR_POST_302 - POST is kept as POST after 302 - * CURL_REDIR_POST_303 - POST is kept as POST after 303 - * CURL_REDIR_POST_ALL - POST is kept as POST after 301, 302 and 303 - * other - POST is kept as POST after 301 and 302 - */ - int postRedir = curlx_sltosi(va_arg(param, long)); - data->set.keep_post = postRedir & CURL_REDIR_POST_ALL; - } - break; - - case CURLOPT_POST: - /* Does this option serve a purpose anymore? Yes it does, when - CURLOPT_POSTFIELDS isn't used and the POST data is read off the - callback! */ - if(va_arg(param, long)) { - data->set.httpreq = HTTPREQ_POST; - data->set.opt_no_body = FALSE; /* this is implied */ - } - else - data->set.httpreq = HTTPREQ_GET; - break; - - case CURLOPT_COPYPOSTFIELDS: - /* - * A string with POST data. Makes curl HTTP POST. Even if it is NULL. - * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to - * CURLOPT_COPYPOSTFIELDS and not altered later. - */ - argptr = va_arg(param, char *); - - if(!argptr || data->set.postfieldsize == -1) - result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr); - else { - /* - * Check that requested length does not overflow the size_t type. - */ - - if((data->set.postfieldsize < 0) || - ((sizeof(curl_off_t) != sizeof(size_t)) && - (data->set.postfieldsize > (curl_off_t)((size_t)-1)))) - result = CURLE_OUT_OF_MEMORY; - else { - char * p; - - (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); - - /* Allocate even when size == 0. This satisfies the need of possible - later address compare to detect the COPYPOSTFIELDS mode, and - to mark that postfields is used rather than read function or - form data. - */ - p = malloc((size_t)(data->set.postfieldsize? - data->set.postfieldsize:1)); - - if(!p) - result = CURLE_OUT_OF_MEMORY; - else { - if(data->set.postfieldsize) - memcpy(p, argptr, (size_t)data->set.postfieldsize); - - data->set.str[STRING_COPYPOSTFIELDS] = p; - } - } - } - - data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS]; - data->set.httpreq = HTTPREQ_POST; - break; - - case CURLOPT_POSTFIELDS: - /* - * Like above, but use static data instead of copying it. - */ - data->set.postfields = va_arg(param, void *); - /* Release old copied data. */ - (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); - data->set.httpreq = HTTPREQ_POST; - break; - - case CURLOPT_POSTFIELDSIZE: - /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. - */ - bigsize = va_arg(param, long); - - if(data->set.postfieldsize < bigsize && - data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { - /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ - (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); - data->set.postfields = NULL; - } - - data->set.postfieldsize = bigsize; - break; - - case CURLOPT_POSTFIELDSIZE_LARGE: - /* - * The size of the POSTFIELD data to prevent libcurl to do strlen() to - * figure it out. Enables binary posts. - */ - bigsize = va_arg(param, curl_off_t); - - if(data->set.postfieldsize < bigsize && - data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) { - /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */ - (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL); - data->set.postfields = NULL; - } - - data->set.postfieldsize = bigsize; - break; - - case CURLOPT_HTTPPOST: - /* - * Set to make us do HTTP POST - */ - data->set.httppost = va_arg(param, struct curl_httppost *); - data->set.httpreq = HTTPREQ_POST_FORM; - data->set.opt_no_body = FALSE; /* this is implied */ - break; - - case CURLOPT_REFERER: - /* - * String to set in the HTTP Referer: field. - */ - if(data->change.referer_alloc) { - Curl_safefree(data->change.referer); - data->change.referer_alloc = FALSE; - } - result = setstropt(&data->set.str[STRING_SET_REFERER], - va_arg(param, char *)); - data->change.referer = data->set.str[STRING_SET_REFERER]; - break; - - case CURLOPT_USERAGENT: - /* - * String to use in the HTTP User-Agent field - */ - result = setstropt(&data->set.str[STRING_USERAGENT], - va_arg(param, char *)); - break; - - case CURLOPT_HTTPHEADER: - /* - * Set a list with HTTP headers to use (or replace internals with) - */ - data->set.headers = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_PROXYHEADER: - /* - * Set a list with proxy headers to use (or replace internals with) - * - * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a - * long time we remain doing it this way until CURLOPT_PROXYHEADER is - * used. As soon as this option has been used, if set to anything but - * NULL, custom headers for proxies are only picked from this list. - * - * Set this option to NULL to restore the previous behavior. - */ - data->set.proxyheaders = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_HEADEROPT: - /* - * Set header option. - */ - arg = va_arg(param, long); - data->set.sep_headers = (arg & CURLHEADER_SEPARATE)? TRUE: FALSE; - break; - - case CURLOPT_HTTP200ALIASES: - /* - * Set a list of aliases for HTTP 200 in response header - */ - data->set.http200aliases = va_arg(param, struct curl_slist *); - break; - -#if !defined(CURL_DISABLE_COOKIES) - case CURLOPT_COOKIE: - /* - * Cookie string to send to the remote server in the request. - */ - result = setstropt(&data->set.str[STRING_COOKIE], - va_arg(param, char *)); - break; - - case CURLOPT_COOKIEFILE: - /* - * Set cookie file to read and parse. Can be used multiple times. - */ - argptr = (char *)va_arg(param, void *); - if(argptr) { - struct curl_slist *cl; - /* append the cookie file name to the list of file names, and deal with - them later */ - cl = curl_slist_append(data->change.cookielist, argptr); - if(!cl) { - curl_slist_free_all(data->change.cookielist); - data->change.cookielist = NULL; - return CURLE_OUT_OF_MEMORY; - } - data->change.cookielist = cl; /* store the list for later use */ - } - break; - - case CURLOPT_COOKIEJAR: - /* - * Set cookie file name to dump all cookies to when we're done. - */ - { - struct CookieInfo *newcookies; - result = setstropt(&data->set.str[STRING_COOKIEJAR], - va_arg(param, char *)); - - /* - * Activate the cookie parser. This may or may not already - * have been made. - */ - newcookies = Curl_cookie_init(data, NULL, data->cookies, - data->set.cookiesession); - if(!newcookies) - result = CURLE_OUT_OF_MEMORY; - data->cookies = newcookies; - } - break; - - case CURLOPT_COOKIESESSION: - /* - * Set this option to TRUE to start a new "cookie session". It will - * prevent the forthcoming read-cookies-from-file actions to accept - * cookies that are marked as being session cookies, as they belong to a - * previous session. - * - * In the original Netscape cookie spec, "session cookies" are cookies - * with no expire date set. RFC2109 describes the same action if no - * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds - * a 'Discard' action that can enforce the discard even for cookies that - * have a Max-Age. - * - * We run mostly with the original cookie spec, as hardly anyone implements - * anything else. - */ - data->set.cookiesession = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_COOKIELIST: - argptr = va_arg(param, char *); - - if(argptr == NULL) - break; - - if(Curl_raw_equal(argptr, "ALL")) { - /* clear all cookies */ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_clearall(data->cookies); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - else if(Curl_raw_equal(argptr, "SESS")) { - /* clear session cookies */ - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - Curl_cookie_clearsess(data->cookies); - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - } - else if(Curl_raw_equal(argptr, "FLUSH")) { - /* flush cookies to file, takes care of the locking */ - Curl_flush_cookies(data, 0); - } - else if(Curl_raw_equal(argptr, "RELOAD")) { - /* reload cookies from file */ - Curl_cookie_loadfiles(data); - break; - } - else { - if(!data->cookies) - /* if cookie engine was not running, activate it */ - data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE); - - argptr = strdup(argptr); - if(!argptr || !data->cookies) { - result = CURLE_OUT_OF_MEMORY; - free(argptr); - } - else { - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - - if(checkprefix("Set-Cookie:", argptr)) - /* HTTP Header format line */ - Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL); - - else - /* Netscape format line */ - Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL); - - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); - free(argptr); - } - } - - break; -#endif /* CURL_DISABLE_COOKIES */ - - case CURLOPT_HTTPGET: - /* - * Set to force us do HTTP GET - */ - if(va_arg(param, long)) { - data->set.httpreq = HTTPREQ_GET; - data->set.upload = FALSE; /* switch off upload */ - data->set.opt_no_body = FALSE; /* this is implied */ - } - break; - - case CURLOPT_HTTP_VERSION: - /* - * This sets a requested HTTP version to be used. The value is one of - * the listed enums in curl/curl.h. - */ - arg = va_arg(param, long); -#ifndef USE_NGHTTP2 - if(arg >= CURL_HTTP_VERSION_2) - return CURLE_UNSUPPORTED_PROTOCOL; -#endif - data->set.httpversion = arg; - break; - - case CURLOPT_HTTPAUTH: - /* - * Set HTTP Authentication type BITMASK. - */ - { - int bitcheck; - bool authbits; - unsigned long auth = va_arg(param, unsigned long); - - if(auth == CURLAUTH_NONE) { - data->set.httpauth = auth; - break; - } - - /* the DIGEST_IE bit is only used to set a special marker, for all the - rest we need to handle it as normal DIGEST */ - data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE; - - if(auth & CURLAUTH_DIGEST_IE) { - auth |= CURLAUTH_DIGEST; /* set standard digest bit */ - auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ - } - - /* switch off bits we can't support */ -#ifndef USE_NTLM - auth &= ~CURLAUTH_NTLM; /* no NTLM support */ - auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ -#elif !defined(NTLM_WB_ENABLED) - auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ -#endif -#ifndef USE_SPNEGO - auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without - GSS-API or SSPI */ -#endif - - /* check if any auth bit lower than CURLAUTH_ONLY is still set */ - bitcheck = 0; - authbits = FALSE; - while(bitcheck < 31) { - if(auth & (1UL << bitcheck++)) { - authbits = TRUE; - break; - } - } - if(!authbits) - return CURLE_NOT_BUILT_IN; /* no supported types left! */ - - data->set.httpauth = auth; - } - break; - - case CURLOPT_EXPECT_100_TIMEOUT_MS: - /* - * Time to wait for a response to a HTTP request containing an - * Expect: 100-continue header before sending the data anyway. - */ - data->set.expect_100_timeout = va_arg(param, long); - break; - -#endif /* CURL_DISABLE_HTTP */ - - case CURLOPT_CUSTOMREQUEST: - /* - * Set a custom string to use as request - */ - result = setstropt(&data->set.str[STRING_CUSTOMREQUEST], - va_arg(param, char *)); - - /* we don't set - data->set.httpreq = HTTPREQ_CUSTOM; - here, we continue as if we were using the already set type - and this just changes the actual request keyword */ - break; - -#ifndef CURL_DISABLE_PROXY - case CURLOPT_HTTPPROXYTUNNEL: - /* - * Tunnel operations through the proxy instead of normal proxy use - */ - data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long)) ? - TRUE : FALSE; - break; - - case CURLOPT_PROXYPORT: - /* - * Explicitly set HTTP proxy port number. - */ - data->set.proxyport = va_arg(param, long); - break; - - case CURLOPT_PROXYAUTH: - /* - * Set HTTP Authentication type BITMASK. - */ - { - int bitcheck; - bool authbits; - unsigned long auth = va_arg(param, unsigned long); - - if(auth == CURLAUTH_NONE) { - data->set.proxyauth = auth; - break; - } - - /* the DIGEST_IE bit is only used to set a special marker, for all the - rest we need to handle it as normal DIGEST */ - data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE) ? TRUE : FALSE; - - if(auth & CURLAUTH_DIGEST_IE) { - auth |= CURLAUTH_DIGEST; /* set standard digest bit */ - auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ - } - /* switch off bits we can't support */ -#ifndef USE_NTLM - auth &= ~CURLAUTH_NTLM; /* no NTLM support */ - auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ -#elif !defined(NTLM_WB_ENABLED) - auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */ -#endif -#ifndef USE_SPNEGO - auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without - GSS-API or SSPI */ -#endif - - /* check if any auth bit lower than CURLAUTH_ONLY is still set */ - bitcheck = 0; - authbits = FALSE; - while(bitcheck < 31) { - if(auth & (1UL << bitcheck++)) { - authbits = TRUE; - break; - } - } - if(!authbits) - return CURLE_NOT_BUILT_IN; /* no supported types left! */ - - data->set.proxyauth = auth; - } - break; - - case CURLOPT_PROXY: - /* - * Set proxy server:port to use as HTTP proxy. - * - * If the proxy is set to "" we explicitly say that we don't want to use a - * proxy (even though there might be environment variables saying so). - * - * Setting it to NULL, means no proxy but allows the environment variables - * to decide for us. - */ - result = setstropt(&data->set.str[STRING_PROXY], - va_arg(param, char *)); - break; - - case CURLOPT_PROXYTYPE: - /* - * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME - */ - data->set.proxytype = (curl_proxytype)va_arg(param, long); - break; - - case CURLOPT_PROXY_TRANSFER_MODE: - /* - * set transfer mode (;type=) when doing FTP via an HTTP proxy - */ - switch (va_arg(param, long)) { - case 0: - data->set.proxy_transfer_mode = FALSE; - break; - case 1: - data->set.proxy_transfer_mode = TRUE; - break; - default: - /* reserve other values for future use */ - result = CURLE_UNKNOWN_OPTION; - break; - } - break; -#endif /* CURL_DISABLE_PROXY */ - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - case CURLOPT_SOCKS5_GSSAPI_NEC: - /* - * Set flag for NEC SOCK5 support - */ - data->set.socks5_gssapi_nec = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_SOCKS5_GSSAPI_SERVICE: - case CURLOPT_PROXY_SERVICE_NAME: - /* - * Set proxy authentication service name for Kerberos 5 and SPNEGO - */ - result = setstropt(&data->set.str[STRING_PROXY_SERVICE_NAME], - va_arg(param, char *)); - break; -#endif - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ - defined(USE_SPNEGO) - case CURLOPT_SERVICE_NAME: - /* - * Set authentication service name for DIGEST-MD5, Kerberos 5 and SPNEGO - */ - result = setstropt(&data->set.str[STRING_SERVICE_NAME], - va_arg(param, char *)); - break; - -#endif - - case CURLOPT_HEADERDATA: - /* - * Custom pointer to pass the header write callback function - */ - data->set.writeheader = (void *)va_arg(param, void *); - break; - case CURLOPT_ERRORBUFFER: - /* - * Error buffer provided by the caller to get the human readable - * error string in. - */ - data->set.errorbuffer = va_arg(param, char *); - break; - case CURLOPT_WRITEDATA: - /* - * FILE pointer to write to. Or possibly - * used as argument to the write callback. - */ - data->set.out = va_arg(param, void *); - break; - case CURLOPT_FTPPORT: - /* - * Use FTP PORT, this also specifies which IP address to use - */ - result = setstropt(&data->set.str[STRING_FTPPORT], - va_arg(param, char *)); - data->set.ftp_use_port = (data->set.str[STRING_FTPPORT]) ? TRUE : FALSE; - break; - - case CURLOPT_FTP_USE_EPRT: - data->set.ftp_use_eprt = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_FTP_USE_EPSV: - data->set.ftp_use_epsv = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_FTP_USE_PRET: - data->set.ftp_use_pret = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_FTP_SSL_CCC: - data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long); - break; - - case CURLOPT_FTP_SKIP_PASV_IP: - /* - * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the - * bypass of the IP address in PASV responses. - */ - data->set.ftp_skip_ip = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_READDATA: - /* - * FILE pointer to read the file to be uploaded from. Or possibly - * used as argument to the read callback. - */ - data->set.in_set = va_arg(param, void *); - break; - case CURLOPT_INFILESIZE: - /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. - */ - data->set.filesize = va_arg(param, long); - break; - case CURLOPT_INFILESIZE_LARGE: - /* - * If known, this should inform curl about the file size of the - * to-be-uploaded file. - */ - data->set.filesize = va_arg(param, curl_off_t); - break; - case CURLOPT_LOW_SPEED_LIMIT: - /* - * The low speed limit that if transfers are below this for - * CURLOPT_LOW_SPEED_TIME, the transfer is aborted. - */ - data->set.low_speed_limit=va_arg(param, long); - break; - case CURLOPT_MAX_SEND_SPEED_LARGE: - /* - * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE - * bytes per second the transfer is throttled.. - */ - data->set.max_send_speed=va_arg(param, curl_off_t); - break; - case CURLOPT_MAX_RECV_SPEED_LARGE: - /* - * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per - * second the transfer is throttled.. - */ - data->set.max_recv_speed=va_arg(param, curl_off_t); - break; - case CURLOPT_LOW_SPEED_TIME: - /* - * The low speed time that if transfers are below the set - * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted. - */ - data->set.low_speed_time=va_arg(param, long); - break; - case CURLOPT_URL: - /* - * The URL to fetch. - */ - if(data->change.url_alloc) { - /* the already set URL is allocated, free it first! */ - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - result = setstropt(&data->set.str[STRING_SET_URL], - va_arg(param, char *)); - data->change.url = data->set.str[STRING_SET_URL]; - break; - case CURLOPT_PORT: - /* - * The port number to use when getting the URL - */ - data->set.use_port = va_arg(param, long); - break; - case CURLOPT_TIMEOUT: - /* - * The maximum time you allow curl to use for a single transfer - * operation. - */ - data->set.timeout = va_arg(param, long) * 1000L; - break; - - case CURLOPT_TIMEOUT_MS: - data->set.timeout = va_arg(param, long); - break; - - case CURLOPT_CONNECTTIMEOUT: - /* - * The maximum time you allow curl to use to connect. - */ - data->set.connecttimeout = va_arg(param, long) * 1000L; - break; - - case CURLOPT_CONNECTTIMEOUT_MS: - data->set.connecttimeout = va_arg(param, long); - break; - - case CURLOPT_ACCEPTTIMEOUT_MS: - /* - * The maximum time you allow curl to wait for server connect - */ - data->set.accepttimeout = va_arg(param, long); - break; - - case CURLOPT_USERPWD: - /* - * user:password to use in the operation - */ - result = setstropt_userpwd(va_arg(param, char *), - &data->set.str[STRING_USERNAME], - &data->set.str[STRING_PASSWORD]); - break; - - case CURLOPT_USERNAME: - /* - * authentication user name to use in the operation - */ - result = setstropt(&data->set.str[STRING_USERNAME], - va_arg(param, char *)); - break; - - case CURLOPT_PASSWORD: - /* - * authentication password to use in the operation - */ - result = setstropt(&data->set.str[STRING_PASSWORD], - va_arg(param, char *)); - break; - - case CURLOPT_LOGIN_OPTIONS: - /* - * authentication options to use in the operation - */ - result = setstropt(&data->set.str[STRING_OPTIONS], - va_arg(param, char *)); - break; - - case CURLOPT_XOAUTH2_BEARER: - /* - * OAuth 2.0 bearer token to use in the operation - */ - result = setstropt(&data->set.str[STRING_BEARER], - va_arg(param, char *)); - break; - - case CURLOPT_POSTQUOTE: - /* - * List of RAW FTP commands to use after a transfer - */ - data->set.postquote = va_arg(param, struct curl_slist *); - break; - case CURLOPT_PREQUOTE: - /* - * List of RAW FTP commands to use prior to RETR (Wesley Laxton) - */ - data->set.prequote = va_arg(param, struct curl_slist *); - break; - case CURLOPT_QUOTE: - /* - * List of RAW FTP commands to use before a transfer - */ - data->set.quote = va_arg(param, struct curl_slist *); - break; - case CURLOPT_RESOLVE: - /* - * List of NAME:[address] names to populate the DNS cache with - * Prefix the NAME with dash (-) to _remove_ the name from the cache. - * - * Names added with this API will remain in the cache until explicitly - * removed or the handle is cleaned up. - * - * This API can remove any name from the DNS cache, but only entries - * that aren't actually in use right now will be pruned immediately. - */ - data->set.resolve = va_arg(param, struct curl_slist *); - data->change.resolve = data->set.resolve; - break; - case CURLOPT_PROGRESSFUNCTION: - /* - * Progress callback function - */ - data->set.fprogress = va_arg(param, curl_progress_callback); - if(data->set.fprogress) - data->progress.callback = TRUE; /* no longer internal */ - else - data->progress.callback = FALSE; /* NULL enforces internal */ - break; - - case CURLOPT_XFERINFOFUNCTION: - /* - * Transfer info callback function - */ - data->set.fxferinfo = va_arg(param, curl_xferinfo_callback); - if(data->set.fxferinfo) - data->progress.callback = TRUE; /* no longer internal */ - else - data->progress.callback = FALSE; /* NULL enforces internal */ - - break; - - case CURLOPT_PROGRESSDATA: - /* - * Custom client data to pass to the progress callback - */ - data->set.progress_client = va_arg(param, void *); - break; - -#ifndef CURL_DISABLE_PROXY - case CURLOPT_PROXYUSERPWD: - /* - * user:password needed to use the proxy - */ - result = setstropt_userpwd(va_arg(param, char *), - &data->set.str[STRING_PROXYUSERNAME], - &data->set.str[STRING_PROXYPASSWORD]); - break; - case CURLOPT_PROXYUSERNAME: - /* - * authentication user name to use in the operation - */ - result = setstropt(&data->set.str[STRING_PROXYUSERNAME], - va_arg(param, char *)); - break; - case CURLOPT_PROXYPASSWORD: - /* - * authentication password to use in the operation - */ - result = setstropt(&data->set.str[STRING_PROXYPASSWORD], - va_arg(param, char *)); - break; - case CURLOPT_NOPROXY: - /* - * proxy exception list - */ - result = setstropt(&data->set.str[STRING_NOPROXY], - va_arg(param, char *)); - break; -#endif - - case CURLOPT_RANGE: - /* - * What range of the file you want to transfer - */ - result = setstropt(&data->set.str[STRING_SET_RANGE], - va_arg(param, char *)); - break; - case CURLOPT_RESUME_FROM: - /* - * Resume transfer at the give file position - */ - data->set.set_resume_from = va_arg(param, long); - break; - case CURLOPT_RESUME_FROM_LARGE: - /* - * Resume transfer at the give file position - */ - data->set.set_resume_from = va_arg(param, curl_off_t); - break; - case CURLOPT_DEBUGFUNCTION: - /* - * stderr write callback. - */ - data->set.fdebug = va_arg(param, curl_debug_callback); - /* - * if the callback provided is NULL, it'll use the default callback - */ - break; - case CURLOPT_DEBUGDATA: - /* - * Set to a void * that should receive all error writes. This - * defaults to CURLOPT_STDERR for normal operations. - */ - data->set.debugdata = va_arg(param, void *); - break; - case CURLOPT_STDERR: - /* - * Set to a FILE * that should receive all error writes. This - * defaults to stderr for normal operations. - */ - data->set.err = va_arg(param, FILE *); - if(!data->set.err) - data->set.err = stderr; - break; - case CURLOPT_HEADERFUNCTION: - /* - * Set header write callback - */ - data->set.fwrite_header = va_arg(param, curl_write_callback); - break; - case CURLOPT_WRITEFUNCTION: - /* - * Set data write callback - */ - data->set.fwrite_func = va_arg(param, curl_write_callback); - if(!data->set.fwrite_func) { - data->set.is_fwrite_set = 0; - /* When set to NULL, reset to our internal default function */ - data->set.fwrite_func = (curl_write_callback)fwrite; - } - else - data->set.is_fwrite_set = 1; - break; - case CURLOPT_READFUNCTION: - /* - * Read data callback - */ - data->set.fread_func_set = va_arg(param, curl_read_callback); - if(!data->set.fread_func_set) { - data->set.is_fread_set = 0; - /* When set to NULL, reset to our internal default function */ - data->set.fread_func_set = (curl_read_callback)fread; - } - else - data->set.is_fread_set = 1; - break; - case CURLOPT_SEEKFUNCTION: - /* - * Seek callback. Might be NULL. - */ - data->set.seek_func = va_arg(param, curl_seek_callback); - break; - case CURLOPT_SEEKDATA: - /* - * Seek control callback. Might be NULL. - */ - data->set.seek_client = va_arg(param, void *); - break; - case CURLOPT_CONV_FROM_NETWORK_FUNCTION: - /* - * "Convert from network encoding" callback - */ - data->set.convfromnetwork = va_arg(param, curl_conv_callback); - break; - case CURLOPT_CONV_TO_NETWORK_FUNCTION: - /* - * "Convert to network encoding" callback - */ - data->set.convtonetwork = va_arg(param, curl_conv_callback); - break; - case CURLOPT_CONV_FROM_UTF8_FUNCTION: - /* - * "Convert from UTF-8 encoding" callback - */ - data->set.convfromutf8 = va_arg(param, curl_conv_callback); - break; - case CURLOPT_IOCTLFUNCTION: - /* - * I/O control callback. Might be NULL. - */ - data->set.ioctl_func = va_arg(param, curl_ioctl_callback); - break; - case CURLOPT_IOCTLDATA: - /* - * I/O control data pointer. Might be NULL. - */ - data->set.ioctl_client = va_arg(param, void *); - break; - case CURLOPT_SSLCERT: - /* - * String that holds file name of the SSL certificate to use - */ - result = setstropt(&data->set.str[STRING_CERT], - va_arg(param, char *)); - break; - case CURLOPT_SSLCERTTYPE: - /* - * String that holds file type of the SSL certificate to use - */ - result = setstropt(&data->set.str[STRING_CERT_TYPE], - va_arg(param, char *)); - break; - case CURLOPT_SSLKEY: - /* - * String that holds file name of the SSL key to use - */ - result = setstropt(&data->set.str[STRING_KEY], - va_arg(param, char *)); - break; - case CURLOPT_SSLKEYTYPE: - /* - * String that holds file type of the SSL key to use - */ - result = setstropt(&data->set.str[STRING_KEY_TYPE], - va_arg(param, char *)); - break; - case CURLOPT_KEYPASSWD: - /* - * String that holds the SSL or SSH private key password. - */ - result = setstropt(&data->set.str[STRING_KEY_PASSWD], - va_arg(param, char *)); - break; - case CURLOPT_SSLENGINE: - /* - * String that holds the SSL crypto engine. - */ - argptr = va_arg(param, char *); - if(argptr && argptr[0]) - result = Curl_ssl_set_engine(data, argptr); - break; - - case CURLOPT_SSLENGINE_DEFAULT: - /* - * flag to set engine as default. - */ - result = Curl_ssl_set_engine_default(data); - break; - case CURLOPT_CRLF: - /* - * Kludgy option to enable CRLF conversions. Subject for removal. - */ - data->set.crlf = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_INTERFACE: - /* - * Set what interface or address/hostname to bind the socket to when - * performing an operation and thus what from-IP your connection will use. - */ - result = setstropt(&data->set.str[STRING_DEVICE], - va_arg(param, char *)); - break; - case CURLOPT_LOCALPORT: - /* - * Set what local port to bind the socket to when performing an operation. - */ - data->set.localport = curlx_sltous(va_arg(param, long)); - break; - case CURLOPT_LOCALPORTRANGE: - /* - * Set number of local ports to try, starting with CURLOPT_LOCALPORT. - */ - data->set.localportrange = curlx_sltosi(va_arg(param, long)); - break; - case CURLOPT_KRBLEVEL: - /* - * A string that defines the kerberos security level. - */ - result = setstropt(&data->set.str[STRING_KRB_LEVEL], - va_arg(param, char *)); - data->set.krb = (data->set.str[STRING_KRB_LEVEL]) ? TRUE : FALSE; - break; - case CURLOPT_GSSAPI_DELEGATION: - /* - * GSS-API credential delegation - */ - data->set.gssapi_delegation = va_arg(param, long); - break; - case CURLOPT_SSL_VERIFYPEER: - /* - * Enable peer SSL verifying. - */ - data->set.ssl.verifypeer = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_SSL_VERIFYHOST: - /* - * Enable verification of the host name in the peer certificate - */ - arg = va_arg(param, long); - - /* Obviously people are not reading documentation and too many thought - this argument took a boolean when it wasn't and misused it. We thus ban - 1 as a sensible input and we warn about its use. Then we only have the - 2 action internally stored as TRUE. */ - - if(1 == arg) { - failf(data, "CURLOPT_SSL_VERIFYHOST no longer supports 1 as value!"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - - data->set.ssl.verifyhost = (0 != arg) ? TRUE : FALSE; - break; - case CURLOPT_SSL_VERIFYSTATUS: - /* - * Enable certificate status verifying. - */ - if(!Curl_ssl_cert_status_request()) { - result = CURLE_NOT_BUILT_IN; - break; - } - - data->set.ssl.verifystatus = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_SSL_CTX_FUNCTION: -#ifdef have_curlssl_ssl_ctx - /* - * Set a SSL_CTX callback - */ - data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback); -#else - result = CURLE_NOT_BUILT_IN; -#endif - break; - case CURLOPT_SSL_CTX_DATA: -#ifdef have_curlssl_ssl_ctx - /* - * Set a SSL_CTX callback parameter pointer - */ - data->set.ssl.fsslctxp = va_arg(param, void *); -#else - result = CURLE_NOT_BUILT_IN; -#endif - break; - case CURLOPT_SSL_FALSESTART: - /* - * Enable TLS false start. - */ - if(!Curl_ssl_false_start()) { - result = CURLE_NOT_BUILT_IN; - break; - } - - data->set.ssl.falsestart = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_CERTINFO: -#ifdef have_curlssl_certinfo - data->set.ssl.certinfo = (0 != va_arg(param, long)) ? TRUE : FALSE; -#else - result = CURLE_NOT_BUILT_IN; -#endif - break; - case CURLOPT_PINNEDPUBLICKEY: -#ifdef have_curlssl_pinnedpubkey /* only by supported backends */ - /* - * Set pinned public key for SSL connection. - * Specify file name of the public key in DER format. - */ - result = setstropt(&data->set.str[STRING_SSL_PINNEDPUBLICKEY], - va_arg(param, char *)); -#else - result = CURLE_NOT_BUILT_IN; -#endif - break; - case CURLOPT_CAINFO: - /* - * Set CA info for SSL connection. Specify file name of the CA certificate - */ - result = setstropt(&data->set.str[STRING_SSL_CAFILE], - va_arg(param, char *)); - break; - case CURLOPT_CAPATH: -#ifdef have_curlssl_ca_path /* not supported by all backends */ - /* - * Set CA path info for SSL connection. Specify directory name of the CA - * certificates which have been prepared using openssl c_rehash utility. - */ - /* This does not work on windows. */ - result = setstropt(&data->set.str[STRING_SSL_CAPATH], - va_arg(param, char *)); -#else - result = CURLE_NOT_BUILT_IN; -#endif - break; - case CURLOPT_CRLFILE: - /* - * Set CRL file info for SSL connection. Specify file name of the CRL - * to check certificates revocation - */ - result = setstropt(&data->set.str[STRING_SSL_CRLFILE], - va_arg(param, char *)); - break; - case CURLOPT_ISSUERCERT: - /* - * Set Issuer certificate file - * to check certificates issuer - */ - result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT], - va_arg(param, char *)); - break; - case CURLOPT_TELNETOPTIONS: - /* - * Set a linked list of telnet options - */ - data->set.telnet_options = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_BUFFERSIZE: - /* - * The application kindly asks for a differently sized receive buffer. - * If it seems reasonable, we'll use it. - */ - data->set.buffer_size = va_arg(param, long); - - if((data->set.buffer_size> (BUFSIZE -1)) || - (data->set.buffer_size < 1)) - data->set.buffer_size = 0; /* huge internal default */ - - break; - - case CURLOPT_NOSIGNAL: - /* - * The application asks not to set any signal() or alarm() handlers, - * even when using a timeout. - */ - data->set.no_signal = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_SHARE: - { - struct Curl_share *set; - set = va_arg(param, struct Curl_share *); - - /* disconnect from old share, if any */ - if(data->share) { - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - - if(data->dns.hostcachetype == HCACHE_SHARED) { - data->dns.hostcache = NULL; - data->dns.hostcachetype = HCACHE_NONE; - } - -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(data->share->cookies == data->cookies) - data->cookies = NULL; -#endif - - if(data->share->sslsession == data->state.session) - data->state.session = NULL; - - data->share->dirty--; - - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - data->share = NULL; - } - - /* use new share if it set */ - data->share = set; - if(data->share) { - - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - - data->share->dirty++; - - if(data->share->specifier & (1<< CURL_LOCK_DATA_DNS)) { - /* use shared host cache */ - data->dns.hostcache = &data->share->hostcache; - data->dns.hostcachetype = HCACHE_SHARED; - } -#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - if(data->share->cookies) { - /* use shared cookie list, first free own one if any */ - Curl_cookie_cleanup(data->cookies); - /* enable cookies since we now use a share that uses cookies! */ - data->cookies = data->share->cookies; - } -#endif /* CURL_DISABLE_HTTP */ - if(data->share->sslsession) { - data->set.ssl.max_ssl_sessions = data->share->max_ssl_sessions; - data->state.session = data->share->sslsession; - } - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); - - } - /* check for host cache not needed, - * it will be done by curl_easy_perform */ - } - break; - - case CURLOPT_PRIVATE: - /* - * Set private data pointer. - */ - data->set.private_data = va_arg(param, void *); - break; - - case CURLOPT_MAXFILESIZE: - /* - * Set the maximum size of a file to download. - */ - data->set.max_filesize = va_arg(param, long); - break; - -#ifdef USE_SSL - case CURLOPT_USE_SSL: - /* - * Make transfers attempt to use SSL/TLS. - */ - data->set.use_ssl = (curl_usessl)va_arg(param, long); - break; - - case CURLOPT_SSL_OPTIONS: - arg = va_arg(param, long); - data->set.ssl_enable_beast = !!(arg & CURLSSLOPT_ALLOW_BEAST); - data->set.ssl_no_revoke = !!(arg & CURLSSLOPT_NO_REVOKE); - break; - -#endif - case CURLOPT_FTPSSLAUTH: - /* - * Set a specific auth for FTP-SSL transfers. - */ - data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long); - break; - - case CURLOPT_IPRESOLVE: - data->set.ipver = va_arg(param, long); - break; - - case CURLOPT_MAXFILESIZE_LARGE: - /* - * Set the maximum size of a file to download. - */ - data->set.max_filesize = va_arg(param, curl_off_t); - break; - - case CURLOPT_TCP_NODELAY: - /* - * Enable or disable TCP_NODELAY, which will disable/enable the Nagle - * algorithm - */ - data->set.tcp_nodelay = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_FTP_ACCOUNT: - result = setstropt(&data->set.str[STRING_FTP_ACCOUNT], - va_arg(param, char *)); - break; - - case CURLOPT_IGNORE_CONTENT_LENGTH: - data->set.ignorecl = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_CONNECT_ONLY: - /* - * No data transfer, set up connection and let application use the socket - */ - data->set.connect_only = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_FTP_ALTERNATIVE_TO_USER: - result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER], - va_arg(param, char *)); - break; - - case CURLOPT_SOCKOPTFUNCTION: - /* - * socket callback function: called after socket() but before connect() - */ - data->set.fsockopt = va_arg(param, curl_sockopt_callback); - break; - - case CURLOPT_SOCKOPTDATA: - /* - * socket callback data pointer. Might be NULL. - */ - data->set.sockopt_client = va_arg(param, void *); - break; - - case CURLOPT_OPENSOCKETFUNCTION: - /* - * open/create socket callback function: called instead of socket(), - * before connect() - */ - data->set.fopensocket = va_arg(param, curl_opensocket_callback); - break; - - case CURLOPT_OPENSOCKETDATA: - /* - * socket callback data pointer. Might be NULL. - */ - data->set.opensocket_client = va_arg(param, void *); - break; - - case CURLOPT_CLOSESOCKETFUNCTION: - /* - * close socket callback function: called instead of close() - * when shutting down a connection - */ - data->set.fclosesocket = va_arg(param, curl_closesocket_callback); - break; - - case CURLOPT_CLOSESOCKETDATA: - /* - * socket callback data pointer. Might be NULL. - */ - data->set.closesocket_client = va_arg(param, void *); - break; - - case CURLOPT_SSL_SESSIONID_CACHE: - data->set.ssl.sessionid = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - -#ifdef USE_LIBSSH2 - /* we only include SSH options if explicitly built to support SSH */ - case CURLOPT_SSH_AUTH_TYPES: - data->set.ssh_auth_types = va_arg(param, long); - break; - - case CURLOPT_SSH_PUBLIC_KEYFILE: - /* - * Use this file instead of the $HOME/.ssh/id_dsa.pub file - */ - result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY], - va_arg(param, char *)); - break; - - case CURLOPT_SSH_PRIVATE_KEYFILE: - /* - * Use this file instead of the $HOME/.ssh/id_dsa file - */ - result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY], - va_arg(param, char *)); - break; - case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5: - /* - * Option to allow for the MD5 of the host public key to be checked - * for validation purposes. - */ - result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], - va_arg(param, char *)); - break; -#ifdef HAVE_LIBSSH2_KNOWNHOST_API - case CURLOPT_SSH_KNOWNHOSTS: - /* - * Store the file name to read known hosts from. - */ - result = setstropt(&data->set.str[STRING_SSH_KNOWNHOSTS], - va_arg(param, char *)); - break; - - case CURLOPT_SSH_KEYFUNCTION: - /* setting to NULL is fine since the ssh.c functions themselves will - then rever to use the internal default */ - data->set.ssh_keyfunc = va_arg(param, curl_sshkeycallback); - break; - - case CURLOPT_SSH_KEYDATA: - /* - * Custom client data to pass to the SSH keyfunc callback - */ - data->set.ssh_keyfunc_userp = va_arg(param, void *); - break; -#endif /* HAVE_LIBSSH2_KNOWNHOST_API */ - -#endif /* USE_LIBSSH2 */ - - case CURLOPT_HTTP_TRANSFER_DECODING: - /* - * disable libcurl transfer encoding is used - */ - data->set.http_te_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_HTTP_CONTENT_DECODING: - /* - * raw data passed to the application when content encoding is used - */ - data->set.http_ce_skip = (0 == va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_NEW_FILE_PERMS: - /* - * Uses these permissions instead of 0644 - */ - data->set.new_file_perms = va_arg(param, long); - break; - - case CURLOPT_NEW_DIRECTORY_PERMS: - /* - * Uses these permissions instead of 0755 - */ - data->set.new_directory_perms = va_arg(param, long); - break; - - case CURLOPT_ADDRESS_SCOPE: - /* - * We always get longs when passed plain numericals, but for this value we - * know that an unsigned int will always hold the value so we blindly - * typecast to this type - */ - data->set.scope_id = curlx_sltoui(va_arg(param, long)); - break; - - case CURLOPT_PROTOCOLS: - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - data->set.allowed_protocols = va_arg(param, long); - break; - - case CURLOPT_REDIR_PROTOCOLS: - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. Defaults - to all protocols except FILE and SCP. */ - data->set.redir_protocols = va_arg(param, long); - break; - - case CURLOPT_DEFAULT_PROTOCOL: - /* Set the protocol to use when the URL doesn't include any protocol */ - result = setstropt(&data->set.str[STRING_DEFAULT_PROTOCOL], - va_arg(param, char *)); - break; - - case CURLOPT_MAIL_FROM: - /* Set the SMTP mail originator */ - result = setstropt(&data->set.str[STRING_MAIL_FROM], - va_arg(param, char *)); - break; - - case CURLOPT_MAIL_AUTH: - /* Set the SMTP auth originator */ - result = setstropt(&data->set.str[STRING_MAIL_AUTH], - va_arg(param, char *)); - break; - - case CURLOPT_MAIL_RCPT: - /* Set the list of mail recipients */ - data->set.mail_rcpt = va_arg(param, struct curl_slist *); - break; - - case CURLOPT_SASL_IR: - /* Enable/disable SASL initial response */ - data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - - case CURLOPT_RTSP_REQUEST: - { - /* - * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) - * Would this be better if the RTSPREQ_* were just moved into here? - */ - long curl_rtspreq = va_arg(param, long); - Curl_RtspReq rtspreq = RTSPREQ_NONE; - switch(curl_rtspreq) { - case CURL_RTSPREQ_OPTIONS: - rtspreq = RTSPREQ_OPTIONS; - break; - - case CURL_RTSPREQ_DESCRIBE: - rtspreq = RTSPREQ_DESCRIBE; - break; - - case CURL_RTSPREQ_ANNOUNCE: - rtspreq = RTSPREQ_ANNOUNCE; - break; - - case CURL_RTSPREQ_SETUP: - rtspreq = RTSPREQ_SETUP; - break; - - case CURL_RTSPREQ_PLAY: - rtspreq = RTSPREQ_PLAY; - break; - - case CURL_RTSPREQ_PAUSE: - rtspreq = RTSPREQ_PAUSE; - break; - - case CURL_RTSPREQ_TEARDOWN: - rtspreq = RTSPREQ_TEARDOWN; - break; - - case CURL_RTSPREQ_GET_PARAMETER: - rtspreq = RTSPREQ_GET_PARAMETER; - break; - - case CURL_RTSPREQ_SET_PARAMETER: - rtspreq = RTSPREQ_SET_PARAMETER; - break; - - case CURL_RTSPREQ_RECORD: - rtspreq = RTSPREQ_RECORD; - break; - - case CURL_RTSPREQ_RECEIVE: - rtspreq = RTSPREQ_RECEIVE; - break; - default: - rtspreq = RTSPREQ_NONE; - } - - data->set.rtspreq = rtspreq; - break; - } - - - case CURLOPT_RTSP_SESSION_ID: - /* - * Set the RTSP Session ID manually. Useful if the application is - * resuming a previously established RTSP session - */ - result = setstropt(&data->set.str[STRING_RTSP_SESSION_ID], - va_arg(param, char *)); - break; - - case CURLOPT_RTSP_STREAM_URI: - /* - * Set the Stream URI for the RTSP request. Unless the request is - * for generic server options, the application will need to set this. - */ - result = setstropt(&data->set.str[STRING_RTSP_STREAM_URI], - va_arg(param, char *)); - break; - - case CURLOPT_RTSP_TRANSPORT: - /* - * The content of the Transport: header for the RTSP request - */ - result = setstropt(&data->set.str[STRING_RTSP_TRANSPORT], - va_arg(param, char *)); - break; - - case CURLOPT_RTSP_CLIENT_CSEQ: - /* - * Set the CSEQ number to issue for the next RTSP request. Useful if the - * application is resuming a previously broken connection. The CSEQ - * will increment from this new number henceforth. - */ - data->state.rtsp_next_client_CSeq = va_arg(param, long); - break; - - case CURLOPT_RTSP_SERVER_CSEQ: - /* Same as the above, but for server-initiated requests */ - data->state.rtsp_next_client_CSeq = va_arg(param, long); - break; - - case CURLOPT_INTERLEAVEDATA: - data->set.rtp_out = va_arg(param, void *); - break; - case CURLOPT_INTERLEAVEFUNCTION: - /* Set the user defined RTP write function */ - data->set.fwrite_rtp = va_arg(param, curl_write_callback); - break; - - case CURLOPT_WILDCARDMATCH: - data->set.wildcardmatch = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_CHUNK_BGN_FUNCTION: - data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback); - break; - case CURLOPT_CHUNK_END_FUNCTION: - data->set.chunk_end = va_arg(param, curl_chunk_end_callback); - break; - case CURLOPT_FNMATCH_FUNCTION: - data->set.fnmatch = va_arg(param, curl_fnmatch_callback); - break; - case CURLOPT_CHUNK_DATA: - data->wildcard.customptr = va_arg(param, void *); - break; - case CURLOPT_FNMATCH_DATA: - data->set.fnmatch_data = va_arg(param, void *); - break; -#ifdef USE_TLS_SRP - case CURLOPT_TLSAUTH_USERNAME: - result = setstropt(&data->set.str[STRING_TLSAUTH_USERNAME], - va_arg(param, char *)); - if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) - data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ - break; - case CURLOPT_TLSAUTH_PASSWORD: - result = setstropt(&data->set.str[STRING_TLSAUTH_PASSWORD], - va_arg(param, char *)); - if(data->set.str[STRING_TLSAUTH_USERNAME] && !data->set.ssl.authtype) - data->set.ssl.authtype = CURL_TLSAUTH_SRP; /* default to SRP */ - break; - case CURLOPT_TLSAUTH_TYPE: - if(strnequal((char *)va_arg(param, char *), "SRP", strlen("SRP"))) - data->set.ssl.authtype = CURL_TLSAUTH_SRP; - else - data->set.ssl.authtype = CURL_TLSAUTH_NONE; - break; -#endif - case CURLOPT_DNS_SERVERS: - result = Curl_set_dns_servers(data, va_arg(param, char *)); - break; - case CURLOPT_DNS_INTERFACE: - result = Curl_set_dns_interface(data, va_arg(param, char *)); - break; - case CURLOPT_DNS_LOCAL_IP4: - result = Curl_set_dns_local_ip4(data, va_arg(param, char *)); - break; - case CURLOPT_DNS_LOCAL_IP6: - result = Curl_set_dns_local_ip6(data, va_arg(param, char *)); - break; - - case CURLOPT_TCP_KEEPALIVE: - data->set.tcp_keepalive = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_TCP_KEEPIDLE: - data->set.tcp_keepidle = va_arg(param, long); - break; - case CURLOPT_TCP_KEEPINTVL: - data->set.tcp_keepintvl = va_arg(param, long); - break; - case CURLOPT_TCP_FASTOPEN: -#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) - data->set.tcp_fastopen = (0 != va_arg(param, long))?TRUE:FALSE; -#else - result = CURLE_NOT_BUILT_IN; -#endif - break; - case CURLOPT_SSL_ENABLE_NPN: - data->set.ssl_enable_npn = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_SSL_ENABLE_ALPN: - data->set.ssl_enable_alpn = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - -#ifdef USE_UNIX_SOCKETS - case CURLOPT_UNIX_SOCKET_PATH: - result = setstropt(&data->set.str[STRING_UNIX_SOCKET_PATH], - va_arg(param, char *)); - break; -#endif - - case CURLOPT_PATH_AS_IS: - data->set.path_as_is = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_PIPEWAIT: - data->set.pipewait = (0 != va_arg(param, long)) ? TRUE : FALSE; - break; - case CURLOPT_STREAM_WEIGHT: -#ifndef USE_NGHTTP2 - return CURLE_NOT_BUILT_IN; -#else - arg = va_arg(param, long); - if((arg>=1) && (arg <= 256)) - data->set.stream_weight = (int)arg; - break; -#endif - case CURLOPT_STREAM_DEPENDS: - case CURLOPT_STREAM_DEPENDS_E: - { -#ifndef USE_NGHTTP2 - return CURLE_NOT_BUILT_IN; -#else - struct SessionHandle *dep = va_arg(param, struct SessionHandle *); - if(dep && GOOD_EASY_HANDLE(dep)) { - data->set.stream_depends_on = dep; - data->set.stream_depends_e = (option == CURLOPT_STREAM_DEPENDS_E); - } - break; -#endif - } - case CURLOPT_CONNECT_TO: - data->set.connect_to = va_arg(param, struct curl_slist *); - break; - default: - /* unknown tag and its companion, just ignore: */ - result = CURLE_UNKNOWN_OPTION; - break; - } - - return result; -} - -#ifdef USE_RECV_BEFORE_SEND_WORKAROUND -static void conn_reset_postponed_data(struct connectdata *conn, int num) -{ - struct postponed_data * const psnd = &(conn->postponed[num]); - if(psnd->buffer) { - DEBUGASSERT(psnd->allocated_size > 0); - DEBUGASSERT(psnd->recv_size <= psnd->allocated_size); - DEBUGASSERT(psnd->recv_size ? - (psnd->recv_processed < psnd->recv_size) : - (psnd->recv_processed == 0)); - DEBUGASSERT(psnd->bindsock != CURL_SOCKET_BAD); - free(psnd->buffer); - psnd->buffer = NULL; - psnd->allocated_size = 0; - psnd->recv_size = 0; - psnd->recv_processed = 0; -#ifdef DEBUGBUILD - psnd->bindsock = CURL_SOCKET_BAD; /* used only for DEBUGASSERT */ -#endif /* DEBUGBUILD */ - } - else { - DEBUGASSERT (psnd->allocated_size == 0); - DEBUGASSERT (psnd->recv_size == 0); - DEBUGASSERT (psnd->recv_processed == 0); - DEBUGASSERT (psnd->bindsock == CURL_SOCKET_BAD); - } -} - -static void conn_reset_all_postponed_data(struct connectdata *conn) -{ - conn_reset_postponed_data(conn, 0); - conn_reset_postponed_data(conn, 1); -} -#else /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ -/* Use "do-nothing" macros instead of functions when workaround not used */ -#define conn_reset_postponed_data(c,n) do {} WHILE_FALSE -#define conn_reset_all_postponed_data(c) do {} WHILE_FALSE -#endif /* ! USE_RECV_BEFORE_SEND_WORKAROUND */ - -static void conn_free(struct connectdata *conn) -{ - if(!conn) - return; - - /* possible left-overs from the async name resolvers */ - Curl_resolver_cancel(conn); - - /* close the SSL stuff before we close any sockets since they will/may - write to the sockets */ - Curl_ssl_close(conn, FIRSTSOCKET); - Curl_ssl_close(conn, SECONDARYSOCKET); - - /* close possibly still open sockets */ - if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET]) - Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]); - if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET]) - Curl_closesocket(conn, conn->sock[FIRSTSOCKET]); - if(CURL_SOCKET_BAD != conn->tempsock[0]) - Curl_closesocket(conn, conn->tempsock[0]); - if(CURL_SOCKET_BAD != conn->tempsock[1]) - Curl_closesocket(conn, conn->tempsock[1]); - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ - defined(NTLM_WB_ENABLED) - Curl_ntlm_wb_cleanup(conn); -#endif - - Curl_safefree(conn->user); - Curl_safefree(conn->passwd); - Curl_safefree(conn->oauth_bearer); - Curl_safefree(conn->options); - Curl_safefree(conn->proxyuser); - Curl_safefree(conn->proxypasswd); - Curl_safefree(conn->allocptr.proxyuserpwd); - Curl_safefree(conn->allocptr.uagent); - Curl_safefree(conn->allocptr.userpwd); - Curl_safefree(conn->allocptr.accept_encoding); - Curl_safefree(conn->allocptr.te); - Curl_safefree(conn->allocptr.rangeline); - Curl_safefree(conn->allocptr.ref); - Curl_safefree(conn->allocptr.host); - Curl_safefree(conn->allocptr.cookiehost); - Curl_safefree(conn->allocptr.rtsp_transport); - Curl_safefree(conn->trailer); - Curl_safefree(conn->host.rawalloc); /* host name buffer */ - Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */ - Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ - Curl_safefree(conn->master_buffer); - - conn_reset_all_postponed_data(conn); - - Curl_llist_destroy(conn->send_pipe, NULL); - Curl_llist_destroy(conn->recv_pipe, NULL); - - conn->send_pipe = NULL; - conn->recv_pipe = NULL; - - Curl_safefree(conn->localdev); - Curl_free_ssl_config(&conn->ssl_config); - - free(conn); /* free all the connection oriented data */ -} - -/* - * Disconnects the given connection. Note the connection may not be the - * primary connection, like when freeing room in the connection cache or - * killing of a dead old connection. - * - * This function MUST NOT reset state in the SessionHandle struct if that - * isn't strictly bound to the life-time of *this* particular connection. - * - */ - -CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) -{ - struct SessionHandle *data; - if(!conn) - return CURLE_OK; /* this is closed and fine already */ - data = conn->data; - - if(!data) { - DEBUGF(fprintf(stderr, "DISCONNECT without easy handle, ignoring\n")); - return CURLE_OK; - } - - if(conn->dns_entry != NULL) { - Curl_resolv_unlock(data, conn->dns_entry); - conn->dns_entry = NULL; - } - - Curl_hostcache_prune(data); /* kill old DNS cache entries */ - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) - /* Cleanup NTLM connection-related data */ - Curl_http_ntlm_cleanup(conn); -#endif - - if(conn->handler->disconnect) - /* This is set if protocol-specific cleanups should be made */ - conn->handler->disconnect(conn, dead_connection); - - /* unlink ourselves! */ - infof(data, "Closing connection %ld\n", conn->connection_id); - Curl_conncache_remove_conn(data->state.conn_cache, conn); - - free_fixed_hostname(&conn->host); - free_fixed_hostname(&conn->conn_to_host); - free_fixed_hostname(&conn->proxy); - - Curl_ssl_close(conn, FIRSTSOCKET); - - /* Indicate to all handles on the pipe that we're dead */ - if(Curl_pipeline_wanted(data->multi, CURLPIPE_ANY)) { - signalPipeClose(conn->send_pipe, TRUE); - signalPipeClose(conn->recv_pipe, TRUE); - } - - conn_free(conn); - - return CURLE_OK; -} - -/* - * This function should return TRUE if the socket is to be assumed to - * be dead. Most commonly this happens when the server has closed the - * connection due to inactivity. - */ -static bool SocketIsDead(curl_socket_t sock) -{ - int sval; - bool ret_val = TRUE; - - sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0); - if(sval == 0) - /* timeout */ - ret_val = FALSE; - - return ret_val; -} - -/* - * IsPipeliningPossible() returns TRUE if the options set would allow - * pipelining/multiplexing and the connection is using a HTTP protocol. - */ -static bool IsPipeliningPossible(const struct SessionHandle *handle, - const struct connectdata *conn) -{ - /* If a HTTP protocol and pipelining is enabled */ - if(conn->handler->protocol & PROTO_FAMILY_HTTP) { - - if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) && - (handle->set.httpversion != CURL_HTTP_VERSION_1_0) && - (handle->set.httpreq == HTTPREQ_GET || - handle->set.httpreq == HTTPREQ_HEAD)) - /* didn't ask for HTTP/1.0 and a GET or HEAD */ - return TRUE; - - if(Curl_pipeline_wanted(handle->multi, CURLPIPE_MULTIPLEX) && - (handle->set.httpversion >= CURL_HTTP_VERSION_2)) - /* allows HTTP/2 */ - return TRUE; - } - return FALSE; -} - -int Curl_removeHandleFromPipeline(struct SessionHandle *handle, - struct curl_llist *pipeline) -{ - if(pipeline) { - struct curl_llist_element *curr; - - curr = pipeline->head; - while(curr) { - if(curr->ptr == handle) { - Curl_llist_remove(pipeline, curr, NULL); - return 1; /* we removed a handle */ - } - curr = curr->next; - } - } - - return 0; -} - -#if 0 /* this code is saved here as it is useful for debugging purposes */ -static void Curl_printPipeline(struct curl_llist *pipeline) -{ - struct curl_llist_element *curr; - - curr = pipeline->head; - while(curr) { - struct SessionHandle *data = (struct SessionHandle *) curr->ptr; - infof(data, "Handle in pipeline: %s\n", data->state.path); - curr = curr->next; - } -} -#endif - -static struct SessionHandle* gethandleathead(struct curl_llist *pipeline) -{ - struct curl_llist_element *curr = pipeline->head; - if(curr) { - return (struct SessionHandle *) curr->ptr; - } - - return NULL; -} - -/* remove the specified connection from all (possible) pipelines and related - queues */ -void Curl_getoff_all_pipelines(struct SessionHandle *data, - struct connectdata *conn) -{ - bool recv_head = (conn->readchannel_inuse && - Curl_recvpipe_head(data, conn)); - bool send_head = (conn->writechannel_inuse && - Curl_sendpipe_head(data, conn)); - - if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head) - Curl_pipeline_leave_read(conn); - if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head) - Curl_pipeline_leave_write(conn); -} - -static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke) -{ - struct curl_llist_element *curr; - - if(!pipeline) - return; - - curr = pipeline->head; - while(curr) { - struct curl_llist_element *next = curr->next; - struct SessionHandle *data = (struct SessionHandle *) curr->ptr; - -#ifdef DEBUGBUILD /* debug-only code */ - if(data->magic != CURLEASY_MAGIC_NUMBER) { - /* MAJOR BADNESS */ - infof(data, "signalPipeClose() found BAAD easy handle\n"); - } -#endif - - if(pipe_broke) - data->state.pipe_broke = TRUE; - Curl_multi_handlePipeBreak(data); - Curl_llist_remove(pipeline, curr, NULL); - curr = next; - } -} - -/* - * This function finds the connection in the connection - * cache that has been unused for the longest time. - * - * Returns the pointer to the oldest idle connection, or NULL if none was - * found. - */ -struct connectdata * -Curl_oldest_idle_connection(struct SessionHandle *data) -{ - struct conncache *bc = data->state.conn_cache; - struct curl_hash_iterator iter; - struct curl_llist_element *curr; - struct curl_hash_element *he; - long highscore=-1; - long score; - struct timeval now; - struct connectdata *conn_candidate = NULL; - struct connectbundle *bundle; - - now = Curl_tvnow(); - - Curl_hash_start_iterate(&bc->hash, &iter); - - he = Curl_hash_next_element(&iter); - while(he) { - struct connectdata *conn; - - bundle = he->ptr; - - curr = bundle->conn_list->head; - while(curr) { - conn = curr->ptr; - - if(!conn->inuse) { - /* Set higher score for the age passed since the connection was used */ - score = Curl_tvdiff(now, conn->now); - - if(score > highscore) { - highscore = score; - conn_candidate = conn; - } - } - curr = curr->next; - } - - he = Curl_hash_next_element(&iter); - } - - return conn_candidate; -} - -/* - * This function finds the connection in the connection - * bundle that has been unused for the longest time. - * - * Returns the pointer to the oldest idle connection, or NULL if none was - * found. - */ -static struct connectdata * -find_oldest_idle_connection_in_bundle(struct SessionHandle *data, - struct connectbundle *bundle) -{ - struct curl_llist_element *curr; - long highscore=-1; - long score; - struct timeval now; - struct connectdata *conn_candidate = NULL; - struct connectdata *conn; - - (void)data; - - now = Curl_tvnow(); - - curr = bundle->conn_list->head; - while(curr) { - conn = curr->ptr; - - if(!conn->inuse) { - /* Set higher score for the age passed since the connection was used */ - score = Curl_tvdiff(now, conn->now); - - if(score > highscore) { - highscore = score; - conn_candidate = conn; - } - } - curr = curr->next; - } - - return conn_candidate; -} - -/* - * This function checks if given connection is dead and disconnects if so. - * (That also removes it from the connection cache.) - * - * Returns TRUE if the connection actually was dead and disconnected. - */ -static bool disconnect_if_dead(struct connectdata *conn, - struct SessionHandle *data) -{ - size_t pipeLen = conn->send_pipe->size + conn->recv_pipe->size; - if(!pipeLen && !conn->inuse) { - /* The check for a dead socket makes sense only if there are no - handles in pipeline and the connection isn't already marked in - use */ - bool dead; - if(conn->handler->protocol & CURLPROTO_RTSP) - /* RTSP is a special case due to RTP interleaving */ - dead = Curl_rtsp_connisdead(conn); - else - dead = SocketIsDead(conn->sock[FIRSTSOCKET]); - - if(dead) { - conn->data = data; - infof(data, "Connection %ld seems to be dead!\n", conn->connection_id); - - /* disconnect resources */ - Curl_disconnect(conn, /* dead_connection */TRUE); - return TRUE; - } - } - return FALSE; -} - -/* - * Wrapper to use disconnect_if_dead() function in Curl_conncache_foreach() - * - * Returns always 0. - */ -static int call_disconnect_if_dead(struct connectdata *conn, - void *param) -{ - struct SessionHandle* data = (struct SessionHandle*)param; - disconnect_if_dead(conn, data); - return 0; /* continue iteration */ -} - -/* - * This function scans the connection cache for half-open/dead connections, - * closes and removes them. - * The cleanup is done at most once per second. - */ -static void prune_dead_connections(struct SessionHandle *data) -{ - struct timeval now = Curl_tvnow(); - long elapsed = Curl_tvdiff(now, data->state.conn_cache->last_cleanup); - - if(elapsed >= 1000L) { - Curl_conncache_foreach(data->state.conn_cache, data, - call_disconnect_if_dead); - data->state.conn_cache->last_cleanup = now; - } -} - - -static size_t max_pipeline_length(struct Curl_multi *multi) -{ - return multi ? multi->max_pipeline_length : 0; -} - - -/* - * Given one filled in connection struct (named needle), this function should - * detect if there already is one that has all the significant details - * exactly the same and thus should be used instead. - * - * If there is a match, this function returns TRUE - and has marked the - * connection as 'in-use'. It must later be called with ConnectionDone() to - * return back to 'idle' (unused) state. - * - * The force_reuse flag is set if the connection must be used, even if - * the pipelining strategy wants to open a new connection instead of reusing. - */ -static bool -ConnectionExists(struct SessionHandle *data, - struct connectdata *needle, - struct connectdata **usethis, - bool *force_reuse, - bool *waitpipe) -{ - struct connectdata *check; - struct connectdata *chosen = 0; - bool foundPendingCandidate = FALSE; - bool canPipeline = IsPipeliningPossible(data, needle); - struct connectbundle *bundle; - -#ifdef USE_NTLM - bool wantNTLMhttp = ((data->state.authhost.want & - (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && - (needle->handler->protocol & PROTO_FAMILY_HTTP)); - bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd && - ((data->state.authproxy.want & - (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && - (needle->handler->protocol & PROTO_FAMILY_HTTP))); -#endif - - *force_reuse = FALSE; - *waitpipe = FALSE; - - /* We can't pipe if the site is blacklisted */ - if(canPipeline && Curl_pipeline_site_blacklisted(data, needle)) { - canPipeline = FALSE; - } - - /* Look up the bundle with all the connections to this - particular host */ - bundle = Curl_conncache_find_bundle(needle, data->state.conn_cache); - if(bundle) { - /* Max pipe length is zero (unlimited) for multiplexed connections */ - size_t max_pipe_len = (bundle->multiuse != BUNDLE_MULTIPLEX)? - max_pipeline_length(data->multi):0; - size_t best_pipe_len = max_pipe_len; - struct curl_llist_element *curr; - const char *hostname; - - if(needle->bits.conn_to_host) - hostname = needle->conn_to_host.name; - else - hostname = needle->host.name; - - infof(data, "Found bundle for host %s: %p [%s]\n", - hostname, (void *)bundle, - (bundle->multiuse== BUNDLE_PIPELINING? - "can pipeline": - (bundle->multiuse== BUNDLE_MULTIPLEX? - "can multiplex":"serially"))); - - /* We can't pipe if we don't know anything about the server */ - if(canPipeline) { - if(bundle->multiuse <= BUNDLE_UNKNOWN) { - if((bundle->multiuse == BUNDLE_UNKNOWN) && data->set.pipewait) { - infof(data, "Server doesn't support multi-use yet, wait\n"); - *waitpipe = TRUE; - return FALSE; /* no re-use */ - } - - infof(data, "Server doesn't support multi-use (yet)\n"); - canPipeline = FALSE; - } - if((bundle->multiuse == BUNDLE_PIPELINING) && - !Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1)) { - /* not asked for, switch off */ - infof(data, "Could pipeline, but not asked to!\n"); - canPipeline = FALSE; - } - else if((bundle->multiuse == BUNDLE_MULTIPLEX) && - !Curl_pipeline_wanted(data->multi, CURLPIPE_MULTIPLEX)) { - infof(data, "Could multiplex, but not asked to!\n"); - canPipeline = FALSE; - } - } - - curr = bundle->conn_list->head; - while(curr) { - bool match = FALSE; - size_t pipeLen; - - /* - * Note that if we use a HTTP proxy in normal mode (no tunneling), we - * check connections to that proxy and not to the actual remote server. - */ - check = curr->ptr; - curr = curr->next; - - if(disconnect_if_dead(check, data)) - continue; - - pipeLen = check->send_pipe->size + check->recv_pipe->size; - - if(canPipeline) { - - if(!check->bits.multiplex) { - /* If not multiplexing, make sure the pipe has only GET requests */ - struct SessionHandle* sh = gethandleathead(check->send_pipe); - struct SessionHandle* rh = gethandleathead(check->recv_pipe); - if(sh) { - if(!IsPipeliningPossible(sh, check)) - continue; - } - else if(rh) { - if(!IsPipeliningPossible(rh, check)) - continue; - } - } - } - else { - if(pipeLen > 0) { - /* can only happen within multi handles, and means that another easy - handle is using this connection */ - continue; - } - - if(Curl_resolver_asynch()) { - /* ip_addr_str[0] is NUL only if the resolving of the name hasn't - completed yet and until then we don't re-use this connection */ - if(!check->ip_addr_str[0]) { - infof(data, - "Connection #%ld is still name resolving, can't reuse\n", - check->connection_id); - continue; - } - } - - if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || - check->bits.close) { - if(!check->bits.close) - foundPendingCandidate = TRUE; - /* Don't pick a connection that hasn't connected yet or that is going - to get closed. */ - infof(data, "Connection #%ld isn't open enough, can't reuse\n", - check->connection_id); -#ifdef DEBUGBUILD - if(check->recv_pipe->size > 0) { - infof(data, - "BAD! Unconnected #%ld has a non-empty recv pipeline!\n", - check->connection_id); - } -#endif - continue; - } - } - - if((needle->handler->flags&PROTOPT_SSL) != - (check->handler->flags&PROTOPT_SSL)) - /* don't do mixed SSL and non-SSL connections */ - if(get_protocol_family(check->handler->protocol) != - needle->handler->protocol || !check->tls_upgraded) - /* except protocols that have been upgraded via TLS */ - continue; - - if(needle->handler->flags&PROTOPT_SSL) { - if((data->set.ssl.verifypeer != check->verifypeer) || - (data->set.ssl.verifyhost != check->verifyhost)) - continue; - } - - if(needle->bits.proxy != check->bits.proxy) - /* don't do mixed proxy and non-proxy connections */ - continue; - - if(needle->bits.proxy && - (needle->proxytype != check->proxytype || - needle->bits.httpproxy != check->bits.httpproxy || - needle->bits.tunnel_proxy != check->bits.tunnel_proxy || - !Curl_raw_equal(needle->proxy.name, check->proxy.name) || - needle->port != check->port)) - /* don't mix connections that use different proxies */ - continue; - - if(needle->bits.conn_to_host != check->bits.conn_to_host) - /* don't mix connections that use the "connect to host" feature and - * connections that don't use this feature */ - continue; - - if(needle->bits.conn_to_port != check->bits.conn_to_port) - /* don't mix connections that use the "connect to port" feature and - * connections that don't use this feature */ - continue; - - if(!canPipeline && check->inuse) - /* this request can't be pipelined but the checked connection is - already in use so we skip it */ - continue; - - if(needle->localdev || needle->localport) { - /* If we are bound to a specific local end (IP+port), we must not - re-use a random other one, although if we didn't ask for a - particular one we can reuse one that was bound. - - This comparison is a bit rough and too strict. Since the input - parameters can be specified in numerous ways and still end up the - same it would take a lot of processing to make it really accurate. - Instead, this matching will assume that re-uses of bound connections - will most likely also re-use the exact same binding parameters and - missing out a few edge cases shouldn't hurt anyone very much. - */ - if((check->localport != needle->localport) || - (check->localportrange != needle->localportrange) || - !check->localdev || - !needle->localdev || - strcmp(check->localdev, needle->localdev)) - continue; - } - - if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) { - /* This protocol requires credentials per connection, - so verify that we're using the same name and password as well */ - if(!strequal(needle->user, check->user) || - !strequal(needle->passwd, check->passwd)) { - /* one of them was different */ - continue; - } - } - - if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) || - (needle->bits.httpproxy && needle->bits.tunnel_proxy)) { - /* The requested connection does not use a HTTP proxy or it uses SSL or - it is a non-SSL protocol tunneled over the same HTTP proxy name and - port number */ - if((Curl_raw_equal(needle->handler->scheme, check->handler->scheme) || - (get_protocol_family(check->handler->protocol) == - needle->handler->protocol && check->tls_upgraded)) && - (!needle->bits.conn_to_host || Curl_raw_equal( - needle->conn_to_host.name, check->conn_to_host.name)) && - (!needle->bits.conn_to_port || - needle->conn_to_port == check->conn_to_port) && - Curl_raw_equal(needle->host.name, check->host.name) && - needle->remote_port == check->remote_port) { - /* The schemes match or the the protocol family is the same and the - previous connection was TLS upgraded, and the hostname and host - port match */ - if(needle->handler->flags & PROTOPT_SSL) { - /* This is a SSL connection so verify that we're using the same - SSL options as well */ - if(!Curl_ssl_config_matches(&needle->ssl_config, - &check->ssl_config)) { - DEBUGF(infof(data, - "Connection #%ld has different SSL parameters, " - "can't reuse\n", - check->connection_id)); - continue; - } - else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) { - foundPendingCandidate = TRUE; - DEBUGF(infof(data, - "Connection #%ld has not started SSL connect, " - "can't reuse\n", - check->connection_id)); - continue; - } - } - match = TRUE; - } - } - else { - /* The requested connection is using the same HTTP proxy in normal - mode (no tunneling) */ - match = TRUE; - } - - if(match) { -#if defined(USE_NTLM) - /* If we are looking for an HTTP+NTLM connection, check if this is - already authenticating with the right credentials. If not, keep - looking so that we can reuse NTLM connections if - possible. (Especially we must not reuse the same connection if - partway through a handshake!) */ - if(wantNTLMhttp) { - if(!strequal(needle->user, check->user) || - !strequal(needle->passwd, check->passwd)) - continue; - } - else if(check->ntlm.state != NTLMSTATE_NONE) { - /* Connection is using NTLM auth but we don't want NTLM */ - continue; - } - - /* Same for Proxy NTLM authentication */ - if(wantProxyNTLMhttp) { - /* Both check->proxyuser and check->proxypasswd can be NULL */ - if(!check->proxyuser || !check->proxypasswd) - continue; - - if(!strequal(needle->proxyuser, check->proxyuser) || - !strequal(needle->proxypasswd, check->proxypasswd)) - continue; - } - else if(check->proxyntlm.state != NTLMSTATE_NONE) { - /* Proxy connection is using NTLM auth but we don't want NTLM */ - continue; - } - - if(wantNTLMhttp || wantProxyNTLMhttp) { - /* Credentials are already checked, we can use this connection */ - chosen = check; - - if((wantNTLMhttp && - (check->ntlm.state != NTLMSTATE_NONE)) || - (wantProxyNTLMhttp && - (check->proxyntlm.state != NTLMSTATE_NONE))) { - /* We must use this connection, no other */ - *force_reuse = TRUE; - break; - } - - /* Continue look up for a better connection */ - continue; - } -#endif - if(canPipeline) { - /* We can pipeline if we want to. Let's continue looking for - the optimal connection to use, i.e the shortest pipe that is not - blacklisted. */ - - if(pipeLen == 0) { - /* We have the optimal connection. Let's stop looking. */ - chosen = check; - break; - } - - /* We can't use the connection if the pipe is full */ - if(max_pipe_len && (pipeLen >= max_pipe_len)) { - infof(data, "Pipe is full, skip (%zu)\n", pipeLen); - continue; - } -#ifdef USE_NGHTTP2 - /* If multiplexed, make sure we don't go over concurrency limit */ - if(check->bits.multiplex) { - /* Multiplexed connections can only be HTTP/2 for now */ - struct http_conn *httpc = &check->proto.httpc; - if(pipeLen >= httpc->settings.max_concurrent_streams) { - infof(data, "MAX_CONCURRENT_STREAMS reached, skip (%zu)\n", - pipeLen); - continue; - } - } -#endif - /* We can't use the connection if the pipe is penalized */ - if(Curl_pipeline_penalized(data, check)) { - infof(data, "Penalized, skip\n"); - continue; - } - - if(max_pipe_len) { - if(pipeLen < best_pipe_len) { - /* This connection has a shorter pipe so far. We'll pick this - and continue searching */ - chosen = check; - best_pipe_len = pipeLen; - continue; - } - } - else { - /* When not pipelining (== multiplexed), we have a match here! */ - chosen = check; - infof(data, "Multiplexed connection found!\n"); - break; - } - } - else { - /* We have found a connection. Let's stop searching. */ - chosen = check; - break; - } - } - } - } - - if(chosen) { - *usethis = chosen; - return TRUE; /* yes, we found one to use! */ - } - - if(foundPendingCandidate && data->set.pipewait) { - infof(data, - "Found pending candidate for reuse and CURLOPT_PIPEWAIT is set\n"); - *waitpipe = TRUE; - } - - return FALSE; /* no matching connecting exists */ -} - -/* after a TCP connection to the proxy has been verified, this function does - the next magic step. - - Note: this function's sub-functions call failf() - -*/ -CURLcode Curl_connected_proxy(struct connectdata *conn, - int sockindex) -{ - if(!conn->bits.proxy || sockindex) - /* this magic only works for the primary socket as the secondary is used - for FTP only and it has FTP specific magic in ftp.c */ - return CURLE_OK; - - switch(conn->proxytype) { -#ifndef CURL_DISABLE_PROXY - case CURLPROXY_SOCKS5: - case CURLPROXY_SOCKS5_HOSTNAME: - return Curl_SOCKS5(conn->proxyuser, conn->proxypasswd, - conn->bits.conn_to_host ? conn->conn_to_host.name : - conn->host.name, - conn->bits.conn_to_port ? conn->conn_to_port : - conn->remote_port, - FIRSTSOCKET, conn); - - case CURLPROXY_SOCKS4: - return Curl_SOCKS4(conn->proxyuser, - conn->bits.conn_to_host ? conn->conn_to_host.name : - conn->host.name, - conn->bits.conn_to_port ? conn->conn_to_port : - conn->remote_port, - FIRSTSOCKET, conn, FALSE); - - case CURLPROXY_SOCKS4A: - return Curl_SOCKS4(conn->proxyuser, - conn->bits.conn_to_host ? conn->conn_to_host.name : - conn->host.name, - conn->bits.conn_to_port ? conn->conn_to_port : - conn->remote_port, - FIRSTSOCKET, conn, TRUE); - -#endif /* CURL_DISABLE_PROXY */ - case CURLPROXY_HTTP: - case CURLPROXY_HTTP_1_0: - /* do nothing here. handled later. */ - break; - default: - break; - } /* switch proxytype */ - - return CURLE_OK; -} - -/* - * verboseconnect() displays verbose information after a connect - */ -#ifndef CURL_DISABLE_VERBOSE_STRINGS -void Curl_verboseconnect(struct connectdata *conn) -{ - if(conn->data->set.verbose) - infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", - conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname, - conn->ip_addr_str, conn->port, conn->connection_id); -} -#endif - -int Curl_protocol_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - if(conn->handler->proto_getsock) - return conn->handler->proto_getsock(conn, socks, numsocks); - return GETSOCK_BLANK; -} - -int Curl_doing_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks) -{ - if(conn && conn->handler->doing_getsock) - return conn->handler->doing_getsock(conn, socks, numsocks); - return GETSOCK_BLANK; -} - -/* - * We are doing protocol-specific connecting and this is being called over and - * over from the multi interface until the connection phase is done on - * protocol layer. - */ - -CURLcode Curl_protocol_connecting(struct connectdata *conn, - bool *done) -{ - CURLcode result=CURLE_OK; - - if(conn && conn->handler->connecting) { - *done = FALSE; - result = conn->handler->connecting(conn, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We are DOING this is being called over and over from the multi interface - * until the DOING phase is done on protocol layer. - */ - -CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done) -{ - CURLcode result=CURLE_OK; - - if(conn && conn->handler->doing) { - *done = FALSE; - result = conn->handler->doing(conn, done); - } - else - *done = TRUE; - - return result; -} - -/* - * We have discovered that the TCP connection has been successful, we can now - * proceed with some action. - * - */ -CURLcode Curl_protocol_connect(struct connectdata *conn, - bool *protocol_done) -{ - CURLcode result=CURLE_OK; - - *protocol_done = FALSE; - - if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) { - /* We already are connected, get back. This may happen when the connect - worked fine in the first call, like when we connect to a local server - or proxy. Note that we don't know if the protocol is actually done. - - Unless this protocol doesn't have any protocol-connect callback, as - then we know we're done. */ - if(!conn->handler->connecting) - *protocol_done = TRUE; - - return CURLE_OK; - } - - if(!conn->bits.protoconnstart) { - - result = Curl_proxy_connect(conn); - if(result) - return result; - - if(conn->bits.tunnel_proxy && conn->bits.httpproxy && - (conn->tunnel_state[FIRSTSOCKET] != TUNNEL_COMPLETE)) - /* when using an HTTP tunnel proxy, await complete tunnel establishment - before proceeding further. Return CURLE_OK so we'll be called again */ - return CURLE_OK; - - if(conn->handler->connect_it) { - /* is there a protocol-specific connect() procedure? */ - - /* Call the protocol-specific connect function */ - result = conn->handler->connect_it(conn, protocol_done); - } - else - *protocol_done = TRUE; - - /* it has started, possibly even completed but that knowledge isn't stored - in this bit! */ - if(!result) - conn->bits.protoconnstart = TRUE; - } - - return result; /* pass back status */ -} - -/* - * Helpers for IDNA convertions. - */ -static bool is_ASCII_name(const char *hostname) -{ - const unsigned char *ch = (const unsigned char*)hostname; - - while(*ch) { - if(*ch++ & 0x80) - return FALSE; - } - return TRUE; -} - -#ifdef USE_LIBIDN -/* - * Check if characters in hostname is allowed in Top Level Domain. - */ -static bool tld_check_name(struct SessionHandle *data, - const char *ace_hostname) -{ - size_t err_pos; - char *uc_name = NULL; - int rc; -#ifndef CURL_DISABLE_VERBOSE_STRINGS - const char *tld_errmsg = ""; -#else - (void)data; -#endif - - /* Convert (and downcase) ACE-name back into locale's character set */ - rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0); - if(rc != IDNA_SUCCESS) - return FALSE; - - /* Warning: err_pos receives "the decoded character offset rather than the - byte position in the string." And as of libidn 1.32 that character offset - is for UTF-8, even if the passed in string is another locale. */ - rc = tld_check_lz(uc_name, &err_pos, NULL); -#ifndef CURL_DISABLE_VERBOSE_STRINGS -#ifdef HAVE_TLD_STRERROR - if(rc != TLD_SUCCESS) - tld_errmsg = tld_strerror((Tld_rc)rc); -#endif - if(rc != TLD_SUCCESS) - infof(data, "WARNING: TLD check for %s failed; %s\n", - uc_name, tld_errmsg); -#endif /* CURL_DISABLE_VERBOSE_STRINGS */ - if(uc_name) - idn_free(uc_name); - if(rc != TLD_SUCCESS) - return FALSE; - - return TRUE; -} -#endif - -/* - * Perform any necessary IDN conversion of hostname - */ -static void fix_hostname(struct SessionHandle *data, - struct connectdata *conn, struct hostname *host) -{ - size_t len; - -#ifndef USE_LIBIDN - (void)data; - (void)conn; -#elif defined(CURL_DISABLE_VERBOSE_STRINGS) - (void)conn; -#endif - - /* set the name we use to display the host name */ - host->dispname = host->name; - - len = strlen(host->name); - if(len && (host->name[len-1] == '.')) - /* strip off a single trailing dot if present, primarily for SNI but - there's no use for it */ - host->name[len-1]=0; - - /* Check name for non-ASCII and convert hostname to ACE form if we can */ - if(!is_ASCII_name(host->name)) { -#ifdef USE_LIBIDN - if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { - char *ace_hostname = NULL; - - int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); - infof(data, "Input domain encoded as `%s'\n", - stringprep_locale_charset()); - if(rc == IDNA_SUCCESS) { - /* tld_check_name() displays a warning if the host name contains - "illegal" characters for this TLD */ - (void)tld_check_name(data, ace_hostname); - - host->encalloc = ace_hostname; - /* change the name pointer to point to the encoded hostname */ - host->name = host->encalloc; - } - else - infof(data, "Failed to convert %s to ACE; %s\n", host->name, - Curl_idn_strerror(conn, rc)); - } -#elif defined(USE_WIN32_IDN) - char *ace_hostname = NULL; - - if(curl_win32_idn_to_ascii(host->name, &ace_hostname)) { - host->encalloc = ace_hostname; - /* change the name pointer to point to the encoded hostname */ - host->name = host->encalloc; - } - else - infof(data, "Failed to convert %s to ACE;\n", host->name); -#else - infof(data, "IDN support not present, can't parse Unicode domains\n"); -#endif - } -} - -/* - * Frees data allocated by fix_hostname() - */ -static void free_fixed_hostname(struct hostname *host) -{ -#if defined(USE_LIBIDN) - if(host->encalloc) { - idn_free(host->encalloc); /* must be freed with idn_free() since this was - allocated by libidn */ - host->encalloc = NULL; - } -#elif defined(USE_WIN32_IDN) - free(host->encalloc); /* must be freed withidn_free() since this was - allocated by curl_win32_idn_to_ascii */ - host->encalloc = NULL; -#else - (void)host; -#endif -} - -static void llist_dtor(void *user, void *element) -{ - (void)user; - (void)element; - /* Do nothing */ -} - -/* - * Allocate and initialize a new connectdata object. - */ -static struct connectdata *allocate_conn(struct SessionHandle *data) -{ - struct connectdata *conn = calloc(1, sizeof(struct connectdata)); - if(!conn) - return NULL; - - conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined - already from start to avoid NULL - situations and checks */ - - /* and we setup a few fields in case we end up actually using this struct */ - - conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->tempsock[0] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->tempsock[1] = CURL_SOCKET_BAD; /* no file descriptor */ - conn->connection_id = -1; /* no ID */ - conn->port = -1; /* unknown at this point */ - conn->remote_port = -1; /* unknown */ -#if defined(USE_RECV_BEFORE_SEND_WORKAROUND) && defined(DEBUGBUILD) - conn->postponed[0].bindsock = CURL_SOCKET_BAD; /* no file descriptor */ - conn->postponed[1].bindsock = CURL_SOCKET_BAD; /* no file descriptor */ -#endif /* USE_RECV_BEFORE_SEND_WORKAROUND && DEBUGBUILD */ - - /* Default protocol-independent behavior doesn't support persistent - connections, so we set this to force-close. Protocols that support - this need to set this to FALSE in their "curl_do" functions. */ - connclose(conn, "Default to force-close"); - - /* Store creation time to help future close decision making */ - conn->created = Curl_tvnow(); - - conn->data = data; /* Setup the association between this connection - and the SessionHandle */ - - conn->proxytype = data->set.proxytype; /* type */ - -#ifdef CURL_DISABLE_PROXY - - conn->bits.proxy = FALSE; - conn->bits.httpproxy = FALSE; - conn->bits.proxy_user_passwd = FALSE; - conn->bits.tunnel_proxy = FALSE; - -#else /* CURL_DISABLE_PROXY */ - - /* note that these two proxy bits are now just on what looks to be - requested, they may be altered down the road */ - conn->bits.proxy = (data->set.str[STRING_PROXY] && - *data->set.str[STRING_PROXY]) ? TRUE : FALSE; - conn->bits.httpproxy = (conn->bits.proxy && - (conn->proxytype == CURLPROXY_HTTP || - conn->proxytype == CURLPROXY_HTTP_1_0)) ? - TRUE : FALSE; - conn->bits.proxy_user_passwd = (data->set.str[STRING_PROXYUSERNAME]) ? - TRUE : FALSE; - conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy; - -#endif /* CURL_DISABLE_PROXY */ - - conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE; - conn->bits.ftp_use_epsv = data->set.ftp_use_epsv; - conn->bits.ftp_use_eprt = data->set.ftp_use_eprt; - - conn->verifypeer = data->set.ssl.verifypeer; - conn->verifyhost = data->set.ssl.verifyhost; - - conn->ip_version = data->set.ipver; - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ - defined(NTLM_WB_ENABLED) - conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD; - conn->ntlm_auth_hlpr_pid = 0; - conn->challenge_header = NULL; - conn->response_header = NULL; -#endif - - if(Curl_pipeline_wanted(data->multi, CURLPIPE_HTTP1) && - !conn->master_buffer) { - /* Allocate master_buffer to be used for HTTP/1 pipelining */ - conn->master_buffer = calloc(BUFSIZE, sizeof (char)); - if(!conn->master_buffer) - goto error; - } - - /* Initialize the pipeline lists */ - conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor); - if(!conn->send_pipe || !conn->recv_pipe) - goto error; - -#ifdef HAVE_GSSAPI - conn->data_prot = PROT_CLEAR; -#endif - - /* Store the local bind parameters that will be used for this connection */ - if(data->set.str[STRING_DEVICE]) { - conn->localdev = strdup(data->set.str[STRING_DEVICE]); - if(!conn->localdev) - goto error; - } - conn->localportrange = data->set.localportrange; - conn->localport = data->set.localport; - - /* the close socket stuff needs to be copied to the connection struct as - it may live on without (this specific) SessionHandle */ - conn->fclosesocket = data->set.fclosesocket; - conn->closesocket_client = data->set.closesocket_client; - - return conn; - error: - - Curl_llist_destroy(conn->send_pipe, NULL); - Curl_llist_destroy(conn->recv_pipe, NULL); - - conn->send_pipe = NULL; - conn->recv_pipe = NULL; - - free(conn->master_buffer); - free(conn->localdev); - free(conn); - return NULL; -} - -static CURLcode findprotocol(struct SessionHandle *data, - struct connectdata *conn, - const char *protostr) -{ - const struct Curl_handler * const *pp; - const struct Curl_handler *p; - - /* Scan protocol handler table and match against 'protostr' to set a few - variables based on the URL. Now that the handler may be changed later - when the protocol specific setup function is called. */ - for(pp = protocols; (p = *pp) != NULL; pp++) { - if(Curl_raw_equal(p->scheme, protostr)) { - /* Protocol found in table. Check if allowed */ - if(!(data->set.allowed_protocols & p->protocol)) - /* nope, get out */ - break; - - /* it is allowed for "normal" request, now do an extra check if this is - the result of a redirect */ - if(data->state.this_is_a_follow && - !(data->set.redir_protocols & p->protocol)) - /* nope, get out */ - break; - - /* Perform setup complement if some. */ - conn->handler = conn->given = p; - - /* 'port' and 'remote_port' are set in setup_connection_internals() */ - return CURLE_OK; - } - } - - - /* The protocol was not found in the table, but we don't have to assign it - to anything since it is already assigned to a dummy-struct in the - create_conn() function when the connectdata struct is allocated. */ - failf(data, "Protocol \"%s\" not supported or disabled in " LIBCURL_NAME, - protostr); - - return CURLE_UNSUPPORTED_PROTOCOL; -} - -/* - * Parse URL and fill in the relevant members of the connection struct. - */ -static CURLcode parseurlandfillconn(struct SessionHandle *data, - struct connectdata *conn, - bool *prot_missing, - char **userp, char **passwdp, - char **optionsp) -{ - char *at; - char *fragment; - char *path = data->state.path; - char *query; - int rc; - char protobuf[16] = ""; - const char *protop = ""; - CURLcode result; - bool rebuild_url = FALSE; - - *prot_missing = FALSE; - - /* We might pass the entire URL into the request so we need to make sure - * there are no bad characters in there.*/ - if(strpbrk(data->change.url, "\r\n")) { - failf(data, "Illegal characters found in URL"); - return CURLE_URL_MALFORMAT; - } - - /************************************************************* - * Parse the URL. - * - * We need to parse the url even when using the proxy, because we will need - * the hostname and port in case we are trying to SSL connect through the - * proxy -- and we don't know if we will need to use SSL until we parse the - * url ... - ************************************************************/ - if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]", - protobuf, path)) && - Curl_raw_equal(protobuf, "file")) { - if(path[0] == '/' && path[1] == '/') { - /* Allow omitted hostname (e.g. file:/). This is not strictly - * speaking a valid file: URL by RFC 1738, but treating file:/ as - * file://localhost/ is similar to how other schemes treat missing - * hostnames. See RFC 1808. */ - - /* This cannot be done with strcpy() in a portable manner, since the - memory areas overlap! */ - memmove(path, path + 2, strlen(path + 2)+1); - } - /* - * we deal with file:/// differently since it supports no - * hostname other than "localhost" and "127.0.0.1", which is unique among - * the URL protocols specified in RFC 1738 - */ - if(path[0] != '/') { - /* the URL included a host name, we ignore host names in file:// URLs - as the standards don't define what to do with them */ - char *ptr=strchr(path, '/'); - if(ptr) { - /* there was a slash present - - RFC1738 (section 3.1, page 5) says: - - The rest of the locator consists of data specific to the scheme, - and is known as the "url-path". It supplies the details of how the - specified resource can be accessed. Note that the "/" between the - host (or port) and the url-path is NOT part of the url-path. - - As most agents use file://localhost/foo to get '/foo' although the - slash preceding foo is a separator and not a slash for the path, - a URL as file://localhost//foo must be valid as well, to refer to - the same file with an absolute path. - */ - - if(ptr[1] && ('/' == ptr[1])) - /* if there was two slashes, we skip the first one as that is then - used truly as a separator */ - ptr++; - - /* This cannot be made with strcpy, as the memory chunks overlap! */ - memmove(path, ptr, strlen(ptr)+1); - } - } - - protop = "file"; /* protocol string */ - } - else { - /* clear path */ - path[0]=0; - - if(2 > sscanf(data->change.url, - "%15[^\n:]://%[^\n/?]%[^\n]", - protobuf, - conn->host.name, path)) { - - /* - * The URL was badly formatted, let's try the browser-style _without_ - * protocol specified like 'http://'. - */ - rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path); - if(1 > rc) { - /* - * We couldn't even get this format. - * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is - * assigned, but the return value is EOF! - */ -#if defined(__DJGPP__) && (DJGPP_MINOR == 4) - if(!(rc == -1 && *conn->host.name)) -#endif - { - failf(data, " malformed"); - return CURLE_URL_MALFORMAT; - } - } - - /* - * Since there was no protocol part specified in the URL use the - * user-specified default protocol. If we weren't given a default make a - * guess by matching some protocols against the host's outermost - * sub-domain name. Finally if there was no match use HTTP. - */ - - protop = data->set.str[STRING_DEFAULT_PROTOCOL]; - if(!protop) { - /* Note: if you add a new protocol, please update the list in - * lib/version.c too! */ - if(checkprefix("FTP.", conn->host.name)) - protop = "ftp"; - else if(checkprefix("DICT.", conn->host.name)) - protop = "DICT"; - else if(checkprefix("LDAP.", conn->host.name)) - protop = "LDAP"; - else if(checkprefix("IMAP.", conn->host.name)) - protop = "IMAP"; - else if(checkprefix("SMTP.", conn->host.name)) - protop = "smtp"; - else if(checkprefix("POP3.", conn->host.name)) - protop = "pop3"; - else - protop = "http"; - } - - *prot_missing = TRUE; /* not given in URL */ - } - else - protop = protobuf; - } - - /* We search for '?' in the host name (but only on the right side of a - * @-letter to allow ?-letters in username and password) to handle things - * like http://example.com?param= (notice the missing '/'). - */ - at = strchr(conn->host.name, '@'); - if(at) - query = strchr(at+1, '?'); - else - query = strchr(conn->host.name, '?'); - - if(query) { - /* We must insert a slash before the '?'-letter in the URL. If the URL had - a slash after the '?', that is where the path currently begins and the - '?string' is still part of the host name. - - We must move the trailing part from the host name and put it first in - the path. And have it all prefixed with a slash. - */ - - size_t hostlen = strlen(query); - size_t pathlen = strlen(path); - - /* move the existing path plus the zero byte forward, to make room for - the host-name part */ - memmove(path+hostlen+1, path, pathlen+1); - - /* now copy the trailing host part in front of the existing path */ - memcpy(path+1, query, hostlen); - - path[0]='/'; /* prepend the missing slash */ - rebuild_url = TRUE; - - *query=0; /* now cut off the hostname at the ? */ - } - else if(!path[0]) { - /* if there's no path set, use a single slash */ - strcpy(path, "/"); - rebuild_url = TRUE; - } - - /* If the URL is malformatted (missing a '/' after hostname before path) we - * insert a slash here. The only letter except '/' we accept to start a path - * is '?'. - */ - if(path[0] == '?') { - /* We need this function to deal with overlapping memory areas. We know - that the memory area 'path' points to is 'urllen' bytes big and that - is bigger than the path. Use +1 to move the zero byte too. */ - memmove(&path[1], path, strlen(path)+1); - path[0] = '/'; - rebuild_url = TRUE; - } - else if(!data->set.path_as_is) { - /* sanitise paths and remove ../ and ./ sequences according to RFC3986 */ - char *newp = Curl_dedotdotify(path); - if(!newp) - return CURLE_OUT_OF_MEMORY; - - if(strcmp(newp, path)) { - rebuild_url = TRUE; - free(data->state.pathbuffer); - data->state.pathbuffer = newp; - data->state.path = newp; - path = newp; - } - else - free(newp); - } - - /* - * "rebuild_url" means that one or more URL components have been modified so - * we need to generate an updated full version. We need the corrected URL - * when communicating over HTTP proxy and we don't know at this point if - * we're using a proxy or not. - */ - if(rebuild_url) { - char *reurl; - - size_t plen = strlen(path); /* new path, should be 1 byte longer than - the original */ - size_t urllen = strlen(data->change.url); /* original URL length */ - - size_t prefixlen = strlen(conn->host.name); - - if(!*prot_missing) - prefixlen += strlen(protop) + strlen("://"); - - reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */ - if(!reurl) - return CURLE_OUT_OF_MEMORY; - - /* copy the prefix */ - memcpy(reurl, data->change.url, prefixlen); - - /* append the trailing piece + zerobyte */ - memcpy(&reurl[prefixlen], path, plen + 1); - - /* possible free the old one */ - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - - infof(data, "Rebuilt URL to: %s\n", reurl); - - data->change.url = reurl; - data->change.url_alloc = TRUE; /* free this later */ - } - - /* - * Parse the login details from the URL and strip them out of - * the host name - */ - result = parse_url_login(data, conn, userp, passwdp, optionsp); - if(result) - return result; - - if(conn->host.name[0] == '[') { - /* This looks like an IPv6 address literal. See if there is an address - scope if there is no location header */ - char *percent = strchr(conn->host.name, '%'); - if(percent) { - unsigned int identifier_offset = 3; - char *endp; - unsigned long scope; - if(strncmp("%25", percent, 3) != 0) { - infof(data, - "Please URL encode %% as %%25, see RFC 6874.\n"); - identifier_offset = 1; - } - scope = strtoul(percent + identifier_offset, &endp, 10); - if(*endp == ']') { - /* The address scope was well formed. Knock it out of the - hostname. */ - memmove(percent, endp, strlen(endp)+1); - conn->scope_id = (unsigned int)scope; - } - else { - /* Zone identifier is not numeric */ -#if defined(HAVE_NET_IF_H) && defined(IFNAMSIZ) && defined(HAVE_IF_NAMETOINDEX) - char ifname[IFNAMSIZ + 2]; - char *square_bracket; - unsigned int scopeidx = 0; - strncpy(ifname, percent + identifier_offset, IFNAMSIZ + 2); - /* Ensure nullbyte termination */ - ifname[IFNAMSIZ + 1] = '\0'; - square_bracket = strchr(ifname, ']'); - if(square_bracket) { - /* Remove ']' */ - *square_bracket = '\0'; - scopeidx = if_nametoindex(ifname); - if(scopeidx == 0) { - infof(data, "Invalid network interface: %s; %s\n", ifname, - strerror(errno)); - } - } - if(scopeidx > 0) { - char *p = percent + identifier_offset + strlen(ifname); - - /* Remove zone identifier from hostname */ - memmove(percent, p, strlen(p) + 1); - conn->scope_id = scopeidx; - } - else -#endif /* HAVE_NET_IF_H && IFNAMSIZ */ - infof(data, "Invalid IPv6 address format\n"); - } - } - } - - if(data->set.scope_id) - /* Override any scope that was set above. */ - conn->scope_id = data->set.scope_id; - - /* Remove the fragment part of the path. Per RFC 2396, this is always the - last part of the URI. We are looking for the first '#' so that we deal - gracefully with non conformant URI such as http://example.com#foo#bar. */ - fragment = strchr(path, '#'); - if(fragment) { - *fragment = 0; - - /* we know the path part ended with a fragment, so we know the full URL - string does too and we need to cut it off from there so it isn't used - over proxy */ - fragment = strchr(data->change.url, '#'); - if(fragment) - *fragment = 0; - } - - /* - * So if the URL was A://B/C#D, - * protop is A - * conn->host.name is B - * data->state.path is /C - */ - - return findprotocol(data, conn, protop); -} - -/* - * If we're doing a resumed transfer, we need to setup our stuff - * properly. - */ -static CURLcode setup_range(struct SessionHandle *data) -{ - struct UrlState *s = &data->state; - s->resume_from = data->set.set_resume_from; - if(s->resume_from || data->set.str[STRING_SET_RANGE]) { - if(s->rangestringalloc) - free(s->range); - - if(s->resume_from) - s->range = aprintf("%" CURL_FORMAT_CURL_OFF_TU "-", s->resume_from); - else - s->range = strdup(data->set.str[STRING_SET_RANGE]); - - s->rangestringalloc = (s->range) ? TRUE : FALSE; - - if(!s->range) - return CURLE_OUT_OF_MEMORY; - - /* tell ourselves to fetch this range */ - s->use_range = TRUE; /* enable range download */ - } - else - s->use_range = FALSE; /* disable range download */ - - return CURLE_OK; -} - - -/* - * setup_connection_internals() - - * - * Setup connection internals specific to the requested protocol in the - * SessionHandle. This is inited and setup before the connection is made but - * is about the particular protocol that is to be used. - * - * This MUST get called after proxy magic has been figured out. - */ -static CURLcode setup_connection_internals(struct connectdata *conn) -{ - const struct Curl_handler * p; - CURLcode result; - struct SessionHandle *data = conn->data; - - /* in some case in the multi state-machine, we go back to the CONNECT state - and then a second (or third or...) call to this function will be made - without doing a DISCONNECT or DONE in between (since the connection is - yet in place) and therefore this function needs to first make sure - there's no lingering previous data allocated. */ - Curl_free_request_state(data); - - memset(&data->req, 0, sizeof(struct SingleRequest)); - data->req.maxdownload = -1; - - conn->socktype = SOCK_STREAM; /* most of them are TCP streams */ - - /* Perform setup complement if some. */ - p = conn->handler; - - if(p->setup_connection) { - result = (*p->setup_connection)(conn); - - if(result) - return result; - - p = conn->handler; /* May have changed. */ - } - - if(conn->port < 0) - /* we check for -1 here since if proxy was detected already, this - was very likely already set to the proxy port */ - conn->port = p->defport; - - return CURLE_OK; -} - -/* - * Curl_free_request_state() should free temp data that was allocated in the - * SessionHandle for this single request. - */ - -void Curl_free_request_state(struct SessionHandle *data) -{ - Curl_safefree(data->req.protop); - Curl_safefree(data->req.newurl); -} - - -#ifndef CURL_DISABLE_PROXY -/**************************************************************** -* Checks if the host is in the noproxy list. returns true if it matches -* and therefore the proxy should NOT be used. -****************************************************************/ -static bool check_noproxy(const char* name, const char* no_proxy) -{ - /* no_proxy=domain1.dom,host.domain2.dom - * (a comma-separated list of hosts which should - * not be proxied, or an asterisk to override - * all proxy variables) - */ - size_t tok_start; - size_t tok_end; - const char* separator = ", "; - size_t no_proxy_len; - size_t namelen; - char *endptr; - - if(no_proxy && no_proxy[0]) { - if(Curl_raw_equal("*", no_proxy)) { - return TRUE; - } - - /* NO_PROXY was specified and it wasn't just an asterisk */ - - no_proxy_len = strlen(no_proxy); - endptr = strchr(name, ':'); - if(endptr) - namelen = endptr - name; - else - namelen = strlen(name); - - for(tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) { - while(tok_start < no_proxy_len && - strchr(separator, no_proxy[tok_start]) != NULL) { - /* Look for the beginning of the token. */ - ++tok_start; - } - - if(tok_start == no_proxy_len) - break; /* It was all trailing separator chars, no more tokens. */ - - for(tok_end = tok_start; tok_end < no_proxy_len && - strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) - /* Look for the end of the token. */ - ; - - /* To match previous behaviour, where it was necessary to specify - * ".local.com" to prevent matching "notlocal.com", we will leave - * the '.' off. - */ - if(no_proxy[tok_start] == '.') - ++tok_start; - - if((tok_end - tok_start) <= namelen) { - /* Match the last part of the name to the domain we are checking. */ - const char *checkn = name + namelen - (tok_end - tok_start); - if(Curl_raw_nequal(no_proxy + tok_start, checkn, - tok_end - tok_start)) { - if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') { - /* We either have an exact match, or the previous character is a . - * so it is within the same domain, so no proxy for this host. - */ - return TRUE; - } - } - } /* if((tok_end - tok_start) <= namelen) */ - } /* for(tok_start = 0; tok_start < no_proxy_len; - tok_start = tok_end + 1) */ - } /* NO_PROXY was specified and it wasn't just an asterisk */ - - return FALSE; -} - -/**************************************************************** -* Detect what (if any) proxy to use. Remember that this selects a host -* name and is not limited to HTTP proxies only. -* The returned pointer must be freed by the caller (unless NULL) -****************************************************************/ -static char *detect_proxy(struct connectdata *conn) -{ - char *proxy = NULL; - -#ifndef CURL_DISABLE_HTTP - /* If proxy was not specified, we check for default proxy environment - * variables, to enable i.e Lynx compliance: - * - * http_proxy=http://some.server.dom:port/ - * https_proxy=http://some.server.dom:port/ - * ftp_proxy=http://some.server.dom:port/ - * no_proxy=domain1.dom,host.domain2.dom - * (a comma-separated list of hosts which should - * not be proxied, or an asterisk to override - * all proxy variables) - * all_proxy=http://some.server.dom:port/ - * (seems to exist for the CERN www lib. Probably - * the first to check for.) - * - * For compatibility, the all-uppercase versions of these variables are - * checked if the lowercase versions don't exist. - */ - char *no_proxy=NULL; - char proxy_env[128]; - - no_proxy=curl_getenv("no_proxy"); - if(!no_proxy) - no_proxy=curl_getenv("NO_PROXY"); - - if(!check_noproxy(conn->host.name, no_proxy)) { - /* It was not listed as without proxy */ - const char *protop = conn->handler->scheme; - char *envp = proxy_env; - char *prox; - - /* Now, build _proxy and check for such a one to use */ - while(*protop) - *envp++ = (char)tolower((int)*protop++); - - /* append _proxy */ - strcpy(envp, "_proxy"); - - /* read the protocol proxy: */ - prox=curl_getenv(proxy_env); - - /* - * We don't try the uppercase version of HTTP_PROXY because of - * security reasons: - * - * When curl is used in a webserver application - * environment (cgi or php), this environment variable can - * be controlled by the web server user by setting the - * http header 'Proxy:' to some value. - * - * This can cause 'internal' http/ftp requests to be - * arbitrarily redirected by any external attacker. - */ - if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) { - /* There was no lowercase variable, try the uppercase version: */ - Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env)); - prox=curl_getenv(proxy_env); - } - - if(prox) - proxy = prox; /* use this */ - else { - proxy = curl_getenv("all_proxy"); /* default proxy to use */ - if(!proxy) - proxy=curl_getenv("ALL_PROXY"); - } - } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified - non-proxy */ - free(no_proxy); - -#else /* !CURL_DISABLE_HTTP */ - - (void)conn; -#endif /* CURL_DISABLE_HTTP */ - - return proxy; -} - -/* - * If this is supposed to use a proxy, we need to figure out the proxy - * host name, so that we can re-use an existing connection - * that may exist registered to the same proxy host. - */ -static CURLcode parse_proxy(struct SessionHandle *data, - struct connectdata *conn, char *proxy) -{ - char *prox_portno; - char *endofprot; - - /* We use 'proxyptr' to point to the proxy name from now on... */ - char *proxyptr; - char *portptr; - char *atsign; - - /* We do the proxy host string parsing here. We want the host name and the - * port name. Accept a protocol:// prefix - */ - - /* Parse the protocol part if present */ - endofprot = strstr(proxy, "://"); - if(endofprot) { - proxyptr = endofprot+3; - if(checkprefix("socks5h", proxy)) - conn->proxytype = CURLPROXY_SOCKS5_HOSTNAME; - else if(checkprefix("socks5", proxy)) - conn->proxytype = CURLPROXY_SOCKS5; - else if(checkprefix("socks4a", proxy)) - conn->proxytype = CURLPROXY_SOCKS4A; - else if(checkprefix("socks4", proxy) || checkprefix("socks", proxy)) - conn->proxytype = CURLPROXY_SOCKS4; - /* Any other xxx:// : change to http proxy */ - } - else - proxyptr = proxy; /* No xxx:// head: It's a HTTP proxy */ - - /* Is there a username and password given in this proxy url? */ - atsign = strchr(proxyptr, '@'); - if(atsign) { - char *proxyuser = NULL; - char *proxypasswd = NULL; - CURLcode result = - parse_login_details(proxyptr, atsign - proxyptr, - &proxyuser, &proxypasswd, NULL); - if(!result) { - /* found user and password, rip them out. note that we are - unescaping them, as there is otherwise no way to have a - username or password with reserved characters like ':' in - them. */ - Curl_safefree(conn->proxyuser); - if(proxyuser && strlen(proxyuser) < MAX_CURL_USER_LENGTH) - conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); - else - conn->proxyuser = strdup(""); - - if(!conn->proxyuser) - result = CURLE_OUT_OF_MEMORY; - else { - Curl_safefree(conn->proxypasswd); - if(proxypasswd && strlen(proxypasswd) < MAX_CURL_PASSWORD_LENGTH) - conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); - else - conn->proxypasswd = strdup(""); - - if(!conn->proxypasswd) - result = CURLE_OUT_OF_MEMORY; - } - - if(!result) { - conn->bits.proxy_user_passwd = TRUE; /* enable it */ - atsign++; /* the right side of the @-letter */ - - proxyptr = atsign; /* now use this instead */ - } - } - - free(proxyuser); - free(proxypasswd); - - if(result) - return result; - } - - /* start scanning for port number at this point */ - portptr = proxyptr; - - /* detect and extract RFC6874-style IPv6-addresses */ - if(*proxyptr == '[') { - char *ptr = ++proxyptr; /* advance beyond the initial bracket */ - while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.'))) - ptr++; - if(*ptr == '%') { - /* There might be a zone identifier */ - if(strncmp("%25", ptr, 3)) - infof(data, "Please URL encode %% as %%25, see RFC 6874.\n"); - ptr++; - /* Allow unreserved characters as defined in RFC 3986 */ - while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') || - (*ptr == '.') || (*ptr == '_') || (*ptr == '~'))) - ptr++; - } - if(*ptr == ']') - /* yeps, it ended nicely with a bracket as well */ - *ptr++ = 0; - else - infof(data, "Invalid IPv6 address format\n"); - portptr = ptr; - /* Note that if this didn't end with a bracket, we still advanced the - * proxyptr first, but I can't see anything wrong with that as no host - * name nor a numeric can legally start with a bracket. - */ - } - - /* Get port number off proxy.server.com:1080 */ - prox_portno = strchr(portptr, ':'); - if(prox_portno) { - char *endp = NULL; - long port = 0; - *prox_portno = 0x0; /* cut off number from host name */ - prox_portno ++; - /* now set the local port number */ - port = strtol(prox_portno, &endp, 10); - if((endp && *endp && (*endp != '/') && (*endp != ' ')) || - (port < 0) || (port > 65535)) { - /* meant to detect for example invalid IPv6 numerical addresses without - brackets: "2a00:fac0:a000::7:13". Accept a trailing slash only - because we then allow "URL style" with the number followed by a - slash, used in curl test cases already. Space is also an acceptable - terminating symbol. */ - infof(data, "No valid port number in proxy string (%s)\n", - prox_portno); - } - else - conn->port = port; - } - else { - if(proxyptr[0]=='/') - /* If the first character in the proxy string is a slash, fail - immediately. The following code will otherwise clear the string which - will lead to code running as if no proxy was set! */ - return CURLE_COULDNT_RESOLVE_PROXY; - - /* without a port number after the host name, some people seem to use - a slash so we strip everything from the first slash */ - atsign = strchr(proxyptr, '/'); - if(atsign) - *atsign = '\0'; /* cut off path part from host name */ - - if(data->set.proxyport) - /* None given in the proxy string, then get the default one if it is - given */ - conn->port = data->set.proxyport; - } - - /* now, clone the cleaned proxy host name */ - conn->proxy.rawalloc = strdup(proxyptr); - conn->proxy.name = conn->proxy.rawalloc; - - if(!conn->proxy.rawalloc) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} - -/* - * Extract the user and password from the authentication string - */ -static CURLcode parse_proxy_auth(struct SessionHandle *data, - struct connectdata *conn) -{ - char proxyuser[MAX_CURL_USER_LENGTH]=""; - char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - - if(data->set.str[STRING_PROXYUSERNAME] != NULL) { - strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME], - MAX_CURL_USER_LENGTH); - proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ - } - if(data->set.str[STRING_PROXYPASSWORD] != NULL) { - strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD], - MAX_CURL_PASSWORD_LENGTH); - proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ - } - - conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL); - if(!conn->proxyuser) - return CURLE_OUT_OF_MEMORY; - - conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL); - if(!conn->proxypasswd) - return CURLE_OUT_OF_MEMORY; - - return CURLE_OK; -} -#endif /* CURL_DISABLE_PROXY */ - -/* - * parse_url_login() - * - * Parse the login details (user name, password and options) from the URL and - * strip them out of the host name - * - * Inputs: data->set.use_netrc (CURLOPT_NETRC) - * conn->host.name - * - * Outputs: (almost :- all currently undefined) - * conn->bits.user_passwd - non-zero if non-default passwords exist - * user - non-zero length if defined - * passwd - non-zero length if defined - * options - non-zero length if defined - * conn->host.name - remove user name and password - */ -static CURLcode parse_url_login(struct SessionHandle *data, - struct connectdata *conn, - char **user, char **passwd, char **options) -{ - CURLcode result = CURLE_OK; - char *userp = NULL; - char *passwdp = NULL; - char *optionsp = NULL; - - /* At this point, we're hoping all the other special cases have - * been taken care of, so conn->host.name is at most - * [user[:password][;options]]@]hostname - * - * We need somewhere to put the embedded details, so do that first. - */ - - char *ptr = strchr(conn->host.name, '@'); - char *login = conn->host.name; - - DEBUGASSERT(!**user); - DEBUGASSERT(!**passwd); - DEBUGASSERT(!**options); - - if(!ptr) - goto out; - - /* We will now try to extract the - * possible login information in a string like: - * ftp://user:password@ftp.my.site:8021/README */ - conn->host.name = ++ptr; - - /* So the hostname is sane. Only bother interpreting the - * results if we could care. It could still be wasted - * work because it might be overtaken by the programmatically - * set user/passwd, but doing that first adds more cases here :-( - */ - - if(data->set.use_netrc == CURL_NETRC_REQUIRED) - goto out; - - /* We could use the login information in the URL so extract it */ - result = parse_login_details(login, ptr - login - 1, - &userp, &passwdp, &optionsp); - if(result) - goto out; - - if(userp) { - char *newname; - - /* We have a user in the URL */ - conn->bits.userpwd_in_url = TRUE; - conn->bits.user_passwd = TRUE; /* enable user+password */ - - /* Decode the user */ - newname = curl_easy_unescape(data, userp, 0, NULL); - if(!newname) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - free(*user); - *user = newname; - } - - if(passwdp) { - /* We have a password in the URL so decode it */ - char *newpasswd = curl_easy_unescape(data, passwdp, 0, NULL); - if(!newpasswd) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - free(*passwd); - *passwd = newpasswd; - } - - if(optionsp) { - /* We have an options list in the URL so decode it */ - char *newoptions = curl_easy_unescape(data, optionsp, 0, NULL); - if(!newoptions) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - free(*options); - *options = newoptions; - } - - - out: - - free(userp); - free(passwdp); - free(optionsp); - - return result; -} - -/* - * parse_login_details() - * - * This is used to parse a login string for user name, password and options in - * the following formats: - * - * user - * user:password - * user:password;options - * user;options - * user;options:password - * :password - * :password;options - * ;options - * ;options:password - * - * Parameters: - * - * login [in] - The login string. - * len [in] - The length of the login string. - * userp [in/out] - The address where a pointer to newly allocated memory - * holding the user will be stored upon completion. - * passdwp [in/out] - The address where a pointer to newly allocated memory - * holding the password will be stored upon completion. - * optionsp [in/out] - The address where a pointer to newly allocated memory - * holding the options will be stored upon completion. - * - * Returns CURLE_OK on success. - */ -static CURLcode parse_login_details(const char *login, const size_t len, - char **userp, char **passwdp, - char **optionsp) -{ - CURLcode result = CURLE_OK; - char *ubuf = NULL; - char *pbuf = NULL; - char *obuf = NULL; - const char *psep = NULL; - const char *osep = NULL; - size_t ulen; - size_t plen; - size_t olen; - - /* Attempt to find the password separator */ - if(passwdp) { - psep = strchr(login, ':'); - - /* Within the constraint of the login string */ - if(psep >= login + len) - psep = NULL; - } - - /* Attempt to find the options separator */ - if(optionsp) { - osep = strchr(login, ';'); - - /* Within the constraint of the login string */ - if(osep >= login + len) - osep = NULL; - } - - /* Calculate the portion lengths */ - ulen = (psep ? - (size_t)(osep && psep > osep ? osep - login : psep - login) : - (osep ? (size_t)(osep - login) : len)); - plen = (psep ? - (osep && osep > psep ? (size_t)(osep - psep) : - (size_t)(login + len - psep)) - 1 : 0); - olen = (osep ? - (psep && psep > osep ? (size_t)(psep - osep) : - (size_t)(login + len - osep)) - 1 : 0); - - /* Allocate the user portion buffer */ - if(userp && ulen) { - ubuf = malloc(ulen + 1); - if(!ubuf) - result = CURLE_OUT_OF_MEMORY; - } - - /* Allocate the password portion buffer */ - if(!result && passwdp && plen) { - pbuf = malloc(plen + 1); - if(!pbuf) { - free(ubuf); - result = CURLE_OUT_OF_MEMORY; - } - } - - /* Allocate the options portion buffer */ - if(!result && optionsp && olen) { - obuf = malloc(olen + 1); - if(!obuf) { - free(pbuf); - free(ubuf); - result = CURLE_OUT_OF_MEMORY; - } - } - - if(!result) { - /* Store the user portion if necessary */ - if(ubuf) { - memcpy(ubuf, login, ulen); - ubuf[ulen] = '\0'; - Curl_safefree(*userp); - *userp = ubuf; - } - - /* Store the password portion if necessary */ - if(pbuf) { - memcpy(pbuf, psep + 1, plen); - pbuf[plen] = '\0'; - Curl_safefree(*passwdp); - *passwdp = pbuf; - } - - /* Store the options portion if necessary */ - if(obuf) { - memcpy(obuf, osep + 1, olen); - obuf[olen] = '\0'; - Curl_safefree(*optionsp); - *optionsp = obuf; - } - } - - return result; -} - -/************************************************************* - * Figure out the remote port number and fix it in the URL - * - * No matter if we use a proxy or not, we have to figure out the remote - * port number of various reasons. - * - * To be able to detect port number flawlessly, we must not confuse them - * IPv6-specified addresses in the [0::1] style. (RFC2732) - * - * The conn->host.name is currently [user:passwd@]host[:port] where host - * could be a hostname, IPv4 address or IPv6 address. - * - * The port number embedded in the URL is replaced, if necessary. - *************************************************************/ -static CURLcode parse_remote_port(struct SessionHandle *data, - struct connectdata *conn) -{ - char *portptr; - char endbracket; - - /* Note that at this point, the IPv6 address cannot contain any scope - suffix as that has already been removed in the parseurlandfillconn() - function */ - if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c", - &endbracket)) && - (']' == endbracket)) { - /* this is a RFC2732-style specified IP-address */ - conn->bits.ipv6_ip = TRUE; - - conn->host.name++; /* skip over the starting bracket */ - portptr = strchr(conn->host.name, ']'); - if(portptr) { - *portptr++ = '\0'; /* zero terminate, killing the bracket */ - if(':' != *portptr) - portptr = NULL; /* no port number available */ - } - } - else { -#ifdef ENABLE_IPV6 - struct in6_addr in6; - if(Curl_inet_pton(AF_INET6, conn->host.name, &in6) > 0) { - /* This is a numerical IPv6 address, meaning this is a wrongly formatted - URL */ - failf(data, "IPv6 numerical address used in URL without brackets"); - return CURLE_URL_MALFORMAT; - } -#endif - - portptr = strrchr(conn->host.name, ':'); - } - - if(data->set.use_port && data->state.allow_port) { - /* if set, we use this and ignore the port possibly given in the URL */ - conn->remote_port = (unsigned short)data->set.use_port; - if(portptr) - *portptr = '\0'; /* cut off the name there anyway - if there was a port - number - since the port number is to be ignored! */ - if(conn->bits.httpproxy) { - /* we need to create new URL with the new port number */ - char *url; - char type[12]=""; - - if(conn->bits.type_set) - snprintf(type, sizeof(type), ";type=%c", - data->set.prefer_ascii?'A': - (data->set.ftp_list_only?'D':'I')); - - /* - * This synthesized URL isn't always right--suffixes like ;type=A are - * stripped off. It would be better to work directly from the original - * URL and simply replace the port part of it. - */ - url = aprintf("%s://%s%s%s:%hu%s%s%s", conn->given->scheme, - conn->bits.ipv6_ip?"[":"", conn->host.name, - conn->bits.ipv6_ip?"]":"", conn->remote_port, - data->state.slash_removed?"/":"", data->state.path, - type); - if(!url) - return CURLE_OUT_OF_MEMORY; - - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - - data->change.url = url; - data->change.url_alloc = TRUE; - } - } - else if(portptr) { - /* no CURLOPT_PORT given, extract the one from the URL */ - - char *rest; - long port; - - port=strtol(portptr+1, &rest, 10); /* Port number must be decimal */ - - if((port < 0) || (port > 0xffff)) { - /* Single unix standard says port numbers are 16 bits long */ - failf(data, "Port number out of range"); - return CURLE_URL_MALFORMAT; - } - - else if(rest != &portptr[1]) { - *portptr = '\0'; /* cut off the name there */ - conn->remote_port = curlx_ultous(port); - } - else - /* Browser behavior adaptation. If there's a colon with no digits after, - just cut off the name there which makes us ignore the colon and just - use the default port. Firefox and Chrome both do that. */ - *portptr = '\0'; - } - - /* only if remote_port was not already parsed off the URL we use the - default port number */ - if(conn->remote_port < 0) - conn->remote_port = (unsigned short)conn->given->defport; - - return CURLE_OK; -} - -/* - * Override the login details from the URL with that in the CURLOPT_USERPWD - * option or a .netrc file, if applicable. - */ -static CURLcode override_login(struct SessionHandle *data, - struct connectdata *conn, - char **userp, char **passwdp, char **optionsp) -{ - if(data->set.str[STRING_USERNAME]) { - free(*userp); - *userp = strdup(data->set.str[STRING_USERNAME]); - if(!*userp) - return CURLE_OUT_OF_MEMORY; - } - - if(data->set.str[STRING_PASSWORD]) { - free(*passwdp); - *passwdp = strdup(data->set.str[STRING_PASSWORD]); - if(!*passwdp) - return CURLE_OUT_OF_MEMORY; - } - - if(data->set.str[STRING_OPTIONS]) { - free(*optionsp); - *optionsp = strdup(data->set.str[STRING_OPTIONS]); - if(!*optionsp) - return CURLE_OUT_OF_MEMORY; - } - - conn->bits.netrc = FALSE; - if(data->set.use_netrc != CURL_NETRC_IGNORED) { - int ret = Curl_parsenetrc(conn->host.name, - userp, passwdp, - data->set.str[STRING_NETRC_FILE]); - if(ret > 0) { - infof(data, "Couldn't find host %s in the " - DOT_CHAR "netrc file; using defaults\n", - conn->host.name); - } - else if(ret < 0) { - return CURLE_OUT_OF_MEMORY; - } - else { - /* set bits.netrc TRUE to remember that we got the name from a .netrc - file, so that it is safe to use even if we followed a Location: to a - different host or similar. */ - conn->bits.netrc = TRUE; - - conn->bits.user_passwd = TRUE; /* enable user+password */ - } - } - - return CURLE_OK; -} - -/* - * Set the login details so they're available in the connection - */ -static CURLcode set_login(struct connectdata *conn, - const char *user, const char *passwd, - const char *options) -{ - CURLcode result = CURLE_OK; - - /* If our protocol needs a password and we have none, use the defaults */ - if((conn->handler->flags & PROTOPT_NEEDSPWD) && !conn->bits.user_passwd) { - /* Store the default user */ - conn->user = strdup(CURL_DEFAULT_USER); - - /* Store the default password */ - if(conn->user) - conn->passwd = strdup(CURL_DEFAULT_PASSWORD); - else - conn->passwd = NULL; - - /* This is the default password, so DON'T set conn->bits.user_passwd */ - } - else { - /* Store the user, zero-length if not set */ - conn->user = strdup(user); - - /* Store the password (only if user is present), zero-length if not set */ - if(conn->user) - conn->passwd = strdup(passwd); - else - conn->passwd = NULL; - } - - if(!conn->user || !conn->passwd) - result = CURLE_OUT_OF_MEMORY; - - /* Store the options, null if not set */ - if(!result && options[0]) { - conn->options = strdup(options); - - if(!conn->options) - result = CURLE_OUT_OF_MEMORY; - } - - return result; -} - -/* - * Parses a "host:port" string to connect to. - * The hostname and the port may be empty; in this case, NULL is returned for - * the hostname and -1 for the port. - */ -static CURLcode parse_connect_to_host_port(struct SessionHandle *data, - const char *host, - char **hostname_result, - int *port_result) -{ - char *host_dup; - char *hostptr; - char *host_portno; - char *portptr; - int port = -1; - - *hostname_result = NULL; - *port_result = -1; - - if(!host || !*host) - return CURLE_OK; - - host_dup = strdup(host); - if(!host_dup) - return CURLE_OUT_OF_MEMORY; - - hostptr = host_dup; - - /* start scanning for port number at this point */ - portptr = hostptr; - - /* detect and extract RFC6874-style IPv6-addresses */ - if(*hostptr == '[') { - char *ptr = ++hostptr; /* advance beyond the initial bracket */ - while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '.'))) - ptr++; - if(*ptr == '%') { - /* There might be a zone identifier */ - if(strncmp("%25", ptr, 3)) - infof(data, "Please URL encode %% as %%25, see RFC 6874.\n"); - ptr++; - /* Allow unreserved characters as defined in RFC 3986 */ - while(*ptr && (ISALPHA(*ptr) || ISXDIGIT(*ptr) || (*ptr == '-') || - (*ptr == '.') || (*ptr == '_') || (*ptr == '~'))) - ptr++; - } - if(*ptr == ']') - /* yeps, it ended nicely with a bracket as well */ - *ptr++ = '\0'; - else - infof(data, "Invalid IPv6 address format\n"); - portptr = ptr; - /* Note that if this didn't end with a bracket, we still advanced the - * hostptr first, but I can't see anything wrong with that as no host - * name nor a numeric can legally start with a bracket. - */ - } - - /* Get port number off server.com:1080 */ - host_portno = strchr(portptr, ':'); - if(host_portno) { - char *endp = NULL; - *host_portno = '\0'; /* cut off number from host name */ - host_portno++; - if(*host_portno) { - long portparse = strtol(host_portno, &endp, 10); - if((endp && *endp) || (portparse < 0) || (portparse > 65535)) { - infof(data, "No valid port number in connect to host string (%s)\n", - host_portno); - hostptr = NULL; - port = -1; - } - else - port = (int)portparse; /* we know it will fit */ - } - } - - /* now, clone the cleaned host name */ - if(hostptr) { - *hostname_result = strdup(hostptr); - if(!*hostname_result) { - free(host_dup); - return CURLE_OUT_OF_MEMORY; - } - } - - *port_result = port; - - free(host_dup); - return CURLE_OK; -} - -/* - * Parses one "connect to" string in the form: - * "HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT". - */ -static CURLcode parse_connect_to_string(struct SessionHandle *data, - struct connectdata *conn, - const char *conn_to_host, - char **host_result, - int *port_result) -{ - CURLcode result = CURLE_OK; - const char *ptr = conn_to_host; - int host_match = FALSE; - int port_match = FALSE; - - if(*ptr == ':') { - /* an empty hostname always matches */ - host_match = TRUE; - ptr++; - } - else { - /* check whether the URL's hostname matches */ - size_t hostname_to_match_len; - char *hostname_to_match = aprintf("%s%s%s", - conn->bits.ipv6_ip ? "[" : "", - conn->host.name, - conn->bits.ipv6_ip ? "]" : ""); - if(!hostname_to_match) - return CURLE_OUT_OF_MEMORY; - hostname_to_match_len = strlen(hostname_to_match); - host_match = curl_strnequal(ptr, hostname_to_match, hostname_to_match_len); - free(hostname_to_match); - ptr += hostname_to_match_len; - - host_match = host_match && *ptr == ':'; - ptr++; - } - - if(host_match) { - if(*ptr == ':') { - /* an empty port always matches */ - port_match = TRUE; - ptr++; - } - else { - /* check whether the URL's port matches */ - char *ptr_next = strchr(ptr, ':'); - if(ptr_next) { - char *endp = NULL; - long port_to_match = strtol(ptr, &endp, 10); - if((endp == ptr_next) && (port_to_match == conn->remote_port)) { - port_match = TRUE; - ptr = ptr_next + 1; - } - } - } - } - - if(host_match && port_match) { - /* parse the hostname and port to connect to */ - result = parse_connect_to_host_port(data, ptr, host_result, port_result); - } - - return result; -} - -/* - * Processes all strings in the "connect to" slist, and uses the "connect - * to host" and "connect to port" of the first string that matches. - */ -static CURLcode parse_connect_to_slist(struct SessionHandle *data, - struct connectdata *conn, - struct curl_slist *conn_to_host) -{ - CURLcode result = CURLE_OK; - char *host = NULL; - int port = 0; - - while(conn_to_host && !host) { - result = parse_connect_to_string(data, conn, conn_to_host->data, - &host, &port); - if(result) - return result; - - if(host && *host) { - bool ipv6host; - conn->conn_to_host.rawalloc = host; - conn->conn_to_host.name = host; - conn->bits.conn_to_host = TRUE; - - ipv6host = strchr(host, ':') != NULL; - infof(data, "Connecting to hostname: %s%s%s\n", - ipv6host ? "[" : "", host, ipv6host ? "]" : ""); - } - else { - /* no "connect to host" */ - conn->bits.conn_to_host = FALSE; - free(host); - } - - if(port >= 0) { - conn->conn_to_port = port; - conn->bits.conn_to_port = TRUE; - infof(data, "Connecting to port: %d\n", port); - } - else { - /* no "connect to port" */ - conn->bits.conn_to_port = FALSE; - } - - conn_to_host = conn_to_host->next; - } - - return result; -} - -/************************************************************* - * Resolve the address of the server or proxy - *************************************************************/ -static CURLcode resolve_server(struct SessionHandle *data, - struct connectdata *conn, - bool *async) -{ - CURLcode result=CURLE_OK; - long timeout_ms = Curl_timeleft(data, NULL, TRUE); - - /************************************************************* - * Resolve the name of the server or proxy - *************************************************************/ - if(conn->bits.reuse) - /* We're reusing the connection - no need to resolve anything, and - fix_hostname() was called already in create_conn() for the re-use - case. */ - *async = FALSE; - - else { - /* this is a fresh connect */ - int rc; - struct Curl_dns_entry *hostaddr; - -#ifdef USE_UNIX_SOCKETS - if(data->set.str[STRING_UNIX_SOCKET_PATH]) { - /* Unix domain sockets are local. The host gets ignored, just use the - * specified domain socket address. Do not cache "DNS entries". There is - * no DNS involved and we already have the filesystem path available */ - const char *path = data->set.str[STRING_UNIX_SOCKET_PATH]; - - hostaddr = calloc(1, sizeof(struct Curl_dns_entry)); - if(!hostaddr) - result = CURLE_OUT_OF_MEMORY; - else if((hostaddr->addr = Curl_unix2addr(path)) != NULL) - hostaddr->inuse++; - else { - /* Long paths are not supported for now */ - if(strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) { - failf(data, "Unix socket path too long: '%s'", path); - result = CURLE_COULDNT_RESOLVE_HOST; - } - else - result = CURLE_OUT_OF_MEMORY; - free(hostaddr); - hostaddr = NULL; - } - } - else -#endif - if(!conn->proxy.name || !*conn->proxy.name) { - struct hostname *connhost; - if(conn->bits.conn_to_host) - connhost = &conn->conn_to_host; - else - connhost = &conn->host; - - /* If not connecting via a proxy, extract the port from the URL, if it is - * there, thus overriding any defaults that might have been set above. */ - if(conn->bits.conn_to_port) - conn->port = conn->conn_to_port; - else - conn->port = conn->remote_port; /* it is the same port */ - - /* Resolve target host right on */ - rc = Curl_resolv_timeout(conn, connhost->name, (int)conn->port, - &hostaddr, timeout_ms); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - - else if(rc == CURLRESOLV_TIMEDOUT) - result = CURLE_OPERATION_TIMEDOUT; - - else if(!hostaddr) { - failf(data, "Couldn't resolve host '%s'", connhost->dispname); - result = CURLE_COULDNT_RESOLVE_HOST; - /* don't return yet, we need to clean up the timeout first */ - } - } - else { - /* This is a proxy that hasn't been resolved yet. */ - - /* resolve proxy */ - rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port, - &hostaddr, timeout_ms); - - if(rc == CURLRESOLV_PENDING) - *async = TRUE; - - else if(rc == CURLRESOLV_TIMEDOUT) - result = CURLE_OPERATION_TIMEDOUT; - - else if(!hostaddr) { - failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); - result = CURLE_COULDNT_RESOLVE_PROXY; - /* don't return yet, we need to clean up the timeout first */ - } - } - DEBUGASSERT(conn->dns_entry == NULL); - conn->dns_entry = hostaddr; - } - - return result; -} - -/* - * Cleanup the connection just allocated before we can move along and use the - * previously existing one. All relevant data is copied over and old_conn is - * ready for freeing once this function returns. - */ -static void reuse_conn(struct connectdata *old_conn, - struct connectdata *conn) -{ - free_fixed_hostname(&old_conn->proxy); - free(old_conn->proxy.rawalloc); - - /* free the SSL config struct from this connection struct as this was - allocated in vain and is targeted for destruction */ - Curl_free_ssl_config(&old_conn->ssl_config); - - conn->data = old_conn->data; - - /* get the user+password information from the old_conn struct since it may - * be new for this request even when we re-use an existing connection */ - conn->bits.user_passwd = old_conn->bits.user_passwd; - if(conn->bits.user_passwd) { - /* use the new user name and password though */ - Curl_safefree(conn->user); - Curl_safefree(conn->passwd); - conn->user = old_conn->user; - conn->passwd = old_conn->passwd; - old_conn->user = NULL; - old_conn->passwd = NULL; - } - - conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; - if(conn->bits.proxy_user_passwd) { - /* use the new proxy user name and proxy password though */ - Curl_safefree(conn->proxyuser); - Curl_safefree(conn->proxypasswd); - conn->proxyuser = old_conn->proxyuser; - conn->proxypasswd = old_conn->proxypasswd; - old_conn->proxyuser = NULL; - old_conn->proxypasswd = NULL; - } - - /* host can change, when doing keepalive with a proxy or if the case is - different this time etc */ - free_fixed_hostname(&conn->host); - free_fixed_hostname(&conn->conn_to_host); - Curl_safefree(conn->host.rawalloc); - Curl_safefree(conn->conn_to_host.rawalloc); - conn->host=old_conn->host; - conn->bits.conn_to_host = old_conn->bits.conn_to_host; - conn->conn_to_host = old_conn->conn_to_host; - conn->bits.conn_to_port = old_conn->bits.conn_to_port; - conn->conn_to_port = old_conn->conn_to_port; - - /* persist connection info in session handle */ - Curl_persistconninfo(conn); - - conn_reset_all_postponed_data(old_conn); /* free buffers */ - conn_reset_all_postponed_data(conn); /* reset unprocessed data */ - - /* re-use init */ - conn->bits.reuse = TRUE; /* yes, we're re-using here */ - - Curl_safefree(old_conn->user); - Curl_safefree(old_conn->passwd); - Curl_safefree(old_conn->proxyuser); - Curl_safefree(old_conn->proxypasswd); - Curl_safefree(old_conn->localdev); - - Curl_llist_destroy(old_conn->send_pipe, NULL); - Curl_llist_destroy(old_conn->recv_pipe, NULL); - - old_conn->send_pipe = NULL; - old_conn->recv_pipe = NULL; - - Curl_safefree(old_conn->master_buffer); -} - -/** - * create_conn() sets up a new connectdata struct, or re-uses an already - * existing one, and resolves host name. - * - * if this function returns CURLE_OK and *async is set to TRUE, the resolve - * response will be coming asynchronously. If *async is FALSE, the name is - * already resolved. - * - * @param data The sessionhandle pointer - * @param in_connect is set to the next connection data pointer - * @param async is set TRUE when an async DNS resolution is pending - * @see Curl_setup_conn() - * - * *NOTE* this function assigns the conn->data pointer! - */ - -static CURLcode create_conn(struct SessionHandle *data, - struct connectdata **in_connect, - bool *async) -{ - CURLcode result = CURLE_OK; - struct connectdata *conn; - struct connectdata *conn_temp = NULL; - size_t urllen; - char *user = NULL; - char *passwd = NULL; - char *options = NULL; - bool reuse; - char *proxy = NULL; - bool prot_missing = FALSE; - bool connections_available = TRUE; - bool force_reuse = FALSE; - bool waitpipe = FALSE; - size_t max_host_connections = Curl_multi_max_host_connections(data->multi); - size_t max_total_connections = Curl_multi_max_total_connections(data->multi); - - *async = FALSE; - - /************************************************************* - * Check input data - *************************************************************/ - - if(!data->change.url) { - result = CURLE_URL_MALFORMAT; - goto out; - } - - /* First, split up the current URL in parts so that we can use the - parts for checking against the already present connections. In order - to not have to modify everything at once, we allocate a temporary - connection data struct and fill in for comparison purposes. */ - conn = allocate_conn(data); - - if(!conn) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* We must set the return variable as soon as possible, so that our - parent can cleanup any possible allocs we may have done before - any failure */ - *in_connect = conn; - - /* This initing continues below, see the comment "Continue connectdata - * initialization here" */ - - /*********************************************************** - * We need to allocate memory to store the path in. We get the size of the - * full URL to be sure, and we need to make it at least 256 bytes since - * other parts of the code will rely on this fact - ***********************************************************/ -#define LEAST_PATH_ALLOC 256 - urllen=strlen(data->change.url); - if(urllen < LEAST_PATH_ALLOC) - urllen=LEAST_PATH_ALLOC; - - /* - * We malloc() the buffers below urllen+2 to make room for 2 possibilities: - * 1 - an extra terminating zero - * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used) - */ - - Curl_safefree(data->state.pathbuffer); - data->state.path = NULL; - - data->state.pathbuffer = malloc(urllen+2); - if(NULL == data->state.pathbuffer) { - result = CURLE_OUT_OF_MEMORY; /* really bad error */ - goto out; - } - data->state.path = data->state.pathbuffer; - - conn->host.rawalloc = malloc(urllen+2); - if(NULL == conn->host.rawalloc) { - Curl_safefree(data->state.pathbuffer); - data->state.path = NULL; - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - conn->host.name = conn->host.rawalloc; - conn->host.name[0] = 0; - - user = strdup(""); - passwd = strdup(""); - options = strdup(""); - if(!user || !passwd || !options) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - result = parseurlandfillconn(data, conn, &prot_missing, &user, &passwd, - &options); - if(result) - goto out; - - /************************************************************* - * No protocol part in URL was used, add it! - *************************************************************/ - if(prot_missing) { - /* We're guessing prefixes here and if we're told to use a proxy or if - we're gonna follow a Location: later or... then we need the protocol - part added so that we have a valid URL. */ - char *reurl; - char *ch_lower; - - reurl = aprintf("%s://%s", conn->handler->scheme, data->change.url); - - if(!reurl) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - /* Change protocol prefix to lower-case */ - for(ch_lower = reurl; *ch_lower != ':'; ch_lower++) - *ch_lower = (char)TOLOWER(*ch_lower); - - if(data->change.url_alloc) { - Curl_safefree(data->change.url); - data->change.url_alloc = FALSE; - } - - data->change.url = reurl; - data->change.url_alloc = TRUE; /* free this later */ - } - - /************************************************************* - * If the protocol can't handle url query strings, then cut - * off the unhandable part - *************************************************************/ - if((conn->given->flags&PROTOPT_NOURLQUERY)) { - char *path_q_sep = strchr(conn->data->state.path, '?'); - if(path_q_sep) { - /* according to rfc3986, allow the query (?foo=bar) - also on protocols that can't handle it. - - cut the string-part after '?' - */ - - /* terminate the string */ - path_q_sep[0] = 0; - } - } - - if(data->set.str[STRING_BEARER]) { - conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]); - if(!conn->oauth_bearer) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - -#ifndef CURL_DISABLE_PROXY - /************************************************************* - * Extract the user and password from the authentication string - *************************************************************/ - if(conn->bits.proxy_user_passwd) { - result = parse_proxy_auth(data, conn); - if(result) - goto out; - } - - /************************************************************* - * Detect what (if any) proxy to use - *************************************************************/ - if(data->set.str[STRING_PROXY]) { - proxy = strdup(data->set.str[STRING_PROXY]); - /* if global proxy is set, this is it */ - if(NULL == proxy) { - failf(data, "memory shortage"); - result = CURLE_OUT_OF_MEMORY; - goto out; - } - } - - if(data->set.str[STRING_NOPROXY] && - check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) { - free(proxy); /* proxy is in exception list */ - proxy = NULL; - } - else if(!proxy) - proxy = detect_proxy(conn); - -#ifdef USE_UNIX_SOCKETS - if(proxy && data->set.str[STRING_UNIX_SOCKET_PATH]) { - free(proxy); /* Unix domain sockets cannot be proxied, so disable it */ - proxy = NULL; - } -#endif - - if(proxy && (!*proxy || (conn->handler->flags & PROTOPT_NONETWORK))) { - free(proxy); /* Don't bother with an empty proxy string or if the - protocol doesn't work with network */ - proxy = NULL; - } - - /*********************************************************************** - * If this is supposed to use a proxy, we need to figure out the proxy host - * name, proxy type and port number, so that we can re-use an existing - * connection that may exist registered to the same proxy host. - ***********************************************************************/ - if(proxy) { - result = parse_proxy(data, conn, proxy); - - free(proxy); /* parse_proxy copies the proxy string */ - proxy = NULL; - - if(result) - goto out; - - if((conn->proxytype == CURLPROXY_HTTP) || - (conn->proxytype == CURLPROXY_HTTP_1_0)) { -#ifdef CURL_DISABLE_HTTP - /* asking for a HTTP proxy is a bit funny when HTTP is disabled... */ - result = CURLE_UNSUPPORTED_PROTOCOL; - goto out; -#else - /* force this connection's protocol to become HTTP if not already - compatible - if it isn't tunneling through */ - if(!(conn->handler->protocol & PROTO_FAMILY_HTTP) && - !conn->bits.tunnel_proxy) - conn->handler = &Curl_handler_http; - - conn->bits.httpproxy = TRUE; -#endif - } - else { - conn->bits.httpproxy = FALSE; /* not a HTTP proxy */ - conn->bits.tunnel_proxy = FALSE; /* no tunneling if not HTTP */ - } - conn->bits.proxy = TRUE; - } - else { - /* we aren't using the proxy after all... */ - conn->bits.proxy = FALSE; - conn->bits.httpproxy = FALSE; - conn->bits.proxy_user_passwd = FALSE; - conn->bits.tunnel_proxy = FALSE; - } - -#endif /* CURL_DISABLE_PROXY */ - - /************************************************************* - * If the protocol is using SSL and HTTP proxy is used, we set - * the tunnel_proxy bit. - *************************************************************/ - if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy) - conn->bits.tunnel_proxy = TRUE; - - /************************************************************* - * Figure out the remote port number and fix it in the URL - *************************************************************/ - result = parse_remote_port(data, conn); - if(result) - goto out; - - /* Check for overridden login details and set them accordingly so they - they are known when protocol->setup_connection is called! */ - result = override_login(data, conn, &user, &passwd, &options); - if(result) - goto out; - result = set_login(conn, user, passwd, options); - if(result) - goto out; - - /************************************************************* - * Process the "connect to" linked list of hostname/port mappings. - * Do this after the remote port number has been fixed in the URL. - *************************************************************/ - result = parse_connect_to_slist(data, conn, data->set.connect_to); - if(result) - goto out; - - /************************************************************* - * IDN-fix the hostnames - *************************************************************/ - fix_hostname(data, conn, &conn->host); - if(conn->bits.conn_to_host) - fix_hostname(data, conn, &conn->conn_to_host); - if(conn->proxy.name && *conn->proxy.name) - fix_hostname(data, conn, &conn->proxy); - - /************************************************************* - * Check whether the host and the "connect to host" are equal. - * Do this after the hostnames have been IDN-fixed . - *************************************************************/ - if(conn->bits.conn_to_host && - Curl_raw_equal(conn->conn_to_host.name, conn->host.name)) { - conn->bits.conn_to_host = FALSE; - } - - /************************************************************* - * Check whether the port and the "connect to port" are equal. - * Do this after the remote port number has been fixed in the URL. - *************************************************************/ - if(conn->bits.conn_to_port && conn->conn_to_port == conn->remote_port) { - conn->bits.conn_to_port = FALSE; - } - - /************************************************************* - * If the "connect to" feature is used with an HTTP proxy, - * we set the tunnel_proxy bit. - *************************************************************/ - if((conn->bits.conn_to_host || conn->bits.conn_to_port) && - conn->bits.httpproxy) - conn->bits.tunnel_proxy = TRUE; - - /************************************************************* - * Setup internals depending on protocol. Needs to be done after - * we figured out what/if proxy to use. - *************************************************************/ - result = setup_connection_internals(conn); - if(result) - goto out; - - conn->recv[FIRSTSOCKET] = Curl_recv_plain; - conn->send[FIRSTSOCKET] = Curl_send_plain; - conn->recv[SECONDARYSOCKET] = Curl_recv_plain; - conn->send[SECONDARYSOCKET] = Curl_send_plain; - - conn->bits.tcp_fastopen = data->set.tcp_fastopen; - - /*********************************************************************** - * file: is a special case in that it doesn't need a network connection - ***********************************************************************/ -#ifndef CURL_DISABLE_FILE - if(conn->handler->flags & PROTOPT_NONETWORK) { - bool done; - /* this is supposed to be the connect function so we better at least check - that the file is present here! */ - DEBUGASSERT(conn->handler->connect_it); - result = conn->handler->connect_it(conn, &done); - - /* Setup a "faked" transfer that'll do nothing */ - if(!result) { - conn->data = data; - conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */ - - Curl_conncache_add_conn(data->state.conn_cache, conn); - - /* - * Setup whatever necessary for a resumed transfer - */ - result = setup_range(data); - if(result) { - DEBUGASSERT(conn->handler->done); - /* we ignore the return code for the protocol-specific DONE */ - (void)conn->handler->done(conn, result, FALSE); - goto out; - } - - Curl_setup_transfer(conn, -1, -1, FALSE, NULL, /* no download */ - -1, NULL); /* no upload */ - } - - /* since we skip do_init() */ - Curl_init_do(data, conn); - - goto out; - } -#endif - - /* Get a cloned copy of the SSL config situation stored in the - connection struct. But to get this going nicely, we must first make - sure that the strings in the master copy are pointing to the correct - strings in the session handle strings array! - - Keep in mind that the pointers in the master copy are pointing to strings - that will be freed as part of the SessionHandle struct, but all cloned - copies will be separately allocated. - */ - data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH]; - data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE]; - data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE]; - data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT]; - data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; - data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; - data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST]; -#ifdef USE_TLS_SRP - data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME]; - data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD]; -#endif - - if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config)) { - result = CURLE_OUT_OF_MEMORY; - goto out; - } - - prune_dead_connections(data); - - /************************************************************* - * Check the current list of connections to see if we can - * re-use an already existing one or if we have to create a - * new one. - *************************************************************/ - - /* reuse_fresh is TRUE if we are told to use a new connection by force, but - we only acknowledge this option if this is not a re-used connection - already (which happens due to follow-location or during a HTTP - authentication phase). */ - if(data->set.reuse_fresh && !data->state.this_is_a_follow) - reuse = FALSE; - else - reuse = ConnectionExists(data, conn, &conn_temp, &force_reuse, &waitpipe); - - /* If we found a reusable connection, we may still want to - open a new connection if we are pipelining. */ - if(reuse && !force_reuse && IsPipeliningPossible(data, conn_temp)) { - size_t pipelen = conn_temp->send_pipe->size + conn_temp->recv_pipe->size; - if(pipelen > 0) { - infof(data, "Found connection %ld, with requests in the pipe (%zu)\n", - conn_temp->connection_id, pipelen); - - if(conn_temp->bundle->num_connections < max_host_connections && - data->state.conn_cache->num_connections < max_total_connections) { - /* We want a new connection anyway */ - reuse = FALSE; - - infof(data, "We can reuse, but we want a new connection anyway\n"); - } - } - } - - if(reuse) { - /* - * We already have a connection for this, we got the former connection - * in the conn_temp variable and thus we need to cleanup the one we - * just allocated before we can move along and use the previously - * existing one. - */ - conn_temp->inuse = TRUE; /* mark this as being in use so that no other - handle in a multi stack may nick it */ - reuse_conn(conn, conn_temp); - free(conn); /* we don't need this anymore */ - conn = conn_temp; - *in_connect = conn; - - infof(data, "Re-using existing connection! (#%ld) with %s %s\n", - conn->connection_id, - conn->bits.proxy?"proxy":"host", - conn->proxy.name?conn->proxy.dispname:conn->host.dispname); - } - else { - /* We have decided that we want a new connection. However, we may not - be able to do that if we have reached the limit of how many - connections we are allowed to open. */ - struct connectbundle *bundle = NULL; - - if(conn->handler->flags & PROTOPT_ALPN_NPN) { - /* The protocol wants it, so set the bits if enabled in the easy handle - (default) */ - if(data->set.ssl_enable_alpn) - conn->bits.tls_enable_alpn = TRUE; - if(data->set.ssl_enable_npn) - conn->bits.tls_enable_npn = TRUE; - } - - if(waitpipe) - /* There is a connection that *might* become usable for pipelining - "soon", and we wait for that */ - connections_available = FALSE; - else - bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache); - - if(max_host_connections > 0 && bundle && - (bundle->num_connections >= max_host_connections)) { - struct connectdata *conn_candidate; - - /* The bundle is full. Let's see if we can kill a connection. */ - conn_candidate = find_oldest_idle_connection_in_bundle(data, bundle); - - if(conn_candidate) { - /* Set the connection's owner correctly, then kill it */ - conn_candidate->data = data; - (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); - } - else { - infof(data, "No more connections allowed to host: %d\n", - max_host_connections); - connections_available = FALSE; - } - } - - if(connections_available && - (max_total_connections > 0) && - (data->state.conn_cache->num_connections >= max_total_connections)) { - struct connectdata *conn_candidate; - - /* The cache is full. Let's see if we can kill a connection. */ - conn_candidate = Curl_oldest_idle_connection(data); - - if(conn_candidate) { - /* Set the connection's owner correctly, then kill it */ - conn_candidate->data = data; - (void)Curl_disconnect(conn_candidate, /* dead_connection */ FALSE); - } - else { - infof(data, "No connections available in cache\n"); - connections_available = FALSE; - } - } - - if(!connections_available) { - infof(data, "No connections available.\n"); - - conn_free(conn); - *in_connect = NULL; - - result = CURLE_NO_CONNECTION_AVAILABLE; - goto out; - } - else { - /* - * This is a brand new connection, so let's store it in the connection - * cache of ours! - */ - Curl_conncache_add_conn(data->state.conn_cache, conn); - } - -#if defined(USE_NTLM) - /* If NTLM is requested in a part of this connection, make sure we don't - assume the state is fine as this is a fresh connection and NTLM is - connection based. */ - if((data->state.authhost.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && - data->state.authhost.done) { - infof(data, "NTLM picked AND auth done set, clear picked!\n"); - data->state.authhost.picked = CURLAUTH_NONE; - data->state.authhost.done = FALSE; - } - - if((data->state.authproxy.picked & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && - data->state.authproxy.done) { - infof(data, "NTLM-proxy picked AND auth done set, clear picked!\n"); - data->state.authproxy.picked = CURLAUTH_NONE; - data->state.authproxy.done = FALSE; - } -#endif - } - - /* Mark the connection as used */ - conn->inuse = TRUE; - - /* Setup and init stuff before DO starts, in preparing for the transfer. */ - Curl_init_do(data, conn); - - /* - * Setup whatever necessary for a resumed transfer - */ - result = setup_range(data); - if(result) - goto out; - - /* Continue connectdata initialization here. */ - - /* - * Inherit the proper values from the urldata struct AFTER we have arranged - * the persistent connection stuff - */ - conn->seek_func = data->set.seek_func; - conn->seek_client = data->set.seek_client; - - /************************************************************* - * Resolve the address of the server or proxy - *************************************************************/ - result = resolve_server(data, conn, async); - - out: - - free(options); - free(passwd); - free(user); - free(proxy); - return result; -} - -/* Curl_setup_conn() is called after the name resolve initiated in - * create_conn() is all done. - * - * Curl_setup_conn() also handles reused connections - * - * conn->data MUST already have been setup fine (in create_conn) - */ - -CURLcode Curl_setup_conn(struct connectdata *conn, - bool *protocol_done) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - Curl_pgrsTime(data, TIMER_NAMELOOKUP); - - if(conn->handler->flags & PROTOPT_NONETWORK) { - /* nothing to setup when not using a network */ - *protocol_done = TRUE; - return result; - } - *protocol_done = FALSE; /* default to not done */ - - /* set proxy_connect_closed to false unconditionally already here since it - is used strictly to provide extra information to a parent function in the - case of proxy CONNECT failures and we must make sure we don't have it - lingering set from a previous invoke */ - conn->bits.proxy_connect_closed = FALSE; - - /* - * Set user-agent. Used for HTTP, but since we can attempt to tunnel - * basically anything through a http proxy we can't limit this based on - * protocol. - */ - if(data->set.str[STRING_USERAGENT]) { - Curl_safefree(conn->allocptr.uagent); - conn->allocptr.uagent = - aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); - if(!conn->allocptr.uagent) - return CURLE_OUT_OF_MEMORY; - } - - data->req.headerbytecount = 0; - -#ifdef CURL_DO_LINEEND_CONV - data->state.crlf_conversions = 0; /* reset CRLF conversion counter */ -#endif /* CURL_DO_LINEEND_CONV */ - - /* set start time here for timeout purposes in the connect procedure, it - is later set again for the progress meter purpose */ - conn->now = Curl_tvnow(); - - if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) { - conn->bits.tcpconnect[FIRSTSOCKET] = FALSE; - result = Curl_connecthost(conn, conn->dns_entry); - if(result) - return result; - } - else { - Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */ - Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */ - conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; - *protocol_done = TRUE; - Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]); - Curl_verboseconnect(conn); - } - - conn->now = Curl_tvnow(); /* time this *after* the connect is done, we - set this here perhaps a second time */ - -#ifdef __EMX__ - /* - * This check is quite a hack. We're calling _fsetmode to fix the problem - * with fwrite converting newline characters (you get mangled text files, - * and corrupted binary files when you download to stdout and redirect it to - * a file). - */ - - if((data->set.out)->_handle == NULL) { - _fsetmode(stdout, "b"); - } -#endif - - return result; -} - -CURLcode Curl_connect(struct SessionHandle *data, - struct connectdata **in_connect, - bool *asyncp, - bool *protocol_done) -{ - CURLcode result; - - *asyncp = FALSE; /* assume synchronous resolves by default */ - - /* call the stuff that needs to be called */ - result = create_conn(data, in_connect, asyncp); - - if(!result) { - /* no error */ - if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size) - /* pipelining */ - *protocol_done = TRUE; - else if(!*asyncp) { - /* DNS resolution is done: that's either because this is a reused - connection, in which case DNS was unnecessary, or because DNS - really did finish already (synch resolver/fast async resolve) */ - result = Curl_setup_conn(*in_connect, protocol_done); - } - } - - if(result == CURLE_NO_CONNECTION_AVAILABLE) { - *in_connect = NULL; - return result; - } - - if(result && *in_connect) { - /* We're not allowed to return failure with memory left allocated - in the connectdata struct, free those here */ - Curl_disconnect(*in_connect, FALSE); /* close the connection */ - *in_connect = NULL; /* return a NULL */ - } - - return result; -} - -/* - * Curl_init_do() inits the readwrite session. This is inited each time (in - * the DO function before the protocol-specific DO functions are invoked) for - * a transfer, sometimes multiple times on the same SessionHandle. Make sure - * nothing in here depends on stuff that are setup dynamically for the - * transfer. - * - * Allow this function to get called with 'conn' set to NULL. - */ - -CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn) -{ - struct SingleRequest *k = &data->req; - - if(conn) - conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to - * use */ - - data->state.done = FALSE; /* *_done() is not called yet */ - data->state.expect100header = FALSE; - - if(data->set.opt_no_body) - /* in HTTP lingo, no body means using the HEAD request... */ - data->set.httpreq = HTTPREQ_HEAD; - else if(HTTPREQ_HEAD == data->set.httpreq) - /* ... but if unset there really is no perfect method that is the - "opposite" of HEAD but in reality most people probably think GET - then. The important thing is that we can't let it remain HEAD if the - opt_no_body is set FALSE since then we'll behave wrong when getting - HTTP. */ - data->set.httpreq = HTTPREQ_GET; - - k->start = Curl_tvnow(); /* start time */ - k->now = k->start; /* current time is now */ - k->header = TRUE; /* assume header */ - - k->bytecount = 0; - - k->buf = data->state.buffer; - k->uploadbuf = data->state.uploadbuffer; - k->hbufp = data->state.headerbuff; - k->ignorebody=FALSE; - - Curl_speedinit(data); - - Curl_pgrsSetUploadCounter(data, 0); - Curl_pgrsSetDownloadCounter(data, 0); - - return CURLE_OK; -} - -/* -* get_protocol_family() -* -* This is used to return the protocol family for a given protocol. -* -* Parameters: -* -* protocol [in] - A single bit protocol identifier such as HTTP or HTTPS. -* -* Returns the family as a single bit protocol identifier. -*/ - -unsigned int get_protocol_family(unsigned int protocol) -{ - unsigned int family; - - switch(protocol) { - case CURLPROTO_HTTP: - case CURLPROTO_HTTPS: - family = CURLPROTO_HTTP; - break; - - case CURLPROTO_FTP: - case CURLPROTO_FTPS: - family = CURLPROTO_FTP; - break; - - case CURLPROTO_SCP: - family = CURLPROTO_SCP; - break; - - case CURLPROTO_SFTP: - family = CURLPROTO_SFTP; - break; - - case CURLPROTO_TELNET: - family = CURLPROTO_TELNET; - break; - - case CURLPROTO_LDAP: - case CURLPROTO_LDAPS: - family = CURLPROTO_LDAP; - break; - - case CURLPROTO_DICT: - family = CURLPROTO_DICT; - break; - - case CURLPROTO_FILE: - family = CURLPROTO_FILE; - break; - - case CURLPROTO_TFTP: - family = CURLPROTO_TFTP; - break; - - case CURLPROTO_IMAP: - case CURLPROTO_IMAPS: - family = CURLPROTO_IMAP; - break; - - case CURLPROTO_POP3: - case CURLPROTO_POP3S: - family = CURLPROTO_POP3; - break; - - case CURLPROTO_SMTP: - case CURLPROTO_SMTPS: - family = CURLPROTO_SMTP; - break; - - case CURLPROTO_RTSP: - family = CURLPROTO_RTSP; - break; - - case CURLPROTO_RTMP: - case CURLPROTO_RTMPS: - family = CURLPROTO_RTMP; - break; - - case CURLPROTO_RTMPT: - case CURLPROTO_RTMPTS: - family = CURLPROTO_RTMPT; - break; - - case CURLPROTO_RTMPE: - family = CURLPROTO_RTMPE; - break; - - case CURLPROTO_RTMPTE: - family = CURLPROTO_RTMPTE; - break; - - case CURLPROTO_GOPHER: - family = CURLPROTO_GOPHER; - break; - - case CURLPROTO_SMB: - case CURLPROTO_SMBS: - family = CURLPROTO_SMB; - break; - - default: - family = 0; - break; - } - - return family; -} diff --git a/Externals/curl/lib/url.h b/Externals/curl/lib/url.h deleted file mode 100644 index 2b25731ea9..0000000000 --- a/Externals/curl/lib/url.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef HEADER_CURL_URL_H -#define HEADER_CURL_URL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -/* - * Prototypes for library-wide functions provided by url.c - */ - -CURLcode Curl_init_do(struct SessionHandle *data, struct connectdata *conn); -CURLcode Curl_open(struct SessionHandle **curl); -CURLcode Curl_init_userdefined(struct UserDefined *set); -CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, - va_list arg); -CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src); -void Curl_freeset(struct SessionHandle * data); -CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */ -CURLcode Curl_connect(struct SessionHandle *, struct connectdata **, - bool *async, bool *protocol_connect); -CURLcode Curl_disconnect(struct connectdata *, bool dead_connection); -CURLcode Curl_protocol_connect(struct connectdata *conn, bool *done); -CURLcode Curl_protocol_connecting(struct connectdata *conn, bool *done); -CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done); -CURLcode Curl_setup_conn(struct connectdata *conn, - bool *protocol_done); -void Curl_free_request_state(struct SessionHandle *data); - -int Curl_protocol_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); -int Curl_doing_getsock(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); - -bool Curl_isPipeliningEnabled(const struct SessionHandle *handle); -CURLcode Curl_addHandleToPipeline(struct SessionHandle *handle, - struct curl_llist *pipeline); -int Curl_removeHandleFromPipeline(struct SessionHandle *handle, - struct curl_llist *pipeline); -struct connectdata * -Curl_oldest_idle_connection(struct SessionHandle *data); -/* remove the specified connection from all (possible) pipelines and related - queues */ -void Curl_getoff_all_pipelines(struct SessionHandle *data, - struct connectdata *conn); - -void Curl_close_connections(struct SessionHandle *data); - -#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */ - -CURLcode Curl_connected_proxy(struct connectdata *conn, int sockindex); - -#ifdef CURL_DISABLE_VERBOSE_STRINGS -#define Curl_verboseconnect(x) Curl_nop_stmt -#else -void Curl_verboseconnect(struct connectdata *conn); -#endif - - -#endif /* HEADER_CURL_URL_H */ diff --git a/Externals/curl/lib/urldata.h b/Externals/curl/lib/urldata.h deleted file mode 100644 index 25594d3b59..0000000000 --- a/Externals/curl/lib/urldata.h +++ /dev/null @@ -1,1759 +0,0 @@ -#ifndef HEADER_CURL_URLDATA_H -#define HEADER_CURL_URLDATA_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* This file is for lib internal stuff */ - -#include "curl_setup.h" - -#define PORT_FTP 21 -#define PORT_FTPS 990 -#define PORT_TELNET 23 -#define PORT_HTTP 80 -#define PORT_HTTPS 443 -#define PORT_DICT 2628 -#define PORT_LDAP 389 -#define PORT_LDAPS 636 -#define PORT_TFTP 69 -#define PORT_SSH 22 -#define PORT_IMAP 143 -#define PORT_IMAPS 993 -#define PORT_POP3 110 -#define PORT_POP3S 995 -#define PORT_SMB 445 -#define PORT_SMBS 445 -#define PORT_SMTP 25 -#define PORT_SMTPS 465 /* sometimes called SSMTP */ -#define PORT_RTSP 554 -#define PORT_RTMP 1935 -#define PORT_RTMPT PORT_HTTP -#define PORT_RTMPS PORT_HTTPS -#define PORT_GOPHER 70 - -#define DICT_MATCH "/MATCH:" -#define DICT_MATCH2 "/M:" -#define DICT_MATCH3 "/FIND:" -#define DICT_DEFINE "/DEFINE:" -#define DICT_DEFINE2 "/D:" -#define DICT_DEFINE3 "/LOOKUP:" - -#define CURL_DEFAULT_USER "anonymous" -#define CURL_DEFAULT_PASSWORD "ftp@example.com" - -/* Convenience defines for checking protocols or their SSL based version. Each - protocol handler should only ever have a single CURLPROTO_ in its protocol - field. */ -#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP|CURLPROTO_HTTPS) -#define PROTO_FAMILY_FTP (CURLPROTO_FTP|CURLPROTO_FTPS) -#define PROTO_FAMILY_POP3 (CURLPROTO_POP3|CURLPROTO_POP3S) -#define PROTO_FAMILY_SMB (CURLPROTO_SMB|CURLPROTO_SMBS) -#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP|CURLPROTO_SMTPS) - -#define DEFAULT_CONNCACHE_SIZE 5 - -/* length of longest IPv6 address string including the trailing null */ -#define MAX_IPADR_LEN sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - -/* Default FTP/IMAP etc response timeout in milliseconds. - Symbian OS panics when given a timeout much greater than 1/2 hour. -*/ -#define RESP_TIMEOUT (1800*1000) - -#include "cookie.h" -#include "formdata.h" - -#ifdef USE_OPENSSL -#include -#ifdef HAVE_OPENSSL_ENGINE_H -#include -#endif -#endif /* USE_OPENSSL */ - -#ifdef USE_GNUTLS -#include -#endif - -#ifdef USE_MBEDTLS - -#include -#include -#include -#include - -#elif defined USE_POLARSSL - -#include -#include -#if POLARSSL_VERSION_NUMBER<0x01010000 -#include -#else -#include -#include -#endif /* POLARSSL_VERSION_NUMBER<0x01010000 */ - -#endif /* USE_POLARSSL */ - -#ifdef USE_CYASSL -#undef OCSP_REQUEST /* avoid cyassl/openssl/ssl.h clash with wincrypt.h */ -#undef OCSP_RESPONSE /* avoid cyassl/openssl/ssl.h clash with wincrypt.h */ -#include -#endif - -#ifdef USE_NSS -#include -#include -#endif - -#ifdef USE_GSKIT -#include -#endif - -#ifdef USE_AXTLS -#include -#include -#undef malloc -#undef calloc -#undef realloc -#endif /* USE_AXTLS */ - -#ifdef USE_SCHANNEL -#include "curl_sspi.h" -#include -#include -#endif - -#ifdef USE_DARWINSSL -#include -/* For some reason, when building for iOS, the omnibus header above does - * not include SecureTransport.h as of iOS SDK 5.1. */ -#include -#endif - -#ifdef HAVE_NETINET_IN_H -#include -#endif - -#include "timeval.h" - -#ifdef HAVE_ZLIB_H -#include /* for content-encoding */ -#ifdef __SYMBIAN32__ -/* zlib pollutes the namespace with this definition */ -#undef WIN32 -#endif -#endif - -#include - -#include "http_chunks.h" /* for the structs and enum stuff */ -#include "hostip.h" -#include "hash.h" -#include "splay.h" - -#include "imap.h" -#include "pop3.h" -#include "smtp.h" -#include "ftp.h" -#include "file.h" -#include "ssh.h" -#include "http.h" -#include "rtsp.h" -#include "smb.h" -#include "wildcard.h" -#include "multihandle.h" - -#ifdef HAVE_GSSAPI -# ifdef HAVE_GSSGNU -# include -# elif defined HAVE_GSSMIT -# include -# include -# else -# include -# endif -#endif - -#ifdef HAVE_LIBSSH2_H -#include -#include -#endif /* HAVE_LIBSSH2_H */ - -/* Download buffer size, keep it fairly big for speed reasons */ -#undef BUFSIZE -#define BUFSIZE CURL_MAX_WRITE_SIZE - -/* Initial size of the buffer to store headers in, it'll be enlarged in case - of need. */ -#define HEADERSIZE 256 - -#define CURLEASY_MAGIC_NUMBER 0xc0dedbadU -#define GOOD_EASY_HANDLE(x) \ - ((x) && (((struct SessionHandle *)(x))->magic == CURLEASY_MAGIC_NUMBER)) - -/* Some convenience macros to get the larger/smaller value out of two given. - We prefix with CURL to prevent name collisions. */ -#define CURLMAX(x,y) ((x)>(y)?(x):(y)) -#define CURLMIN(x,y) ((x)<(y)?(x):(y)) - - -#ifdef HAVE_GSSAPI -/* Types needed for krb5-ftp connections */ -struct krb5buffer { - void *data; - size_t size; - size_t index; - int eof_flag; -}; - -enum protection_level { - PROT_NONE, /* first in list */ - PROT_CLEAR, - PROT_SAFE, - PROT_CONFIDENTIAL, - PROT_PRIVATE, - PROT_CMD, - PROT_LAST /* last in list */ -}; -#endif - -#ifdef USE_SCHANNEL -/* Structs to store Schannel handles */ -struct curl_schannel_cred { - CredHandle cred_handle; - TimeStamp time_stamp; - int refcount; - bool cached; -}; - -struct curl_schannel_ctxt { - CtxtHandle ctxt_handle; - TimeStamp time_stamp; -}; -#endif - -/* enum for the nonblocking SSL connection state machine */ -typedef enum { - ssl_connect_1, - ssl_connect_2, - ssl_connect_2_reading, - ssl_connect_2_writing, - ssl_connect_3, - ssl_connect_done -} ssl_connect_state; - -typedef enum { - ssl_connection_none, - ssl_connection_negotiating, - ssl_connection_complete -} ssl_connection_state; - -/* struct for data related to each SSL connection */ -struct ssl_connect_data { - /* Use ssl encrypted communications TRUE/FALSE, not necessarily using it atm - but at least asked to or meaning to use it. See 'state' for the exact - current state of the connection. */ - bool use; - ssl_connection_state state; - ssl_connect_state connecting_state; -#if defined(USE_OPENSSL) - /* these ones requires specific SSL-types */ - SSL_CTX* ctx; - SSL* handle; - X509* server_cert; -#elif defined(USE_GNUTLS) - gnutls_session_t session; - gnutls_certificate_credentials_t cred; -#ifdef USE_TLS_SRP - gnutls_srp_client_credentials_t srp_client_cred; -#endif -#elif defined(USE_MBEDTLS) - mbedtls_ctr_drbg_context ctr_drbg; - mbedtls_entropy_context entropy; - mbedtls_ssl_context ssl; - int server_fd; - mbedtls_x509_crt cacert; - mbedtls_x509_crt clicert; - mbedtls_x509_crl crl; - mbedtls_pk_context pk; - mbedtls_ssl_config config; - const char *protocols[3]; -#elif defined(USE_POLARSSL) - ctr_drbg_context ctr_drbg; - entropy_context entropy; - ssl_context ssl; - int server_fd; - x509_crt cacert; - x509_crt clicert; - x509_crl crl; - rsa_context rsa; -#elif defined(USE_CYASSL) - SSL_CTX* ctx; - SSL* handle; -#elif defined(USE_NSS) - PRFileDesc *handle; - char *client_nickname; - struct SessionHandle *data; - struct curl_llist *obj_list; - PK11GenericObject *obj_clicert; -#elif defined(USE_GSKIT) - gsk_handle handle; - int iocport; -#elif defined(USE_AXTLS) - SSL_CTX* ssl_ctx; - SSL* ssl; -#elif defined(USE_SCHANNEL) - struct curl_schannel_cred *cred; - struct curl_schannel_ctxt *ctxt; - SecPkgContext_StreamSizes stream_sizes; - size_t encdata_length, decdata_length; - size_t encdata_offset, decdata_offset; - unsigned char *encdata_buffer, *decdata_buffer; - unsigned long req_flags, ret_flags; - CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */ - bool recv_sspi_close_notify; /* true if connection closed by close_notify */ - bool recv_connection_closed; /* true if connection closed, regardless how */ -#elif defined(USE_DARWINSSL) - SSLContextRef ssl_ctx; - curl_socket_t ssl_sockfd; - bool ssl_direction; /* true if writing, false if reading */ - size_t ssl_write_buffered_length; -#elif defined(USE_SSL) -#error "SSL backend specific information missing from ssl_connect_data" -#endif -}; - -struct ssl_config_data { - long version; /* what version the client wants to use */ - long certverifyresult; /* result from the certificate verification */ - - bool verifypeer; /* set TRUE if this is desired */ - bool verifyhost; /* set TRUE if CN/SAN must match hostname */ - bool verifystatus; /* set TRUE if certificate status must be checked */ - char *CApath; /* certificate dir (doesn't work on windows) */ - char *CAfile; /* certificate to verify peer against */ - const char *CRLfile; /* CRL to check certificate revocation */ - const char *issuercert;/* optional issuer certificate filename */ - char *random_file; /* path to file containing "random" data */ - char *egdsocket; /* path to file containing the EGD daemon socket */ - char *cipher_list; /* list of ciphers to use */ - size_t max_ssl_sessions; /* SSL session id cache size */ - curl_ssl_ctx_callback fsslctx; /* function to initialize ssl ctx */ - void *fsslctxp; /* parameter for call back */ - bool sessionid; /* cache session IDs or not */ - bool certinfo; /* gather lots of certificate info */ - bool falsestart; - -#ifdef USE_TLS_SRP - char *username; /* TLS username (for, e.g., SRP) */ - char *password; /* TLS password (for, e.g., SRP) */ - enum CURL_TLSAUTH authtype; /* TLS authentication type (default SRP) */ -#endif -}; - -/* information stored about one single SSL session */ -struct curl_ssl_session { - char *name; /* host name for which this ID was used */ - char *conn_to_host; /* host name for the connection (may be NULL) */ - void *sessionid; /* as returned from the SSL layer */ - size_t idsize; /* if known, otherwise 0 */ - long age; /* just a number, the higher the more recent */ - int remote_port; /* remote port */ - int conn_to_port; /* remote port for the connection (may be -1) */ - struct ssl_config_data ssl_config; /* setup for this session */ -}; - -/* Struct used for Digest challenge-response authentication */ -struct digestdata { -#if defined(USE_WINDOWS_SSPI) - BYTE *input_token; - size_t input_token_len; -#else - char *nonce; - char *cnonce; - char *realm; - int algo; - bool stale; /* set true for re-negotiation */ - char *opaque; - char *qop; - char *algorithm; - int nc; /* nounce count */ -#endif -}; - -typedef enum { - NTLMSTATE_NONE, - NTLMSTATE_TYPE1, - NTLMSTATE_TYPE2, - NTLMSTATE_TYPE3, - NTLMSTATE_LAST -} curlntlm; - -#ifdef USE_WINDOWS_SSPI -#include "curl_sspi.h" -#endif - -#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) -#include -#endif - -/* Struct used for GSSAPI (Kerberos V5) authentication */ -#if defined(USE_KERBEROS5) -struct kerberos5data { -#if defined(USE_WINDOWS_SSPI) - CredHandle *credentials; - CtxtHandle *context; - TCHAR *spn; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - size_t token_max; - BYTE *output_token; -#else - gss_ctx_id_t context; - gss_name_t spn; -#endif -}; -#endif - -/* Struct used for NTLM challenge-response authentication */ -#if defined(USE_NTLM) -struct ntlmdata { - curlntlm state; -#ifdef USE_WINDOWS_SSPI - CredHandle *credentials; - CtxtHandle *context; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - size_t token_max; - BYTE *output_token; - BYTE *input_token; - size_t input_token_len; -#else - unsigned int flags; - unsigned char nonce[8]; - void* target_info; /* TargetInfo received in the ntlm type-2 message */ - unsigned int target_info_len; -#endif -}; -#endif - -#ifdef USE_SPNEGO -struct negotiatedata { - /* When doing Negotiate (SPNEGO) auth, we first need to send a token - and then validate the received one. */ - enum { GSS_AUTHNONE, GSS_AUTHRECV, GSS_AUTHSENT } state; -#ifdef HAVE_GSSAPI - OM_uint32 status; - gss_ctx_id_t context; - gss_name_t spn; - gss_buffer_desc output_token; -#else -#ifdef USE_WINDOWS_SSPI - DWORD status; - CredHandle *credentials; - CtxtHandle *context; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - TCHAR *spn; - size_t token_max; - BYTE *output_token; - size_t output_token_length; -#endif -#endif -}; -#endif - - -/* - * Boolean values that concerns this connection. - */ -struct ConnectBits { - /* always modify bits.close with the connclose() and connkeep() macros! */ - bool close; /* if set, we close the connection after this request */ - bool reuse; /* if set, this is a re-used connection */ - bool conn_to_host; /* if set, this connection has a "connect to host" - that overrides the host in the URL */ - bool conn_to_port; /* if set, this connection has a "connect to port" - that overrides the port in the URL (remote port) */ - bool proxy; /* if set, this transfer is done through a proxy - any type */ - bool httpproxy; /* if set, this transfer is done through a http proxy */ - bool user_passwd; /* do we use user+password for this connection? */ - bool proxy_user_passwd; /* user+password for the proxy? */ - bool ipv6_ip; /* we communicate with a remote site specified with pure IPv6 - IP address */ - bool ipv6; /* we communicate with a site using an IPv6 address */ - - bool do_more; /* this is set TRUE if the ->curl_do_more() function is - supposed to be called, after ->curl_do() */ - bool tcpconnect[2]; /* the TCP layer (or similar) is connected, this is set - the first time on the first connect function call */ - bool protoconnstart;/* the protocol layer has STARTED its operation after - the TCP layer connect */ - - bool retry; /* this connection is about to get closed and then - re-attempted at another connection. */ - bool tunnel_proxy; /* if CONNECT is used to "tunnel" through the proxy. - This is implicit when SSL-protocols are used through - proxies, but can also be enabled explicitly by - apps */ - bool authneg; /* TRUE when the auth phase has started, which means - that we are creating a request with an auth header, - but it is not the final request in the auth - negotiation. */ - bool rewindaftersend;/* TRUE when the sending couldn't be stopped even - though it will be discarded. When the whole send - operation is done, we must call the data rewind - callback. */ - bool ftp_use_epsv; /* As set with CURLOPT_FTP_USE_EPSV, but if we find out - EPSV doesn't work we disable it for the forthcoming - requests */ - - bool ftp_use_eprt; /* As set with CURLOPT_FTP_USE_EPRT, but if we find out - EPRT doesn't work we disable it for the forthcoming - requests */ - bool netrc; /* name+password provided by netrc */ - bool userpwd_in_url; /* name+password found in url */ - bool stream_was_rewound; /* Indicates that the stream was rewound after a - request read past the end of its response byte - boundary */ - bool proxy_connect_closed; /* set true if a proxy disconnected the - connection in a CONNECT request with auth, so - that libcurl should reconnect and continue. */ - bool bound; /* set true if bind() has already been done on this socket/ - connection */ - bool type_set; /* type= was used in the URL */ - bool multiplex; /* connection is multiplexed */ - - bool tcp_fastopen; /* use TCP Fast Open */ - bool tls_enable_npn; /* TLS NPN extension? */ - bool tls_enable_alpn; /* TLS ALPN extension? */ -}; - -struct hostname { - char *rawalloc; /* allocated "raw" version of the name */ - char *encalloc; /* allocated IDN-encoded version of the name */ - char *name; /* name to use internally, might be encoded, might be raw */ - const char *dispname; /* name to display, as 'name' might be encoded */ -}; - -/* - * Flags on the keepon member of the Curl_transfer_keeper - */ - -#define KEEP_NONE 0 -#define KEEP_RECV (1<<0) /* there is or may be data to read */ -#define KEEP_SEND (1<<1) /* there is or may be data to write */ -#define KEEP_RECV_HOLD (1<<2) /* when set, no reading should be done but there - might still be data to read */ -#define KEEP_SEND_HOLD (1<<3) /* when set, no writing should be done but there - might still be data to write */ -#define KEEP_RECV_PAUSE (1<<4) /* reading is paused */ -#define KEEP_SEND_PAUSE (1<<5) /* writing is paused */ - -#define KEEP_RECVBITS (KEEP_RECV | KEEP_RECV_HOLD | KEEP_RECV_PAUSE) -#define KEEP_SENDBITS (KEEP_SEND | KEEP_SEND_HOLD | KEEP_SEND_PAUSE) - - -#ifdef HAVE_LIBZ -typedef enum { - ZLIB_UNINIT, /* uninitialized */ - ZLIB_INIT, /* initialized */ - ZLIB_GZIP_HEADER, /* reading gzip header */ - ZLIB_GZIP_INFLATING, /* inflating gzip stream */ - ZLIB_INIT_GZIP /* initialized in transparent gzip mode */ -} zlibInitState; -#endif - -#ifdef CURLRES_ASYNCH -struct Curl_async { - char *hostname; - int port; - struct Curl_dns_entry *dns; - bool done; /* set TRUE when the lookup is complete */ - int status; /* if done is TRUE, this is the status from the callback */ - void *os_specific; /* 'struct thread_data' for Windows */ -}; -#endif - -#define FIRSTSOCKET 0 -#define SECONDARYSOCKET 1 - -/* These function pointer types are here only to allow easier typecasting - within the source when we need to cast between data pointers (such as NULL) - and function pointers. */ -typedef CURLcode (*Curl_do_more_func)(struct connectdata *, int *); -typedef CURLcode (*Curl_done_func)(struct connectdata *, CURLcode, bool); - -enum expect100 { - EXP100_SEND_DATA, /* enough waiting, just send the body now */ - EXP100_AWAITING_CONTINUE, /* waiting for the 100 Continue header */ - EXP100_SENDING_REQUEST, /* still sending the request but will wait for - the 100 header once done with the request */ - EXP100_FAILED /* used on 417 Expectation Failed */ -}; - -enum upgrade101 { - UPGR101_INIT, /* default state */ - UPGR101_REQUESTED, /* upgrade requested */ - UPGR101_RECEIVED, /* response received */ - UPGR101_WORKING /* talking upgraded protocol */ -}; - -/* - * Request specific data in the easy handle (SessionHandle). Previously, - * these members were on the connectdata struct but since a conn struct may - * now be shared between different SessionHandles, we store connection-specific - * data here. This struct only keeps stuff that's interesting for *this* - * request, as it will be cleared between multiple ones - */ -struct SingleRequest { - curl_off_t size; /* -1 if unknown at this point */ - curl_off_t *bytecountp; /* return number of bytes read or NULL */ - - curl_off_t maxdownload; /* in bytes, the maximum amount of data to fetch, - -1 means unlimited */ - curl_off_t *writebytecountp; /* return number of bytes written or NULL */ - - curl_off_t bytecount; /* total number of bytes read */ - curl_off_t writebytecount; /* number of bytes written */ - - long headerbytecount; /* only count received headers */ - long deductheadercount; /* this amount of bytes doesn't count when we check - if anything has been transferred at the end of a - connection. We use this counter to make only a - 100 reply (without a following second response - code) result in a CURLE_GOT_NOTHING error code */ - - struct timeval start; /* transfer started at this time */ - struct timeval now; /* current time */ - bool header; /* incoming data has HTTP header */ - enum { - HEADER_NORMAL, /* no bad header at all */ - HEADER_PARTHEADER, /* part of the chunk is a bad header, the rest - is normal data */ - HEADER_ALLBAD /* all was believed to be header */ - } badheader; /* the header was deemed bad and will be - written as body */ - int headerline; /* counts header lines to better track the - first one */ - char *hbufp; /* points at *end* of header line */ - size_t hbuflen; - char *str; /* within buf */ - char *str_start; /* within buf */ - char *end_ptr; /* within buf */ - char *p; /* within headerbuff */ - bool content_range; /* set TRUE if Content-Range: was found */ - curl_off_t offset; /* possible resume offset read from the - Content-Range: header */ - int httpcode; /* error code from the 'HTTP/1.? XXX' or - 'RTSP/1.? XXX' line */ - struct timeval start100; /* time stamp to wait for the 100 code from */ - enum expect100 exp100; /* expect 100 continue state */ - enum upgrade101 upgr101; /* 101 upgrade state */ - - int auto_decoding; /* What content encoding. sec 3.5, RFC2616. */ - -#define IDENTITY 0 /* No encoding */ -#define DEFLATE 1 /* zlib deflate [RFC 1950 & 1951] */ -#define GZIP 2 /* gzip algorithm [RFC 1952] */ - -#ifdef HAVE_LIBZ - zlibInitState zlib_init; /* possible zlib init state; - undefined if Content-Encoding header. */ - z_stream z; /* State structure for zlib. */ -#endif - - time_t timeofdoc; - long bodywrites; - - char *buf; - char *uploadbuf; - curl_socket_t maxfd; - - int keepon; - - bool upload_done; /* set to TRUE when doing chunked transfer-encoding upload - and we're uploading the last chunk */ - - bool ignorebody; /* we read a response-body but we ignore it! */ - bool ignorecl; /* This HTTP response has no body so we ignore the Content- - Length: header */ - - char *location; /* This points to an allocated version of the Location: - header data */ - char *newurl; /* Set to the new URL to use when a redirect or a retry is - wanted */ - - /* 'upload_present' is used to keep a byte counter of how much data there is - still left in the buffer, aimed for upload. */ - ssize_t upload_present; - - /* 'upload_fromhere' is used as a read-pointer when we uploaded parts of a - buffer, so the next read should read from where this pointer points to, - and the 'upload_present' contains the number of bytes available at this - position */ - char *upload_fromhere; - - bool chunk; /* if set, this is a chunked transfer-encoding */ - bool upload_chunky; /* set TRUE if we are doing chunked transfer-encoding - on upload */ - bool getheader; /* TRUE if header parsing is wanted */ - - bool forbidchunk; /* used only to explicitly forbid chunk-upload for - specific upload buffers. See readmoredata() in - http.c for details. */ - - void *protop; /* Allocated protocol-specific data. Each protocol - handler makes sure this points to data it needs. */ -}; - -/* - * Specific protocol handler. - */ - -struct Curl_handler { - const char * scheme; /* URL scheme name. */ - - /* Complement to setup_connection_internals(). */ - CURLcode (*setup_connection)(struct connectdata *); - - /* These two functions MUST be set to be protocol dependent */ - CURLcode (*do_it)(struct connectdata *, bool *done); - Curl_done_func done; - - /* If the curl_do() function is better made in two halves, this - * curl_do_more() function will be called afterwards, if set. For example - * for doing the FTP stuff after the PASV/PORT command. - */ - Curl_do_more_func do_more; - - /* This function *MAY* be set to a protocol-dependent function that is run - * after the connect() and everything is done, as a step in the connection. - * The 'done' pointer points to a bool that should be set to TRUE if the - * function completes before return. If it doesn't complete, the caller - * should call the curl_connecting() function until it is. - */ - CURLcode (*connect_it)(struct connectdata *, bool *done); - - /* See above. Currently only used for FTP. */ - CURLcode (*connecting)(struct connectdata *, bool *done); - CURLcode (*doing)(struct connectdata *, bool *done); - - /* Called from the multi interface during the PROTOCONNECT phase, and it - should then return a proper fd set */ - int (*proto_getsock)(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); - - /* Called from the multi interface during the DOING phase, and it should - then return a proper fd set */ - int (*doing_getsock)(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); - - /* Called from the multi interface during the DO_MORE phase, and it should - then return a proper fd set */ - int (*domore_getsock)(struct connectdata *conn, - curl_socket_t *socks, - int numsocks); - - /* Called from the multi interface during the DO_DONE, PERFORM and - WAITPERFORM phases, and it should then return a proper fd set. Not setting - this will make libcurl use the generic default one. */ - int (*perform_getsock)(const struct connectdata *conn, - curl_socket_t *socks, - int numsocks); - - /* This function *MAY* be set to a protocol-dependent function that is run - * by the curl_disconnect(), as a step in the disconnection. If the handler - * is called because the connection has been considered dead, dead_connection - * is set to TRUE. - */ - CURLcode (*disconnect)(struct connectdata *, bool dead_connection); - - /* If used, this function gets called from transfer.c:readwrite_data() to - allow the protocol to do extra reads/writes */ - CURLcode (*readwrite)(struct SessionHandle *data, struct connectdata *conn, - ssize_t *nread, bool *readmore); - - long defport; /* Default port. */ - unsigned int protocol; /* See CURLPROTO_* - this needs to be the single - specific protocol bit */ - unsigned int flags; /* Extra particular characteristics, see PROTOPT_* */ -}; - -#define PROTOPT_NONE 0 /* nothing extra */ -#define PROTOPT_SSL (1<<0) /* uses SSL */ -#define PROTOPT_DUAL (1<<1) /* this protocol uses two connections */ -#define PROTOPT_CLOSEACTION (1<<2) /* need action before socket close */ -/* some protocols will have to call the underlying functions without regard to - what exact state the socket signals. IE even if the socket says "readable", - the send function might need to be called while uploading, or vice versa. -*/ -#define PROTOPT_DIRLOCK (1<<3) -#define PROTOPT_NONETWORK (1<<4) /* protocol doesn't use the network! */ -#define PROTOPT_NEEDSPWD (1<<5) /* needs a password, and if none is set it - gets a default */ -#define PROTOPT_NOURLQUERY (1<<6) /* protocol can't handle - url query strings (?foo=bar) ! */ -#define PROTOPT_CREDSPERREQUEST (1<<7) /* requires login credentials per - request instead of per connection */ -#define PROTOPT_ALPN_NPN (1<<8) /* set ALPN and/or NPN for this */ - -/* return the count of bytes sent, or -1 on error */ -typedef ssize_t (Curl_send)(struct connectdata *conn, /* connection data */ - int sockindex, /* socketindex */ - const void *buf, /* data to write */ - size_t len, /* max amount to write */ - CURLcode *err); /* error to return */ - -/* return the count of bytes read, or -1 on error */ -typedef ssize_t (Curl_recv)(struct connectdata *conn, /* connection data */ - int sockindex, /* socketindex */ - char *buf, /* store data here */ - size_t len, /* max amount to read */ - CURLcode *err); /* error to return */ - -#ifdef USE_RECV_BEFORE_SEND_WORKAROUND -struct postponed_data { - char *buffer; /* Temporal store for received data during - sending, must be freed */ - size_t allocated_size; /* Size of temporal store */ - size_t recv_size; /* Size of received data during sending */ - size_t recv_processed; /* Size of processed part of postponed data */ -#ifdef DEBUGBUILD - curl_socket_t bindsock;/* Structure must be bound to specific socket, - used only for DEBUGASSERT */ -#endif /* DEBUGBUILD */ -}; -#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */ - -/* - * The connectdata struct contains all fields and variables that should be - * unique for an entire connection. - */ -struct connectdata { - /* 'data' is the CURRENT SessionHandle using this connection -- take great - caution that this might very well vary between different times this - connection is used! */ - struct SessionHandle *data; - - /* chunk is for HTTP chunked encoding, but is in the general connectdata - struct only because we can do just about any protocol through a HTTP proxy - and a HTTP proxy may in fact respond using chunked encoding */ - struct Curl_chunker chunk; - - curl_closesocket_callback fclosesocket; /* function closing the socket(s) */ - void *closesocket_client; - - bool inuse; /* This is a marker for the connection cache logic. If this is - TRUE this handle is being used by an easy handle and cannot - be used by any other easy handle without careful - consideration (== only for pipelining). */ - - /**** Fields set when inited and not modified again */ - long connection_id; /* Contains a unique number to make it easier to - track the connections in the log output */ - - /* 'dns_entry' is the particular host we use. This points to an entry in the - DNS cache and it will not get pruned while locked. It gets unlocked in - Curl_done(). This entry will be NULL if the connection is re-used as then - there is no name resolve done. */ - struct Curl_dns_entry *dns_entry; - - /* 'ip_addr' is the particular IP we connected to. It points to a struct - within the DNS cache, so this pointer is only valid as long as the DNS - cache entry remains locked. It gets unlocked in Curl_done() */ - Curl_addrinfo *ip_addr; - Curl_addrinfo *tempaddr[2]; /* for happy eyeballs */ - - /* 'ip_addr_str' is the ip_addr data as a human readable string. - It remains available as long as the connection does, which is longer than - the ip_addr itself. */ - char ip_addr_str[MAX_IPADR_LEN]; - - unsigned int scope_id; /* Scope id for IPv6 */ - - int socktype; /* SOCK_STREAM or SOCK_DGRAM */ - - struct hostname host; - struct hostname conn_to_host; /* the host to connect to. valid only if - bits.conn_to_host is set */ - struct hostname proxy; - - long port; /* which port to use locally */ - int remote_port; /* the remote port, not the proxy port! */ - int conn_to_port; /* the remote port to connect to. valid only if - bits.conn_to_port is set */ - - /* 'primary_ip' and 'primary_port' get filled with peer's numerical - ip address and port number whenever an outgoing connection is - *attempted* from the primary socket to a remote address. When more - than one address is tried for a connection these will hold data - for the last attempt. When the connection is actually established - these are updated with data which comes directly from the socket. */ - - char primary_ip[MAX_IPADR_LEN]; - long primary_port; - - /* 'local_ip' and 'local_port' get filled with local's numerical - ip address and port number whenever an outgoing connection is - **established** from the primary socket to a remote address. */ - - char local_ip[MAX_IPADR_LEN]; - long local_port; - - char *user; /* user name string, allocated */ - char *passwd; /* password string, allocated */ - char *options; /* options string, allocated */ - - char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */ - - char *proxyuser; /* proxy user name string, allocated */ - char *proxypasswd; /* proxy password string, allocated */ - curl_proxytype proxytype; /* what kind of proxy that is in use */ - - int httpversion; /* the HTTP version*10 reported by the server */ - int rtspversion; /* the RTSP version*10 reported by the server */ - - struct timeval now; /* "current" time */ - struct timeval created; /* creation time */ - curl_socket_t sock[2]; /* two sockets, the second is used for the data - transfer when doing FTP */ - curl_socket_t tempsock[2]; /* temporary sockets for happy eyeballs */ - bool sock_accepted[2]; /* TRUE if the socket on this index was created with - accept() */ - Curl_recv *recv[2]; - Curl_send *send[2]; - -#ifdef USE_RECV_BEFORE_SEND_WORKAROUND - struct postponed_data postponed[2]; /* two buffers for two sockets */ -#endif /* USE_RECV_BEFORE_SEND_WORKAROUND */ - struct ssl_connect_data ssl[2]; /* this is for ssl-stuff */ - struct ssl_config_data ssl_config; - bool tls_upgraded; - - struct ConnectBits bits; /* various state-flags for this connection */ - - /* connecttime: when connect() is called on the current IP address. Used to - be able to track when to move on to try next IP - but only when the multi - interface is used. */ - struct timeval connecttime; - /* The two fields below get set in Curl_connecthost */ - int num_addr; /* number of addresses to try to connect to */ - long timeoutms_per_addr; /* how long time in milliseconds to spend on - trying to connect to each IP address */ - - const struct Curl_handler *handler; /* Connection's protocol handler */ - const struct Curl_handler *given; /* The protocol first given */ - - long ip_version; /* copied from the SessionHandle at creation time */ - - /**** curl_get() phase fields */ - - curl_socket_t sockfd; /* socket to read from or CURL_SOCKET_BAD */ - curl_socket_t writesockfd; /* socket to write to, it may very - well be the same we read from. - CURL_SOCKET_BAD disables */ - - /** Dynamicly allocated strings, MUST be freed before this **/ - /** struct is killed. **/ - struct dynamically_allocated_data { - char *proxyuserpwd; - char *uagent; - char *accept_encoding; - char *userpwd; - char *rangeline; - char *ref; - char *host; - char *cookiehost; - char *rtsp_transport; - char *te; /* TE: request header */ - } allocptr; - -#ifdef HAVE_GSSAPI - int sec_complete; /* if Kerberos is enabled for this connection */ - enum protection_level command_prot; - enum protection_level data_prot; - enum protection_level request_data_prot; - size_t buffer_size; - struct krb5buffer in_buffer; - void *app_data; - const struct Curl_sec_client_mech *mech; - struct sockaddr_in local_addr; -#endif - -#if defined(USE_KERBEROS5) /* Consider moving some of the above GSS-API */ - struct kerberos5data krb5; /* variables into the structure definition, */ -#endif /* however, some of them are ftp specific. */ - - /* the two following *_inuse fields are only flags, not counters in any way. - If TRUE it means the channel is in use, and if FALSE it means the channel - is up for grabs by one. */ - - bool readchannel_inuse; /* whether the read channel is in use by an easy - handle */ - bool writechannel_inuse; /* whether the write channel is in use by an easy - handle */ - struct curl_llist *send_pipe; /* List of handles waiting to - send on this pipeline */ - struct curl_llist *recv_pipe; /* List of handles waiting to read - their responses on this pipeline */ - char* master_buffer; /* The master buffer allocated on-demand; - used for pipelining. */ - size_t read_pos; /* Current read position in the master buffer */ - size_t buf_len; /* Length of the buffer?? */ - - - curl_seek_callback seek_func; /* function that seeks the input */ - void *seek_client; /* pointer to pass to the seek() above */ - - /*************** Request - specific items ************/ - -#if defined(USE_NTLM) - struct ntlmdata ntlm; /* NTLM differs from other authentication schemes - because it authenticates connections, not - single requests! */ - struct ntlmdata proxyntlm; /* NTLM data for proxy */ - -#if defined(NTLM_WB_ENABLED) - /* used for communication with Samba's winbind daemon helper ntlm_auth */ - curl_socket_t ntlm_auth_hlpr_socket; - pid_t ntlm_auth_hlpr_pid; - char* challenge_header; - char* response_header; -#endif -#endif - - char syserr_buf [256]; /* buffer for Curl_strerror() */ - -#ifdef CURLRES_ASYNCH - /* data used for the asynch name resolve callback */ - struct Curl_async async; -#endif - - /* These three are used for chunked-encoding trailer support */ - char *trailer; /* allocated buffer to store trailer in */ - int trlMax; /* allocated buffer size */ - int trlPos; /* index of where to store data */ - - union { - struct ftp_conn ftpc; - struct http_conn httpc; - struct ssh_conn sshc; - struct tftp_state_data *tftpc; - struct imap_conn imapc; - struct pop3_conn pop3c; - struct smtp_conn smtpc; - struct rtsp_conn rtspc; - struct smb_conn smbc; - void *generic; /* RTMP and LDAP use this */ - } proto; - - int cselect_bits; /* bitmask of socket events */ - int waitfor; /* current READ/WRITE bits to wait for */ - -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - int socks5_gssapi_enctype; -#endif - - bool verifypeer; - bool verifyhost; - - /* When this connection is created, store the conditions for the local end - bind. This is stored before the actual bind and before any connection is - made and will serve the purpose of being used for comparison reasons so - that subsequent bound-requested connections aren't accidentally re-using - wrong connections. */ - char *localdev; - unsigned short localport; - int localportrange; - - /* tunnel as in tunnel through a HTTP proxy with CONNECT */ - enum { - TUNNEL_INIT, /* init/default/no tunnel state */ - TUNNEL_CONNECT, /* CONNECT has been sent off */ - TUNNEL_COMPLETE /* CONNECT response received completely */ - } tunnel_state[2]; /* two separate ones to allow FTP */ - struct connectbundle *bundle; /* The bundle we are member of */ - - int negnpn; /* APLN or NPN TLS negotiated protocol, CURL_HTTP_VERSION* */ -}; - -/* The end of connectdata. */ - -/* - * Struct to keep statistical and informational data. - */ -struct PureInfo { - int httpcode; /* Recent HTTP, FTP, or RTSP response code */ - int httpproxycode; /* response code from proxy when received separate */ - int httpversion; /* the http version number X.Y = X*10+Y */ - long filetime; /* If requested, this is might get set. Set to -1 if the time - was unretrievable. We cannot have this of type time_t, - since time_t is unsigned on several platforms such as - OpenVMS. */ - bool timecond; /* set to TRUE if the time condition didn't match, which - thus made the document NOT get fetched */ - long header_size; /* size of read header(s) in bytes */ - long request_size; /* the amount of bytes sent in the request(s) */ - unsigned long proxyauthavail; /* what proxy auth types were announced */ - unsigned long httpauthavail; /* what host auth types were announced */ - long numconnects; /* how many new connection did libcurl created */ - char *contenttype; /* the content type of the object */ - char *wouldredirect; /* URL this would've been redirected to if asked to */ - - /* PureInfo members 'conn_primary_ip', 'conn_primary_port', 'conn_local_ip' - and, 'conn_local_port' are copied over from the connectdata struct in - order to allow curl_easy_getinfo() to return this information even when - the session handle is no longer associated with a connection, and also - allow curl_easy_reset() to clear this information from the session handle - without disturbing information which is still alive, and that might be - reused, in the connection cache. */ - - char conn_primary_ip[MAX_IPADR_LEN]; - long conn_primary_port; - - char conn_local_ip[MAX_IPADR_LEN]; - long conn_local_port; - - struct curl_certinfo certs; /* info about the certs, only populated in - OpenSSL builds. Asked for with - CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -}; - - -struct Progress { - long lastshow; /* time() of the last displayed progress meter or NULL to - force redraw at next call */ - curl_off_t size_dl; /* total expected size */ - curl_off_t size_ul; /* total expected size */ - curl_off_t downloaded; /* transferred so far */ - curl_off_t uploaded; /* transferred so far */ - - curl_off_t current_speed; /* uses the currently fastest transfer */ - - bool callback; /* set when progress callback is used */ - int width; /* screen width at download start */ - int flags; /* see progress.h */ - - double timespent; - - curl_off_t dlspeed; - curl_off_t ulspeed; - - double t_nslookup; - double t_connect; - double t_appconnect; - double t_pretransfer; - double t_starttransfer; - double t_redirect; - - struct timeval start; - struct timeval t_startsingle; - struct timeval t_startop; - struct timeval t_acceptdata; -#define CURR_TIME (5+1) /* 6 entries for 5 seconds */ - - curl_off_t speeder[ CURR_TIME ]; - struct timeval speeder_time[ CURR_TIME ]; - int speeder_c; -}; - -typedef enum { - HTTPREQ_NONE, /* first in list */ - HTTPREQ_GET, - HTTPREQ_POST, - HTTPREQ_POST_FORM, /* we make a difference internally */ - HTTPREQ_PUT, - HTTPREQ_HEAD, - HTTPREQ_CUSTOM, - HTTPREQ_LAST /* last in list */ -} Curl_HttpReq; - -typedef enum { - RTSPREQ_NONE, /* first in list */ - RTSPREQ_OPTIONS, - RTSPREQ_DESCRIBE, - RTSPREQ_ANNOUNCE, - RTSPREQ_SETUP, - RTSPREQ_PLAY, - RTSPREQ_PAUSE, - RTSPREQ_TEARDOWN, - RTSPREQ_GET_PARAMETER, - RTSPREQ_SET_PARAMETER, - RTSPREQ_RECORD, - RTSPREQ_RECEIVE, - RTSPREQ_LAST /* last in list */ -} Curl_RtspReq; - -/* - * Values that are generated, temporary or calculated internally for a - * "session handle" must be defined within the 'struct UrlState'. This struct - * will be used within the SessionHandle struct. When the 'SessionHandle' - * struct is cloned, this data MUST NOT be copied. - * - * Remember that any "state" information goes globally for the curl handle. - * Session-data MUST be put in the connectdata struct and here. */ -#define MAX_CURL_USER_LENGTH 256 -#define MAX_CURL_PASSWORD_LENGTH 256 - -struct auth { - unsigned long want; /* Bitmask set to the authentication methods wanted by - app (with CURLOPT_HTTPAUTH or CURLOPT_PROXYAUTH). */ - unsigned long picked; - unsigned long avail; /* Bitmask for what the server reports to support for - this resource */ - bool done; /* TRUE when the auth phase is done and ready to do the *actual* - request */ - bool multi; /* TRUE if this is not yet authenticated but within the auth - multipass negotiation */ - bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should - be RFC compliant */ -}; - -struct UrlState { - - /* Points to the connection cache */ - struct conncache *conn_cache; - - /* when curl_easy_perform() is called, the multi handle is "owned" by - the easy handle so curl_easy_cleanup() on such an easy handle will - also close the multi handle! */ - bool multi_owned_by_easy; - - /* buffers to store authentication data in, as parsed from input options */ - struct timeval keeps_speed; /* for the progress meter really */ - - struct connectdata *lastconnect; /* The last connection, NULL if undefined */ - - char *headerbuff; /* allocated buffer to store headers in */ - size_t headersize; /* size of the allocation */ - - char buffer[BUFSIZE+1]; /* download buffer */ - char uploadbuffer[BUFSIZE+1]; /* upload buffer */ - curl_off_t current_speed; /* the ProgressShow() funcion sets this, - bytes / second */ - bool this_is_a_follow; /* this is a followed Location: request */ - - char *first_host; /* host name of the first (not followed) request. - if set, this should be the host name that we will - sent authorization to, no else. Used to make Location: - following not keep sending user+password... This is - strdup() data. - */ - int first_remote_port; /* remote port of the first (not followed) request */ - struct curl_ssl_session *session; /* array of 'max_ssl_sessions' size */ - long sessionage; /* number of the most recent session */ - char *tempwrite; /* allocated buffer to keep data in when a write - callback returns to make the connection paused */ - size_t tempwritesize; /* size of the 'tempwrite' allocated buffer */ - int tempwritetype; /* type of the 'tempwrite' buffer as a bitmask that is - used with Curl_client_write() */ - char *scratch; /* huge buffer[BUFSIZE*2] when doing upload CRLF replacing */ - bool errorbuf; /* Set to TRUE if the error buffer is already filled in. - This must be set to FALSE every time _easy_perform() is - called. */ - int os_errno; /* filled in with errno whenever an error occurs */ -#ifdef HAVE_SIGNAL - /* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */ - void (*prev_signal)(int sig); -#endif - bool allow_port; /* Is set.use_port allowed to take effect or not. This - is always set TRUE when curl_easy_perform() is called. */ - struct digestdata digest; /* state data for host Digest auth */ - struct digestdata proxydigest; /* state data for proxy Digest auth */ - -#ifdef USE_SPNEGO - struct negotiatedata negotiate; /* state data for host Negotiate auth */ - struct negotiatedata proxyneg; /* state data for proxy Negotiate auth */ -#endif - - struct auth authhost; /* auth details for host */ - struct auth authproxy; /* auth details for proxy */ - - bool authproblem; /* TRUE if there's some problem authenticating */ - - void *resolver; /* resolver state, if it is used in the URL state - - ares_channel f.e. */ - -#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H) - ENGINE *engine; -#endif /* USE_OPENSSL */ - struct timeval expiretime; /* set this with Curl_expire() only */ - struct Curl_tree timenode; /* for the splay stuff */ - struct curl_llist *timeoutlist; /* list of pending timeouts */ - - /* a place to store the most recently set FTP entrypath */ - char *most_recent_ftp_entrypath; - - /* set after initial USER failure, to prevent an authentication loop */ - bool ftp_trying_alternative; - - int httpversion; /* the lowest HTTP version*10 reported by any server - involved in this request */ - bool expect100header; /* TRUE if we added Expect: 100-continue */ - - bool pipe_broke; /* TRUE if the connection we were pipelined on broke - and we need to restart from the beginning */ - -#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__) && \ - !defined(__SYMBIAN32__) -/* do FTP line-end conversions on most platforms */ -#define CURL_DO_LINEEND_CONV - /* for FTP downloads: track CRLF sequences that span blocks */ - bool prev_block_had_trailing_cr; - /* for FTP downloads: how many CRLFs did we converted to LFs? */ - curl_off_t crlf_conversions; -#endif - char *pathbuffer;/* allocated buffer to store the URL's path part in */ - char *path; /* path to use, points to somewhere within the pathbuffer - area */ - bool slash_removed; /* set TRUE if the 'path' points to a path where the - initial URL slash separator has been taken off */ - bool use_range; - bool rangestringalloc; /* the range string is malloc()'ed */ - - char *range; /* range, if used. See README for detailed specification on - this syntax. */ - curl_off_t resume_from; /* continue [ftp] transfer from here */ - - /* This RTSP state information survives requests and connections */ - long rtsp_next_client_CSeq; /* the session's next client CSeq */ - long rtsp_next_server_CSeq; /* the session's next server CSeq */ - long rtsp_CSeq_recv; /* most recent CSeq received */ - - curl_off_t infilesize; /* size of file to upload, -1 means unknown. - Copied from set.filesize at start of operation */ - - size_t drain; /* Increased when this stream has data to read, even if its - socket is not necessarily is readable. Decreased when - checked. */ - bool done; /* set to FALSE when Curl_do() is called and set to TRUE when - Curl_done() is called, to prevent Curl_done() to get invoked - twice when the multi interface is used. */ - - curl_read_callback fread_func; /* read callback/function */ - void *in; /* CURLOPT_READDATA */ - - struct SessionHandle *stream_depends_on; - bool stream_depends_e; /* set or don't set the Exclusive bit */ - int stream_weight; -}; - - -/* - * This 'DynamicStatic' struct defines dynamic states that actually change - * values in the 'UserDefined' area, which MUST be taken into consideration - * if the UserDefined struct is cloned or similar. You can probably just - * copy these, but each one indicate a special action on other data. - */ - -struct DynamicStatic { - char *url; /* work URL, copied from UserDefined */ - bool url_alloc; /* URL string is malloc()'ed */ - char *referer; /* referer string */ - bool referer_alloc; /* referer sting is malloc()ed */ - struct curl_slist *cookielist; /* list of cookie files set by - curl_easy_setopt(COOKIEFILE) calls */ - struct curl_slist *resolve; /* set to point to the set.resolve list when - this should be dealt with in pretransfer */ -}; - -/* - * This 'UserDefined' struct must only contain data that is set once to go - * for many (perhaps) independent connections. Values that are generated or - * calculated internally for the "session handle" MUST be defined within the - * 'struct UrlState' instead. The only exceptions MUST note the changes in - * the 'DynamicStatic' struct. - * Character pointer fields point to dynamic storage, unless otherwise stated. - */ - -struct Curl_multi; /* declared and used only in multi.c */ - -enum dupstring { - STRING_CERT, /* client certificate file name */ - STRING_CERT_TYPE, /* format for certificate (default: PEM)*/ - STRING_COOKIE, /* HTTP cookie string to send */ - STRING_COOKIEJAR, /* dump all cookies to this file */ - STRING_CUSTOMREQUEST, /* HTTP/FTP/RTSP request/method to use */ - STRING_DEFAULT_PROTOCOL, /* Protocol to use when the URL doesn't specify */ - STRING_DEVICE, /* local network interface/address to use */ - STRING_ENCODING, /* Accept-Encoding string */ - STRING_FTP_ACCOUNT, /* ftp account data */ - STRING_FTP_ALTERNATIVE_TO_USER, /* command to send if USER/PASS fails */ - STRING_FTPPORT, /* port to send with the FTP PORT command */ - STRING_KEY, /* private key file name */ - STRING_KEY_PASSWD, /* plain text private key password */ - STRING_KEY_TYPE, /* format for private key (default: PEM) */ - STRING_KRB_LEVEL, /* krb security level */ - STRING_NETRC_FILE, /* if not NULL, use this instead of trying to find - $HOME/.netrc */ - STRING_PROXY, /* proxy to use */ - STRING_SET_RANGE, /* range, if used */ - STRING_SET_REFERER, /* custom string for the HTTP referer field */ - STRING_SET_URL, /* what original URL to work on */ - STRING_SSL_CAPATH, /* CA directory name (doesn't work on windows) */ - STRING_SSL_CAFILE, /* certificate file to verify peer against */ - STRING_SSL_PINNEDPUBLICKEY, /* public key file to verify peer against */ - STRING_SSL_CIPHER_LIST, /* list of ciphers to use */ - STRING_SSL_EGDSOCKET, /* path to file containing the EGD daemon socket */ - STRING_SSL_RANDOM_FILE, /* path to file containing "random" data */ - STRING_USERAGENT, /* User-Agent string */ - STRING_SSL_CRLFILE, /* crl file to check certificate */ - STRING_SSL_ISSUERCERT, /* issuer cert file to check certificate */ - STRING_USERNAME, /* , if used */ - STRING_PASSWORD, /* , if used */ - STRING_OPTIONS, /* , if used */ - STRING_PROXYUSERNAME, /* Proxy , if used */ - STRING_PROXYPASSWORD, /* Proxy , if used */ - STRING_NOPROXY, /* List of hosts which should not use the proxy, if - used */ - STRING_RTSP_SESSION_ID, /* Session ID to use */ - STRING_RTSP_STREAM_URI, /* Stream URI for this request */ - STRING_RTSP_TRANSPORT, /* Transport for this session */ -#ifdef USE_LIBSSH2 - STRING_SSH_PRIVATE_KEY, /* path to the private key file for auth */ - STRING_SSH_PUBLIC_KEY, /* path to the public key file for auth */ - STRING_SSH_HOST_PUBLIC_KEY_MD5, /* md5 of host public key in ascii hex */ - STRING_SSH_KNOWNHOSTS, /* file name of knownhosts file */ -#endif -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - STRING_PROXY_SERVICE_NAME, /* Proxy service name */ -#endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \ - defined(USE_SPNEGO) - STRING_SERVICE_NAME, /* Service name */ -#endif - STRING_MAIL_FROM, - STRING_MAIL_AUTH, - -#ifdef USE_TLS_SRP - STRING_TLSAUTH_USERNAME, /* TLS auth */ - STRING_TLSAUTH_PASSWORD, /* TLS auth */ -#endif - STRING_BEARER, /* , if used */ -#ifdef USE_UNIX_SOCKETS - STRING_UNIX_SOCKET_PATH, /* path to Unix socket, if used */ -#endif - - /* -- end of zero-terminated strings -- */ - - STRING_LASTZEROTERMINATED, - - /* -- below this are pointers to binary data that cannot be strdup'ed. - Each such pointer must be added manually to Curl_dupset() --- */ - - STRING_COPYPOSTFIELDS, /* if POST, set the fields' values here */ - - STRING_LAST /* not used, just an end-of-list marker */ -}; - -struct UserDefined { - FILE *err; /* the stderr user data goes here */ - void *debugdata; /* the data that will be passed to fdebug */ - char *errorbuffer; /* (Static) store failure messages in here */ - long proxyport; /* If non-zero, use this port number by default. If the - proxy string features a ":[port]" that one will override - this. */ - void *out; /* CURLOPT_WRITEDATA */ - void *in_set; /* CURLOPT_READDATA */ - void *writeheader; /* write the header to this if non-NULL */ - void *rtp_out; /* write RTP to this if non-NULL */ - long use_port; /* which port to use (when not using default) */ - unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ - unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ - long followlocation; /* as in HTTP Location: */ - long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1 - for infinity */ - - int keep_post; /* keep POSTs as POSTs after a 30x request; each - bit represents a request, from 301 to 303 */ - bool free_referer; /* set TRUE if 'referer' points to a string we - allocated */ - void *postfields; /* if POST, set the fields' values here */ - curl_seek_callback seek_func; /* function that seeks the input */ - curl_off_t postfieldsize; /* if POST, this might have a size to use instead - of strlen(), and then the data *may* be binary - (contain zero bytes) */ - unsigned short localport; /* local port number to bind to */ - int localportrange; /* number of additional port numbers to test in case the - 'localport' one can't be bind()ed */ - curl_write_callback fwrite_func; /* function that stores the output */ - curl_write_callback fwrite_header; /* function that stores headers */ - curl_write_callback fwrite_rtp; /* function that stores interleaved RTP */ - curl_read_callback fread_func_set; /* function that reads the input */ - int is_fread_set; /* boolean, has read callback been set to non-NULL? */ - int is_fwrite_set; /* boolean, has write callback been set to non-NULL? */ - curl_progress_callback fprogress; /* OLD and deprecated progress callback */ - curl_xferinfo_callback fxferinfo; /* progress callback */ - curl_debug_callback fdebug; /* function that write informational data */ - curl_ioctl_callback ioctl_func; /* function for I/O control */ - curl_sockopt_callback fsockopt; /* function for setting socket options */ - void *sockopt_client; /* pointer to pass to the socket options callback */ - curl_opensocket_callback fopensocket; /* function for checking/translating - the address and opening the - socket */ - void* opensocket_client; - curl_closesocket_callback fclosesocket; /* function for closing the - socket */ - void* closesocket_client; - - void *seek_client; /* pointer to pass to the seek callback */ - /* the 3 curl_conv_callback functions below are used on non-ASCII hosts */ - /* function to convert from the network encoding: */ - curl_conv_callback convfromnetwork; - /* function to convert to the network encoding: */ - curl_conv_callback convtonetwork; - /* function to convert from UTF-8 encoding: */ - curl_conv_callback convfromutf8; - - void *progress_client; /* pointer to pass to the progress callback */ - void *ioctl_client; /* pointer to pass to the ioctl callback */ - long timeout; /* in milliseconds, 0 means no timeout */ - long connecttimeout; /* in milliseconds, 0 means no timeout */ - long accepttimeout; /* in milliseconds, 0 means no timeout */ - long server_response_timeout; /* in milliseconds, 0 means no timeout */ - long tftp_blksize; /* in bytes, 0 means use default */ - bool tftp_no_options; /* do not send TFTP options requests */ - curl_off_t filesize; /* size of file to upload, -1 means unknown */ - long low_speed_limit; /* bytes/second */ - long low_speed_time; /* number of seconds */ - curl_off_t max_send_speed; /* high speed limit in bytes/second for upload */ - curl_off_t max_recv_speed; /* high speed limit in bytes/second for - download */ - curl_off_t set_resume_from; /* continue [ftp] transfer from here */ - struct curl_slist *headers; /* linked list of extra headers */ - struct curl_slist *proxyheaders; /* linked list of extra CONNECT headers */ - struct curl_httppost *httppost; /* linked list of POST data */ - bool sep_headers; /* handle host and proxy headers separately */ - bool cookiesession; /* new cookie session? */ - bool crlf; /* convert crlf on ftp upload(?) */ - struct curl_slist *quote; /* after connection is established */ - struct curl_slist *postquote; /* after the transfer */ - struct curl_slist *prequote; /* before the transfer, after type */ - struct curl_slist *source_quote; /* 3rd party quote */ - struct curl_slist *source_prequote; /* in 3rd party transfer mode - before - the transfer on source host */ - struct curl_slist *source_postquote; /* in 3rd party transfer mode - after - the transfer on source host */ - struct curl_slist *telnet_options; /* linked list of telnet options */ - struct curl_slist *resolve; /* list of names to add/remove from - DNS cache */ - struct curl_slist *connect_to; /* list of host:port mappings to override - the hostname and port to connect to */ - curl_TimeCond timecondition; /* kind of time/date comparison */ - time_t timevalue; /* what time to compare with */ - Curl_HttpReq httpreq; /* what kind of HTTP request (if any) is this */ - long httpversion; /* when non-zero, a specific HTTP version requested to - be used in the library's request(s) */ - struct ssl_config_data ssl; /* user defined SSL stuff */ - curl_proxytype proxytype; /* what kind of proxy that is in use */ - long dns_cache_timeout; /* DNS cache timeout */ - long buffer_size; /* size of receive buffer to use */ - void *private_data; /* application-private data */ - - struct curl_slist *http200aliases; /* linked list of aliases for http200 */ - - long ipver; /* the CURL_IPRESOLVE_* defines in the public header file - 0 - whatever, 1 - v2, 2 - v6 */ - - curl_off_t max_filesize; /* Maximum file size to download */ - - curl_ftpfile ftp_filemethod; /* how to get to a file when FTP is used */ - - int ftp_create_missing_dirs; /* 1 - create directories that don't exist - 2 - the same but also allow MKD to fail once - */ - - curl_sshkeycallback ssh_keyfunc; /* key matching callback */ - void *ssh_keyfunc_userp; /* custom pointer to callback */ - -/* Here follows boolean settings that define how to behave during - this session. They are STATIC, set by libcurl users or at least initially - and they don't change during operations. */ - - bool printhost; /* printing host name in debug info */ - bool get_filetime; /* get the time and get of the remote file */ - bool tunnel_thru_httpproxy; /* use CONNECT through a HTTP proxy */ - bool prefer_ascii; /* ASCII rather than binary */ - bool ftp_append; /* append, not overwrite, on upload */ - bool ftp_list_only; /* switch FTP command for listing directories */ - bool ftp_use_port; /* use the FTP PORT command */ - bool hide_progress; /* don't use the progress meter */ - bool http_fail_on_error; /* fail on HTTP error codes >= 400 */ - bool http_follow_location; /* follow HTTP redirects */ - bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */ - bool http_disable_hostname_check_before_authentication; - bool include_header; /* include received protocol headers in data output */ - bool http_set_referer; /* is a custom referer used */ - bool http_auto_referer; /* set "correct" referer when following location: */ - bool opt_no_body; /* as set with CURLOPT_NOBODY */ - bool upload; /* upload request */ - enum CURL_NETRC_OPTION - use_netrc; /* defined in include/curl.h */ - bool verbose; /* output verbosity */ - bool krb; /* Kerberos connection requested */ - bool reuse_forbid; /* forbidden to be reused, close after use */ - bool reuse_fresh; /* do not re-use an existing connection */ - bool ftp_use_epsv; /* if EPSV is to be attempted or not */ - bool ftp_use_eprt; /* if EPRT is to be attempted or not */ - bool ftp_use_pret; /* if PRET is to be used before PASV or not */ - - curl_usessl use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or - IMAP or POP3 or others! */ - curl_ftpauth ftpsslauth; /* what AUTH XXX to be attempted */ - curl_ftpccc ftp_ccc; /* FTP CCC options */ - bool no_signal; /* do not use any signal/alarm handler */ - bool global_dns_cache; /* subject for future removal */ - bool tcp_nodelay; /* whether to enable TCP_NODELAY or not */ - bool ignorecl; /* ignore content length */ - bool ftp_skip_ip; /* skip the IP address the FTP server passes on to - us */ - bool connect_only; /* make connection, let application use the socket */ - bool ssl_enable_beast; /* especially allow this flaw for interoperability's - sake*/ - bool ssl_no_revoke; /* disable SSL certificate revocation checks */ - long ssh_auth_types; /* allowed SSH auth types */ - bool http_te_skip; /* pass the raw body data to the user, even when - transfer-encoded (chunked, compressed) */ - bool http_ce_skip; /* pass the raw body data to the user, even when - content-encoded (chunked, compressed) */ - long new_file_perms; /* Permissions to use when creating remote files */ - long new_directory_perms; /* Permissions to use when creating remote dirs */ - bool proxy_transfer_mode; /* set transfer mode (;type=) when doing FTP - via an HTTP proxy */ - char *str[STRING_LAST]; /* array of strings, pointing to allocated memory */ - unsigned int scope_id; /* Scope id for IPv6 */ - long allowed_protocols; - long redir_protocols; -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - bool socks5_gssapi_nec; /* Flag to support NEC SOCKS5 server */ -#endif - struct curl_slist *mail_rcpt; /* linked list of mail recipients */ - bool sasl_ir; /* Enable/disable SASL initial response */ - /* Common RTSP header options */ - Curl_RtspReq rtspreq; /* RTSP request type */ - long rtspversion; /* like httpversion, for RTSP */ - bool wildcardmatch; /* enable wildcard matching */ - curl_chunk_bgn_callback chunk_bgn; /* called before part of transfer - starts */ - curl_chunk_end_callback chunk_end; /* called after part transferring - stopped */ - curl_fnmatch_callback fnmatch; /* callback to decide which file corresponds - to pattern (e.g. if WILDCARDMATCH is on) */ - void *fnmatch_data; - - long gssapi_delegation; /* GSS-API credential delegation, see the - documentation of CURLOPT_GSSAPI_DELEGATION */ - - bool tcp_keepalive; /* use TCP keepalives */ - long tcp_keepidle; /* seconds in idle before sending keepalive probe */ - long tcp_keepintvl; /* seconds between TCP keepalive probes */ - bool tcp_fastopen; /* use TCP Fast Open */ - - size_t maxconnects; /* Max idle connections in the connection cache */ - - bool ssl_enable_npn; /* TLS NPN extension? */ - bool ssl_enable_alpn; /* TLS ALPN extension? */ - bool path_as_is; /* allow dotdots? */ - bool pipewait; /* wait for pipe/multiplex status before starting a - new connection */ - long expect_100_timeout; /* in milliseconds */ - - struct SessionHandle *stream_depends_on; - bool stream_depends_e; /* set or don't set the Exclusive bit */ - int stream_weight; -}; - -struct Names { - struct curl_hash *hostcache; - enum { - HCACHE_NONE, /* not pointing to anything */ - HCACHE_GLOBAL, /* points to the (shrug) global one */ - HCACHE_MULTI, /* points to a shared one in the multi handle */ - HCACHE_SHARED /* points to a shared one in a shared object */ - } hostcachetype; -}; - -/* - * The 'connectdata' struct MUST have all the connection oriented stuff as we - * may have several simultaneous connections and connection structs in memory. - * - * The 'struct UserDefined' must only contain data that is set once to go for - * many (perhaps) independent connections. Values that are generated or - * calculated internally for the "session handle" must be defined within the - * 'struct UrlState' instead. - */ - -struct SessionHandle { - /* first, two fields for the linked list of these */ - struct SessionHandle *next; - struct SessionHandle *prev; - - struct connectdata *easy_conn; /* the "unit's" connection */ - - CURLMstate mstate; /* the handle's state */ - CURLcode result; /* previous result */ - - struct Curl_message msg; /* A single posted message. */ - - /* Array with the plain socket numbers this handle takes care of, in no - particular order. Note that all sockets are added to the sockhash, where - the state etc are also kept. This array is mostly used to detect when a - socket is to be removed from the hash. See singlesocket(). */ - curl_socket_t sockets[MAX_SOCKSPEREASYHANDLE]; - int numsocks; - - struct Names dns; - struct Curl_multi *multi; /* if non-NULL, points to the multi handle - struct to which this "belongs" when used by - the multi interface */ - struct Curl_multi *multi_easy; /* if non-NULL, points to the multi handle - struct to which this "belongs" when used - by the easy interface */ - struct Curl_share *share; /* Share, handles global variable mutexing */ - struct SingleRequest req; /* Request-specific data */ - struct UserDefined set; /* values set by the libcurl user */ - struct DynamicStatic change; /* possibly modified userdefined data */ - struct CookieInfo *cookies; /* the cookies, read from files and servers. - NOTE that the 'cookie' field in the - UserDefined struct defines if the "engine" - is to be used or not. */ - struct Progress progress; /* for all the progress meter data */ - struct UrlState state; /* struct for fields used for state info and - other dynamic purposes */ - struct WildcardData wildcard; /* wildcard download state info */ - struct PureInfo info; /* stats, reports and info data */ - struct curl_tlssessioninfo tsi; /* Information about the TLS session, only - valid after a client has asked for it */ -#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) - iconv_t outbound_cd; /* for translating to the network encoding */ - iconv_t inbound_cd; /* for translating from the network encoding */ - iconv_t utf8_cd; /* for translating to UTF8 */ -#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ - unsigned int magic; /* set to a CURLEASY_MAGIC_NUMBER */ -}; - -#define LIBCURL_NAME "libcurl" - -#endif /* HEADER_CURL_URLDATA_H */ diff --git a/Externals/curl/lib/vauth/cleartext.c b/Externals/curl/lib/vauth/cleartext.c deleted file mode 100644 index a003f51de8..0000000000 --- a/Externals/curl/lib/vauth/cleartext.c +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC4616 PLAIN authentication - * Draft LOGIN SASL Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include -#include "urldata.h" - -#include "vauth/vauth.h" -#include "curl_base64.h" -#include "curl_md5.h" -#include "warnless.h" -#include "strtok.h" -#include "strequal.h" -#include "rawstr.h" -#include "sendf.h" -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_create_plain_message() - * - * This is used to generate an already encoded PLAIN message ready - * for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name. - * passdwp [in] - The user's password. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_plain_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - char **outptr, size_t *outlen) -{ - CURLcode result; - char *plainauth; - size_t ulen; - size_t plen; - - ulen = strlen(userp); - plen = strlen(passwdp); - - plainauth = malloc(2 * ulen + plen + 2); - if(!plainauth) { - *outlen = 0; - *outptr = NULL; - return CURLE_OUT_OF_MEMORY; - } - - /* Calculate the reply */ - memcpy(plainauth, userp, ulen); - plainauth[ulen] = '\0'; - memcpy(plainauth + ulen + 1, userp, ulen); - plainauth[2 * ulen + 1] = '\0'; - memcpy(plainauth + 2 * ulen + 2, passwdp, plen); - - /* Base64 encode the reply */ - result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr, - outlen); - free(plainauth); - - return result; -} - -/* - * Curl_auth_create_login_message() - * - * This is used to generate an already encoded LOGIN message containing the - * user name or password ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * valuep [in] - The user name or user's password. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_login_message(struct SessionHandle *data, - const char *valuep, char **outptr, - size_t *outlen) -{ - size_t vlen = strlen(valuep); - - if(!vlen) { - /* Calculate an empty reply */ - *outptr = strdup("="); - if(*outptr) { - *outlen = (size_t) 1; - return CURLE_OK; - } - - *outlen = 0; - return CURLE_OUT_OF_MEMORY; - } - - /* Base64 encode the value */ - return Curl_base64_encode(data, valuep, vlen, outptr, outlen); -} - -/* - * Curl_auth_create_external_message() - * - * This is used to generate an already encoded EXTERNAL message containing - * the user name ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * user [in] - The user name. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_external_message(struct SessionHandle *data, - const char *user, char **outptr, - size_t *outlen) -{ - /* This is the same formatting as the login message */ - return Curl_auth_create_login_message(data, user, outptr, outlen); -} diff --git a/Externals/curl/lib/vauth/cram.c b/Externals/curl/lib/vauth/cram.c deleted file mode 100644 index cd02e04bab..0000000000 --- a/Externals/curl/lib/vauth/cram.c +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC2195 CRAM-MD5 authentication - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) - -#include -#include "urldata.h" - -#include "vauth/vauth.h" -#include "curl_base64.h" -#include "curl_hmac.h" -#include "curl_md5.h" -#include "warnless.h" -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_decode_cram_md5_message() - * - * This is used to decode an already encoded CRAM-MD5 challenge message. - * - * Parameters: - * - * chlg64 [in] - The base64 encoded challenge message. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr, - size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t chlg64len = strlen(chlg64); - - *outptr = NULL; - *outlen = 0; - - /* Decode the challenge if necessary */ - if(chlg64len && *chlg64 != '=') - result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen); - - return result; -} - -/* - * Curl_auth_create_cram_md5_message() - * - * This is used to generate an already encoded CRAM-MD5 response message ready - * for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * chlg [in] - The challenge. - * userp [in] - The user name. - * passdwp [in] - The user's password. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_cram_md5_message(struct SessionHandle *data, - const char *chlg, - const char *userp, - const char *passwdp, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - HMAC_context *ctxt; - unsigned char digest[MD5_DIGEST_LEN]; - char *response; - - if(chlg) - chlglen = strlen(chlg); - - /* Compute the digest using the password as the key */ - ctxt = Curl_HMAC_init(Curl_HMAC_MD5, - (const unsigned char *) passwdp, - curlx_uztoui(strlen(passwdp))); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - /* Update the digest with the given challenge */ - if(chlglen > 0) - Curl_HMAC_update(ctxt, (const unsigned char *) chlg, - curlx_uztoui(chlglen)); - - /* Finalise the digest */ - Curl_HMAC_final(ctxt, digest); - - /* Generate the response */ - response = aprintf( - "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - userp, digest[0], digest[1], digest[2], digest[3], digest[4], - digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], - digest[11], digest[12], digest[13], digest[14], digest[15]); - if(!response) - return CURLE_OUT_OF_MEMORY; - - /* Base64 encode the response */ - result = Curl_base64_encode(data, response, 0, outptr, outlen); - - free(response); - - return result; -} - -#endif /* !CURL_DISABLE_CRYPTO_AUTH */ diff --git a/Externals/curl/lib/vauth/digest.c b/Externals/curl/lib/vauth/digest.c deleted file mode 100644 index 72cf048293..0000000000 --- a/Externals/curl/lib/vauth/digest.c +++ /dev/null @@ -1,883 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC2831 DIGEST-MD5 authentication - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) - -#include - -#include "vauth/vauth.h" -#include "vauth/digest.h" -#include "urldata.h" -#include "curl_base64.h" -#include "curl_hmac.h" -#include "curl_md5.h" -#include "vtls/vtls.h" -#include "warnless.h" -#include "strtok.h" -#include "rawstr.h" -#include "non-ascii.h" /* included for Curl_convert_... prototypes */ -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -#if !defined(USE_WINDOWS_SSPI) -#define DIGEST_QOP_VALUE_AUTH (1 << 0) -#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1) -#define DIGEST_QOP_VALUE_AUTH_CONF (1 << 2) - -#define DIGEST_QOP_VALUE_STRING_AUTH "auth" -#define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int" -#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf" - -/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines. - It converts digest text to ASCII so the MD5 will be correct for - what ultimately goes over the network. -*/ -#define CURL_OUTPUT_DIGEST_CONV(a, b) \ - result = Curl_convert_to_network(a, (char *)b, strlen((const char*)b)); \ - if(result) { \ - free(b); \ - return result; \ - } -#endif /* !USE_WINDOWS_SSPI */ - -bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, - const char **endptr) -{ - int c; - bool starts_with_quote = FALSE; - bool escape = FALSE; - - for(c = DIGEST_MAX_VALUE_LENGTH - 1; (*str && (*str != '=') && c--);) - *value++ = *str++; - *value = 0; - - if('=' != *str++) - /* eek, no match */ - return FALSE; - - if('\"' == *str) { - /* This starts with a quote so it must end with one as well! */ - str++; - starts_with_quote = TRUE; - } - - for(c = DIGEST_MAX_CONTENT_LENGTH - 1; *str && c--; str++) { - switch(*str) { - case '\\': - if(!escape) { - /* possibly the start of an escaped quote */ - escape = TRUE; - *content++ = '\\'; /* Even though this is an escape character, we still - store it as-is in the target buffer */ - continue; - } - break; - - case ',': - if(!starts_with_quote) { - /* This signals the end of the content if we didn't get a starting - quote and then we do "sloppy" parsing */ - c = 0; /* the end */ - continue; - } - break; - - case '\r': - case '\n': - /* end of string */ - c = 0; - continue; - - case '\"': - if(!escape && starts_with_quote) { - /* end of string */ - c = 0; - continue; - } - break; - } - - escape = FALSE; - *content++ = *str; - } - - *content = 0; - *endptr = str; - - return TRUE; -} - -#if !defined(USE_WINDOWS_SSPI) -/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/ -static void auth_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */ - unsigned char *dest) /* 33 bytes */ -{ - int i; - for(i = 0; i < 16; i++) - snprintf((char *) &dest[i * 2], 3, "%02x", source[i]); -} - -/* Perform quoted-string escaping as described in RFC2616 and its errata */ -static char *auth_digest_string_quoted(const char *source) -{ - char *dest, *d; - const char *s = source; - size_t n = 1; /* null terminator */ - - /* Calculate size needed */ - while(*s) { - ++n; - if(*s == '"' || *s == '\\') { - ++n; - } - ++s; - } - - dest = malloc(n); - if(dest) { - s = source; - d = dest; - while(*s) { - if(*s == '"' || *s == '\\') { - *d++ = '\\'; - } - *d++ = *s++; - } - *d = 0; - } - - return dest; -} - -/* Retrieves the value for a corresponding key from the challenge string - * returns TRUE if the key could be found, FALSE if it does not exists - */ -static bool auth_digest_get_key_value(const char *chlg, - const char *key, - char *value, - size_t max_val_len, - char end_char) -{ - char *find_pos; - size_t i; - - find_pos = strstr(chlg, key); - if(!find_pos) - return FALSE; - - find_pos += strlen(key); - - for(i = 0; *find_pos && *find_pos != end_char && i < max_val_len - 1; ++i) - value[i] = *find_pos++; - value[i] = '\0'; - - return TRUE; -} - -static CURLcode auth_digest_get_qop_values(const char *options, int *value) -{ - char *tmp; - char *token; - char *tok_buf; - - /* Initialise the output */ - *value = 0; - - /* Tokenise the list of qop values. Use a temporary clone of the buffer since - strtok_r() ruins it. */ - tmp = strdup(options); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - - token = strtok_r(tmp, ",", &tok_buf); - while(token != NULL) { - if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH)) - *value |= DIGEST_QOP_VALUE_AUTH; - else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) - *value |= DIGEST_QOP_VALUE_AUTH_INT; - else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF)) - *value |= DIGEST_QOP_VALUE_AUTH_CONF; - - token = strtok_r(NULL, ",", &tok_buf); - } - - free(tmp); - - return CURLE_OK; -} - -/* - * auth_decode_digest_md5_message() - * - * This is used internally to decode an already encoded DIGEST-MD5 challenge - * message into the seperate attributes. - * - * Parameters: - * - * chlg64 [in] - The base64 encoded challenge message. - * nonce [in/out] - The buffer where the nonce will be stored. - * nlen [in] - The length of the nonce buffer. - * realm [in/out] - The buffer where the realm will be stored. - * rlen [in] - The length of the realm buffer. - * alg [in/out] - The buffer where the algorithm will be stored. - * alen [in] - The length of the algorithm buffer. - * qop [in/out] - The buffer where the qop-options will be stored. - * qlen [in] - The length of the qop buffer. - * - * Returns CURLE_OK on success. - */ -static CURLcode auth_decode_digest_md5_message(const char *chlg64, - char *nonce, size_t nlen, - char *realm, size_t rlen, - char *alg, size_t alen, - char *qop, size_t qlen) -{ - CURLcode result = CURLE_OK; - unsigned char *chlg = NULL; - size_t chlglen = 0; - size_t chlg64len = strlen(chlg64); - - /* Decode the base-64 encoded challenge message */ - if(chlg64len && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) - return CURLE_BAD_CONTENT_ENCODING; - - /* Retrieve nonce string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "nonce=\"", nonce, nlen, - '\"')) { - free(chlg); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Retrieve realm string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "realm=\"", realm, rlen, - '\"')) { - /* Challenge does not have a realm, set empty string [RFC2831] page 6 */ - strcpy(realm, ""); - } - - /* Retrieve algorithm string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "algorithm=", alg, alen, ',')) { - free(chlg); - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Retrieve qop-options string from the challenge */ - if(!auth_digest_get_key_value((char *) chlg, "qop=\"", qop, qlen, '\"')) { - free(chlg); - return CURLE_BAD_CONTENT_ENCODING; - } - - free(chlg); - - return CURLE_OK; -} - -/* - * Curl_auth_create_digest_md5_message() - * - * This is used to generate an already encoded DIGEST-MD5 response message - * ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * chlg64 [in] - The base64 encoded challenge message. - * userp [in] - The user name. - * passdwp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_md5_message(struct SessionHandle *data, - const char *chlg64, - const char *userp, - const char *passwdp, - const char *service, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t i; - MD5_context *ctxt; - char *response = NULL; - unsigned char digest[MD5_DIGEST_LEN]; - char HA1_hex[2 * MD5_DIGEST_LEN + 1]; - char HA2_hex[2 * MD5_DIGEST_LEN + 1]; - char resp_hash_hex[2 * MD5_DIGEST_LEN + 1]; - char nonce[64]; - char realm[128]; - char algorithm[64]; - char qop_options[64]; - int qop_values; - char cnonce[33]; - unsigned int entropy[4]; - char nonceCount[] = "00000001"; - char method[] = "AUTHENTICATE"; - char qop[] = DIGEST_QOP_VALUE_STRING_AUTH; - char *spn = NULL; - - /* Decode the challange message */ - result = auth_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), - realm, sizeof(realm), - algorithm, sizeof(algorithm), - qop_options, sizeof(qop_options)); - if(result) - return result; - - /* We only support md5 sessions */ - if(strcmp(algorithm, "md5-sess") != 0) - return CURLE_BAD_CONTENT_ENCODING; - - /* Get the qop-values from the qop-options */ - result = auth_digest_get_qop_values(qop_options, &qop_values); - if(result) - return result; - - /* We only support auth quality-of-protection */ - if(!(qop_values & DIGEST_QOP_VALUE_AUTH)) - return CURLE_BAD_CONTENT_ENCODING; - - /* Generate 16 bytes of random data */ - entropy[0] = Curl_rand(data); - entropy[1] = Curl_rand(data); - entropy[2] = Curl_rand(data); - entropy[3] = Curl_rand(data); - - /* Convert the random data into a 32 byte hex string */ - snprintf(cnonce, sizeof(cnonce), "%08x%08x%08x%08x", - entropy[0], entropy[1], entropy[2], entropy[3]); - - /* So far so good, now calculate A1 and H(A1) according to RFC 2831 */ - ctxt = Curl_MD5_init(Curl_DIGEST_MD5); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - Curl_MD5_update(ctxt, (const unsigned char *) userp, - curlx_uztoui(strlen(userp))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) realm, - curlx_uztoui(strlen(realm))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) passwdp, - curlx_uztoui(strlen(passwdp))); - Curl_MD5_final(ctxt, digest); - - ctxt = Curl_MD5_init(Curl_DIGEST_MD5); - if(!ctxt) - return CURLE_OUT_OF_MEMORY; - - Curl_MD5_update(ctxt, (const unsigned char *) digest, MD5_DIGEST_LEN); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) nonce, - curlx_uztoui(strlen(nonce))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) cnonce, - curlx_uztoui(strlen(cnonce))); - Curl_MD5_final(ctxt, digest); - - /* Convert calculated 16 octet hex into 32 bytes string */ - for(i = 0; i < MD5_DIGEST_LEN; i++) - snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]); - - /* Generate our SPN */ - spn = Curl_auth_build_spn(service, realm, NULL); - if(!spn) - return CURLE_OUT_OF_MEMORY; - - /* Calculate H(A2) */ - ctxt = Curl_MD5_init(Curl_DIGEST_MD5); - if(!ctxt) { - free(spn); - - return CURLE_OUT_OF_MEMORY; - } - - Curl_MD5_update(ctxt, (const unsigned char *) method, - curlx_uztoui(strlen(method))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) spn, - curlx_uztoui(strlen(spn))); - Curl_MD5_final(ctxt, digest); - - for(i = 0; i < MD5_DIGEST_LEN; i++) - snprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]); - - /* Now calculate the response hash */ - ctxt = Curl_MD5_init(Curl_DIGEST_MD5); - if(!ctxt) { - free(spn); - - return CURLE_OUT_OF_MEMORY; - } - - Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) nonce, - curlx_uztoui(strlen(nonce))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - - Curl_MD5_update(ctxt, (const unsigned char *) nonceCount, - curlx_uztoui(strlen(nonceCount))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) cnonce, - curlx_uztoui(strlen(cnonce))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - Curl_MD5_update(ctxt, (const unsigned char *) qop, - curlx_uztoui(strlen(qop))); - Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); - - Curl_MD5_update(ctxt, (const unsigned char *) HA2_hex, 2 * MD5_DIGEST_LEN); - Curl_MD5_final(ctxt, digest); - - for(i = 0; i < MD5_DIGEST_LEN; i++) - snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]); - - /* Generate the response */ - response = aprintf("username=\"%s\",realm=\"%s\",nonce=\"%s\"," - "cnonce=\"%s\",nc=\"%s\",digest-uri=\"%s\",response=%s," - "qop=%s", - userp, realm, nonce, - cnonce, nonceCount, spn, resp_hash_hex, qop); - free(spn); - if(!response) - return CURLE_OUT_OF_MEMORY; - - /* Base64 encode the response */ - result = Curl_base64_encode(data, response, 0, outptr, outlen); - - free(response); - - return result; -} - -/* - * Curl_auth_decode_digest_http_message() - * - * This is used to decode a HTTP DIGEST challenge message into the seperate - * attributes. - * - * Parameters: - * - * chlg [in] - The challenge message. - * digest [in/out] - The digest data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_digest_http_message(const char *chlg, - struct digestdata *digest) -{ - bool before = FALSE; /* got a nonce before */ - bool foundAuth = FALSE; - bool foundAuthInt = FALSE; - char *token = NULL; - char *tmp = NULL; - - /* If we already have received a nonce, keep that in mind */ - if(digest->nonce) - before = TRUE; - - /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_digest_cleanup(digest); - - for(;;) { - char value[DIGEST_MAX_VALUE_LENGTH]; - char content[DIGEST_MAX_CONTENT_LENGTH]; - - /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) - chlg++; - - /* Extract a value=content pair */ - if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { - if(Curl_raw_equal(value, "nonce")) { - free(digest->nonce); - digest->nonce = strdup(content); - if(!digest->nonce) - return CURLE_OUT_OF_MEMORY; - } - else if(Curl_raw_equal(value, "stale")) { - if(Curl_raw_equal(content, "true")) { - digest->stale = TRUE; - digest->nc = 1; /* we make a new nonce now */ - } - } - else if(Curl_raw_equal(value, "realm")) { - free(digest->realm); - digest->realm = strdup(content); - if(!digest->realm) - return CURLE_OUT_OF_MEMORY; - } - else if(Curl_raw_equal(value, "opaque")) { - free(digest->opaque); - digest->opaque = strdup(content); - if(!digest->opaque) - return CURLE_OUT_OF_MEMORY; - } - else if(Curl_raw_equal(value, "qop")) { - char *tok_buf; - /* Tokenize the list and choose auth if possible, use a temporary - clone of the buffer since strtok_r() ruins it */ - tmp = strdup(content); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - - token = strtok_r(tmp, ",", &tok_buf); - while(token != NULL) { - if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH)) { - foundAuth = TRUE; - } - else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT)) { - foundAuthInt = TRUE; - } - token = strtok_r(NULL, ",", &tok_buf); - } - - free(tmp); - - /* Select only auth or auth-int. Otherwise, ignore */ - if(foundAuth) { - free(digest->qop); - digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH); - if(!digest->qop) - return CURLE_OUT_OF_MEMORY; - } - else if(foundAuthInt) { - free(digest->qop); - digest->qop = strdup(DIGEST_QOP_VALUE_STRING_AUTH_INT); - if(!digest->qop) - return CURLE_OUT_OF_MEMORY; - } - } - else if(Curl_raw_equal(value, "algorithm")) { - free(digest->algorithm); - digest->algorithm = strdup(content); - if(!digest->algorithm) - return CURLE_OUT_OF_MEMORY; - - if(Curl_raw_equal(content, "MD5-sess")) - digest->algo = CURLDIGESTALGO_MD5SESS; - else if(Curl_raw_equal(content, "MD5")) - digest->algo = CURLDIGESTALGO_MD5; - else - return CURLE_BAD_CONTENT_ENCODING; - } - else { - /* Unknown specifier, ignore it! */ - } - } - else - break; /* We're done here */ - - /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) - chlg++; - - /* Allow the list to be comma-separated */ - if(',' == *chlg) - chlg++; - } - - /* We had a nonce since before, and we got another one now without - 'stale=true'. This means we provided bad credentials in the previous - request */ - if(before && !digest->stale) - return CURLE_BAD_CONTENT_ENCODING; - - /* We got this header without a nonce, that's a bad Digest line! */ - if(!digest->nonce) - return CURLE_BAD_CONTENT_ENCODING; - - return CURLE_OK; -} - -/* - * Curl_auth_create_digest_http_message() - * - * This is used to generate a HTTP DIGEST response message ready for sending - * to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name. - * passdwp [in] - The user's password. - * request [in] - The HTTP request. - * uripath [in] - The path of the HTTP uri. - * digest [in/out] - The digest data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_http_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - const unsigned char *request, - const unsigned char *uripath, - struct digestdata *digest, - char **outptr, size_t *outlen) -{ - CURLcode result; - unsigned char md5buf[16]; /* 16 bytes/128 bits */ - unsigned char request_digest[33]; - unsigned char *md5this; - unsigned char ha1[33]; /* 32 digits and 1 zero byte */ - unsigned char ha2[33]; /* 32 digits and 1 zero byte */ - char cnoncebuf[33]; - char *cnonce = NULL; - size_t cnonce_sz = 0; - char *userp_quoted; - char *response = NULL; - char *tmp = NULL; - - if(!digest->nc) - digest->nc = 1; - - if(!digest->cnonce) { - snprintf(cnoncebuf, sizeof(cnoncebuf), "%08x%08x%08x%08x", - Curl_rand(data), Curl_rand(data), - Curl_rand(data), Curl_rand(data)); - - result = Curl_base64_encode(data, cnoncebuf, strlen(cnoncebuf), - &cnonce, &cnonce_sz); - if(result) - return result; - - digest->cnonce = cnonce; - } - - /* - If the algorithm is "MD5" or unspecified (which then defaults to MD5): - - A1 = unq(username-value) ":" unq(realm-value) ":" passwd - - If the algorithm is "MD5-sess" then: - - A1 = H(unq(username-value) ":" unq(realm-value) ":" passwd) ":" - unq(nonce-value) ":" unq(cnonce-value) - */ - - md5this = (unsigned char *) - aprintf("%s:%s:%s", userp, digest->realm, passwdp); - if(!md5this) - return CURLE_OUT_OF_MEMORY; - - CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ - Curl_md5it(md5buf, md5this); - free(md5this); - auth_digest_md5_to_ascii(md5buf, ha1); - - if(digest->algo == CURLDIGESTALGO_MD5SESS) { - /* nonce and cnonce are OUTSIDE the hash */ - tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - - CURL_OUTPUT_DIGEST_CONV(data, tmp); /* Convert on non-ASCII machines */ - Curl_md5it(md5buf, (unsigned char *) tmp); - free(tmp); - auth_digest_md5_to_ascii(md5buf, ha1); - } - - /* - If the "qop" directive's value is "auth" or is unspecified, then A2 is: - - A2 = Method ":" digest-uri-value - - If the "qop" value is "auth-int", then A2 is: - - A2 = Method ":" digest-uri-value ":" H(entity-body) - - (The "Method" value is the HTTP request method as specified in section - 5.1.1 of RFC 2616) - */ - - md5this = (unsigned char *) aprintf("%s:%s", request, uripath); - - if(digest->qop && Curl_raw_equal(digest->qop, "auth-int")) { - /* We don't support auth-int for PUT or POST at the moment. - TODO: replace md5 of empty string with entity-body for PUT/POST */ - unsigned char *md5this2 = (unsigned char *) - aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e"); - free(md5this); - md5this = md5this2; - } - - if(!md5this) - return CURLE_OUT_OF_MEMORY; - - CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ - Curl_md5it(md5buf, md5this); - free(md5this); - auth_digest_md5_to_ascii(md5buf, ha2); - - if(digest->qop) { - md5this = (unsigned char *) aprintf("%s:%s:%08x:%s:%s:%s", - ha1, - digest->nonce, - digest->nc, - digest->cnonce, - digest->qop, - ha2); - } - else { - md5this = (unsigned char *) aprintf("%s:%s:%s", - ha1, - digest->nonce, - ha2); - } - - if(!md5this) - return CURLE_OUT_OF_MEMORY; - - CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ - Curl_md5it(md5buf, md5this); - free(md5this); - auth_digest_md5_to_ascii(md5buf, request_digest); - - /* For test case 64 (snooped from a Mozilla 1.3a request) - - Authorization: Digest username="testuser", realm="testrealm", \ - nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca" - - Digest parameters are all quoted strings. Username which is provided by - the user will need double quotes and backslashes within it escaped. For - the other fields, this shouldn't be an issue. realm, nonce, and opaque - are copied as is from the server, escapes and all. cnonce is generated - with web-safe characters. uri is already percent encoded. nc is 8 hex - characters. algorithm and qop with standard values only contain web-safe - characters. - */ - userp_quoted = auth_digest_string_quoted(userp); - if(!userp_quoted) - return CURLE_OUT_OF_MEMORY; - - if(digest->qop) { - response = aprintf("username=\"%s\", " - "realm=\"%s\", " - "nonce=\"%s\", " - "uri=\"%s\", " - "cnonce=\"%s\", " - "nc=%08x, " - "qop=%s, " - "response=\"%s\"", - userp_quoted, - digest->realm, - digest->nonce, - uripath, - digest->cnonce, - digest->nc, - digest->qop, - request_digest); - - if(Curl_raw_equal(digest->qop, "auth")) - digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 - padded which tells to the server how many times you are - using the same nonce in the qop=auth mode */ - } - else { - response = aprintf("username=\"%s\", " - "realm=\"%s\", " - "nonce=\"%s\", " - "uri=\"%s\", " - "response=\"%s\"", - userp_quoted, - digest->realm, - digest->nonce, - uripath, - request_digest); - } - free(userp_quoted); - if(!response) - return CURLE_OUT_OF_MEMORY; - - /* Add the optional fields */ - if(digest->opaque) { - /* Append the opaque */ - tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque); - free(response); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - - response = tmp; - } - - if(digest->algorithm) { - /* Append the algorithm */ - tmp = aprintf("%s, algorithm=\"%s\"", response, digest->algorithm); - free(response); - if(!tmp) - return CURLE_OUT_OF_MEMORY; - - response = tmp; - } - - /* Return the output */ - *outptr = response; - *outlen = strlen(response); - - return CURLE_OK; -} - -/* - * Curl_auth_digest_cleanup() - * - * This is used to clean up the digest specific data. - * - * Parameters: - * - * digest [in/out] - The digest data struct being cleaned up. - * - */ -void Curl_auth_digest_cleanup(struct digestdata *digest) -{ - Curl_safefree(digest->nonce); - Curl_safefree(digest->cnonce); - Curl_safefree(digest->realm); - Curl_safefree(digest->opaque); - Curl_safefree(digest->qop); - Curl_safefree(digest->algorithm); - - digest->nc = 0; - digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */ - digest->stale = FALSE; /* default means normal, not stale */ -} -#endif /* !USE_WINDOWS_SSPI */ - -#endif /* CURL_DISABLE_CRYPTO_AUTH */ diff --git a/Externals/curl/lib/vauth/digest.h b/Externals/curl/lib/vauth/digest.h deleted file mode 100644 index 5722dceced..0000000000 --- a/Externals/curl/lib/vauth/digest.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef HEADER_CURL_DIGEST_H -#define HEADER_CURL_DIGEST_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) - -#define DIGEST_MAX_VALUE_LENGTH 256 -#define DIGEST_MAX_CONTENT_LENGTH 1024 - -enum { - CURLDIGESTALGO_MD5, - CURLDIGESTALGO_MD5SESS -}; - -/* This is used to extract the realm from a challenge message */ -bool Curl_auth_digest_get_pair(const char *str, char *value, char *content, - const char **endptr); - -#endif - -#endif /* HEADER_CURL_DIGEST_H */ diff --git a/Externals/curl/lib/vauth/digest_sspi.c b/Externals/curl/lib/vauth/digest_sspi.c deleted file mode 100644 index d13d08e569..0000000000 --- a/Externals/curl/lib/vauth/digest_sspi.c +++ /dev/null @@ -1,527 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2014 - 2016, Steve Holme, . - * Copyright (C) 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC2831 DIGEST-MD5 authentication - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && !defined(CURL_DISABLE_CRYPTO_AUTH) - -#include - -#include "vauth/vauth.h" -#include "vauth/digest.h" -#include "urldata.h" -#include "curl_base64.h" -#include "warnless.h" -#include "curl_multibyte.h" -#include "sendf.h" -#include "strdup.h" -#include "rawstr.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_create_digest_md5_message() - * - * This is used to generate an already encoded DIGEST-MD5 response message - * ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * chlg64 [in] - The base64 encoded challenge message. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_md5_message(struct SessionHandle *data, - const char *chlg64, - const char *userp, - const char *passwdp, - const char *service, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - TCHAR *spn = NULL; - size_t chlglen = 0; - size_t token_max = 0; - unsigned char *input_token = NULL; - unsigned char *output_token = NULL; - CredHandle credentials; - CtxtHandle context; - PSecPkgInfo SecurityPackage; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - SecBuffer chlg_buf; - SecBuffer resp_buf; - SecBufferDesc chlg_desc; - SecBufferDesc resp_desc; - SECURITY_STATUS status; - unsigned long attrs; - TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ - - /* Decode the base-64 encoded challenge message */ - if(strlen(chlg64) && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &input_token, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!input_token) { - infof(data, "DIGEST-MD5 handshake failure (empty challenge message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Query the security package for DigestSSP */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), - &SecurityPackage); - if(status != SEC_E_OK) { - free(input_token); - - return CURLE_NOT_BUILT_IN; - } - - token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our response buffer */ - output_token = malloc(token_max); - if(!output_token) { - free(input_token); - - return CURLE_OUT_OF_MEMORY; - } - - /* Generate our SPN */ - spn = Curl_auth_build_spn(service, data->easy_conn->host.name, NULL); - if(!spn) { - free(output_token); - free(input_token); - - return CURLE_OUT_OF_MEMORY; - } - - if(userp && *userp) { - /* Populate our identity structure */ - result = Curl_create_sspi_identity(userp, passwdp, &identity); - if(result) { - free(spn); - free(output_token); - free(input_token); - - return result; - } - - /* Allow proper cleanup of the identity structure */ - p_identity = &identity; - } - else - /* Use the current Windows user */ - p_identity = NULL; - - /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *) TEXT(SP_NAME_DIGEST), - SECPKG_CRED_OUTBOUND, NULL, - p_identity, NULL, NULL, - &credentials, &expiry); - - if(status != SEC_E_OK) { - Curl_sspi_free_identity(p_identity); - free(spn); - free(output_token); - free(input_token); - - return CURLE_LOGIN_DENIED; - } - - /* Setup the challenge "input" security buffer */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 1; - chlg_desc.pBuffers = &chlg_buf; - chlg_buf.BufferType = SECBUFFER_TOKEN; - chlg_buf.pvBuffer = input_token; - chlg_buf.cbBuffer = curlx_uztoul(chlglen); - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = output_token; - resp_buf.cbBuffer = curlx_uztoul(token_max); - - /* Generate our response message */ - status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, spn, - 0, 0, 0, &chlg_desc, 0, - &context, &resp_desc, &attrs, - &expiry); - - if(status == SEC_I_COMPLETE_NEEDED || - status == SEC_I_COMPLETE_AND_CONTINUE) - s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); - else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { - s_pSecFn->FreeCredentialsHandle(&credentials); - Curl_sspi_free_identity(p_identity); - free(spn); - free(output_token); - free(input_token); - - return CURLE_RECV_ERROR; - } - - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) output_token, resp_buf.cbBuffer, - outptr, outlen); - - /* Free our handles */ - s_pSecFn->DeleteSecurityContext(&context); - s_pSecFn->FreeCredentialsHandle(&credentials); - - /* Free the identity structure */ - Curl_sspi_free_identity(p_identity); - - /* Free the SPN */ - free(spn); - - /* Free the response buffer */ - free(output_token); - - /* Free the decoded challenge message */ - free(input_token); - - return result; -} - -/* - * Curl_override_sspi_http_realm() - * - * This is used to populate the domain in a SSPI identity structure - * The realm is extracted from the challenge message and used as the - * domain if it is not already explicitly set. - * - * Parameters: - * - * chlg [in] - The challenge message. - * identity [in/out] - The identity structure. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_override_sspi_http_realm(const char *chlg, - SEC_WINNT_AUTH_IDENTITY *identity) -{ - xcharp_u domain, dup_domain; - - /* If domain is blank or unset, check challenge message for realm */ - if(!identity->Domain || !identity->DomainLength) { - for(;;) { - char value[DIGEST_MAX_VALUE_LENGTH]; - char content[DIGEST_MAX_CONTENT_LENGTH]; - - /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) - chlg++; - - /* Extract a value=content pair */ - if(Curl_auth_digest_get_pair(chlg, value, content, &chlg)) { - if(Curl_raw_equal(value, "realm")) { - - /* Setup identity's domain and length */ - domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *) content); - if(!domain.tchar_ptr) - return CURLE_OUT_OF_MEMORY; - - dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr); - if(!dup_domain.tchar_ptr) { - Curl_unicodefree(domain.tchar_ptr); - return CURLE_OUT_OF_MEMORY; - } - - free(identity->Domain); - identity->Domain = dup_domain.tbyte_ptr; - identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr)); - dup_domain.tchar_ptr = NULL; - - Curl_unicodefree(domain.tchar_ptr); - } - else { - /* Unknown specifier, ignore it! */ - } - } - else - break; /* We're done here */ - - /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) - chlg++; - - /* Allow the list to be comma-separated */ - if(',' == *chlg) - chlg++; - } - } - - return CURLE_OK; -} - -/* - * Curl_auth_decode_digest_http_message() - * - * This is used to decode a HTTP DIGEST challenge message into the seperate - * attributes. - * - * Parameters: - * - * chlg [in] - The challenge message. - * digest [in/out] - The digest data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_digest_http_message(const char *chlg, - struct digestdata *digest) -{ - size_t chlglen = strlen(chlg); - - /* We had an input token before and we got another one now. This means we - provided bad credentials in the previous request. */ - if(digest->input_token) - return CURLE_BAD_CONTENT_ENCODING; - - /* Simply store the challenge for use later */ - digest->input_token = (BYTE *) Curl_memdup(chlg, chlglen); - if(!digest->input_token) - return CURLE_OUT_OF_MEMORY; - - digest->input_token_len = chlglen; - - return CURLE_OK; -} - -/* - * Curl_auth_create_digest_http_message() - * - * This is used to generate a HTTP DIGEST response message ready for sending - * to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * request [in] - The HTTP request. - * uripath [in] - The path of the HTTP uri. - * digest [in/out] - The digest data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_digest_http_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - const unsigned char *request, - const unsigned char *uripath, - struct digestdata *digest, - char **outptr, size_t *outlen) -{ - size_t token_max; - CredHandle credentials; - CtxtHandle context; - char *resp; - BYTE *output_token; - PSecPkgInfo SecurityPackage; - SEC_WINNT_AUTH_IDENTITY identity; - SEC_WINNT_AUTH_IDENTITY *p_identity; - SecBuffer chlg_buf[3]; - SecBuffer resp_buf; - SecBufferDesc chlg_desc; - SecBufferDesc resp_desc; - SECURITY_STATUS status; - unsigned long attrs; - TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ - TCHAR *spn; - - (void) data; - - /* Query the security package for DigestSSP */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_DIGEST), - &SecurityPackage); - if(status != SEC_E_OK) - return CURLE_NOT_BUILT_IN; - - token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate the output buffer according to the max token size as indicated - by the security package */ - output_token = malloc(token_max); - if(!output_token) - return CURLE_OUT_OF_MEMORY; - - if(userp && *userp) { - /* Populate our identity structure */ - if(Curl_create_sspi_identity(userp, passwdp, &identity)) - return CURLE_OUT_OF_MEMORY; - - /* Populate our identity domain */ - if(Curl_override_sspi_http_realm((const char*) digest->input_token, - &identity)) - return CURLE_OUT_OF_MEMORY; - - /* Allow proper cleanup of the identity structure */ - p_identity = &identity; - } - else - /* Use the current Windows user */ - p_identity = NULL; - - /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *) TEXT(SP_NAME_DIGEST), - SECPKG_CRED_OUTBOUND, NULL, - p_identity, NULL, NULL, - &credentials, &expiry); - if(status != SEC_E_OK) { - Curl_sspi_free_identity(p_identity); - free(output_token); - - return CURLE_LOGIN_DENIED; - } - - /* Setup the challenge "input" security buffer if present */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 3; - chlg_desc.pBuffers = chlg_buf; - chlg_buf[0].BufferType = SECBUFFER_TOKEN; - chlg_buf[0].pvBuffer = digest->input_token; - chlg_buf[0].cbBuffer = curlx_uztoul(digest->input_token_len); - chlg_buf[1].BufferType = SECBUFFER_PKG_PARAMS; - chlg_buf[1].pvBuffer = (void *) request; - chlg_buf[1].cbBuffer = curlx_uztoul(strlen((const char *) request)); - chlg_buf[2].BufferType = SECBUFFER_PKG_PARAMS; - chlg_buf[2].pvBuffer = NULL; - chlg_buf[2].cbBuffer = 0; - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = output_token; - resp_buf.cbBuffer = curlx_uztoul(token_max); - - spn = Curl_convert_UTF8_to_tchar((char *) uripath); - if(!spn) { - Curl_sspi_free_identity(p_identity); - free(output_token); - - return CURLE_OUT_OF_MEMORY; - } - - /* Generate our reponse message */ - status = s_pSecFn->InitializeSecurityContext(&credentials, NULL, - spn, - ISC_REQ_USE_HTTP_STYLE, 0, 0, - &chlg_desc, 0, &context, - &resp_desc, &attrs, &expiry); - Curl_unicodefree(spn); - - if(status == SEC_I_COMPLETE_NEEDED || - status == SEC_I_COMPLETE_AND_CONTINUE) - s_pSecFn->CompleteAuthToken(&credentials, &resp_desc); - else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { - s_pSecFn->FreeCredentialsHandle(&credentials); - - Curl_sspi_free_identity(p_identity); - free(output_token); - - return CURLE_OUT_OF_MEMORY; - } - - resp = malloc(resp_buf.cbBuffer + 1); - if(!resp) { - s_pSecFn->DeleteSecurityContext(&context); - s_pSecFn->FreeCredentialsHandle(&credentials); - - Curl_sspi_free_identity(p_identity); - free(output_token); - - return CURLE_OUT_OF_MEMORY; - } - - /* Copy the generated reponse */ - memcpy(resp, resp_buf.pvBuffer, resp_buf.cbBuffer); - resp[resp_buf.cbBuffer] = 0x00; - - /* Return the response */ - *outptr = resp; - *outlen = resp_buf.cbBuffer; - - /* Free our handles */ - s_pSecFn->DeleteSecurityContext(&context); - s_pSecFn->FreeCredentialsHandle(&credentials); - - /* Free the identity structure */ - Curl_sspi_free_identity(p_identity); - - /* Free the response buffer */ - free(output_token); - - return CURLE_OK; -} - -/* - * Curl_auth_digest_cleanup() - * - * This is used to clean up the digest specific data. - * - * Parameters: - * - * digest [in/out] - The digest data struct being cleaned up. - * - */ -void Curl_auth_digest_cleanup(struct digestdata *digest) -{ - /* Free the input token */ - Curl_safefree(digest->input_token); - - /* Reset any variables */ - digest->input_token_len = 0; -} - -#endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_CRYPTO_AUTH */ diff --git a/Externals/curl/lib/vauth/krb5_gssapi.c b/Externals/curl/lib/vauth/krb5_gssapi.c deleted file mode 100644 index 975675b5d1..0000000000 --- a/Externals/curl/lib/vauth/krb5_gssapi.c +++ /dev/null @@ -1,387 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2014 - 2016, Steve Holme, . - * Copyright (C) 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(HAVE_GSSAPI) && defined(USE_KERBEROS5) - -#include - -#include "vauth/vauth.h" -#include "curl_sasl.h" -#include "urldata.h" -#include "curl_base64.h" -#include "curl_gssapi.h" -#include "sendf.h" -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_create_gssapi_user_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) user token - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name. - * passdwp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in[ - The host name. - * mutual_auth [in] - Flag specifing whether or not mutual authentication - * is enabled. - * chlg64 [in] - Pointer to the optional base64 encoded challenge - * message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_user_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - const bool mutual_auth, - const char *chlg64, - struct kerberos5data *krb5, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; - OM_uint32 major_status; - OM_uint32 minor_status; - OM_uint32 unused_status; - gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - - (void) userp; - (void) passwdp; - - if(!krb5->spn) { - /* Generate our SPN */ - char *spn = Curl_auth_build_spn(service, NULL, host); - if(!spn) - return CURLE_OUT_OF_MEMORY; - - /* Populate the SPN structure */ - spn_token.value = spn; - spn_token.length = strlen(spn); - - /* Import the SPN */ - major_status = gss_import_name(&minor_status, &spn_token, - GSS_C_NT_HOSTBASED_SERVICE, &krb5->spn); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_import_name() failed: ", - major_status, minor_status); - - free(spn); - - return CURLE_OUT_OF_MEMORY; - } - - free(spn); - } - - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "GSSAPI handshake failure (empty challenge message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - input_token.value = chlg; - input_token.length = chlglen; - } - - major_status = Curl_gss_init_sec_context(data, - &minor_status, - &krb5->context, - krb5->spn, - &Curl_krb5_mech_oid, - GSS_C_NO_CHANNEL_BINDINGS, - &input_token, - &output_token, - mutual_auth, - NULL); - - /* Free the decoded challenge as it is not required anymore */ - free(input_token.value); - - if(GSS_ERROR(major_status)) { - if(output_token.value) - gss_release_buffer(&unused_status, &output_token); - - Curl_gss_log_error(data, "gss_init_sec_context() failed: ", - major_status, minor_status); - - return CURLE_RECV_ERROR; - } - - if(output_token.value && output_token.length) { - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) output_token.value, - output_token.length, outptr, outlen); - - gss_release_buffer(&unused_status, &output_token); - } - else if(mutual_auth) { - *outptr = strdup(""); - if(!*outptr) - result = CURLE_OUT_OF_MEMORY; - } - - return result; -} - -/* - * Curl_auth_create_gssapi_security_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) security - * token message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * chlg64 [in] - Pointer to the optional base64 encoded challenge message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_security_message(struct SessionHandle *data, - const char *chlg64, - struct kerberos5data *krb5, - char **outptr, - size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - size_t messagelen = 0; - unsigned char *chlg = NULL; - unsigned char *message = NULL; - OM_uint32 major_status; - OM_uint32 minor_status; - OM_uint32 unused_status; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - unsigned int indata = 0; - unsigned int outdata = 0; - gss_qop_t qop = GSS_C_QOP_DEFAULT; - unsigned int sec_layer = 0; - unsigned int max_size = 0; - gss_name_t username = GSS_C_NO_NAME; - gss_buffer_desc username_token; - - /* Decode the base-64 encoded input message */ - if(strlen(chlg64) && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "GSSAPI handshake failure (empty security message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Get the fully qualified username back from the context */ - major_status = gss_inquire_context(&minor_status, krb5->context, - &username, NULL, NULL, NULL, NULL, - NULL, NULL); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_inquire_context() failed: ", - major_status, minor_status); - - free(chlg); - - return CURLE_OUT_OF_MEMORY; - } - - /* Convert the username from internal format to a displayable token */ - major_status = gss_display_name(&minor_status, username, - &username_token, NULL); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_display_name() failed: ", - major_status, minor_status); - - free(chlg); - - return CURLE_OUT_OF_MEMORY; - } - - /* Setup the challenge "input" security buffer */ - input_token.value = chlg; - input_token.length = chlglen; - - /* Decrypt the inbound challenge and obtain the qop */ - major_status = gss_unwrap(&minor_status, krb5->context, &input_token, - &output_token, NULL, &qop); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_unwrap() failed: ", - major_status, minor_status); - - gss_release_buffer(&unused_status, &username_token); - free(chlg); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ - if(output_token.length != 4) { - infof(data, "GSSAPI handshake failure (invalid security data)\n"); - - gss_release_buffer(&unused_status, &username_token); - free(chlg); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Copy the data out and free the challenge as it is not required anymore */ - memcpy(&indata, output_token.value, 4); - gss_release_buffer(&unused_status, &output_token); - free(chlg); - - /* Extract the security layer */ - sec_layer = indata & 0x000000FF; - if(!(sec_layer & GSSAUTH_P_NONE)) { - infof(data, "GSSAPI handshake failure (invalid security layer)\n"); - - gss_release_buffer(&unused_status, &username_token); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Extract the maximum message size the server can receive */ - max_size = ntohl(indata & 0xFFFFFF00); - if(max_size > 0) { - /* The server has told us it supports a maximum receive buffer, however, as - we don't require one unless we are encrypting data, we tell the server - our receive buffer is zero. */ - max_size = 0; - } - - /* Allocate our message */ - messagelen = sizeof(outdata) + username_token.length + 1; - message = malloc(messagelen); - if(!message) { - gss_release_buffer(&unused_status, &username_token); - - return CURLE_OUT_OF_MEMORY; - } - - /* Populate the message with the security layer, client supported receive - message size and authorization identity including the 0x00 based - terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization - identity is not terminated with the zero-valued (%x00) octet." it seems - necessary to include it. */ - outdata = htonl(max_size) | sec_layer; - memcpy(message, &outdata, sizeof(outdata)); - memcpy(message + sizeof(outdata), username_token.value, - username_token.length); - message[messagelen - 1] = '\0'; - - /* Free the username token as it is not required anymore */ - gss_release_buffer(&unused_status, &username_token); - - /* Setup the "authentication data" security buffer */ - input_token.value = message; - input_token.length = messagelen; - - /* Encrypt the data */ - major_status = gss_wrap(&minor_status, krb5->context, 0, - GSS_C_QOP_DEFAULT, &input_token, NULL, - &output_token); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_wrap() failed: ", - major_status, minor_status); - - free(message); - - return CURLE_OUT_OF_MEMORY; - } - - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) output_token.value, - output_token.length, outptr, outlen); - - /* Free the output buffer */ - gss_release_buffer(&unused_status, &output_token); - - /* Free the message buffer */ - free(message); - - return result; -} - -/* - * Curl_auth_gssapi_cleanup() - * - * This is used to clean up the GSSAPI (Kerberos V5) specific data. - * - * Parameters: - * - * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. - * - */ -void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5) -{ - OM_uint32 minor_status; - - /* Free our security context */ - if(krb5->context != GSS_C_NO_CONTEXT) { - gss_delete_sec_context(&minor_status, &krb5->context, GSS_C_NO_BUFFER); - krb5->context = GSS_C_NO_CONTEXT; - } - - /* Free the SPN */ - if(krb5->spn != GSS_C_NO_NAME) { - gss_release_name(&minor_status, &krb5->spn); - krb5->spn = GSS_C_NO_NAME; - } -} - -#endif /* HAVE_GSSAPI && USE_KERBEROS5 */ diff --git a/Externals/curl/lib/vauth/krb5_sspi.c b/Externals/curl/lib/vauth/krb5_sspi.c deleted file mode 100644 index bf56a64e79..0000000000 --- a/Externals/curl/lib/vauth/krb5_sspi.c +++ /dev/null @@ -1,496 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2014 - 2016, Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC4752 The Kerberos V5 ("GSSAPI") SASL Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && defined(USE_KERBEROS5) - -#include - -#include "vauth/vauth.h" -#include "urldata.h" -#include "curl_base64.h" -#include "warnless.h" -#include "curl_multibyte.h" -#include "sendf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_create_gssapi_user_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) user token - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The host name. - * mutual_auth [in] - Flag specifing whether or not mutual authentication - * is enabled. - * chlg64 [in] - The optional base64 encoded challenge message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_user_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - const bool mutual_auth, - const char *chlg64, - struct kerberos5data *krb5, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; - CtxtHandle context; - PSecPkgInfo SecurityPackage; - SecBuffer chlg_buf; - SecBuffer resp_buf; - SecBufferDesc chlg_desc; - SecBufferDesc resp_desc; - SECURITY_STATUS status; - unsigned long attrs; - TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ - - if(!krb5->spn) { - /* Generate our SPN */ - krb5->spn = Curl_auth_build_spn(service, host, NULL); - if(!krb5->spn) - return CURLE_OUT_OF_MEMORY; - } - - if(!krb5->output_token) { - /* Query the security package for Kerberos */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) - TEXT(SP_NAME_KERBEROS), - &SecurityPackage); - if(status != SEC_E_OK) { - return CURLE_NOT_BUILT_IN; - } - - krb5->token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our response buffer */ - krb5->output_token = malloc(krb5->token_max); - if(!krb5->output_token) - return CURLE_OUT_OF_MEMORY; - } - - if(!krb5->credentials) { - /* Do we have credientials to use or are we using single sign-on? */ - if(userp && *userp) { - /* Populate our identity structure */ - result = Curl_create_sspi_identity(userp, passwdp, &krb5->identity); - if(result) - return result; - - /* Allow proper cleanup of the identity structure */ - krb5->p_identity = &krb5->identity; - } - else - /* Use the current Windows user */ - krb5->p_identity = NULL; - - /* Allocate our credentials handle */ - krb5->credentials = malloc(sizeof(CredHandle)); - if(!krb5->credentials) - return CURLE_OUT_OF_MEMORY; - - memset(krb5->credentials, 0, sizeof(CredHandle)); - - /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *) - TEXT(SP_NAME_KERBEROS), - SECPKG_CRED_OUTBOUND, NULL, - krb5->p_identity, NULL, NULL, - krb5->credentials, &expiry); - if(status != SEC_E_OK) - return CURLE_LOGIN_DENIED; - - /* Allocate our new context handle */ - krb5->context = malloc(sizeof(CtxtHandle)); - if(!krb5->context) - return CURLE_OUT_OF_MEMORY; - - memset(krb5->context, 0, sizeof(CtxtHandle)); - } - - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "GSSAPI handshake failure (empty challenge message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 1; - chlg_desc.pBuffers = &chlg_buf; - chlg_buf.BufferType = SECBUFFER_TOKEN; - chlg_buf.pvBuffer = chlg; - chlg_buf.cbBuffer = curlx_uztoul(chlglen); - } - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = krb5->output_token; - resp_buf.cbBuffer = curlx_uztoul(krb5->token_max); - - /* Generate our challenge-response message */ - status = s_pSecFn->InitializeSecurityContext(krb5->credentials, - chlg ? krb5->context : NULL, - krb5->spn, - (mutual_auth ? - ISC_REQ_MUTUAL_AUTH : 0), - 0, SECURITY_NATIVE_DREP, - chlg ? &chlg_desc : NULL, 0, - &context, - &resp_desc, &attrs, - &expiry); - - /* Free the decoded challenge as it is not required anymore */ - free(chlg); - - if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { - return CURLE_RECV_ERROR; - } - - if(memcmp(&context, krb5->context, sizeof(context))) { - s_pSecFn->DeleteSecurityContext(krb5->context); - - memcpy(krb5->context, &context, sizeof(context)); - } - - if(resp_buf.cbBuffer) { - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) resp_buf.pvBuffer, - resp_buf.cbBuffer, outptr, outlen); - } - else if(mutual_auth) { - *outptr = strdup(""); - if(!*outptr) - result = CURLE_OUT_OF_MEMORY; - } - - return result; -} - -/* - * Curl_auth_create_gssapi_security_message() - * - * This is used to generate an already encoded GSSAPI (Kerberos V5) security - * token message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * chlg64 [in] - The optional base64 encoded challenge message. - * krb5 [in/out] - The Kerberos 5 data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_gssapi_security_message(struct SessionHandle *data, - const char *chlg64, - struct kerberos5data *krb5, - char **outptr, - size_t *outlen) -{ - CURLcode result = CURLE_OK; - size_t offset = 0; - size_t chlglen = 0; - size_t messagelen = 0; - size_t appdatalen = 0; - unsigned char *chlg = NULL; - unsigned char *trailer = NULL; - unsigned char *message = NULL; - unsigned char *padding = NULL; - unsigned char *appdata = NULL; - SecBuffer input_buf[2]; - SecBuffer wrap_buf[3]; - SecBufferDesc input_desc; - SecBufferDesc wrap_desc; - unsigned long indata = 0; - unsigned long outdata = 0; - unsigned long qop = 0; - unsigned long sec_layer = 0; - unsigned long max_size = 0; - SecPkgContext_Sizes sizes; - SecPkgCredentials_Names names; - SECURITY_STATUS status; - char *user_name; - - /* Decode the base-64 encoded input message */ - if(strlen(chlg64) && *chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "GSSAPI handshake failure (empty security message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Get our response size information */ - status = s_pSecFn->QueryContextAttributes(krb5->context, - SECPKG_ATTR_SIZES, - &sizes); - if(status != SEC_E_OK) { - free(chlg); - - return CURLE_OUT_OF_MEMORY; - } - - /* Get the fully qualified username back from the context */ - status = s_pSecFn->QueryCredentialsAttributes(krb5->credentials, - SECPKG_CRED_ATTR_NAMES, - &names); - if(status != SEC_E_OK) { - free(chlg); - - return CURLE_RECV_ERROR; - } - - /* Setup the "input" security buffer */ - input_desc.ulVersion = SECBUFFER_VERSION; - input_desc.cBuffers = 2; - input_desc.pBuffers = input_buf; - input_buf[0].BufferType = SECBUFFER_STREAM; - input_buf[0].pvBuffer = chlg; - input_buf[0].cbBuffer = curlx_uztoul(chlglen); - input_buf[1].BufferType = SECBUFFER_DATA; - input_buf[1].pvBuffer = NULL; - input_buf[1].cbBuffer = 0; - - /* Decrypt the inbound challenge and obtain the qop */ - status = s_pSecFn->DecryptMessage(krb5->context, &input_desc, 0, &qop); - if(status != SEC_E_OK) { - infof(data, "GSSAPI handshake failure (empty security message)\n"); - - free(chlg); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Not 4 octets long so fail as per RFC4752 Section 3.1 */ - if(input_buf[1].cbBuffer != 4) { - infof(data, "GSSAPI handshake failure (invalid security data)\n"); - - free(chlg); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Copy the data out and free the challenge as it is not required anymore */ - memcpy(&indata, input_buf[1].pvBuffer, 4); - s_pSecFn->FreeContextBuffer(input_buf[1].pvBuffer); - free(chlg); - - /* Extract the security layer */ - sec_layer = indata & 0x000000FF; - if(!(sec_layer & KERB_WRAP_NO_ENCRYPT)) { - infof(data, "GSSAPI handshake failure (invalid security layer)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Extract the maximum message size the server can receive */ - max_size = ntohl(indata & 0xFFFFFF00); - if(max_size > 0) { - /* The server has told us it supports a maximum receive buffer, however, as - we don't require one unless we are encrypting data, we tell the server - our receive buffer is zero. */ - max_size = 0; - } - - /* Allocate the trailer */ - trailer = malloc(sizes.cbSecurityTrailer); - if(!trailer) - return CURLE_OUT_OF_MEMORY; - - /* Convert the user name to UTF8 when operating with Unicode */ - user_name = Curl_convert_tchar_to_UTF8(names.sUserName); - if(!user_name) { - free(trailer); - - return CURLE_OUT_OF_MEMORY; - } - - /* Allocate our message */ - messagelen = sizeof(outdata) + strlen(user_name) + 1; - message = malloc(messagelen); - if(!message) { - free(trailer); - Curl_unicodefree(user_name); - - return CURLE_OUT_OF_MEMORY; - } - - /* Populate the message with the security layer, client supported receive - message size and authorization identity including the 0x00 based - terminator. Note: Despite RFC4752 Section 3.1 stating "The authorization - identity is not terminated with the zero-valued (%x00) octet." it seems - necessary to include it. */ - outdata = htonl(max_size) | sec_layer; - memcpy(message, &outdata, sizeof(outdata)); - strcpy((char *) message + sizeof(outdata), user_name); - Curl_unicodefree(user_name); - - /* Allocate the padding */ - padding = malloc(sizes.cbBlockSize); - if(!padding) { - free(message); - free(trailer); - - return CURLE_OUT_OF_MEMORY; - } - - /* Setup the "authentication data" security buffer */ - wrap_desc.ulVersion = SECBUFFER_VERSION; - wrap_desc.cBuffers = 3; - wrap_desc.pBuffers = wrap_buf; - wrap_buf[0].BufferType = SECBUFFER_TOKEN; - wrap_buf[0].pvBuffer = trailer; - wrap_buf[0].cbBuffer = sizes.cbSecurityTrailer; - wrap_buf[1].BufferType = SECBUFFER_DATA; - wrap_buf[1].pvBuffer = message; - wrap_buf[1].cbBuffer = curlx_uztoul(messagelen); - wrap_buf[2].BufferType = SECBUFFER_PADDING; - wrap_buf[2].pvBuffer = padding; - wrap_buf[2].cbBuffer = sizes.cbBlockSize; - - /* Encrypt the data */ - status = s_pSecFn->EncryptMessage(krb5->context, KERB_WRAP_NO_ENCRYPT, - &wrap_desc, 0); - if(status != SEC_E_OK) { - free(padding); - free(message); - free(trailer); - - return CURLE_OUT_OF_MEMORY; - } - - /* Allocate the encryption (wrap) buffer */ - appdatalen = wrap_buf[0].cbBuffer + wrap_buf[1].cbBuffer + - wrap_buf[2].cbBuffer; - appdata = malloc(appdatalen); - if(!appdata) { - free(padding); - free(message); - free(trailer); - - return CURLE_OUT_OF_MEMORY; - } - - /* Populate the encryption buffer */ - memcpy(appdata, wrap_buf[0].pvBuffer, wrap_buf[0].cbBuffer); - offset += wrap_buf[0].cbBuffer; - memcpy(appdata + offset, wrap_buf[1].pvBuffer, wrap_buf[1].cbBuffer); - offset += wrap_buf[1].cbBuffer; - memcpy(appdata + offset, wrap_buf[2].pvBuffer, wrap_buf[2].cbBuffer); - - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) appdata, appdatalen, outptr, - outlen); - - /* Free all of our local buffers */ - free(appdata); - free(padding); - free(message); - free(trailer); - - return result; -} - -/* - * Curl_auth_gssapi_cleanup() - * - * This is used to clean up the GSSAPI (Kerberos V5) specific data. - * - * Parameters: - * - * krb5 [in/out] - The Kerberos 5 data struct being cleaned up. - * - */ -void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5) -{ - /* Free our security context */ - if(krb5->context) { - s_pSecFn->DeleteSecurityContext(krb5->context); - free(krb5->context); - krb5->context = NULL; - } - - /* Free our credentials handle */ - if(krb5->credentials) { - s_pSecFn->FreeCredentialsHandle(krb5->credentials); - free(krb5->credentials); - krb5->credentials = NULL; - } - - /* Free our identity */ - Curl_sspi_free_identity(krb5->p_identity); - krb5->p_identity = NULL; - - /* Free the SPN and output token */ - Curl_safefree(krb5->spn); - Curl_safefree(krb5->output_token); - - /* Reset any variables */ - krb5->token_max = 0; -} - -#endif /* USE_WINDOWS_SSPI && USE_KERBEROS5*/ diff --git a/Externals/curl/lib/vauth/ntlm.c b/Externals/curl/lib/vauth/ntlm.c deleted file mode 100644 index e27f4237b5..0000000000 --- a/Externals/curl/lib/vauth/ntlm.c +++ /dev/null @@ -1,842 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI) - -/* - * NTLM details: - * - * http://davenport.sourceforge.net/ntlm.html - * https://www.innovation.ch/java/ntlm.html - */ - -#define DEBUG_ME 0 - -#include "urldata.h" -#include "non-ascii.h" -#include "sendf.h" -#include "curl_base64.h" -#include "curl_ntlm_core.h" -#include "curl_gethostname.h" -#include "curl_multibyte.h" -#include "warnless.h" - -#include "vtls/vtls.h" - -#ifdef USE_NSS -#include "vtls/nssg.h" /* for Curl_nss_force_init() */ -#endif - -#define BUILDING_CURL_NTLM_MSGS_C -#include "vauth/vauth.h" -#include "vauth/ntlm.h" -#include "curl_endian.h" -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* "NTLMSSP" signature is always in ASCII regardless of the platform */ -#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" - -#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff) -#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \ - (((x) >> 16) & 0xff), (((x) >> 24) & 0xff) - -#if DEBUG_ME -# define DEBUG_OUT(x) x -static void ntlm_print_flags(FILE *handle, unsigned long flags) -{ - if(flags & NTLMFLAG_NEGOTIATE_UNICODE) - fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE "); - if(flags & NTLMFLAG_NEGOTIATE_OEM) - fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM "); - if(flags & NTLMFLAG_REQUEST_TARGET) - fprintf(handle, "NTLMFLAG_REQUEST_TARGET "); - if(flags & (1<<3)) - fprintf(handle, "NTLMFLAG_UNKNOWN_3 "); - if(flags & NTLMFLAG_NEGOTIATE_SIGN) - fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN "); - if(flags & NTLMFLAG_NEGOTIATE_SEAL) - fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL "); - if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE) - fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE "); - if(flags & NTLMFLAG_NEGOTIATE_LM_KEY) - fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY "); - if(flags & NTLMFLAG_NEGOTIATE_NETWARE) - fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE "); - if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) - fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY "); - if(flags & (1<<10)) - fprintf(handle, "NTLMFLAG_UNKNOWN_10 "); - if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS) - fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS "); - if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED) - fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED "); - if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED) - fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED "); - if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL) - fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL "); - if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN) - fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN "); - if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN) - fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN "); - if(flags & NTLMFLAG_TARGET_TYPE_SERVER) - fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER "); - if(flags & NTLMFLAG_TARGET_TYPE_SHARE) - fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE "); - if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) - fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY "); - if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE) - fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE "); - if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE) - fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE "); - if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY) - fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY "); - if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) - fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO "); - if(flags & (1<<24)) - fprintf(handle, "NTLMFLAG_UNKNOWN_24 "); - if(flags & (1<<25)) - fprintf(handle, "NTLMFLAG_UNKNOWN_25 "); - if(flags & (1<<26)) - fprintf(handle, "NTLMFLAG_UNKNOWN_26 "); - if(flags & (1<<27)) - fprintf(handle, "NTLMFLAG_UNKNOWN_27 "); - if(flags & (1<<28)) - fprintf(handle, "NTLMFLAG_UNKNOWN_28 "); - if(flags & NTLMFLAG_NEGOTIATE_128) - fprintf(handle, "NTLMFLAG_NEGOTIATE_128 "); - if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE) - fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE "); - if(flags & NTLMFLAG_NEGOTIATE_56) - fprintf(handle, "NTLMFLAG_NEGOTIATE_56 "); -} - -static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) -{ - const char *p = buf; - - (void) handle; - - fprintf(stderr, "0x"); - while(len-- > 0) - fprintf(stderr, "%02.2x", (unsigned int)*p++); -} -#else -# define DEBUG_OUT(x) Curl_nop_stmt -#endif - -/* - * ntlm_decode_type2_target() - * - * This is used to decode the "target info" in the NTLM type-2 message - * received. - * - * Parameters: - * - * data [in] - The session handle. - * buffer [in] - The decoded type-2 message. - * size [in] - The input buffer size, at least 32 bytes. - * ntlm [in/out] - The NTLM data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -static CURLcode ntlm_decode_type2_target(struct SessionHandle *data, - unsigned char *buffer, - size_t size, - struct ntlmdata *ntlm) -{ - unsigned short target_info_len = 0; - unsigned int target_info_offset = 0; - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; -#endif - - if(size >= 48) { - target_info_len = Curl_read16_le(&buffer[40]); - target_info_offset = Curl_read32_le(&buffer[44]); - if(target_info_len > 0) { - if(((target_info_offset + target_info_len) > size) || - (target_info_offset < 48)) { - infof(data, "NTLM handshake failure (bad type-2 message). " - "Target Info Offset Len is set incorrect by the peer\n"); - return CURLE_BAD_CONTENT_ENCODING; - } - - ntlm->target_info = malloc(target_info_len); - if(!ntlm->target_info) - return CURLE_OUT_OF_MEMORY; - - memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len); - } - } - - ntlm->target_info_len = target_info_len; - - return CURLE_OK; -} - -/* - NTLM message structure notes: - - A 'short' is a 'network short', a little-endian 16-bit unsigned value. - - A 'long' is a 'network long', a little-endian, 32-bit unsigned value. - - A 'security buffer' represents a triplet used to point to a buffer, - consisting of two shorts and one long: - - 1. A 'short' containing the length of the buffer content in bytes. - 2. A 'short' containing the allocated space for the buffer in bytes. - 3. A 'long' containing the offset to the start of the buffer in bytes, - from the beginning of the NTLM message. -*/ - -/* - * Curl_auth_decode_ntlm_type2_message() - * - * This is used to decode an already encoded NTLM type-2 message. The message - * is first decoded from a base64 string into a raw NTLM message and checked - * for validity before the appropriate data for creating a type-3 message is - * written to the given NTLM data structure. - * - * Parameters: - * - * data [in] - The session handle. - * type2msg [in] - The base64 encoded type-2 message. - * ntlm [in/out] - The NTLM data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_ntlm_type2_message(struct SessionHandle *data, - const char *type2msg, - struct ntlmdata *ntlm) -{ - static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 }; - - /* NTLM type-2 message structure: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x02000000) - 12 Target Name security buffer - 20 Flags long - 24 Challenge 8 bytes - (32) Context 8 bytes (two consecutive longs) (*) - (40) Target Information security buffer (*) - (48) OS Version Structure 8 bytes (*) - 32 (48) (56) Start of data block (*) - (*) -> Optional - */ - - CURLcode result = CURLE_OK; - unsigned char *type2 = NULL; - size_t type2_len = 0; - -#if defined(USE_NSS) - /* Make sure the crypto backend is initialized */ - result = Curl_nss_force_init(data); - if(result) - return result; -#elif defined(CURL_DISABLE_VERBOSE_STRINGS) - (void)data; -#endif - - /* Decode the base-64 encoded type-2 message */ - if(strlen(type2msg) && *type2msg != '=') { - result = Curl_base64_decode(type2msg, &type2, &type2_len); - if(result) - return result; - } - - /* Ensure we have a valid type-2 message */ - if(!type2) { - infof(data, "NTLM handshake failure (empty type-2 message)\n"); - return CURLE_BAD_CONTENT_ENCODING; - } - - ntlm->flags = 0; - - if((type2_len < 32) || - (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) || - (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) { - /* This was not a good enough type-2 message */ - free(type2); - infof(data, "NTLM handshake failure (bad type-2 message)\n"); - return CURLE_BAD_CONTENT_ENCODING; - } - - ntlm->flags = Curl_read32_le(&type2[20]); - memcpy(ntlm->nonce, &type2[24], 8); - - if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) { - result = ntlm_decode_type2_target(data, type2, type2_len, ntlm); - if(result) { - free(type2); - infof(data, "NTLM handshake failure (bad type-2 message)\n"); - return result; - } - } - - DEBUG_OUT({ - fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags); - ntlm_print_flags(stderr, ntlm->flags); - fprintf(stderr, "\n nonce="); - ntlm_print_hex(stderr, (char *)ntlm->nonce, 8); - fprintf(stderr, "\n****\n"); - fprintf(stderr, "**** Header %s\n ", header); - }); - - free(type2); - - return result; -} - -/* copy the source to the destination and fill in zeroes in every - other destination byte! */ -static void unicodecpy(unsigned char *dest, const char *src, size_t length) -{ - size_t i; - for(i = 0; i < length; i++) { - dest[2 * i] = (unsigned char)src[i]; - dest[2 * i + 1] = '\0'; - } -} - -/* - * Curl_auth_create_ntlm_type1_message() - * - * This is used to generate an already encoded NTLM type-1 message ready for - * sending to the recipient using the appropriate compile time crypto API. - * - * Parameters: - * - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type1_message(const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - char **outptr, size_t *outlen) -{ - /* NTLM type-1 message structure: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x01000000) - 12 Flags long - (16) Supplied Domain security buffer (*) - (24) Supplied Workstation security buffer (*) - (32) OS Version Structure 8 bytes (*) - (32) (40) Start of data block (*) - (*) -> Optional - */ - - size_t size; - - unsigned char ntlmbuf[NTLM_BUFSIZE]; - const char *host = ""; /* empty */ - const char *domain = ""; /* empty */ - size_t hostlen = 0; - size_t domlen = 0; - size_t hostoff = 0; - size_t domoff = hostoff + hostlen; /* This is 0: remember that host and - domain are empty */ - (void)userp; - (void)passwdp; - - /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_ntlm_cleanup(ntlm); - -#if USE_NTRESPONSES && USE_NTLM2SESSION -#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY -#else -#define NTLM2FLAG 0 -#endif - snprintf((char *)ntlmbuf, NTLM_BUFSIZE, - NTLMSSP_SIGNATURE "%c" - "\x01%c%c%c" /* 32-bit type = 1 */ - "%c%c%c%c" /* 32-bit NTLM flag field */ - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host name offset */ - "%c%c" /* 2 zeroes */ - "%s" /* host name */ - "%s", /* domain string */ - 0, /* trailing zero */ - 0, 0, 0, /* part of type-1 long */ - - LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLM2FLAG | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0, 0, - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0, 0, - host, /* this is empty */ - domain /* this is empty */); - - /* Initial packet length */ - size = 32 + hostlen + domlen; - - DEBUG_OUT({ - fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x " - "0x%08.8x ", - LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLM2FLAG | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), - NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLM2FLAG | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); - ntlm_print_flags(stderr, - NTLMFLAG_NEGOTIATE_OEM | - NTLMFLAG_REQUEST_TARGET | - NTLMFLAG_NEGOTIATE_NTLM_KEY | - NTLM2FLAG | - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); - fprintf(stderr, "\n****\n"); - }); - - /* Return with binary blob encoded into base64 */ - return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); -} - -/* - * Curl_auth_create_ntlm_type3_message() - * - * This is used to generate an already encoded NTLM type-3 message ready for - * sending to the recipient using the appropriate compile time crypto API. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type3_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - char **outptr, size_t *outlen) - -{ - /* NTLM type-3 message structure: - - Index Description Content - 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" - (0x4e544c4d53535000) - 8 NTLM Message Type long (0x03000000) - 12 LM/LMv2 Response security buffer - 20 NTLM/NTLMv2 Response security buffer - 28 Target Name security buffer - 36 User Name security buffer - 44 Workstation Name security buffer - (52) Session Key security buffer (*) - (60) Flags long (*) - (64) OS Version Structure 8 bytes (*) - 52 (64) (72) Start of data block - (*) -> Optional - */ - - CURLcode result = CURLE_OK; - size_t size; - unsigned char ntlmbuf[NTLM_BUFSIZE]; - int lmrespoff; - unsigned char lmresp[24]; /* fixed-size */ -#if USE_NTRESPONSES - int ntrespoff; - unsigned int ntresplen = 24; - unsigned char ntresp[24]; /* fixed-size */ - unsigned char *ptr_ntresp = &ntresp[0]; - unsigned char *ntlmv2resp = NULL; -#endif - bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE; - char host[HOSTNAME_MAX + 1] = ""; - const char *user; - const char *domain = ""; - size_t hostoff = 0; - size_t useroff = 0; - size_t domoff = 0; - size_t hostlen = 0; - size_t userlen = 0; - size_t domlen = 0; - - user = strchr(userp, '\\'); - if(!user) - user = strchr(userp, '/'); - - if(user) { - domain = userp; - domlen = (user - domain); - user++; - } - else - user = userp; - - if(user) - userlen = strlen(user); - - /* Get the machine's un-qualified host name as NTLM doesn't like the fully - qualified domain name */ - if(Curl_gethostname(host, sizeof(host))) { - infof(data, "gethostname() failed, continuing without!\n"); - hostlen = 0; - } - else { - hostlen = strlen(host); - } - -#if USE_NTRESPONSES && USE_NTLM_V2 - if(ntlm->target_info_len) { - unsigned char ntbuffer[0x18]; - unsigned int entropy[2]; - unsigned char ntlmv2hash[0x18]; - - entropy[0] = Curl_rand(data); - entropy[1] = Curl_rand(data); - - result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer); - if(result) - return result; - - result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen, - ntbuffer, ntlmv2hash); - if(result) - return result; - - /* LMv2 response */ - result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, - (unsigned char *)&entropy[0], - &ntlm->nonce[0], lmresp); - if(result) - return result; - - /* NTLMv2 response */ - result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, - (unsigned char *)&entropy[0], - ntlm, &ntlmv2resp, &ntresplen); - if(result) - return result; - - ptr_ntresp = ntlmv2resp; - } - else -#endif - -#if USE_NTRESPONSES && USE_NTLM2SESSION - /* We don't support NTLM2 if we don't have USE_NTRESPONSES */ - if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { - unsigned char ntbuffer[0x18]; - unsigned char tmp[0x18]; - unsigned char md5sum[MD5_DIGEST_LENGTH]; - unsigned int entropy[2]; - - /* Need to create 8 bytes random data */ - entropy[0] = Curl_rand(data); - entropy[1] = Curl_rand(data); - - /* 8 bytes random data as challenge in lmresp */ - memcpy(lmresp, entropy, 8); - - /* Pad with zeros */ - memset(lmresp + 8, 0, 0x10); - - /* Fill tmp with challenge(nonce?) + entropy */ - memcpy(tmp, &ntlm->nonce[0], 8); - memcpy(tmp + 8, entropy, 8); - - result = Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH); - if(!result) - /* We shall only use the first 8 bytes of md5sum, but the des code in - Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */ - result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer); - if(result) - return result; - - Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp); - - /* End of NTLM2 Session code */ - - } - else -#endif - { - -#if USE_NTRESPONSES - unsigned char ntbuffer[0x18]; -#endif - unsigned char lmbuffer[0x18]; - -#if USE_NTRESPONSES - result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer); - if(result) - return result; - - Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp); -#endif - - result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer); - if(result) - return result; - - Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp); - - /* A safer but less compatible alternative is: - * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp); - * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */ - } - - if(unicode) { - domlen = domlen * 2; - userlen = userlen * 2; - hostlen = hostlen * 2; - } - - lmrespoff = 64; /* size of the message header */ -#if USE_NTRESPONSES - ntrespoff = lmrespoff + 0x18; - domoff = ntrespoff + ntresplen; -#else - domoff = lmrespoff + 0x18; -#endif - useroff = domoff + domlen; - hostoff = useroff + userlen; - - /* Create the big type-3 message binary blob */ - size = snprintf((char *)ntlmbuf, NTLM_BUFSIZE, - NTLMSSP_SIGNATURE "%c" - "\x03%c%c%c" /* 32-bit type = 3 */ - - "%c%c" /* LanManager length */ - "%c%c" /* LanManager allocated space */ - "%c%c" /* LanManager offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* NT-response length */ - "%c%c" /* NT-response allocated space */ - "%c%c" /* NT-response offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* user length */ - "%c%c" /* user allocated space */ - "%c%c" /* user offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host offset */ - "%c%c" /* 2 zeroes */ - - "%c%c" /* session key length (unknown purpose) */ - "%c%c" /* session key allocated space (unknown purpose) */ - "%c%c" /* session key offset (unknown purpose) */ - "%c%c" /* 2 zeroes */ - - "%c%c%c%c", /* flags */ - - /* domain string */ - /* user string */ - /* host string */ - /* LanManager response */ - /* NT response */ - - 0, /* zero termination */ - 0, 0, 0, /* type-3 long, the 24 upper bits */ - - SHORTPAIR(0x18), /* LanManager response length, twice */ - SHORTPAIR(0x18), - SHORTPAIR(lmrespoff), - 0x0, 0x0, - -#if USE_NTRESPONSES - SHORTPAIR(ntresplen), /* NT-response length, twice */ - SHORTPAIR(ntresplen), - SHORTPAIR(ntrespoff), - 0x0, 0x0, -#else - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, -#endif - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0x0, 0x0, - - SHORTPAIR(userlen), - SHORTPAIR(userlen), - SHORTPAIR(useroff), - 0x0, 0x0, - - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0x0, 0x0, - - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - - LONGQUARTET(ntlm->flags)); - - DEBUGASSERT(size == 64); - DEBUGASSERT(size == (size_t)lmrespoff); - - /* We append the binary hashes */ - if(size < (NTLM_BUFSIZE - 0x18)) { - memcpy(&ntlmbuf[size], lmresp, 0x18); - size += 0x18; - } - - DEBUG_OUT({ - fprintf(stderr, "**** TYPE3 header lmresp="); - ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18); - }); - -#if USE_NTRESPONSES - if(size < (NTLM_BUFSIZE - ntresplen)) { - DEBUGASSERT(size == (size_t)ntrespoff); - memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); - size += ntresplen; - } - - DEBUG_OUT({ - fprintf(stderr, "\n ntresp="); - ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen); - }); - - free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */ - -#endif - - DEBUG_OUT({ - fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ", - LONGQUARTET(ntlm->flags), ntlm->flags); - ntlm_print_flags(stderr, ntlm->flags); - fprintf(stderr, "\n****\n"); - }); - - /* Make sure that the domain, user and host strings fit in the - buffer before we copy them there. */ - if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) { - failf(data, "user + domain + host name too big"); - return CURLE_OUT_OF_MEMORY; - } - - DEBUGASSERT(size == domoff); - if(unicode) - unicodecpy(&ntlmbuf[size], domain, domlen / 2); - else - memcpy(&ntlmbuf[size], domain, domlen); - - size += domlen; - - DEBUGASSERT(size == useroff); - if(unicode) - unicodecpy(&ntlmbuf[size], user, userlen / 2); - else - memcpy(&ntlmbuf[size], user, userlen); - - size += userlen; - - DEBUGASSERT(size == hostoff); - if(unicode) - unicodecpy(&ntlmbuf[size], host, hostlen / 2); - else - memcpy(&ntlmbuf[size], host, hostlen); - - size += hostlen; - - /* Convert domain, user, and host to ASCII but leave the rest as-is */ - result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff], - size - domoff); - if(result) - return CURLE_CONV_FAILED; - - /* Return with binary blob encoded into base64 */ - result = Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); - - Curl_auth_ntlm_cleanup(ntlm); - - return result; -} - -/* -* Curl_auth_ntlm_cleanup() -* -* This is used to clean up the NTLM specific data. -* -* Parameters: -* -* ntlm [in/out] - The NTLM data struct being cleaned up. -* -*/ -void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm) -{ - /* Free the target info */ - Curl_safefree(ntlm->target_info); - - /* Reset any variables */ - ntlm->target_info_len = 0; -} - -#endif /* USE_NTLM && !USE_WINDOWS_SSPI */ diff --git a/Externals/curl/lib/vauth/ntlm.h b/Externals/curl/lib/vauth/ntlm.h deleted file mode 100644 index b14e7a56a4..0000000000 --- a/Externals/curl/lib/vauth/ntlm.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef HEADER_CURL_NTLM_H -#define HEADER_CURL_NTLM_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_NTLM - -/* NTLM buffer fixed size, large enough for long user + host + domain */ -#define NTLM_BUFSIZE 1024 - -/* Stuff only required for curl_ntlm_msgs.c */ -#ifdef BUILDING_CURL_NTLM_MSGS_C - -/* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */ - -#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0) -/* Indicates that Unicode strings are supported for use in security buffer - data. */ - -#define NTLMFLAG_NEGOTIATE_OEM (1<<1) -/* Indicates that OEM strings are supported for use in security buffer data. */ - -#define NTLMFLAG_REQUEST_TARGET (1<<2) -/* Requests that the server's authentication realm be included in the Type 2 - message. */ - -/* unknown (1<<3) */ -#define NTLMFLAG_NEGOTIATE_SIGN (1<<4) -/* Specifies that authenticated communication between the client and server - should carry a digital signature (message integrity). */ - -#define NTLMFLAG_NEGOTIATE_SEAL (1<<5) -/* Specifies that authenticated communication between the client and server - should be encrypted (message confidentiality). */ - -#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6) -/* Indicates that datagram authentication is being used. */ - -#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7) -/* Indicates that the LAN Manager session key should be used for signing and - sealing authenticated communications. */ - -#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8) -/* unknown purpose */ - -#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9) -/* Indicates that NTLM authentication is being used. */ - -/* unknown (1<<10) */ - -#define NTLMFLAG_NEGOTIATE_ANONYMOUS (1<<11) -/* Sent by the client in the Type 3 message to indicate that an anonymous - context has been established. This also affects the response fields. */ - -#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12) -/* Sent by the client in the Type 1 message to indicate that a desired - authentication realm is included in the message. */ - -#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13) -/* Sent by the client in the Type 1 message to indicate that the client - workstation's name is included in the message. */ - -#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14) -/* Sent by the server to indicate that the server and client are on the same - machine. Implies that the client may use a pre-established local security - context rather than responding to the challenge. */ - -#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15) -/* Indicates that authenticated communication between the client and server - should be signed with a "dummy" signature. */ - -#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a domain. */ - -#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a server. */ - -#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18) -/* Sent by the server in the Type 2 message to indicate that the target - authentication realm is a share. Presumably, this is for share-level - authentication. Usage is unclear. */ - -#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19) -/* Indicates that the NTLM2 signing and sealing scheme should be used for - protecting authenticated communications. */ - -#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20) -/* unknown purpose */ - -#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21) -/* unknown purpose */ - -#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22) -/* unknown purpose */ - -#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23) -/* Sent by the server in the Type 2 message to indicate that it is including a - Target Information block in the message. */ - -/* unknown (1<24) */ -/* unknown (1<25) */ -/* unknown (1<26) */ -/* unknown (1<27) */ -/* unknown (1<28) */ - -#define NTLMFLAG_NEGOTIATE_128 (1<<29) -/* Indicates that 128-bit encryption is supported. */ - -#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30) -/* Indicates that the client will provide an encrypted master key in - the "Session Key" field of the Type 3 message. */ - -#define NTLMFLAG_NEGOTIATE_56 (1<<31) -/* Indicates that 56-bit encryption is supported. */ - -#endif /* BUILDING_CURL_NTLM_MSGS_C */ - -#endif /* USE_NTLM */ - -#endif /* HEADER_CURL_NTLM_H */ diff --git a/Externals/curl/lib/vauth/ntlm_sspi.c b/Externals/curl/lib/vauth/ntlm_sspi.c deleted file mode 100644 index 532e270fdb..0000000000 --- a/Externals/curl/lib/vauth/ntlm_sspi.c +++ /dev/null @@ -1,314 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && defined(USE_NTLM) - -#include - -#include "vauth/vauth.h" -#include "urldata.h" -#include "curl_base64.h" -#include "warnless.h" -#include "curl_multibyte.h" -#include "sendf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_create_ntlm_type1_message() - * - * This is used to generate an already encoded NTLM type-1 message ready for - * sending to the recipient. - * - * Parameters: - * - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type1_message(const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - char **outptr, size_t *outlen) -{ - PSecPkgInfo SecurityPackage; - SecBuffer type_1_buf; - SecBufferDesc type_1_desc; - SECURITY_STATUS status; - unsigned long attrs; - TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ - - /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_ntlm_cleanup(ntlm); - - /* Query the security package for NTLM */ - status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT(SP_NAME_NTLM), - &SecurityPackage); - if(status != SEC_E_OK) - return CURLE_NOT_BUILT_IN; - - ntlm->token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our output buffer */ - ntlm->output_token = malloc(ntlm->token_max); - if(!ntlm->output_token) - return CURLE_OUT_OF_MEMORY; - - if(userp && *userp) { - CURLcode result; - - /* Populate our identity structure */ - result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity); - if(result) - return result; - - /* Allow proper cleanup of the identity structure */ - ntlm->p_identity = &ntlm->identity; - } - else - /* Use the current Windows user */ - ntlm->p_identity = NULL; - - /* Allocate our credentials handle */ - ntlm->credentials = malloc(sizeof(CredHandle)); - if(!ntlm->credentials) - return CURLE_OUT_OF_MEMORY; - - memset(ntlm->credentials, 0, sizeof(CredHandle)); - - /* Acquire our credentials handle */ - status = s_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *) TEXT(SP_NAME_NTLM), - SECPKG_CRED_OUTBOUND, NULL, - ntlm->p_identity, NULL, NULL, - ntlm->credentials, &expiry); - if(status != SEC_E_OK) - return CURLE_LOGIN_DENIED; - - /* Allocate our new context handle */ - ntlm->context = malloc(sizeof(CtxtHandle)); - if(!ntlm->context) - return CURLE_OUT_OF_MEMORY; - - memset(ntlm->context, 0, sizeof(CtxtHandle)); - - /* Setup the type-1 "output" security buffer */ - type_1_desc.ulVersion = SECBUFFER_VERSION; - type_1_desc.cBuffers = 1; - type_1_desc.pBuffers = &type_1_buf; - type_1_buf.BufferType = SECBUFFER_TOKEN; - type_1_buf.pvBuffer = ntlm->output_token; - type_1_buf.cbBuffer = curlx_uztoul(ntlm->token_max); - - /* Generate our type-1 message */ - status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL, - (TCHAR *) TEXT(""), - 0, 0, SECURITY_NETWORK_DREP, - NULL, 0, - ntlm->context, &type_1_desc, - &attrs, &expiry); - if(status == SEC_I_COMPLETE_NEEDED || - status == SEC_I_COMPLETE_AND_CONTINUE) - s_pSecFn->CompleteAuthToken(ntlm->context, &type_1_desc); - else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) - return CURLE_RECV_ERROR; - - /* Base64 encode the response */ - return Curl_base64_encode(NULL, (char *) ntlm->output_token, - type_1_buf.cbBuffer, outptr, outlen); -} - -/* - * Curl_auth_decode_ntlm_type2_message() - * - * This is used to decode an already encoded NTLM type-2 message. - * - * Parameters: - * - * data [in] - The session handle. - * type2msg [in] - The base64 encoded type-2 message. - * ntlm [in/out] - The NTLM data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_ntlm_type2_message(struct SessionHandle *data, - const char *type2msg, - struct ntlmdata *ntlm) -{ - CURLcode result = CURLE_OK; - unsigned char *type2 = NULL; - size_t type2_len = 0; - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; -#endif - - /* Decode the base-64 encoded type-2 message */ - if(strlen(type2msg) && *type2msg != '=') { - result = Curl_base64_decode(type2msg, &type2, &type2_len); - if(result) - return result; - } - - /* Ensure we have a valid type-2 message */ - if(!type2) { - infof(data, "NTLM handshake failure (empty type-2 message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Simply store the challenge for use later */ - ntlm->input_token = type2; - ntlm->input_token_len = type2_len; - - return result; -} - -/* -* Curl_auth_create_ntlm_type3_message() - * Curl_auth_create_ntlm_type3_message() - * - * This is used to generate an already encoded NTLM type-3 message ready for - * sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * ntlm [in/out] - The NTLM data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_ntlm_type3_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - SecBuffer type_2_buf; - SecBuffer type_3_buf; - SecBufferDesc type_2_desc; - SecBufferDesc type_3_desc; - SECURITY_STATUS status; - unsigned long attrs; - TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ - - (void) passwdp; - (void) userp; - - /* Setup the type-2 "input" security buffer */ - type_2_desc.ulVersion = SECBUFFER_VERSION; - type_2_desc.cBuffers = 1; - type_2_desc.pBuffers = &type_2_buf; - type_2_buf.BufferType = SECBUFFER_TOKEN; - type_2_buf.pvBuffer = ntlm->input_token; - type_2_buf.cbBuffer = curlx_uztoul(ntlm->input_token_len); - - /* Setup the type-3 "output" security buffer */ - type_3_desc.ulVersion = SECBUFFER_VERSION; - type_3_desc.cBuffers = 1; - type_3_desc.pBuffers = &type_3_buf; - type_3_buf.BufferType = SECBUFFER_TOKEN; - type_3_buf.pvBuffer = ntlm->output_token; - type_3_buf.cbBuffer = curlx_uztoul(ntlm->token_max); - - /* Generate our type-3 message */ - status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, - ntlm->context, - (TCHAR *) TEXT(""), - 0, 0, SECURITY_NETWORK_DREP, - &type_2_desc, - 0, ntlm->context, - &type_3_desc, - &attrs, &expiry); - if(status != SEC_E_OK) { - infof(data, "NTLM handshake failure (type-3 message): Status=%x\n", - status); - - return CURLE_RECV_ERROR; - } - - /* Base64 encode the response */ - result = Curl_base64_encode(data, (char *) ntlm->output_token, - type_3_buf.cbBuffer, outptr, outlen); - - Curl_auth_ntlm_cleanup(ntlm); - - return result; -} - -/* - * Curl_auth_ntlm_cleanup() - * - * This is used to clean up the NTLM specific data. - * - * Parameters: - * - * ntlm [in/out] - The NTLM data struct being cleaned up. - * - */ -void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm) -{ - /* Free our security context */ - if(ntlm->context) { - s_pSecFn->DeleteSecurityContext(ntlm->context); - free(ntlm->context); - ntlm->context = NULL; - } - - /* Free our credentials handle */ - if(ntlm->credentials) { - s_pSecFn->FreeCredentialsHandle(ntlm->credentials); - free(ntlm->credentials); - ntlm->credentials = NULL; - } - - /* Free our identity */ - Curl_sspi_free_identity(ntlm->p_identity); - ntlm->p_identity = NULL; - - /* Free the input and output tokens */ - Curl_safefree(ntlm->input_token); - Curl_safefree(ntlm->output_token); - - /* Reset any variables */ - ntlm->token_max = 0; -} - -#endif /* USE_WINDOWS_SSPI && USE_NTLM */ diff --git a/Externals/curl/lib/vauth/oauth2.c b/Externals/curl/lib/vauth/oauth2.c deleted file mode 100644 index fccdfb86c9..0000000000 --- a/Externals/curl/lib/vauth/oauth2.c +++ /dev/null @@ -1,86 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC6749 OAuth 2.0 Authorization Framework - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include -#include "urldata.h" - -#include "vauth/vauth.h" -#include "curl_base64.h" -#include "warnless.h" -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_create_oauth_bearer_message() - * - * This is used to generate an already encoded OAuth 2.0 message ready for - * sending to the recipient. - * - * Parameters: - * - * data[in] - The session handle. - * user[in] - The user name. - * host[in] - The host name(for OAUTHBEARER). - * port[in] - The port(for OAUTHBEARER when not Port 80). - * bearer[in] - The bearer token. - * outptr[in / out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen[out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_oauth_bearer_message(struct SessionHandle *data, - const char *user, - const char *host, - const long port, - const char *bearer, - char **outptr, size_t *outlen) -{ - CURLcode result = CURLE_OK; - char *oauth = NULL; - - /* Generate the message */ - if(host == NULL && (port == 0 || port == 80)) - oauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer); - else if(port == 0 || port == 80) - oauth = aprintf("user=%s\1host=%s\1auth=Bearer %s\1\1", user, host, - bearer); - else - oauth = aprintf("user=%s\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user, - host, port, bearer); - if(!oauth) - return CURLE_OUT_OF_MEMORY; - - /* Base64 encode the reply */ - result = Curl_base64_encode(data, oauth, strlen(oauth), outptr, outlen); - - free(oauth); - - return result; -} diff --git a/Externals/curl/lib/vauth/spnego_gssapi.c b/Externals/curl/lib/vauth/spnego_gssapi.c deleted file mode 100644 index 739e35b6e5..0000000000 --- a/Externals/curl/lib/vauth/spnego_gssapi.c +++ /dev/null @@ -1,260 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC4178 Simple and Protected GSS-API Negotiation Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(HAVE_GSSAPI) && defined(USE_SPNEGO) - -#include - -#include "vauth/vauth.h" -#include "urldata.h" -#include "curl_base64.h" -#include "curl_gssapi.h" -#include "warnless.h" -#include "curl_multibyte.h" -#include "sendf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_decode_spnego_message() - * - * This is used to decode an already encoded SPNEGO (Negotiate) challenge - * message. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The host name. - * chlg64 [in] - The optional base64 encoded challenge message. - * nego [in/out] - The Negotiate data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_spnego_message(struct SessionHandle *data, - const char *user, - const char *password, - const char *service, - const char *host, - const char *chlg64, - struct negotiatedata *nego) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; - OM_uint32 major_status; - OM_uint32 minor_status; - OM_uint32 unused_status; - gss_buffer_desc spn_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; - gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; - - (void) user; - (void) password; - - if(nego->context && nego->status == GSS_S_COMPLETE) { - /* We finished successfully our part of authentication, but server - * rejected it (since we're again here). Exit with an error since we - * can't invent anything better */ - Curl_auth_spnego_cleanup(nego); - return CURLE_LOGIN_DENIED; - } - - if(!nego->spn) { - /* Generate our SPN */ - char *spn = Curl_auth_build_spn(service, NULL, host); - if(!spn) - return CURLE_OUT_OF_MEMORY; - - /* Populate the SPN structure */ - spn_token.value = spn; - spn_token.length = strlen(spn); - - /* Import the SPN */ - major_status = gss_import_name(&minor_status, &spn_token, - GSS_C_NT_HOSTBASED_SERVICE, - &nego->spn); - if(GSS_ERROR(major_status)) { - Curl_gss_log_error(data, "gss_import_name() failed: ", - major_status, minor_status); - - free(spn); - - return CURLE_OUT_OF_MEMORY; - } - - free(spn); - } - - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "SPNEGO handshake failure (empty challenge message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - input_token.value = chlg; - input_token.length = chlglen; - } - - /* Generate our challenge-response message */ - major_status = Curl_gss_init_sec_context(data, - &minor_status, - &nego->context, - nego->spn, - &Curl_spnego_mech_oid, - GSS_C_NO_CHANNEL_BINDINGS, - &input_token, - &output_token, - TRUE, - NULL); - - /* Free the decoded challenge as it is not required anymore */ - Curl_safefree(input_token.value); - - nego->status = major_status; - if(GSS_ERROR(major_status)) { - if(output_token.value) - gss_release_buffer(&unused_status, &output_token); - - Curl_gss_log_error(data, "gss_init_sec_context() failed: ", - major_status, minor_status); - - return CURLE_OUT_OF_MEMORY; - } - - if(!output_token.value || !output_token.length) { - if(output_token.value) - gss_release_buffer(&unused_status, &output_token); - - return CURLE_OUT_OF_MEMORY; - } - - nego->output_token = output_token; - - return CURLE_OK; -} - -/* - * Curl_auth_create_spnego_message() - * - * This is used to generate an already encoded SPNEGO (Negotiate) response - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * nego [in/out] - The Negotiate data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_spnego_message(struct SessionHandle *data, - struct negotiatedata *nego, - char **outptr, size_t *outlen) -{ - CURLcode result; - OM_uint32 minor_status; - - /* Base64 encode the already generated response */ - result = Curl_base64_encode(data, - nego->output_token.value, - nego->output_token.length, - outptr, outlen); - - if(result) { - gss_release_buffer(&minor_status, &nego->output_token); - nego->output_token.value = NULL; - nego->output_token.length = 0; - - return result; - } - - if(!*outptr || !*outlen) { - gss_release_buffer(&minor_status, &nego->output_token); - nego->output_token.value = NULL; - nego->output_token.length = 0; - - return CURLE_REMOTE_ACCESS_DENIED; - } - - return CURLE_OK; -} - -/* - * Curl_auth_spnego_cleanup() - * - * This is used to clean up the SPNEGO (Negotiate) specific data. - * - * Parameters: - * - * nego [in/out] - The Negotiate data struct being cleaned up. - * - */ -void Curl_auth_spnego_cleanup(struct negotiatedata* nego) -{ - OM_uint32 minor_status; - - /* Free our security context */ - if(nego->context != GSS_C_NO_CONTEXT) { - gss_delete_sec_context(&minor_status, &nego->context, GSS_C_NO_BUFFER); - nego->context = GSS_C_NO_CONTEXT; - } - - /* Free the output token */ - if(nego->output_token.value) { - gss_release_buffer(&minor_status, &nego->output_token); - nego->output_token.value = NULL; - nego->output_token.length = 0; - - } - - /* Free the SPN */ - if(nego->spn != GSS_C_NO_NAME) { - gss_release_name(&minor_status, &nego->spn); - nego->spn = GSS_C_NO_NAME; - } - - /* Reset any variables */ - nego->status = 0; -} - -#endif /* HAVE_GSSAPI && USE_SPNEGO */ diff --git a/Externals/curl/lib/vauth/spnego_sspi.c b/Externals/curl/lib/vauth/spnego_sspi.c deleted file mode 100644 index 7974664702..0000000000 --- a/Externals/curl/lib/vauth/spnego_sspi.c +++ /dev/null @@ -1,297 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - * RFC4178 Simple and Protected GSS-API Negotiation Mechanism - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_WINDOWS_SSPI) && defined(USE_SPNEGO) - -#include - -#include "vauth/vauth.h" -#include "urldata.h" -#include "curl_base64.h" -#include "warnless.h" -#include "curl_multibyte.h" -#include "sendf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_decode_spnego_message() - * - * This is used to decode an already encoded SPNEGO (Negotiate) challenge - * message. - * - * Parameters: - * - * data [in] - The session handle. - * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The host name. - * chlg64 [in] - The optional base64 encoded challenge message. - * nego [in/out] - The Negotiate data struct being used and modified. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_decode_spnego_message(struct SessionHandle *data, - const char *user, - const char *password, - const char *service, - const char *host, - const char *chlg64, - struct negotiatedata *nego) -{ - CURLcode result = CURLE_OK; - size_t chlglen = 0; - unsigned char *chlg = NULL; - PSecPkgInfo SecurityPackage; - SecBuffer chlg_buf; - SecBuffer resp_buf; - SecBufferDesc chlg_desc; - SecBufferDesc resp_desc; - unsigned long attrs; - TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ - -#if defined(CURL_DISABLE_VERBOSE_STRINGS) - (void) data; -#endif - - if(nego->context && nego->status == SEC_E_OK) { - /* We finished successfully our part of authentication, but server - * rejected it (since we're again here). Exit with an error since we - * can't invent anything better */ - Curl_auth_spnego_cleanup(nego); - return CURLE_LOGIN_DENIED; - } - - if(!nego->spn) { - /* Generate our SPN */ - nego->spn = Curl_auth_build_spn(service, host, NULL); - if(!nego->spn) - return CURLE_OUT_OF_MEMORY; - } - - if(!nego->output_token) { - /* Query the security package for Negotiate */ - nego->status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) - TEXT(SP_NAME_NEGOTIATE), - &SecurityPackage); - if(nego->status != SEC_E_OK) - return CURLE_NOT_BUILT_IN; - - nego->token_max = SecurityPackage->cbMaxToken; - - /* Release the package buffer as it is not required anymore */ - s_pSecFn->FreeContextBuffer(SecurityPackage); - - /* Allocate our output buffer */ - nego->output_token = malloc(nego->token_max); - if(!nego->output_token) - return CURLE_OUT_OF_MEMORY; - } - - if(!nego->credentials) { - /* Do we have credientials to use or are we using single sign-on? */ - if(user && *user) { - /* Populate our identity structure */ - result = Curl_create_sspi_identity(user, password, &nego->identity); - if(result) - return result; - - /* Allow proper cleanup of the identity structure */ - nego->p_identity = &nego->identity; - } - else - /* Use the current Windows user */ - nego->p_identity = NULL; - - /* Allocate our credentials handle */ - nego->credentials = malloc(sizeof(CredHandle)); - if(!nego->credentials) - return CURLE_OUT_OF_MEMORY; - - memset(nego->credentials, 0, sizeof(CredHandle)); - - /* Acquire our credentials handle */ - nego->status = - s_pSecFn->AcquireCredentialsHandle(NULL, - (TCHAR *)TEXT(SP_NAME_NEGOTIATE), - SECPKG_CRED_OUTBOUND, NULL, - nego->p_identity, NULL, NULL, - nego->credentials, &expiry); - if(nego->status != SEC_E_OK) - return CURLE_LOGIN_DENIED; - - /* Allocate our new context handle */ - nego->context = malloc(sizeof(CtxtHandle)); - if(!nego->context) - return CURLE_OUT_OF_MEMORY; - - memset(nego->context, 0, sizeof(CtxtHandle)); - } - - if(chlg64 && *chlg64) { - /* Decode the base-64 encoded challenge message */ - if(*chlg64 != '=') { - result = Curl_base64_decode(chlg64, &chlg, &chlglen); - if(result) - return result; - } - - /* Ensure we have a valid challenge message */ - if(!chlg) { - infof(data, "SPNEGO handshake failure (empty challenge message)\n"); - - return CURLE_BAD_CONTENT_ENCODING; - } - - /* Setup the challenge "input" security buffer */ - chlg_desc.ulVersion = SECBUFFER_VERSION; - chlg_desc.cBuffers = 1; - chlg_desc.pBuffers = &chlg_buf; - chlg_buf.BufferType = SECBUFFER_TOKEN; - chlg_buf.pvBuffer = chlg; - chlg_buf.cbBuffer = curlx_uztoul(chlglen); - } - - /* Setup the response "output" security buffer */ - resp_desc.ulVersion = SECBUFFER_VERSION; - resp_desc.cBuffers = 1; - resp_desc.pBuffers = &resp_buf; - resp_buf.BufferType = SECBUFFER_TOKEN; - resp_buf.pvBuffer = nego->output_token; - resp_buf.cbBuffer = curlx_uztoul(nego->token_max); - - /* Generate our challenge-response message */ - nego->status = s_pSecFn->InitializeSecurityContext(nego->credentials, - chlg ? nego->context : - NULL, - nego->spn, - ISC_REQ_CONFIDENTIALITY, - 0, SECURITY_NATIVE_DREP, - chlg ? &chlg_desc : NULL, - 0, nego->context, - &resp_desc, &attrs, - &expiry); - - /* Free the decoded challenge as it is not required anymore */ - free(chlg); - - if(GSS_ERROR(nego->status)) { - return CURLE_OUT_OF_MEMORY; - } - - if(nego->status == SEC_I_COMPLETE_NEEDED || - nego->status == SEC_I_COMPLETE_AND_CONTINUE) { - nego->status = s_pSecFn->CompleteAuthToken(nego->context, &resp_desc); - if(GSS_ERROR(nego->status)) { - return CURLE_RECV_ERROR; - } - } - - nego->output_token_length = resp_buf.cbBuffer; - - return result; -} - -/* - * Curl_auth_create_spnego_message() - * - * This is used to generate an already encoded SPNEGO (Negotiate) response - * message ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * nego [in/out] - The Negotiate data struct being used and modified. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -CURLcode Curl_auth_create_spnego_message(struct SessionHandle *data, - struct negotiatedata *nego, - char **outptr, size_t *outlen) -{ - CURLcode result; - - /* Base64 encode the already generated response */ - result = Curl_base64_encode(data, - (const char*) nego->output_token, - nego->output_token_length, - outptr, outlen); - - if(result) - return result; - - if(!*outptr || !*outlen) - return CURLE_REMOTE_ACCESS_DENIED; - - return CURLE_OK; -} - -/* - * Curl_auth_spnego_cleanup() - * - * This is used to clean up the SPNEGO (Negotiate) specific data. - * - * Parameters: - * - * nego [in/out] - The Negotiate data struct being cleaned up. - * - */ -void Curl_auth_spnego_cleanup(struct negotiatedata* nego) -{ - /* Free our security context */ - if(nego->context) { - s_pSecFn->DeleteSecurityContext(nego->context); - free(nego->context); - nego->context = NULL; - } - - /* Free our credentials handle */ - if(nego->credentials) { - s_pSecFn->FreeCredentialsHandle(nego->credentials); - free(nego->credentials); - nego->credentials = NULL; - } - - /* Free our identity */ - Curl_sspi_free_identity(nego->p_identity); - nego->p_identity = NULL; - - /* Free the SPN and output token */ - Curl_safefree(nego->spn); - Curl_safefree(nego->output_token); - - /* Reset any variables */ - nego->status = 0; - nego->token_max = 0; -} - -#endif /* USE_WINDOWS_SSPI && USE_SPNEGO */ diff --git a/Externals/curl/lib/vauth/vauth.c b/Externals/curl/lib/vauth/vauth.c deleted file mode 100644 index 702e2d4bc7..0000000000 --- a/Externals/curl/lib/vauth/vauth.c +++ /dev/null @@ -1,106 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2014 - 2016, Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include - -#include "vauth.h" -#include "curl_multibyte.h" -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* - * Curl_auth_build_spn() - * - * This is used to build a SPN string in the following formats: - * - * service/host@realm (Not currently used) - * service/host (Not used by GSS-API) - * service@realm (Not used by Windows SSPI) - * - * Parameters: - * - * service [in] - The service type such as http, smtp, pop or imap. - * host [in] - The host name. - * realm [in] - The realm. - * - * Returns a pointer to the newly allocated SPN. - */ -#if !defined(USE_WINDOWS_SSPI) -char *Curl_auth_build_spn(const char *service, const char *host, - const char *realm) -{ - char *spn = NULL; - - /* Generate our SPN */ - if(host && realm) - spn = aprintf("%s/%s@%s", service, host, realm); - else if(host) - spn = aprintf("%s/%s", service, host); - else if(realm) - spn = aprintf("%s@%s", service, realm); - - /* Return our newly allocated SPN */ - return spn; -} -#else -TCHAR *Curl_auth_build_spn(const char *service, const char *host, - const char *realm) -{ - char *utf8_spn = NULL; - TCHAR *tchar_spn = NULL; - - (void) realm; - - /* Note: We could use DsMakeSPN() or DsClientMakeSpnForTargetServer() rather - than doing this ourselves but the first is only available in Windows XP - and Windows Server 2003 and the latter is only available in Windows 2000 - but not Windows95/98/ME or Windows NT4.0 unless the Active Directory - Client Extensions are installed. As such it is far simpler for us to - formulate the SPN instead. */ - - /* Generate our UTF8 based SPN */ - utf8_spn = aprintf("%s/%s", service, host); - if(!utf8_spn) { - return NULL; - } - - /* Allocate our TCHAR based SPN */ - tchar_spn = Curl_convert_UTF8_to_tchar(utf8_spn); - if(!tchar_spn) { - free(utf8_spn); - - return NULL; - } - - /* Release the UTF8 variant when operating with Unicode */ - Curl_unicodefree(utf8_spn); - - /* Return our newly allocated SPN */ - return tchar_spn; -} -#endif /* USE_WINDOWS_SSPI */ - diff --git a/Externals/curl/lib/vauth/vauth.h b/Externals/curl/lib/vauth/vauth.h deleted file mode 100644 index 2c5131c70a..0000000000 --- a/Externals/curl/lib/vauth/vauth.h +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef HEADER_CURL_VAUTH_H -#define HEADER_CURL_VAUTH_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2014 - 2016, Steve Holme, . - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -struct SessionHandle; - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) -struct digestdata; -#endif - -#if defined(USE_NTLM) -struct ntlmdata; -#endif - -#if defined(USE_KERBEROS5) -struct kerberos5data; -#endif - -#if (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) && defined(USE_SPNEGO) -struct negotiatedata; -#endif - -#if defined(USE_WINDOWS_SSPI) -#define GSS_ERROR(status) (status & 0x80000000) -#endif - -/* This is used to build a SPN string */ -#if !defined(USE_WINDOWS_SSPI) -char *Curl_auth_build_spn(const char *service, const char *host, - const char *realm); -#else -TCHAR *Curl_auth_build_spn(const char *service, const char *host, - const char *realm); -#endif - -/* This is used to generate a base64 encoded PLAIN cleartext message */ -CURLcode Curl_auth_create_plain_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - char **outptr, size_t *outlen); - -/* This is used to generate a base64 encoded LOGIN cleartext message */ -CURLcode Curl_auth_create_login_message(struct SessionHandle *data, - const char *valuep, char **outptr, - size_t *outlen); - -/* This is used to generate a base64 encoded EXTERNAL cleartext message */ -CURLcode Curl_auth_create_external_message(struct SessionHandle *data, - const char *user, char **outptr, - size_t *outlen); - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) -/* This is used to decode a CRAM-MD5 challenge message */ -CURLcode Curl_auth_decode_cram_md5_message(const char *chlg64, char **outptr, - size_t *outlen); - -/* This is used to generate a CRAM-MD5 response message */ -CURLcode Curl_auth_create_cram_md5_message(struct SessionHandle *data, - const char *chlg, - const char *userp, - const char *passwdp, - char **outptr, size_t *outlen); - -/* This is used to generate a base64 encoded DIGEST-MD5 response message */ -CURLcode Curl_auth_create_digest_md5_message(struct SessionHandle *data, - const char *chlg64, - const char *userp, - const char *passwdp, - const char *service, - char **outptr, size_t *outlen); - -/* This is used to decode a HTTP DIGEST challenge message */ -CURLcode Curl_auth_decode_digest_http_message(const char *chlg, - struct digestdata *digest); - -/* This is used to generate a HTTP DIGEST response message */ -CURLcode Curl_auth_create_digest_http_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - const unsigned char *request, - const unsigned char *uri, - struct digestdata *digest, - char **outptr, size_t *outlen); - -/* This is used to clean up the digest specific data */ -void Curl_auth_digest_cleanup(struct digestdata *digest); -#endif /* !CURL_DISABLE_CRYPTO_AUTH */ - -#if defined(USE_NTLM) -/* This is used to generate a base64 encoded NTLM type-1 message */ -CURLcode Curl_auth_create_ntlm_type1_message(const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - char **outptr, - size_t *outlen); - -/* This is used to decode a base64 encoded NTLM type-2 message */ -CURLcode Curl_auth_decode_ntlm_type2_message(struct SessionHandle *data, - const char *type2msg, - struct ntlmdata *ntlm); - -/* This is used to generate a base64 encoded NTLM type-3 message */ -CURLcode Curl_auth_create_ntlm_type3_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - struct ntlmdata *ntlm, - char **outptr, size_t *outlen); - -/* This is used to clean up the NTLM specific data */ -void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm); -#endif /* USE_NTLM */ - -/* This is used to generate a base64 encoded OAuth 2.0 message */ -CURLcode Curl_auth_create_oauth_bearer_message(struct SessionHandle *data, - const char *user, - const char *host, - const long port, - const char *bearer, - char **outptr, size_t *outlen); -#if defined(USE_KERBEROS5) -/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) user token - message */ -CURLcode Curl_auth_create_gssapi_user_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - const char *service, - const char *host, - const bool mutual, - const char *chlg64, - struct kerberos5data *krb5, - char **outptr, size_t *outlen); - -/* This is used to generate a base64 encoded GSSAPI (Kerberos V5) security - token message */ -CURLcode Curl_auth_create_gssapi_security_message(struct SessionHandle *data, - const char *input, - struct kerberos5data *krb5, - char **outptr, - size_t *outlen); - -/* This is used to clean up the GSSAPI specific data */ -void Curl_auth_gssapi_cleanup(struct kerberos5data *krb5); -#endif /* USE_KERBEROS5 */ - -#if (defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)) && defined(USE_SPNEGO) -/* This is used to decode a base64 encoded SPNEGO (Negotiate) challenge - message */ -CURLcode Curl_auth_decode_spnego_message(struct SessionHandle *data, - const char *user, - const char *passwood, - const char *service, - const char *host, - const char *chlg64, - struct negotiatedata *nego); - -/* This is used to generate a base64 encoded SPNEGO (Negotiate) response - message */ -CURLcode Curl_auth_create_spnego_message(struct SessionHandle *data, - struct negotiatedata *nego, - char **outptr, size_t *outlen); - -/* This is used to clean up the SPNEGO specifiec data */ -void Curl_auth_spnego_cleanup(struct negotiatedata* nego); - -#endif /* (HAVE_GSSAPI || USE_WINDOWS_SSPI) && USE_SPNEGO */ - -#endif /* HEADER_CURL_VAUTH_H */ diff --git a/Externals/curl/lib/version.c b/Externals/curl/lib/version.c deleted file mode 100644 index 12924453c8..0000000000 --- a/Externals/curl/lib/version.c +++ /dev/null @@ -1,396 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include -#include "urldata.h" -#include "vtls/vtls.h" -#include "http2.h" -#include "curl_printf.h" - -#ifdef USE_ARES -# if defined(CURL_STATICLIB) && !defined(CARES_STATICLIB) && \ - (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) -# define CARES_STATICLIB -# endif -# include -#endif - -#ifdef USE_LIBIDN -#include -#endif - -#ifdef USE_LIBPSL -#include -#endif - -#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) -#include -#endif - -#ifdef USE_LIBRTMP -#include -#endif - -#ifdef USE_LIBSSH2 -#include -#endif - -#ifdef HAVE_LIBSSH2_VERSION -/* get it run-time if possible */ -#define CURL_LIBSSH2_VERSION libssh2_version(0) -#else -/* use build-time if run-time not possible */ -#define CURL_LIBSSH2_VERSION LIBSSH2_VERSION -#endif - -void Curl_version_init(void); - -/* For thread safety purposes this function is called by global_init so that - the static data in both version functions is initialized. */ -void Curl_version_init(void) -{ - curl_version(); - curl_version_info(CURLVERSION_NOW); -} - -char *curl_version(void) -{ - static bool initialized; - static char version[200]; - char *ptr = version; - size_t len; - size_t left = sizeof(version); - - if(initialized) - return version; - - strcpy(ptr, LIBCURL_NAME "/" LIBCURL_VERSION); - len = strlen(ptr); - left -= len; - ptr += len; - - if(left > 1) { - len = Curl_ssl_version(ptr + 1, left - 1); - - if(len > 0) { - *ptr = ' '; - left -= ++len; - ptr += len; - } - } - -#ifdef HAVE_LIBZ - len = snprintf(ptr, left, " zlib/%s", zlibVersion()); - left -= len; - ptr += len; -#endif -#ifdef USE_ARES - /* this function is only present in c-ares, not in the original ares */ - len = snprintf(ptr, left, " c-ares/%s", ares_version(NULL)); - left -= len; - ptr += len; -#endif -#ifdef USE_LIBIDN - if(stringprep_check_version(LIBIDN_REQUIRED_VERSION)) { - len = snprintf(ptr, left, " libidn/%s", stringprep_check_version(NULL)); - left -= len; - ptr += len; - } -#endif -#ifdef USE_LIBPSL - len = snprintf(ptr, left, " libpsl/%s", psl_get_version()); - left -= len; - ptr += len; -#endif -#ifdef USE_WIN32_IDN - len = snprintf(ptr, left, " WinIDN"); - left -= len; - ptr += len; -#endif -#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) -#ifdef _LIBICONV_VERSION - len = snprintf(ptr, left, " iconv/%d.%d", - _LIBICONV_VERSION >> 8, _LIBICONV_VERSION & 255); -#else - /* version unknown */ - len = snprintf(ptr, left, " iconv"); -#endif /* _LIBICONV_VERSION */ - left -= len; - ptr += len; -#endif -#ifdef USE_LIBSSH2 - len = snprintf(ptr, left, " libssh2/%s", CURL_LIBSSH2_VERSION); - left -= len; - ptr += len; -#endif -#ifdef USE_NGHTTP2 - len = Curl_http2_ver(ptr, left); - left -= len; - ptr += len; -#endif -#ifdef USE_LIBRTMP - { - char suff[2]; - if(RTMP_LIB_VERSION & 0xff) { - suff[0] = (RTMP_LIB_VERSION & 0xff) + 'a' - 1; - suff[1] = '\0'; - } - else - suff[0] = '\0'; - - snprintf(ptr, left, " librtmp/%d.%d%s", - RTMP_LIB_VERSION >> 16, (RTMP_LIB_VERSION >> 8) & 0xff, - suff); -/* - If another lib version is added below this one, this code would - also have to do: - - len = what snprintf() returned - - left -= len; - ptr += len; -*/ - } -#endif - - initialized = true; - return version; -} - -/* data for curl_version_info - - Keep the list sorted alphabetically. It is also written so that each - protocol line has its own #if line to make things easier on the eye. - */ - -static const char * const protocols[] = { -#ifndef CURL_DISABLE_DICT - "dict", -#endif -#ifndef CURL_DISABLE_FILE - "file", -#endif -#ifndef CURL_DISABLE_FTP - "ftp", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP) - "ftps", -#endif -#ifndef CURL_DISABLE_GOPHER - "gopher", -#endif -#ifndef CURL_DISABLE_HTTP - "http", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) - "https", -#endif -#ifndef CURL_DISABLE_IMAP - "imap", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_IMAP) - "imaps", -#endif -#ifndef CURL_DISABLE_LDAP - "ldap", -#if !defined(CURL_DISABLE_LDAPS) && \ - ((defined(USE_OPENLDAP) && defined(USE_SSL)) || \ - (!defined(USE_OPENLDAP) && defined(HAVE_LDAP_SSL))) - "ldaps", -#endif -#endif -#ifndef CURL_DISABLE_POP3 - "pop3", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_POP3) - "pop3s", -#endif -#ifdef USE_LIBRTMP - "rtmp", -#endif -#ifndef CURL_DISABLE_RTSP - "rtsp", -#endif -#ifdef USE_LIBSSH2 - "scp", -#endif -#ifdef USE_LIBSSH2 - "sftp", -#endif -#if !defined(CURL_DISABLE_SMB) && defined(USE_NTLM) && \ - (CURL_SIZEOF_CURL_OFF_T > 4) && \ - (!defined(USE_WINDOWS_SSPI) || defined(USE_WIN32_CRYPTO)) - "smb", -# ifdef USE_SSL - "smbs", -# endif -#endif -#ifndef CURL_DISABLE_SMTP - "smtp", -#endif -#if defined(USE_SSL) && !defined(CURL_DISABLE_SMTP) - "smtps", -#endif -#ifndef CURL_DISABLE_TELNET - "telnet", -#endif -#ifndef CURL_DISABLE_TFTP - "tftp", -#endif - - NULL -}; - -static curl_version_info_data version_info = { - CURLVERSION_NOW, - LIBCURL_VERSION, - LIBCURL_VERSION_NUM, - OS, /* as found by configure or set by hand at build-time */ - 0 /* features is 0 by default */ -#ifdef ENABLE_IPV6 - | CURL_VERSION_IPV6 -#endif -#ifdef USE_SSL - | CURL_VERSION_SSL -#endif -#ifdef USE_NTLM - | CURL_VERSION_NTLM -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) && \ - defined(NTLM_WB_ENABLED) - | CURL_VERSION_NTLM_WB -#endif -#ifdef USE_SPNEGO - | CURL_VERSION_SPNEGO -#endif -#ifdef USE_KERBEROS5 - | CURL_VERSION_KERBEROS5 -#endif -#ifdef HAVE_GSSAPI - | CURL_VERSION_GSSAPI -#endif -#ifdef USE_WINDOWS_SSPI - | CURL_VERSION_SSPI -#endif -#ifdef HAVE_LIBZ - | CURL_VERSION_LIBZ -#endif -#ifdef DEBUGBUILD - | CURL_VERSION_DEBUG -#endif -#ifdef CURLDEBUG - | CURL_VERSION_CURLDEBUG -#endif -#ifdef CURLRES_ASYNCH - | CURL_VERSION_ASYNCHDNS -#endif -#if (CURL_SIZEOF_CURL_OFF_T > 4) && \ - ( (SIZEOF_OFF_T > 4) || defined(USE_WIN32_LARGE_FILES) ) - | CURL_VERSION_LARGEFILE -#endif -#if defined(CURL_DOES_CONVERSIONS) - | CURL_VERSION_CONV -#endif -#if defined(USE_TLS_SRP) - | CURL_VERSION_TLSAUTH_SRP -#endif -#if defined(USE_NGHTTP2) - | CURL_VERSION_HTTP2 -#endif -#if defined(USE_UNIX_SOCKETS) - | CURL_VERSION_UNIX_SOCKETS -#endif -#if defined(USE_LIBPSL) - | CURL_VERSION_PSL -#endif - , - NULL, /* ssl_version */ - 0, /* ssl_version_num, this is kept at zero */ - NULL, /* zlib_version */ - protocols, - NULL, /* c-ares version */ - 0, /* c-ares version numerical */ - NULL, /* libidn version */ - 0, /* iconv version */ - NULL, /* ssh lib version */ -}; - -curl_version_info_data *curl_version_info(CURLversion stamp) -{ - static bool initialized; -#ifdef USE_LIBSSH2 - static char ssh_buffer[80]; -#endif -#ifdef USE_SSL - static char ssl_buffer[80]; -#endif - - if(initialized) - return &version_info; - -#ifdef USE_SSL - Curl_ssl_version(ssl_buffer, sizeof(ssl_buffer)); - version_info.ssl_version = ssl_buffer; -#endif - -#ifdef HAVE_LIBZ - version_info.libz_version = zlibVersion(); - /* libz left NULL if non-existing */ -#endif -#ifdef USE_ARES - { - int aresnum; - version_info.ares = ares_version(&aresnum); - version_info.ares_num = aresnum; - } -#endif -#ifdef USE_LIBIDN - /* This returns a version string if we use the given version or later, - otherwise it returns NULL */ - version_info.libidn = stringprep_check_version(LIBIDN_REQUIRED_VERSION); - if(version_info.libidn) - version_info.features |= CURL_VERSION_IDN; -#elif defined(USE_WIN32_IDN) - version_info.features |= CURL_VERSION_IDN; -#endif - -#if defined(HAVE_ICONV) && defined(CURL_DOES_CONVERSIONS) -#ifdef _LIBICONV_VERSION - version_info.iconv_ver_num = _LIBICONV_VERSION; -#else - /* version unknown */ - version_info.iconv_ver_num = -1; -#endif /* _LIBICONV_VERSION */ -#endif - -#ifdef USE_LIBSSH2 - snprintf(ssh_buffer, sizeof(ssh_buffer), "libssh2/%s", LIBSSH2_VERSION); - version_info.libssh_version = ssh_buffer; -#endif - - (void)stamp; /* avoid compiler warnings, we don't use this */ - - initialized = true; - return &version_info; -} diff --git a/Externals/curl/lib/vtls/axtls.c b/Externals/curl/lib/vtls/axtls.c deleted file mode 100644 index 0afcfaa58a..0000000000 --- a/Externals/curl/lib/vtls/axtls.c +++ /dev/null @@ -1,690 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010, DirecTV, Contact: Eric Hu, . - * Copyright (C) 2010 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all axTLS-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - */ - -#include "curl_setup.h" - -#ifdef USE_AXTLS -#include -#include -#include "axtls.h" - -#include "sendf.h" -#include "inet_pton.h" -#include "vtls.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "curl_printf.h" -#include "hostcheck.h" -#include - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - - -/* Global axTLS init, called from Curl_ssl_init() */ -int Curl_axtls_init(void) -{ -/* axTLS has no global init. Everything is done through SSL and SSL_CTX - * structs stored in connectdata structure. Perhaps can move to axtls.h. - */ - return 1; -} - -int Curl_axtls_cleanup(void) -{ - /* axTLS has no global cleanup. Perhaps can move this to axtls.h. */ - return 1; -} - -static CURLcode map_error_to_curl(int axtls_err) -{ - switch (axtls_err) { - case SSL_ERROR_NOT_SUPPORTED: - case SSL_ERROR_INVALID_VERSION: - case -70: /* protocol version alert from server */ - return CURLE_UNSUPPORTED_PROTOCOL; - break; - case SSL_ERROR_NO_CIPHER: - return CURLE_SSL_CIPHER; - break; - case SSL_ERROR_BAD_CERTIFICATE: /* this may be bad server cert too */ - case SSL_ERROR_NO_CERT_DEFINED: - case -42: /* bad certificate alert from server */ - case -43: /* unsupported cert alert from server */ - case -44: /* cert revoked alert from server */ - case -45: /* cert expired alert from server */ - case -46: /* cert unknown alert from server */ - return CURLE_SSL_CERTPROBLEM; - break; - case SSL_X509_ERROR(X509_NOT_OK): - case SSL_X509_ERROR(X509_VFY_ERROR_NO_TRUSTED_CERT): - case SSL_X509_ERROR(X509_VFY_ERROR_BAD_SIGNATURE): - case SSL_X509_ERROR(X509_VFY_ERROR_NOT_YET_VALID): - case SSL_X509_ERROR(X509_VFY_ERROR_EXPIRED): - case SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED): - case SSL_X509_ERROR(X509_VFY_ERROR_INVALID_CHAIN): - case SSL_X509_ERROR(X509_VFY_ERROR_UNSUPPORTED_DIGEST): - case SSL_X509_ERROR(X509_INVALID_PRIV_KEY): - return CURLE_PEER_FAILED_VERIFICATION; - break; - case -48: /* unknown ca alert from server */ - return CURLE_SSL_CACERT; - break; - case -49: /* access denied alert from server */ - return CURLE_REMOTE_ACCESS_DENIED; - break; - case SSL_ERROR_CONN_LOST: - case SSL_ERROR_SOCK_SETUP_FAILURE: - case SSL_ERROR_INVALID_HANDSHAKE: - case SSL_ERROR_INVALID_PROT_MSG: - case SSL_ERROR_INVALID_HMAC: - case SSL_ERROR_INVALID_SESSION: - case SSL_ERROR_INVALID_KEY: /* it's too bad this doesn't map better */ - case SSL_ERROR_FINISHED_INVALID: - case SSL_ERROR_NO_CLIENT_RENOG: - default: - return CURLE_SSL_CONNECT_ERROR; - break; - } -} - -static Curl_recv axtls_recv; -static Curl_send axtls_send; - -static void free_ssl_structs(struct ssl_connect_data *connssl) -{ - if(connssl->ssl) { - ssl_free (connssl->ssl); - connssl->ssl = NULL; - } - if(connssl->ssl_ctx) { - ssl_ctx_free(connssl->ssl_ctx); - connssl->ssl_ctx = NULL; - } -} - -/* - * For both blocking and non-blocking connects, this function sets up the - * ssl context and state. This function is called after the TCP connect - * has completed. - */ -static CURLcode connect_prep(struct connectdata *conn, int sockindex) -{ - struct SessionHandle *data = conn->data; - SSL_CTX *ssl_ctx; - SSL *ssl = NULL; - int cert_types[] = {SSL_OBJ_X509_CERT, SSL_OBJ_PKCS12, 0}; - int key_types[] = {SSL_OBJ_RSA_KEY, SSL_OBJ_PKCS8, SSL_OBJ_PKCS12, 0}; - int i, ssl_fcn_return; - const uint8_t *ssl_sessionid; - size_t ssl_idsize; - - /* Assuming users will not compile in custom key/cert to axTLS. - * Also, even for blocking connects, use axTLS non-blocking feature. - */ - uint32_t client_option = SSL_NO_DEFAULT_KEY | - SSL_SERVER_VERIFY_LATER | - SSL_CONNECT_IN_PARTS; - - if(conn->ssl[sockindex].state == ssl_connection_complete) - /* to make us tolerant against being called more than once for the - same connection */ - return CURLE_OK; - - /* axTLS only supports TLSv1 */ - /* check to see if we've been told to use an explicit SSL/TLS version */ - switch(data->set.ssl.version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - break; - default: - failf(data, "axTLS only supports TLS 1.0 and 1.1, " - "and it cannot be specified which one to use"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef AXTLSDEBUG - client_option |= SSL_DISPLAY_STATES | SSL_DISPLAY_RSA | SSL_DISPLAY_CERTS; -#endif /* AXTLSDEBUG */ - - /* Allocate an SSL_CTX struct */ - ssl_ctx = ssl_ctx_new(client_option, SSL_DEFAULT_CLNT_SESS); - if(ssl_ctx == NULL) { - failf(data, "unable to create client SSL context"); - return CURLE_SSL_CONNECT_ERROR; - } - - conn->ssl[sockindex].ssl_ctx = ssl_ctx; - conn->ssl[sockindex].ssl = NULL; - - /* Load the trusted CA cert bundle file */ - if(data->set.ssl.CAfile) { - if(ssl_obj_load(ssl_ctx, SSL_OBJ_X509_CACERT, data->set.ssl.CAfile, NULL) - != SSL_OK) { - infof(data, "error reading ca cert file %s \n", - data->set.ssl.CAfile); - if(data->set.ssl.verifypeer) { - return CURLE_SSL_CACERT_BADFILE; - } - } - else - infof(data, "found certificates in %s\n", data->set.ssl.CAfile); - } - - /* gtls.c tasks we're skipping for now: - * 1) certificate revocation list checking - * 2) dns name assignment to host - * 3) set protocol priority. axTLS is TLSv1 only, so can probably ignore - * 4) set certificate priority. axTLS ignores type and sends certs in - * order added. can probably ignore this. - */ - - /* Load client certificate */ - if(data->set.str[STRING_CERT]) { - i=0; - /* Instead of trying to analyze cert type here, let axTLS try them all. */ - while(cert_types[i] != 0) { - ssl_fcn_return = ssl_obj_load(ssl_ctx, cert_types[i], - data->set.str[STRING_CERT], NULL); - if(ssl_fcn_return == SSL_OK) { - infof(data, "successfully read cert file %s \n", - data->set.str[STRING_CERT]); - break; - } - i++; - } - /* Tried all cert types, none worked. */ - if(cert_types[i] == 0) { - failf(data, "%s is not x509 or pkcs12 format", - data->set.str[STRING_CERT]); - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Load client key. - If a pkcs12 file successfully loaded a cert, then there's nothing to do - because the key has already been loaded. */ - if(data->set.str[STRING_KEY] && cert_types[i] != SSL_OBJ_PKCS12) { - i=0; - /* Instead of trying to analyze key type here, let axTLS try them all. */ - while(key_types[i] != 0) { - ssl_fcn_return = ssl_obj_load(ssl_ctx, key_types[i], - data->set.str[STRING_KEY], NULL); - if(ssl_fcn_return == SSL_OK) { - infof(data, "successfully read key file %s \n", - data->set.str[STRING_KEY]); - break; - } - i++; - } - /* Tried all key types, none worked. */ - if(key_types[i] == 0) { - failf(data, "Failure: %s is not a supported key file", - data->set.str[STRING_KEY]); - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* gtls.c does more here that is being left out for now - * 1) set session credentials. can probably ignore since axtls puts this - * info in the ssl_ctx struct - * 2) setting up callbacks. these seem gnutls specific - */ - - /* In axTLS, handshaking happens inside ssl_client_new. */ - if(!Curl_ssl_getsessionid(conn, (void **) &ssl_sessionid, &ssl_idsize)) { - /* we got a session id, use it! */ - infof (data, "SSL re-using session ID\n"); - ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], - ssl_sessionid, (uint8_t)ssl_idsize); - } - else - ssl = ssl_client_new(ssl_ctx, conn->sock[sockindex], NULL, 0); - - conn->ssl[sockindex].ssl = ssl; - return CURLE_OK; -} - -/* - * For both blocking and non-blocking connects, this function finalizes the - * SSL connection. - */ -static CURLcode connect_finish(struct connectdata *conn, int sockindex) -{ - struct SessionHandle *data = conn->data; - SSL *ssl = conn->ssl[sockindex].ssl; - const uint8_t *ssl_sessionid; - size_t ssl_idsize; - const char *peer_CN; - uint32_t dns_altname_index; - const char *dns_altname; - int8_t found_subject_alt_names = 0; - int8_t found_subject_alt_name_matching_conn = 0; - - /* Here, gtls.c gets the peer certificates and fails out depending on - * settings in "data." axTLS api doesn't have get cert chain fcn, so omit? - */ - - /* Verify server's certificate */ - if(data->set.ssl.verifypeer) { - if(ssl_verify_cert(ssl) != SSL_OK) { - Curl_axtls_close(conn, sockindex); - failf(data, "server cert verify failed"); - return CURLE_PEER_FAILED_VERIFICATION; - } - } - else - infof(data, "\t server certificate verification SKIPPED\n"); - - /* Here, gtls.c does issuer verification. axTLS has no straightforward - * equivalent, so omitting for now.*/ - - /* Here, gtls.c does the following - * 1) x509 hostname checking per RFC2818. axTLS doesn't support this, but - * it seems useful. This is now implemented, by Oscar Koeroo - * 2) checks cert validity based on time. axTLS does this in ssl_verify_cert - * 3) displays a bunch of cert information. axTLS doesn't support most of - * this, but a couple fields are available. - */ - - /* There is no (DNS) Altnames count in the version 1.4.8 API. There is a - risk of an inifite loop */ - for(dns_altname_index = 0; ; dns_altname_index++) { - dns_altname = ssl_get_cert_subject_alt_dnsname(ssl, dns_altname_index); - if(dns_altname == NULL) { - break; - } - found_subject_alt_names = 1; - - infof(data, "\tComparing subject alt name DNS with hostname: %s <-> %s\n", - dns_altname, conn->host.name); - if(Curl_cert_hostcheck(dns_altname, conn->host.name)) { - found_subject_alt_name_matching_conn = 1; - break; - } - } - - /* RFC2818 checks */ - if(found_subject_alt_names && !found_subject_alt_name_matching_conn) { - if(data->set.ssl.verifyhost) { - /* Break connection ! */ - Curl_axtls_close(conn, sockindex); - failf(data, "\tsubjectAltName(s) do not match %s\n", - conn->host.dispname); - return CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, "\tsubjectAltName(s) do not match %s\n", - conn->host.dispname); - } - else if(found_subject_alt_names == 0) { - /* Per RFC2818, when no Subject Alt Names were available, examine the peer - CN as a legacy fallback */ - peer_CN = ssl_get_cert_dn(ssl, SSL_X509_CERT_COMMON_NAME); - if(peer_CN == NULL) { - if(data->set.ssl.verifyhost) { - Curl_axtls_close(conn, sockindex); - failf(data, "unable to obtain common name from peer certificate"); - return CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, "unable to obtain common name from peer certificate"); - } - else { - if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) { - if(data->set.ssl.verifyhost) { - /* Break connection ! */ - Curl_axtls_close(conn, sockindex); - failf(data, "\tcommon name \"%s\" does not match \"%s\"\n", - peer_CN, conn->host.dispname); - return CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, "\tcommon name \"%s\" does not match \"%s\"\n", - peer_CN, conn->host.dispname); - } - } - } - - /* General housekeeping */ - conn->ssl[sockindex].state = ssl_connection_complete; - conn->recv[sockindex] = axtls_recv; - conn->send[sockindex] = axtls_send; - - /* Put our freshly minted SSL session in cache */ - ssl_idsize = ssl_get_session_id_size(ssl); - ssl_sessionid = ssl_get_session_id(ssl); - if(Curl_ssl_addsessionid(conn, (void *) ssl_sessionid, ssl_idsize) - != CURLE_OK) - infof (data, "failed to add session to cache\n"); - - return CURLE_OK; -} - -/* - * Use axTLS's non-blocking connection feature to open an SSL connection. - * This is called after a TCP connection is already established. - */ -CURLcode Curl_axtls_connect_nonblocking( - struct connectdata *conn, - int sockindex, - bool *done) -{ - CURLcode conn_step; - int ssl_fcn_return; - int i; - - *done = FALSE; - /* connectdata is calloc'd and connecting_state is only changed in this - function, so this is safe, as the state is effectively initialized. */ - if(conn->ssl[sockindex].connecting_state == ssl_connect_1) { - conn_step = connect_prep(conn, sockindex); - if(conn_step != CURLE_OK) { - Curl_axtls_close(conn, sockindex); - return conn_step; - } - conn->ssl[sockindex].connecting_state = ssl_connect_2; - } - - if(conn->ssl[sockindex].connecting_state == ssl_connect_2) { - /* Check to make sure handshake was ok. */ - if(ssl_handshake_status(conn->ssl[sockindex].ssl) != SSL_OK) { - /* Loop to perform more work in between sleeps. This is work around the - fact that axtls does not expose any knowledge about when work needs - to be performed. This can save ~25% of time on SSL handshakes. */ - for(i=0; i<5; i++) { - ssl_fcn_return = ssl_read(conn->ssl[sockindex].ssl, NULL); - if(ssl_fcn_return < 0) { - Curl_axtls_close(conn, sockindex); - ssl_display_error(ssl_fcn_return); /* goes to stdout. */ - return map_error_to_curl(ssl_fcn_return); - } - return CURLE_OK; - } - } - infof (conn->data, "handshake completed successfully\n"); - conn->ssl[sockindex].connecting_state = ssl_connect_3; - } - - if(conn->ssl[sockindex].connecting_state == ssl_connect_3) { - conn_step = connect_finish(conn, sockindex); - if(conn_step != CURLE_OK) { - Curl_axtls_close(conn, sockindex); - return conn_step; - } - - /* Reset connect state */ - conn->ssl[sockindex].connecting_state = ssl_connect_1; - - *done = TRUE; - return CURLE_OK; - } - - /* Unrecognized state. Things are very bad. */ - conn->ssl[sockindex].state = ssl_connection_none; - conn->ssl[sockindex].connecting_state = ssl_connect_1; - /* Return value perhaps not strictly correct, but distinguishes the issue.*/ - return CURLE_BAD_FUNCTION_ARGUMENT; -} - - -/* - * This function is called after the TCP connect has completed. Setup the TLS - * layer and do all necessary magic for a blocking connect. - */ -CURLcode -Curl_axtls_connect(struct connectdata *conn, - int sockindex) - -{ - struct SessionHandle *data = conn->data; - CURLcode conn_step = connect_prep(conn, sockindex); - int ssl_fcn_return; - SSL *ssl = conn->ssl[sockindex].ssl; - long timeout_ms; - - if(conn_step != CURLE_OK) { - Curl_axtls_close(conn, sockindex); - return conn_step; - } - - /* Check to make sure handshake was ok. */ - while(ssl_handshake_status(ssl) != SSL_OK) { - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - ssl_fcn_return = ssl_read(ssl, NULL); - if(ssl_fcn_return < 0) { - Curl_axtls_close(conn, sockindex); - ssl_display_error(ssl_fcn_return); /* goes to stdout. */ - return map_error_to_curl(ssl_fcn_return); - } - /* TODO: avoid polling */ - usleep(10000); - } - infof (conn->data, "handshake completed successfully\n"); - - conn_step = connect_finish(conn, sockindex); - if(conn_step != CURLE_OK) { - Curl_axtls_close(conn, sockindex); - return conn_step; - } - - return CURLE_OK; -} - -/* return number of sent (non-SSL) bytes */ -static ssize_t axtls_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *err) -{ - /* ssl_write() returns 'int' while write() and send() returns 'size_t' */ - int rc = ssl_write(conn->ssl[sockindex].ssl, mem, (int)len); - - infof(conn->data, " axtls_send\n"); - - if(rc < 0) { - *err = map_error_to_curl(rc); - rc = -1; /* generic error code for send failure */ - } - - *err = CURLE_OK; - return rc; -} - -void Curl_axtls_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - infof(conn->data, " Curl_axtls_close\n"); - - /* line from openssl.c: (void)SSL_shutdown(connssl->ssl); - axTLS compat layer does nothing for SSL_shutdown */ - - /* The following line is from openssl.c. There seems to be no axTLS - equivalent. ssl_free and ssl_ctx_free close things. - SSL_set_connect_state(connssl->handle); */ - - free_ssl_structs(connssl); -} - -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -int Curl_axtls_shutdown(struct connectdata *conn, int sockindex) -{ - /* Outline taken from openssl.c since functions are in axTLS compat layer. - axTLS's error set is much smaller, so a lot of error-handling was removed. - */ - int retval = 0; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - uint8_t *buf; - ssize_t nread; - - infof(conn->data, " Curl_axtls_shutdown\n"); - - /* This has only been tested on the proftpd server, and the mod_tls code - sends a close notify alert without waiting for a close notify alert in - response. Thus we wait for a close notify alert from the server, but - we do not send one. Let's hope other servers do the same... */ - - /* axTLS compat layer does nothing for SSL_shutdown, so we do nothing too - if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) - (void)SSL_shutdown(connssl->ssl); - */ - - if(connssl->ssl) { - int what = Curl_socket_ready(conn->sock[sockindex], - CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); - if(what > 0) { - /* Something to read, let's do it and hope that it is the close - notify alert from the server. buf is managed internally by - axTLS and will be released upon calling ssl_free via - free_ssl_structs. */ - nread = (ssize_t)ssl_read(connssl->ssl, &buf); - - if(nread < SSL_OK) { - failf(data, "close notify alert not received during shutdown"); - retval = -1; - } - } - else if(0 == what) { - /* timeout */ - failf(data, "SSL shutdown timeout"); - } - else { - /* anything that gets here is fatally bad */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - retval = -1; - } - - free_ssl_structs(connssl); - } - return retval; -} - -static ssize_t axtls_recv(struct connectdata *conn, /* connection data */ - int num, /* socketindex */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - CURLcode *err) -{ - struct ssl_connect_data *connssl = &conn->ssl[num]; - ssize_t ret = 0; - uint8_t *read_buf; - - infof(conn->data, " axtls_recv\n"); - - *err = CURLE_OK; - if(connssl) { - ret = ssl_read(connssl->ssl, &read_buf); - if(ret > SSL_OK) { - /* ssl_read returns SSL_OK if there is more data to read, so if it is - larger, then all data has been read already. */ - memcpy(buf, read_buf, - (size_t)ret > buffersize ? buffersize : (size_t)ret); - } - else if(ret == SSL_OK) { - /* more data to be read, signal caller to call again */ - *err = CURLE_AGAIN; - ret = -1; - } - else if(ret == -3) { - /* With patched axTLS, SSL_CLOSE_NOTIFY=-3. Hard-coding until axTLS - team approves proposed fix. */ - Curl_axtls_close(conn, num); - } - else { - failf(conn->data, "axTLS recv error (%d)", ret); - *err = map_error_to_curl((int) ret); - ret = -1; - } - } - - return ret; -} - -/* - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -int Curl_axtls_check_cxn(struct connectdata *conn) -{ - /* openssl.c line: rc = SSL_peek(conn->ssl[FIRSTSOCKET].ssl, (void*)&buf, 1); - axTLS compat layer always returns the last argument, so connection is - always alive? */ - - infof(conn->data, " Curl_axtls_check_cxn\n"); - return 1; /* connection still in place */ -} - -void Curl_axtls_session_free(void *ptr) -{ - (void)ptr; - /* free the ID */ - /* both openssl.c and gtls.c do something here, but axTLS's OpenSSL - compatibility layer does nothing, so we do nothing too. */ -} - -size_t Curl_axtls_version(char *buffer, size_t size) -{ - return snprintf(buffer, size, "axTLS/%s", ssl_version()); -} - -int Curl_axtls_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) -{ - static bool ssl_seeded = FALSE; - (void)data; - if(!ssl_seeded) { - ssl_seeded = TRUE; - /* Initialize the seed if not already done. This call is not exactly thread - * safe (and neither is the ssl_seeded check), but the worst effect of a - * race condition is that some global resources will leak. */ - RNG_initialize(); - } - get_random((int)length, entropy); - return 0; -} - -#endif /* USE_AXTLS */ diff --git a/Externals/curl/lib/vtls/axtls.h b/Externals/curl/lib/vtls/axtls.h deleted file mode 100644 index b9d441f1af..0000000000 --- a/Externals/curl/lib/vtls/axtls.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef HEADER_CURL_AXTLS_H -#define HEADER_CURL_AXTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010, DirecTV, Contact: Eric Hu - * Copyright (C) 2010 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifdef USE_AXTLS -#include "curl/curl.h" -#include "urldata.h" - -int Curl_axtls_init(void); -int Curl_axtls_cleanup(void); -CURLcode Curl_axtls_connect(struct connectdata *conn, int sockindex); -CURLcode Curl_axtls_connect_nonblocking( - struct connectdata *conn, - int sockindex, - bool *done); - - /* close a SSL connection */ -void Curl_axtls_close(struct connectdata *conn, int sockindex); - -void Curl_axtls_session_free(void *ptr); -size_t Curl_axtls_version(char *buffer, size_t size); -int Curl_axtls_shutdown(struct connectdata *conn, int sockindex); -int Curl_axtls_check_cxn(struct connectdata *conn); -int Curl_axtls_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length); - -/* Set the API backend definition to axTLS */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_AXTLS - -/* API setup for axTLS */ -#define curlssl_init Curl_axtls_init -#define curlssl_cleanup Curl_axtls_cleanup -#define curlssl_connect Curl_axtls_connect -#define curlssl_connect_nonblocking Curl_axtls_connect_nonblocking -#define curlssl_session_free(x) Curl_axtls_session_free(x) -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_axtls_close -#define curlssl_shutdown(x,y) Curl_axtls_shutdown(x,y) -#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) -#define curlssl_version Curl_axtls_version -#define curlssl_check_cxn(x) Curl_axtls_check_cxn(x) -#define curlssl_data_pending(x,y) ((void)x, (void)y, 0) -#define curlssl_random(x,y,z) Curl_axtls_random(x,y,z) - -#endif /* USE_AXTLS */ -#endif /* HEADER_CURL_AXTLS_H */ - diff --git a/Externals/curl/lib/vtls/cyassl.c b/Externals/curl/lib/vtls/cyassl.c deleted file mode 100644 index da737c7271..0000000000 --- a/Externals/curl/lib/vtls/cyassl.c +++ /dev/null @@ -1,902 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all CyaSSL-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ - -#include "curl_setup.h" - -#ifdef USE_CYASSL - -#define WOLFSSL_OPTIONS_IGNORE_SYS -/* CyaSSL's version.h, which should contain only the version, should come -before all other CyaSSL includes and be immediately followed by build config -aka options.h. https://curl.haxx.se/mail/lib-2015-04/0069.html */ -#include -#if defined(HAVE_CYASSL_OPTIONS_H) && (LIBCYASSL_VERSION_HEX > 0x03004008) -#if defined(CYASSL_API) || defined(WOLFSSL_API) -/* Safety measure. If either is defined some API include was already included -and that's a problem since options.h hasn't been included yet. */ -#error "CyaSSL API was included before the CyaSSL build options." -#endif -#include -#endif - -#ifdef HAVE_LIMITS_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "vtls.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "rawstr.h" -#include "x509asn1.h" -#include "curl_printf.h" - -#include -#ifdef HAVE_CYASSL_ERROR_SSL_H -#include -#else -#include -#endif -#include -#include - -#include "cyassl.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -#if LIBCYASSL_VERSION_HEX < 0x02007002 /* < 2.7.2 */ -#define CYASSL_MAX_ERROR_SZ 80 -#endif - -/* To determine what functions are available we rely on one or both of: - - the user's options.h generated by CyaSSL/wolfSSL - - the symbols detected by curl's configure - Since they are markedly different from one another, and one or the other may - not be available, we do some checking below to bring things in sync. */ - -/* HAVE_ALPN is wolfSSL's build time symbol for enabling ALPN in options.h. */ -#ifndef HAVE_ALPN -#ifdef HAVE_WOLFSSL_USEALPN -#define HAVE_ALPN -#endif -#endif - -/* WOLFSSL_ALLOW_SSLV3 is wolfSSL's build time symbol for enabling SSLv3 in - options.h, but is only seen in >= 3.6.6 since that's when they started - disabling SSLv3 by default. */ -#ifndef WOLFSSL_ALLOW_SSLV3 -#if (LIBCYASSL_VERSION_HEX < 0x03006006) || \ - defined(HAVE_WOLFSSLV3_CLIENT_METHOD) -#define WOLFSSL_ALLOW_SSLV3 -#endif -#endif - -/* HAVE_SUPPORTED_CURVES is wolfSSL's build time symbol for enabling the ECC - supported curve extension in options.h. Note ECC is enabled separately. */ -#ifndef HAVE_SUPPORTED_CURVES -#if defined(HAVE_CYASSL_CTX_USESUPPORTEDCURVE) || \ - defined(HAVE_WOLFSSL_CTX_USESUPPORTEDCURVE) -#define HAVE_SUPPORTED_CURVES -#endif -#endif - -static Curl_recv cyassl_recv; -static Curl_send cyassl_send; - - -static int do_file_type(const char *type) -{ - if(!type || !type[0]) - return SSL_FILETYPE_PEM; - if(Curl_raw_equal(type, "PEM")) - return SSL_FILETYPE_PEM; - if(Curl_raw_equal(type, "DER")) - return SSL_FILETYPE_ASN1; - return -1; -} - -/* - * This function loads all the client/CA certificates and CRLs. Setup the TLS - * layer and do all necessary magic. - */ -static CURLcode -cyassl_connect_step1(struct connectdata *conn, - int sockindex) -{ - char error_buffer[CYASSL_MAX_ERROR_SZ]; - struct SessionHandle *data = conn->data; - struct ssl_connect_data* conssl = &conn->ssl[sockindex]; - SSL_METHOD* req_method = NULL; - void* ssl_sessionid = NULL; - curl_socket_t sockfd = conn->sock[sockindex]; -#ifdef HAVE_SNI - bool sni = FALSE; -#define use_sni(x) sni = (x) -#else -#define use_sni(x) Curl_nop_stmt -#endif - - if(conssl->state == ssl_connection_complete) - return CURLE_OK; - - /* check to see if we've been told to use an explicit SSL/TLS version */ - switch(data->set.ssl.version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: -#if LIBCYASSL_VERSION_HEX >= 0x03003000 /* >= 3.3.0 */ - /* minimum protocol version is set later after the CTX object is created */ - req_method = SSLv23_client_method(); -#else - infof(data, "CyaSSL <3.3.0 cannot be configured to use TLS 1.0-1.2, " - "TLS 1.0 is used exclusively\n"); - req_method = TLSv1_client_method(); -#endif - use_sni(TRUE); - break; - case CURL_SSLVERSION_TLSv1_0: - req_method = TLSv1_client_method(); - use_sni(TRUE); - break; - case CURL_SSLVERSION_TLSv1_1: - req_method = TLSv1_1_client_method(); - use_sni(TRUE); - break; - case CURL_SSLVERSION_TLSv1_2: - req_method = TLSv1_2_client_method(); - use_sni(TRUE); - break; - case CURL_SSLVERSION_SSLv3: -#ifdef WOLFSSL_ALLOW_SSLV3 - req_method = SSLv3_client_method(); - use_sni(FALSE); -#else - failf(data, "No support for SSLv3"); - return CURLE_NOT_BUILT_IN; -#endif - break; - case CURL_SSLVERSION_SSLv2: - failf(data, "CyaSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(!req_method) { - failf(data, "SSL: couldn't create a method!"); - return CURLE_OUT_OF_MEMORY; - } - - if(conssl->ctx) - SSL_CTX_free(conssl->ctx); - conssl->ctx = SSL_CTX_new(req_method); - - if(!conssl->ctx) { - failf(data, "SSL: couldn't create a context!"); - return CURLE_OUT_OF_MEMORY; - } - - switch(data->set.ssl.version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: -#if LIBCYASSL_VERSION_HEX > 0x03004006 /* > 3.4.6 */ - /* Versions 3.3.0 to 3.4.6 we know the minimum protocol version is whatever - minimum version of TLS was built in and at least TLS 1.0. For later library - versions that could change (eg TLS 1.0 built in but defaults to TLS 1.1) so - we have this short circuit evaluation to find the minimum supported TLS - version. We use wolfSSL_CTX_SetMinVersion and not CyaSSL_SetMinVersion - because only the former will work before the user's CTX callback is called. - */ - if((wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1) != 1) && - (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_1) != 1) && - (wolfSSL_CTX_SetMinVersion(conssl->ctx, WOLFSSL_TLSV1_2) != 1)) { - failf(data, "SSL: couldn't set the minimum protocol version"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif - break; - } - -#ifndef NO_FILESYSTEM - /* load trusted cacert */ - if(data->set.str[STRING_SSL_CAFILE]) { - if(1 != SSL_CTX_load_verify_locations(conssl->ctx, - data->set.str[STRING_SSL_CAFILE], - data->set.str[STRING_SSL_CAPATH])) { - if(data->set.ssl.verifypeer) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate verify locations:\n" - " CAfile: %s\n CApath: %s", - data->set.str[STRING_SSL_CAFILE]? - data->set.str[STRING_SSL_CAFILE]: "none", - data->set.str[STRING_SSL_CAPATH]? - data->set.str[STRING_SSL_CAPATH] : "none"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - /* Just continue with a warning if no strict certificate - verification is required. */ - infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); - } - } - else { - /* Everything is fine. */ - infof(data, "successfully set certificate verify locations:\n"); - } - infof(data, - " CAfile: %s\n" - " CApath: %s\n", - data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]: - "none", - data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]: - "none"); - } - - /* Load the client certificate, and private key */ - if(data->set.str[STRING_CERT] && data->set.str[STRING_KEY]) { - int file_type = do_file_type(data->set.str[STRING_CERT_TYPE]); - - if(SSL_CTX_use_certificate_file(conssl->ctx, data->set.str[STRING_CERT], - file_type) != 1) { - failf(data, "unable to use client certificate (no key or wrong pass" - " phrase?)"); - return CURLE_SSL_CONNECT_ERROR; - } - - file_type = do_file_type(data->set.str[STRING_KEY_TYPE]); - if(SSL_CTX_use_PrivateKey_file(conssl->ctx, data->set.str[STRING_KEY], - file_type) != 1) { - failf(data, "unable to set private key"); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* !NO_FILESYSTEM */ - - /* SSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ - SSL_CTX_set_verify(conssl->ctx, - data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE, - NULL); - -#ifdef HAVE_SNI - if(sni) { - struct in_addr addr4; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif - size_t hostname_len = strlen(conn->host.name); - if((hostname_len < USHRT_MAX) && - (0 == Curl_inet_pton(AF_INET, conn->host.name, &addr4)) && -#ifdef ENABLE_IPV6 - (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr6)) && -#endif - (CyaSSL_CTX_UseSNI(conssl->ctx, CYASSL_SNI_HOST_NAME, conn->host.name, - (unsigned short)hostname_len) != 1)) { - infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension\n"); - } - } -#endif - -#ifdef HAVE_SUPPORTED_CURVES - /* CyaSSL/wolfSSL does not send the supported ECC curves ext automatically: - https://github.com/wolfSSL/wolfssl/issues/366 - The supported curves below are those also supported by OpenSSL 1.0.2 and - in the same order. */ - CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x17); /* secp256r1 */ - CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x19); /* secp521r1 */ - CyaSSL_CTX_UseSupportedCurve(conssl->ctx, 0x18); /* secp384r1 */ -#endif - - /* give application a chance to interfere with SSL set up. */ - if(data->set.ssl.fsslctx) { - CURLcode result = CURLE_OK; - result = (*data->set.ssl.fsslctx)(data, conssl->ctx, - data->set.ssl.fsslctxp); - if(result) { - failf(data, "error signaled by ssl ctx callback"); - return result; - } - } -#ifdef NO_FILESYSTEM - else if(data->set.ssl.verifypeer) { - failf(data, "SSL: Certificates couldn't be loaded because CyaSSL was built" - " with \"no filesystem\". Either disable peer verification" - " (insecure) or if you are building an application with libcurl you" - " can load certificates via CURLOPT_SSL_CTX_FUNCTION."); - return CURLE_SSL_CONNECT_ERROR; - } -#endif - - /* Let's make an SSL structure */ - if(conssl->handle) - SSL_free(conssl->handle); - conssl->handle = SSL_new(conssl->ctx); - if(!conssl->handle) { - failf(data, "SSL: couldn't create a context (handle)!"); - return CURLE_OUT_OF_MEMORY; - } - -#ifdef HAVE_ALPN - if(conn->bits.tls_enable_alpn) { - char protocols[128]; - *protocols = '\0'; - - /* wolfSSL's ALPN protocol name list format is a comma separated string of - protocols in descending order of preference, eg: "h2,http/1.1" */ - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ","); - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - strcpy(protocols + strlen(protocols), ALPN_HTTP_1_1); - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - if(wolfSSL_UseALPN(conssl->handle, protocols, - (unsigned)strlen(protocols), - WOLFSSL_ALPN_CONTINUE_ON_MISMATCH) != SSL_SUCCESS) { - failf(data, "SSL: failed setting ALPN protocols"); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* HAVE_ALPN */ - - /* Check if there's a cached ID we can/should use here! */ - if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { - /* we got a session id, use it! */ - if(!SSL_set_session(conssl->handle, ssl_sessionid)) { - failf(data, "SSL: SSL_set_session failed: %s", - ERR_error_string(SSL_get_error(conssl->handle, 0), error_buffer)); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - infof (data, "SSL re-using session ID\n"); - } - - /* pass the raw socket into the SSL layer */ - if(!SSL_set_fd(conssl->handle, (int)sockfd)) { - failf(data, "SSL: SSL_set_fd failed"); - return CURLE_SSL_CONNECT_ERROR; - } - - conssl->connecting_state = ssl_connect_2; - return CURLE_OK; -} - - -static CURLcode -cyassl_connect_step2(struct connectdata *conn, - int sockindex) -{ - int ret = -1; - struct SessionHandle *data = conn->data; - struct ssl_connect_data* conssl = &conn->ssl[sockindex]; - - conn->recv[sockindex] = cyassl_recv; - conn->send[sockindex] = cyassl_send; - - /* Enable RFC2818 checks */ - if(data->set.ssl.verifyhost) { - ret = CyaSSL_check_domain_name(conssl->handle, conn->host.name); - if(ret == SSL_FAILURE) - return CURLE_OUT_OF_MEMORY; - } - - ret = SSL_connect(conssl->handle); - if(ret != 1) { - char error_buffer[CYASSL_MAX_ERROR_SZ]; - int detail = SSL_get_error(conssl->handle, ret); - - if(SSL_ERROR_WANT_READ == detail) { - conssl->connecting_state = ssl_connect_2_reading; - return CURLE_OK; - } - else if(SSL_ERROR_WANT_WRITE == detail) { - conssl->connecting_state = ssl_connect_2_writing; - return CURLE_OK; - } - /* There is no easy way to override only the CN matching. - * This will enable the override of both mismatching SubjectAltNames - * as also mismatching CN fields */ - else if(DOMAIN_NAME_MISMATCH == detail) { -#if 1 - failf(data, "\tsubject alt name(s) or common name do not match \"%s\"\n", - conn->host.dispname); - return CURLE_PEER_FAILED_VERIFICATION; -#else - /* When the CyaSSL_check_domain_name() is used and you desire to continue - * on a DOMAIN_NAME_MISMATCH, i.e. 'data->set.ssl.verifyhost == 0', - * CyaSSL version 2.4.0 will fail with an INCOMPLETE_DATA error. The only - * way to do this is currently to switch the CyaSSL_check_domain_name() - * in and out based on the 'data->set.ssl.verifyhost' value. */ - if(data->set.ssl.verifyhost) { - failf(data, - "\tsubject alt name(s) or common name do not match \"%s\"\n", - conn->host.dispname); - return CURLE_PEER_FAILED_VERIFICATION; - } - else { - infof(data, - "\tsubject alt name(s) and/or common name do not match \"%s\"\n", - conn->host.dispname); - return CURLE_OK; - } -#endif - } -#if LIBCYASSL_VERSION_HEX >= 0x02007000 /* 2.7.0 */ - else if(ASN_NO_SIGNER_E == detail) { - if(data->set.ssl.verifypeer) { - failf(data, "\tCA signer not available for verification\n"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - /* Just continue with a warning if no strict certificate - verification is required. */ - infof(data, "CA signer not available for verification, " - "continuing anyway\n"); - } - } -#endif - else { - failf(data, "SSL_connect failed with error %d: %s", detail, - ERR_error_string(detail, error_buffer)); - return CURLE_SSL_CONNECT_ERROR; - } - } - - if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { -#ifdef KEEP_PEER_CERT - X509 *x509; - const char *x509_der; - int x509_der_len; - curl_X509certificate x509_parsed; - curl_asn1Element *pubkey; - CURLcode result; - - x509 = SSL_get_peer_certificate(conssl->handle); - if(!x509) { - failf(data, "SSL: failed retrieving server certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - x509_der = (const char *)CyaSSL_X509_get_der(x509, &x509_der_len); - if(!x509_der) { - failf(data, "SSL: failed retrieving ASN.1 server certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - memset(&x509_parsed, 0, sizeof x509_parsed); - Curl_parseX509(&x509_parsed, x509_der, x509_der + x509_der_len); - - pubkey = &x509_parsed.subjectPublicKeyInfo; - if(!pubkey->header || pubkey->end <= pubkey->header) { - failf(data, "SSL: failed retrieving public key from server certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - result = Curl_pin_peer_pubkey(data, - data->set.str[STRING_SSL_PINNEDPUBLICKEY], - (const unsigned char *)pubkey->header, - (size_t)(pubkey->end - pubkey->header)); - if(result) { - failf(data, "SSL: public key does not match pinned public key!"); - return result; - } -#else - failf(data, "Library lacks pinning support built-in"); - return CURLE_NOT_BUILT_IN; -#endif - } - -#ifdef HAVE_ALPN - if(conn->bits.tls_enable_alpn) { - int rc; - char *protocol = NULL; - unsigned short protocol_len = 0; - - rc = wolfSSL_ALPN_GetProtocol(conssl->handle, &protocol, &protocol_len); - - if(rc == SSL_SUCCESS) { - infof(data, "ALPN, server accepted to use %.*s\n", protocol_len, - protocol); - - if(protocol_len == ALPN_HTTP_1_1_LENGTH && - !memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) - conn->negnpn = CURL_HTTP_VERSION_1_1; -#ifdef USE_NGHTTP2 - else if(data->set.httpversion >= CURL_HTTP_VERSION_2 && - protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(protocol, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) - conn->negnpn = CURL_HTTP_VERSION_2; -#endif - else - infof(data, "ALPN, unrecognized protocol %.*s\n", protocol_len, - protocol); - } - else if(rc == SSL_ALPN_NOT_FOUND) - infof(data, "ALPN, server did not agree to a protocol\n"); - else { - failf(data, "ALPN, failure getting protocol, error %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif /* HAVE_ALPN */ - - conssl->connecting_state = ssl_connect_3; - infof(data, "SSL connected\n"); - - return CURLE_OK; -} - - -static CURLcode -cyassl_connect_step3(struct connectdata *conn, - int sockindex) -{ - CURLcode result = CURLE_OK; - void *old_ssl_sessionid=NULL; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - bool incache; - SSL_SESSION *our_ssl_sessionid; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - our_ssl_sessionid = SSL_get_session(connssl->handle); - - incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)); - if(incache) { - if(old_ssl_sessionid != our_ssl_sessionid) { - infof(data, "old SSL session ID is stale, removing\n"); - Curl_ssl_delsessionid(conn, old_ssl_sessionid); - incache = FALSE; - } - } - - if(!incache) { - result = Curl_ssl_addsessionid(conn, our_ssl_sessionid, - 0 /* unknown size */); - if(result) { - failf(data, "failed to store ssl session"); - return result; - } - } - - connssl->connecting_state = ssl_connect_done; - - return result; -} - - -static ssize_t cyassl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - char error_buffer[CYASSL_MAX_ERROR_SZ]; - int memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; - int rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen); - - if(rc < 0) { - int err = SSL_get_error(conn->ssl[sockindex].handle, rc); - - switch(err) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* there's data pending, re-invoke SSL_write() */ - *curlcode = CURLE_AGAIN; - return -1; - default: - failf(conn->data, "SSL write: %s, errno %d", - ERR_error_string(err, error_buffer), - SOCKERRNO); - *curlcode = CURLE_SEND_ERROR; - return -1; - } - } - return rc; -} - -void Curl_cyassl_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *conssl = &conn->ssl[sockindex]; - - if(conssl->handle) { - (void)SSL_shutdown(conssl->handle); - SSL_free (conssl->handle); - conssl->handle = NULL; - } - if(conssl->ctx) { - SSL_CTX_free (conssl->ctx); - conssl->ctx = NULL; - } -} - -static ssize_t cyassl_recv(struct connectdata *conn, - int num, - char *buf, - size_t buffersize, - CURLcode *curlcode) -{ - char error_buffer[CYASSL_MAX_ERROR_SZ]; - int buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; - int nread = SSL_read(conn->ssl[num].handle, buf, buffsize); - - if(nread < 0) { - int err = SSL_get_error(conn->ssl[num].handle, nread); - - switch(err) { - case SSL_ERROR_ZERO_RETURN: /* no more data */ - break; - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* there's data pending, re-invoke SSL_read() */ - *curlcode = CURLE_AGAIN; - return -1; - default: - failf(conn->data, "SSL read: %s, errno %d", - ERR_error_string(err, error_buffer), - SOCKERRNO); - *curlcode = CURLE_RECV_ERROR; - return -1; - } - } - return nread; -} - - -void Curl_cyassl_session_free(void *ptr) -{ - (void)ptr; - /* CyaSSL reuses sessions on own, no free */ -} - - -size_t Curl_cyassl_version(char *buffer, size_t size) -{ -#ifdef WOLFSSL_VERSION - return snprintf(buffer, size, "wolfSSL/%s", WOLFSSL_VERSION); -#elif defined(CYASSL_VERSION) - return snprintf(buffer, size, "CyaSSL/%s", CYASSL_VERSION); -#else - return snprintf(buffer, size, "CyaSSL/%s", "<1.8.8"); -#endif -} - - -int Curl_cyassl_init(void) -{ - return (CyaSSL_Init() == SSL_SUCCESS); -} - - -bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex) -{ - if(conn->ssl[connindex].handle) /* SSL is in use */ - return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE; - else - return FALSE; -} - - -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex) -{ - int retval = 0; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - if(connssl->handle) { - SSL_free (connssl->handle); - connssl->handle = NULL; - } - return retval; -} - - -static CURLcode -cyassl_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - long timeout_ms; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1==connssl->connecting_state) { - /* Find out how much more time we're allowed */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - result = cyassl_connect_step1(conn, sockindex); - if(result) - return result; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading - || connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if - * this connection is part of a multi handle and this loop would - * execute again. This permits the owner of a multi handle to - * abort a connection attempt before step2 has completed while - * ensuring that a client using select() or epoll() will always - * have a valid fdset to wait on. - */ - result = cyassl_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - } /* repeat step2 until all transactions are done. */ - - if(ssl_connect_3 == connssl->connecting_state) { - result = cyassl_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = cyassl_recv; - conn->send[sockindex] = cyassl_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - - -CURLcode -Curl_cyassl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done) -{ - return cyassl_connect_common(conn, sockindex, TRUE, done); -} - - -CURLcode -Curl_cyassl_connect(struct connectdata *conn, - int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = cyassl_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -int Curl_cyassl_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) -{ - RNG rng; - (void)data; - if(InitRng(&rng)) - return 1; - if(length > UINT_MAX) - return 1; - if(RNG_GenerateBlock(&rng, entropy, (unsigned)length)) - return 1; - return 0; -} - -void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum /* output */, - size_t unused) -{ - Sha256 SHA256pw; - (void)unused; - InitSha256(&SHA256pw); - Sha256Update(&SHA256pw, tmp, (word32)tmplen); - Sha256Final(&SHA256pw, sha256sum); -} - -#endif diff --git a/Externals/curl/lib/vtls/cyassl.h b/Externals/curl/lib/vtls/cyassl.h deleted file mode 100644 index 1106125550..0000000000 --- a/Externals/curl/lib/vtls/cyassl.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef HEADER_CURL_CYASSL_H -#define HEADER_CURL_CYASSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_CYASSL - -/* KEEP_PEER_CERT is a product of the presence of build time symbol - OPENSSL_EXTRA without NO_CERTS, depending on the version. KEEP_PEER_CERT is - in wolfSSL's settings.h, and the latter two are build time symbols in - options.h. */ -#ifndef KEEP_PEER_CERT -#if defined(HAVE_CYASSL_GET_PEER_CERTIFICATE) || \ - defined(HAVE_WOLFSSL_GET_PEER_CERTIFICATE) || \ - (defined(OPENSSL_EXTRA) && !defined(NO_CERTS)) -#define KEEP_PEER_CERT -#endif -#endif - -CURLcode Curl_cyassl_connect(struct connectdata *conn, int sockindex); -bool Curl_cyassl_data_pending(const struct connectdata* conn, int connindex); -int Curl_cyassl_shutdown(struct connectdata* conn, int sockindex); - - /* close a SSL connection */ -void Curl_cyassl_close(struct connectdata *conn, int sockindex); - -void Curl_cyassl_session_free(void *ptr); -size_t Curl_cyassl_version(char *buffer, size_t size); -int Curl_cyassl_shutdown(struct connectdata *conn, int sockindex); -int Curl_cyassl_init(void); -CURLcode Curl_cyassl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); -int Curl_cyassl_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length); -void Curl_cyassl_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t unused); - -/* Set the API backend definition to Schannel */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_CYASSL - -/* this backend supports CURLOPT_SSL_CTX_* */ -#define have_curlssl_ssl_ctx 1 - -#ifdef KEEP_PEER_CERT -/* this backend supports CURLOPT_PINNEDPUBLICKEY */ -#define have_curlssl_pinnedpubkey 1 -#endif - -/* API setup for CyaSSL */ -#define curlssl_init Curl_cyassl_init -#define curlssl_cleanup() Curl_nop_stmt -#define curlssl_connect Curl_cyassl_connect -#define curlssl_connect_nonblocking Curl_cyassl_connect_nonblocking -#define curlssl_session_free(x) Curl_cyassl_session_free(x) -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_cyassl_close -#define curlssl_shutdown(x,y) Curl_cyassl_shutdown(x,y) -#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) -#define curlssl_version Curl_cyassl_version -#define curlssl_check_cxn(x) ((void)x, -1) -#define curlssl_data_pending(x,y) Curl_cyassl_data_pending(x,y) -#define curlssl_random(x,y,z) Curl_cyassl_random(x,y,z) -#define curlssl_sha256sum(a,b,c,d) Curl_cyassl_sha256sum(a,b,c,d) - -#endif /* USE_CYASSL */ -#endif /* HEADER_CURL_CYASSL_H */ diff --git a/Externals/curl/lib/vtls/darwinssl.c b/Externals/curl/lib/vtls/darwinssl.c deleted file mode 100644 index 71d379b902..0000000000 --- a/Externals/curl/lib/vtls/darwinssl.c +++ /dev/null @@ -1,2490 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2014, Nick Zitzmann, . - * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all iOS and Mac OS X SecureTransport-specific code for the - * TLS/SSL layer. No code but vtls.c should ever call or use these functions. - */ - -#include "curl_setup.h" - -#include "urldata.h" /* for the SessionHandle definition */ -#include "curl_base64.h" -#include "strtok.h" - -#ifdef USE_DARWINSSL - -#ifdef HAVE_LIMITS_H -#include -#endif - -#include -#include -#include -#include - -/* The Security framework has changed greatly between iOS and different OS X - versions, and we will try to support as many of them as we can (back to - Leopard and iOS 5) by using macros and weak-linking. - - IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then - you must build this project against the 10.8 SDK or later. */ -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -#error "The darwinssl back-end requires Leopard or later." -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */ - -#define CURL_BUILD_IOS 0 -#define CURL_BUILD_IOS_7 0 -#define CURL_BUILD_MAC 1 -/* This is the maximum API level we are allowed to use when building: */ -#define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 -#define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 -#define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 -#define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 -#define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090 -/* These macros mean "the following code is present to allow runtime backward - compatibility with at least this cat or earlier": - (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET - environmental variable.) */ -#define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050 -#define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060 -#define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 -#define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080 -#define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090 - -#elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE -#define CURL_BUILD_IOS 1 -#define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 -#define CURL_BUILD_MAC 0 -#define CURL_BUILD_MAC_10_5 0 -#define CURL_BUILD_MAC_10_6 0 -#define CURL_BUILD_MAC_10_7 0 -#define CURL_BUILD_MAC_10_8 0 -#define CURL_SUPPORT_MAC_10_5 0 -#define CURL_SUPPORT_MAC_10_6 0 -#define CURL_SUPPORT_MAC_10_7 0 -#define CURL_SUPPORT_MAC_10_8 0 -#define CURL_SUPPORT_MAC_10_9 0 - -#else -#error "The darwinssl back-end requires iOS or OS X." -#endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */ - -#if CURL_BUILD_MAC -#include -#endif /* CURL_BUILD_MAC */ - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "connect.h" -#include "select.h" -#include "vtls.h" -#include "darwinssl.h" -#include "curl_printf.h" - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* From MacTypes.h (which we can't include because it isn't present in iOS: */ -#define ioErr -36 -#define paramErr -50 - -/* The following two functions were ripped from Apple sample code, - * with some modifications: */ -static OSStatus SocketRead(SSLConnectionRef connection, - void *data, /* owned by - * caller, data - * RETURNED */ - size_t *dataLength) /* IN/OUT */ -{ - size_t bytesToGo = *dataLength; - size_t initLen = bytesToGo; - UInt8 *currData = (UInt8 *)data; - /*int sock = *(int *)connection;*/ - struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; - int sock = connssl->ssl_sockfd; - OSStatus rtn = noErr; - size_t bytesRead; - ssize_t rrtn; - int theErr; - - *dataLength = 0; - - for(;;) { - bytesRead = 0; - rrtn = read(sock, currData, bytesToGo); - if(rrtn <= 0) { - /* this is guesswork... */ - theErr = errno; - if(rrtn == 0) { /* EOF = server hung up */ - /* the framework will turn this into errSSLClosedNoNotify */ - rtn = errSSLClosedGraceful; - } - else /* do the switch */ - switch(theErr) { - case ENOENT: - /* connection closed */ - rtn = errSSLClosedGraceful; - break; - case ECONNRESET: - rtn = errSSLClosedAbort; - break; - case EAGAIN: - rtn = errSSLWouldBlock; - connssl->ssl_direction = false; - break; - default: - rtn = ioErr; - break; - } - break; - } - else { - bytesRead = rrtn; - } - bytesToGo -= bytesRead; - currData += bytesRead; - - if(bytesToGo == 0) { - /* filled buffer with incoming data, done */ - break; - } - } - *dataLength = initLen - bytesToGo; - - return rtn; -} - -static OSStatus SocketWrite(SSLConnectionRef connection, - const void *data, - size_t *dataLength) /* IN/OUT */ -{ - size_t bytesSent = 0; - /*int sock = *(int *)connection;*/ - struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection; - int sock = connssl->ssl_sockfd; - ssize_t length; - size_t dataLen = *dataLength; - const UInt8 *dataPtr = (UInt8 *)data; - OSStatus ortn; - int theErr; - - *dataLength = 0; - - do { - length = write(sock, - (char*)dataPtr + bytesSent, - dataLen - bytesSent); - } while((length > 0) && - ( (bytesSent += length) < dataLen) ); - - if(length <= 0) { - theErr = errno; - if(theErr == EAGAIN) { - ortn = errSSLWouldBlock; - connssl->ssl_direction = true; - } - else { - ortn = ioErr; - } - } - else { - ortn = noErr; - } - *dataLength = bytesSent; - return ortn; -} - -CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher) { - switch (cipher) { - /* SSL version 3.0 */ - case SSL_RSA_WITH_NULL_MD5: - return "SSL_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "SSL_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "SSL_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "SSL_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_SHA: - return "SSL_RSA_WITH_IDEA_CBC_SHA"; - break; - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_RSA_WITH_DES_CBC_SHA: - return "SSL_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_DES_CBC_SHA: - return "SSL_DH_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_DES_CBC_SHA: - return "SSL_DH_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - return "SSL_DHE_DSS_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - return "SSL_DHE_RSA_WITH_DES_CBC_SHA"; - break; - case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "SSL_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; - break; - case SSL_DH_anon_WITH_DES_CBC_SHA: - return "SSL_DH_anon_WITH_DES_CBC_SHA"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; - break; - case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA: - return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; - break; - /* TLS 1.0 with AES (RFC 3268) - (Apparently these are used in SSLv3 implementations as well.) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; - /* SSL version 2.0 */ - case SSL_RSA_WITH_RC2_CBC_MD5: - return "SSL_RSA_WITH_RC2_CBC_MD5"; - break; - case SSL_RSA_WITH_IDEA_CBC_MD5: - return "SSL_RSA_WITH_IDEA_CBC_MD5"; - break; - case SSL_RSA_WITH_DES_CBC_MD5: - return "SSL_RSA_WITH_DES_CBC_MD5"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_MD5: - return "SSL_RSA_WITH_3DES_EDE_CBC_MD5"; - break; - } - return "SSL_NULL_WITH_NULL_NULL"; -} - -CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher) { - switch(cipher) { - /* TLS 1.0 with AES (RFC 3268) */ - case TLS_RSA_WITH_AES_128_CBC_SHA: - return "TLS_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA: - return "TLS_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - break; -#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS - /* TLS 1.0 with ECDSA (RFC 4492) */ - case TLS_ECDH_ECDSA_WITH_NULL_SHA: - return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_NULL_SHA: - return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_NULL_SHA: - return "TLS_ECDH_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDH_RSA_WITH_RC4_128_SHA: - return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_NULL_SHA: - return "TLS_ECDHE_RSA_WITH_NULL_SHA"; - break; - case TLS_ECDHE_RSA_WITH_RC4_128_SHA: - return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; - break; - case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_NULL_SHA: - return "TLS_ECDH_anon_WITH_NULL_SHA"; - break; - case TLS_ECDH_anon_WITH_RC4_128_SHA: - return "TLS_ECDH_anon_WITH_RC4_128_SHA"; - break; - case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; - break; - case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: - return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - /* TLS 1.2 (RFC 5246) */ - case TLS_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case TLS_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case TLS_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case TLS_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case TLS_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_WITH_NULL_SHA256: - return "TLS_RSA_WITH_NULL_SHA256"; - break; - case TLS_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: - return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DH_anon_WITH_AES_128_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_CBC_SHA256: - return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; - break; - /* TLS 1.2 with AES GCM (RFC 5288) */ - case TLS_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: - return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: - return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DH_anon_WITH_AES_128_GCM_SHA256: - return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DH_anon_WITH_AES_256_GCM_SHA384: - return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; - break; - /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */ - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: - return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; - break; - case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: - return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; - break; - case TLS_EMPTY_RENEGOTIATION_INFO_SCSV: - return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"; - break; -#else - case SSL_RSA_WITH_NULL_MD5: - return "TLS_RSA_WITH_NULL_MD5"; - break; - case SSL_RSA_WITH_NULL_SHA: - return "TLS_RSA_WITH_NULL_SHA"; - break; - case SSL_RSA_WITH_RC4_128_MD5: - return "TLS_RSA_WITH_RC4_128_MD5"; - break; - case SSL_RSA_WITH_RC4_128_SHA: - return "TLS_RSA_WITH_RC4_128_SHA"; - break; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - break; - case SSL_DH_anon_WITH_RC4_128_MD5: - return "TLS_DH_anon_WITH_RC4_128_MD5"; - break; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - break; -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - /* TLS PSK (RFC 4279): */ - case TLS_PSK_WITH_RC4_128_SHA: - return "TLS_PSK_WITH_RC4_128_SHA"; - break; - case TLS_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA: - return "TLS_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA: - return "TLS_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_RC4_128_SHA: - return "TLS_DHE_PSK_WITH_RC4_128_SHA"; - break; - case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_RC4_128_SHA: - return "TLS_RSA_PSK_WITH_RC4_128_SHA"; - break; - case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA: - return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"; - break; - /* More TLS PSK (RFC 4785): */ - case TLS_PSK_WITH_NULL_SHA: - return "TLS_PSK_WITH_NULL_SHA"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA: - return "TLS_DHE_PSK_WITH_NULL_SHA"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA: - return "TLS_RSA_PSK_WITH_NULL_SHA"; - break; - /* Even more TLS PSK (RFC 5487): */ - case TLS_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384: - return "TLS_PSK_WITH_AES_256_GCM_SHA384"; - break; - case TLS_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_PSK_WITH_NULL_SHA256: - return "TLS_PSK_WITH_NULL_SHA256"; - break; - case TLS_PSK_WITH_NULL_SHA384: - return "TLS_PSK_WITH_NULL_SHA384"; - break; - case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA256: - return "TLS_DHE_PSK_WITH_NULL_SHA256"; - break; - case TLS_DHE_PSK_WITH_NULL_SHA384: - return "TLS_RSA_PSK_WITH_NULL_SHA384"; - break; - case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256: - return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"; - break; - case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384: - return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA256: - return "TLS_RSA_PSK_WITH_NULL_SHA256"; - break; - case TLS_RSA_PSK_WITH_NULL_SHA384: - return "TLS_RSA_PSK_WITH_NULL_SHA384"; - break; -#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ - } - return "TLS_NULL_WITH_NULL_NULL"; -} - -#if CURL_BUILD_MAC -CF_INLINE void GetDarwinVersionNumber(int *major, int *minor) -{ - int mib[2]; - char *os_version; - size_t os_version_len; - char *os_version_major, *os_version_minor; - char *tok_buf; - - /* Get the Darwin kernel version from the kernel using sysctl(): */ - mib[0] = CTL_KERN; - mib[1] = KERN_OSRELEASE; - if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1) - return; - os_version = malloc(os_version_len*sizeof(char)); - if(!os_version) - return; - if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) { - free(os_version); - return; - } - - /* Parse the version: */ - os_version_major = strtok_r(os_version, ".", &tok_buf); - os_version_minor = strtok_r(NULL, ".", &tok_buf); - *major = atoi(os_version_major); - *minor = atoi(os_version_minor); - free(os_version); -} -#endif /* CURL_BUILD_MAC */ - -/* Apple provides a myriad of ways of getting information about a certificate - into a string. Some aren't available under iOS or newer cats. So here's - a unified function for getting a string describing the certificate that - ought to work in all cats starting with Leopard. */ -CF_INLINE CFStringRef CopyCertSubject(SecCertificateRef cert) -{ - CFStringRef server_cert_summary = CFSTR("(null)"); - -#if CURL_BUILD_IOS - /* iOS: There's only one way to do this. */ - server_cert_summary = SecCertificateCopySubjectSummary(cert); -#else -#if CURL_BUILD_MAC_10_7 - /* Lion & later: Get the long description if we can. */ - if(SecCertificateCopyLongDescription != NULL) - server_cert_summary = - SecCertificateCopyLongDescription(NULL, cert, NULL); - else -#endif /* CURL_BUILD_MAC_10_7 */ -#if CURL_BUILD_MAC_10_6 - /* Snow Leopard: Get the certificate summary. */ - if(SecCertificateCopySubjectSummary != NULL) - server_cert_summary = SecCertificateCopySubjectSummary(cert); - else -#endif /* CURL_BUILD_MAC_10_6 */ - /* Leopard is as far back as we go... */ - (void)SecCertificateCopyCommonName(cert, &server_cert_summary); -#endif /* CURL_BUILD_IOS */ - return server_cert_summary; -} - -#if CURL_SUPPORT_MAC_10_6 -/* The SecKeychainSearch API was deprecated in Lion, and using it will raise - deprecation warnings, so let's not compile this unless it's necessary: */ -static OSStatus CopyIdentityWithLabelOldSchool(char *label, - SecIdentityRef *out_c_a_k) -{ - OSStatus status = errSecItemNotFound; - SecKeychainAttributeList attr_list; - SecKeychainAttribute attr; - SecKeychainSearchRef search = NULL; - SecCertificateRef cert = NULL; - - /* Set up the attribute list: */ - attr_list.count = 1L; - attr_list.attr = &attr; - - /* Set up our lone search criterion: */ - attr.tag = kSecLabelItemAttr; - attr.data = label; - attr.length = (UInt32)strlen(label); - - /* Start searching: */ - status = SecKeychainSearchCreateFromAttributes(NULL, - kSecCertificateItemClass, - &attr_list, - &search); - if(status == noErr) { - status = SecKeychainSearchCopyNext(search, - (SecKeychainItemRef *)&cert); - if(status == noErr && cert) { - /* If we found a certificate, does it have a private key? */ - status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k); - CFRelease(cert); - } - } - - if(search) - CFRelease(search); - return status; -} -#endif /* CURL_SUPPORT_MAC_10_6 */ - -static OSStatus CopyIdentityWithLabel(char *label, - SecIdentityRef *out_cert_and_key) -{ - OSStatus status = errSecItemNotFound; - -#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS - /* SecItemCopyMatching() was introduced in iOS and Snow Leopard. - kSecClassIdentity was introduced in Lion. If both exist, let's use them - to find the certificate. */ - if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) { - CFTypeRef keys[4]; - CFTypeRef values[4]; - CFDictionaryRef query_dict; - CFStringRef label_cf = CFStringCreateWithCString(NULL, label, - kCFStringEncodingUTF8); - - /* Set up our search criteria and expected results: */ - values[0] = kSecClassIdentity; /* we want a certificate and a key */ - keys[0] = kSecClass; - values[1] = kCFBooleanTrue; /* we want a reference */ - keys[1] = kSecReturnRef; - values[2] = kSecMatchLimitOne; /* one is enough, thanks */ - keys[2] = kSecMatchLimit; - /* identity searches need a SecPolicyRef in order to work */ - values[3] = SecPolicyCreateSSL(false, label_cf); - keys[3] = kSecMatchPolicy; - query_dict = CFDictionaryCreate(NULL, (const void **)keys, - (const void **)values, 4L, - &kCFCopyStringDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFRelease(values[3]); - CFRelease(label_cf); - - /* Do we have a match? */ - status = SecItemCopyMatching(query_dict, (CFTypeRef *)out_cert_and_key); - CFRelease(query_dict); - } - else { -#if CURL_SUPPORT_MAC_10_6 - /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */ - status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key); -#endif /* CURL_SUPPORT_MAC_10_7 */ - } -#elif CURL_SUPPORT_MAC_10_6 - /* For developers building on older cats, we have no choice but to fall back - to SecKeychainSearch. */ - status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key); -#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ - return status; -} - -static OSStatus CopyIdentityFromPKCS12File(const char *cPath, - const char *cPassword, - SecIdentityRef *out_cert_and_key) -{ - OSStatus status = errSecItemNotFound; - CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL, - (const UInt8 *)cPath, strlen(cPath), false); - CFStringRef password = cPassword ? CFStringCreateWithCString(NULL, - cPassword, kCFStringEncodingUTF8) : NULL; - CFDataRef pkcs_data = NULL; - - /* We can import P12 files on iOS or OS X 10.7 or later: */ - /* These constants are documented as having first appeared in 10.6 but they - raise linker errors when used on that cat for some reason. */ -#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS - if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data, - NULL, NULL, &status)) { - const void *cKeys[] = {kSecImportExportPassphrase}; - const void *cValues[] = {password}; - CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues, - password ? 1L : 0L, NULL, NULL); - CFArrayRef items = NULL; - - /* Here we go: */ - status = SecPKCS12Import(pkcs_data, options, &items); - if(status == noErr && items && CFArrayGetCount(items)) { - CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L); - const void *temp_identity = CFDictionaryGetValue(identity_and_trust, - kSecImportItemIdentity); - - /* Retain the identity; we don't care about any other data... */ - CFRetain(temp_identity); - *out_cert_and_key = (SecIdentityRef)temp_identity; - } - - if(items) - CFRelease(items); - CFRelease(options); - CFRelease(pkcs_data); - } -#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ - if(password) - CFRelease(password); - CFRelease(pkcs_url); - return status; -} - -/* This code was borrowed from nss.c, with some modifications: - * Determine whether the nickname passed in is a filename that needs to - * be loaded as a PEM or a regular NSS nickname. - * - * returns 1 for a file - * returns 0 for not a file - */ -CF_INLINE bool is_file(const char *filename) -{ - struct_stat st; - - if(filename == NULL) - return false; - - if(stat(filename, &st) == 0) - return S_ISREG(st.st_mode); - return false; -} - -static CURLcode darwinssl_connect_step1(struct connectdata *conn, - int sockindex) -{ - struct SessionHandle *data = conn->data; - curl_socket_t sockfd = conn->sock[sockindex]; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif /* ENABLE_IPV6 */ - size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i; - SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL; - char *ssl_sessionid; - size_t ssl_sessionid_len; - OSStatus err = noErr; -#if CURL_BUILD_MAC - int darwinver_maj = 0, darwinver_min = 0; - - GetDarwinVersionNumber(&darwinver_maj, &darwinver_min); -#endif /* CURL_BUILD_MAC */ - -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLCreateContext != NULL) { /* use the newer API if avaialble */ - if(connssl->ssl_ctx) - CFRelease(connssl->ssl_ctx); - connssl->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType); - if(!connssl->ssl_ctx) { - failf(data, "SSL: couldn't create a context!"); - return CURLE_OUT_OF_MEMORY; - } - } - else { - /* The old ST API does not exist under iOS, so don't compile it: */ -#if CURL_SUPPORT_MAC_10_8 - if(connssl->ssl_ctx) - (void)SSLDisposeContext(connssl->ssl_ctx); - err = SSLNewContext(false, &(connssl->ssl_ctx)); - if(err != noErr) { - failf(data, "SSL: couldn't create a context: OSStatus %d", err); - return CURLE_OUT_OF_MEMORY; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else - if(connssl->ssl_ctx) - (void)SSLDisposeContext(connssl->ssl_ctx); - err = SSLNewContext(false, &(connssl->ssl_ctx)); - if(err != noErr) { - failf(data, "SSL: couldn't create a context: OSStatus %d", err); - return CURLE_OUT_OF_MEMORY; - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - connssl->ssl_write_buffered_length = 0UL; /* reset buffered write length */ - - /* check to see if we've been told to use an explicit SSL/TLS version */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLSetProtocolVersionMax != NULL) { - switch(data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1); - (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); - break; - case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol1); - (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol1); - break; - case CURL_SSLVERSION_TLSv1_1: - (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol11); - (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol11); - break; - case CURL_SSLVERSION_TLSv1_2: - (void)SSLSetProtocolVersionMin(connssl->ssl_ctx, kTLSProtocol12); - (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kTLSProtocol12); - break; - case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol3); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol3); - break; - case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionMin(connssl->ssl_ctx, kSSLProtocol2); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - (void)SSLSetProtocolVersionMax(connssl->ssl_ctx, kSSLProtocol2); - } - } - else { -#if CURL_SUPPORT_MAC_10_8 - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kSSLProtocolAll, - false); - switch (data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kTLSProtocol1, - true); - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kTLSProtocol11, - true); - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kTLSProtocol11, - true); - break; - case CURL_SSLVERSION_TLSv1_2: - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, kSSLProtocolAll, false); - switch(data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: - failf(data, "Your version of the OS does not support TLSv1.1"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_2: - failf(data, "Your version of the OS does not support TLSv1.2"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_SSLv2: - err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kSSLProtocol2, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - case CURL_SSLVERSION_SSLv3: - err = SSLSetProtocolVersionEnabled(connssl->ssl_ctx, - kSSLProtocol3, - true); - if(err != noErr) { - failf(data, "Your version of the OS does not support SSLv3"); - return CURLE_SSL_CONNECT_ERROR; - } - break; - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - - if(data->set.str[STRING_KEY]) { - infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure " - "Transport. The private key must be in the Keychain.\n"); - } - - if(data->set.str[STRING_CERT]) { - SecIdentityRef cert_and_key = NULL; - bool is_cert_file = is_file(data->set.str[STRING_CERT]); - - /* User wants to authenticate with a client cert. Look for it: - If we detect that this is a file on disk, then let's load it. - Otherwise, assume that the user wants to use an identity loaded - from the Keychain. */ - if(is_cert_file) { - if(!data->set.str[STRING_CERT_TYPE]) - infof(data, "WARNING: SSL: Certificate type not set, assuming " - "PKCS#12 format.\n"); - else if(strncmp(data->set.str[STRING_CERT_TYPE], "P12", - strlen(data->set.str[STRING_CERT_TYPE])) != 0) - infof(data, "WARNING: SSL: The Security framework only supports " - "loading identities that are in PKCS#12 format.\n"); - - err = CopyIdentityFromPKCS12File(data->set.str[STRING_CERT], - data->set.str[STRING_KEY_PASSWD], &cert_and_key); - } - else - err = CopyIdentityWithLabel(data->set.str[STRING_CERT], &cert_and_key); - - if(err == noErr) { - SecCertificateRef cert = NULL; - CFTypeRef certs_c[1]; - CFArrayRef certs; - - /* If we found one, print it out: */ - err = SecIdentityCopyCertificate(cert_and_key, &cert); - if(err == noErr) { - CFStringRef cert_summary = CopyCertSubject(cert); - char cert_summary_c[128]; - - if(cert_summary) { - memset(cert_summary_c, 0, 128); - if(CFStringGetCString(cert_summary, - cert_summary_c, - 128, - kCFStringEncodingUTF8)) { - infof(data, "Client certificate: %s\n", cert_summary_c); - } - CFRelease(cert_summary); - CFRelease(cert); - } - } - certs_c[0] = cert_and_key; - certs = CFArrayCreate(NULL, (const void **)certs_c, 1L, - &kCFTypeArrayCallBacks); - err = SSLSetCertificate(connssl->ssl_ctx, certs); - if(certs) - CFRelease(certs); - if(err != noErr) { - failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err); - return CURLE_SSL_CERTPROBLEM; - } - CFRelease(cert_and_key); - } - else { - switch(err) { - case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */ - failf(data, "SSL: Incorrect password for the certificate \"%s\" " - "and its private key.", data->set.str[STRING_CERT]); - break; - case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */ - failf(data, "SSL: Couldn't make sense of the data in the " - "certificate \"%s\" and its private key.", - data->set.str[STRING_CERT]); - break; - case -25260: /* errSecPassphraseRequired */ - failf(data, "SSL The certificate \"%s\" requires a password.", - data->set.str[STRING_CERT]); - break; - case errSecItemNotFound: - failf(data, "SSL: Can't find the certificate \"%s\" and its private " - "key in the Keychain.", data->set.str[STRING_CERT]); - break; - default: - failf(data, "SSL: Can't load the certificate \"%s\" and its private " - "key: OSStatus %d", data->set.str[STRING_CERT], err); - break; - } - return CURLE_SSL_CERTPROBLEM; - } - } - - /* SSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ -#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS - /* Snow Leopard introduced the SSLSetSessionOption() function, but due to - a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag - works, it doesn't work as expected under Snow Leopard, Lion or - Mountain Lion. - So we need to call SSLSetEnableCertVerify() on those older cats in order - to disable certificate validation if the user turned that off. - (SecureTransport will always validate the certificate chain by - default.) - Note: - Darwin 11.x.x is Lion (10.7) - Darwin 12.x.x is Mountain Lion (10.8) - Darwin 13.x.x is Mavericks (10.9) - Darwin 14.x.x is Yosemite (10.10) - Darwin 15.x.x is El Capitan (10.11) - */ -#if CURL_BUILD_MAC - if(SSLSetSessionOption != NULL && darwinver_maj >= 13) { -#else - if(SSLSetSessionOption != NULL) { -#endif /* CURL_BUILD_MAC */ - bool break_on_auth = !data->set.ssl.verifypeer || - data->set.str[STRING_SSL_CAFILE]; - err = SSLSetSessionOption(connssl->ssl_ctx, - kSSLSessionOptionBreakOnServerAuth, - break_on_auth); - if(err != noErr) { - failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { -#if CURL_SUPPORT_MAC_10_8 - err = SSLSetEnableCertVerify(connssl->ssl_ctx, - data->set.ssl.verifypeer?true:false); - if(err != noErr) { - failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else - err = SSLSetEnableCertVerify(connssl->ssl_ctx, - data->set.ssl.verifypeer?true:false); - if(err != noErr) { - failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */ - - if(data->set.str[STRING_SSL_CAFILE]) { - bool is_cert_file = is_file(data->set.str[STRING_SSL_CAFILE]); - - if(!is_cert_file) { - failf(data, "SSL: can't load CA certificate file %s", - data->set.str[STRING_SSL_CAFILE]); - return CURLE_SSL_CACERT_BADFILE; - } - if(!data->set.ssl.verifypeer) { - failf(data, "SSL: CA certificate set, but certificate verification " - "is disabled"); - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* Configure hostname check. SNI is used if available. - * Both hostname check and SNI require SSLSetPeerDomainName(). - * Also: the verifyhost setting influences SNI usage */ - if(data->set.ssl.verifyhost) { - err = SSLSetPeerDomainName(connssl->ssl_ctx, conn->host.name, - strlen(conn->host.name)); - - if(err != noErr) { - infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n", - err); - } - - if((Curl_inet_pton(AF_INET, conn->host.name, &addr)) - #ifdef ENABLE_IPV6 - || (Curl_inet_pton(AF_INET6, conn->host.name, &addr)) - #endif - ) { - infof(data, "WARNING: using IP address, SNI is being disabled by " - "the OS.\n"); - } - } - - /* Disable cipher suites that ST supports but are not safe. These ciphers - are unlikely to be used in any case since ST gives other ciphers a much - higher priority, but it's probably better that we not connect at all than - to give the user a false sense of security if the server only supports - insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */ - (void)SSLGetNumberSupportedCiphers(connssl->ssl_ctx, &all_ciphers_count); - all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite)); - if(all_ciphers && allowed_ciphers && - SSLGetSupportedCiphers(connssl->ssl_ctx, all_ciphers, - &all_ciphers_count) == noErr) { - for(i = 0UL ; i < all_ciphers_count ; i++) { -#if CURL_BUILD_MAC - /* There's a known bug in early versions of Mountain Lion where ST's ECC - ciphers (cipher suite 0xC001 through 0xC032) simply do not work. - Work around the problem here by disabling those ciphers if we are - running in an affected version of OS X. */ - if(darwinver_maj == 12 && darwinver_min <= 3 && - all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) { - continue; - } -#endif /* CURL_BUILD_MAC */ - switch(all_ciphers[i]) { - /* Disable NULL ciphersuites: */ - case SSL_NULL_WITH_NULL_NULL: - case SSL_RSA_WITH_NULL_MD5: - case SSL_RSA_WITH_NULL_SHA: - case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */ - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: - case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */ - case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */ - case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */ - case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */ - case 0x002C: /* TLS_PSK_WITH_NULL_SHA */ - case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */ - case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */ - case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */ - case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */ - case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */ - case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */ - case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */ - case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */ - /* Disable anonymous ciphersuites: */ - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: - case SSL_DH_anon_WITH_RC4_128_MD5: - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_anon_WITH_DES_CBC_SHA: - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: - case TLS_DH_anon_WITH_AES_128_CBC_SHA: - case TLS_DH_anon_WITH_AES_256_CBC_SHA: - case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */ - case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */ - case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */ - case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */ - case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */ - case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */ - case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */ - case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */ - case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */ - /* Disable weak key ciphersuites: */ - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: - case SSL_RSA_WITH_DES_CBC_SHA: - case SSL_DH_DSS_WITH_DES_CBC_SHA: - case SSL_DH_RSA_WITH_DES_CBC_SHA: - case SSL_DHE_DSS_WITH_DES_CBC_SHA: - case SSL_DHE_RSA_WITH_DES_CBC_SHA: - /* Disable IDEA: */ - case SSL_RSA_WITH_IDEA_CBC_SHA: - case SSL_RSA_WITH_IDEA_CBC_MD5: - break; - default: /* enable everything else */ - allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i]; - break; - } - } - err = SSLSetEnabledCiphers(connssl->ssl_ctx, allowed_ciphers, - allowed_ciphers_count); - if(err != noErr) { - failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); - failf(data, "SSL: Failed to allocate memory for allowed ciphers"); - return CURLE_OUT_OF_MEMORY; - } - Curl_safefree(all_ciphers); - Curl_safefree(allowed_ciphers); - -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - /* We want to enable 1/n-1 when using a CBC cipher unless the user - specifically doesn't want us doing that: */ - if(SSLSetSessionOption != NULL) { - SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionSendOneByteRecord, - !data->set.ssl_enable_beast); - SSLSetSessionOption(connssl->ssl_ctx, kSSLSessionOptionFalseStart, - data->set.ssl.falsestart); /* false start support */ - } -#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */ - - /* Check if there's a cached ID we can/should use here! */ - if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid, - &ssl_sessionid_len)) { - /* we got a session id, use it! */ - err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len); - if(err != noErr) { - failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - infof(data, "SSL re-using session ID\n"); - } - /* If there isn't one, then let's make one up! This has to be done prior - to starting the handshake. */ - else { - CURLcode result; - ssl_sessionid = - aprintf("%s:%d:%d:%s:%hu", data->set.str[STRING_SSL_CAFILE], - data->set.ssl.verifypeer, data->set.ssl.verifyhost, - conn->host.name, conn->remote_port); - ssl_sessionid_len = strlen(ssl_sessionid); - - err = SSLSetPeerID(connssl->ssl_ctx, ssl_sessionid, ssl_sessionid_len); - if(err != noErr) { - failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - - result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len); - if(result) { - failf(data, "failed to store ssl session"); - return result; - } - } - - err = SSLSetIOFuncs(connssl->ssl_ctx, SocketRead, SocketWrite); - if(err != noErr) { - failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - - /* pass the raw socket into the SSL layers */ - /* We need to store the FD in a constant memory address, because - * SSLSetConnection() will not copy that address. I've found that - * conn->sock[sockindex] may change on its own. */ - connssl->ssl_sockfd = sockfd; - err = SSLSetConnection(connssl->ssl_ctx, connssl); - if(err != noErr) { - failf(data, "SSL: SSLSetConnection() failed: %d", err); - return CURLE_SSL_CONNECT_ERROR; - } - - connssl->connecting_state = ssl_connect_2; - return CURLE_OK; -} - -static long pem_to_der(const char *in, unsigned char **out, size_t *outlen) -{ - char *sep_start, *sep_end, *cert_start, *cert_end; - size_t i, j, err; - size_t len; - unsigned char *b64; - - /* Jump through the separators at the beginning of the certificate. */ - sep_start = strstr(in, "-----"); - if(sep_start == NULL) - return 0; - cert_start = strstr(sep_start + 1, "-----"); - if(cert_start == NULL) - return -1; - - cert_start += 5; - - /* Find separator after the end of the certificate. */ - cert_end = strstr(cert_start, "-----"); - if(cert_end == NULL) - return -1; - - sep_end = strstr(cert_end + 1, "-----"); - if(sep_end == NULL) - return -1; - sep_end += 5; - - len = cert_end - cert_start; - b64 = malloc(len + 1); - if(!b64) - return -1; - - /* Create base64 string without linefeeds. */ - for(i = 0, j = 0; i < len; i++) { - if(cert_start[i] != '\r' && cert_start[i] != '\n') - b64[j++] = cert_start[i]; - } - b64[j] = '\0'; - - err = Curl_base64_decode((const char *)b64, out, outlen); - free(b64); - if(err) { - free(*out); - return -1; - } - - return sep_end - in; -} - -static int read_cert(const char *file, unsigned char **out, size_t *outlen) -{ - int fd; - ssize_t n, len = 0, cap = 512; - unsigned char buf[cap], *data; - - fd = open(file, 0); - if(fd < 0) - return -1; - - data = malloc(cap); - if(!data) { - close(fd); - return -1; - } - - for(;;) { - n = read(fd, buf, sizeof(buf)); - if(n < 0) { - close(fd); - free(data); - return -1; - } - else if(n == 0) { - close(fd); - break; - } - - if(len + n >= cap) { - cap *= 2; - data = realloc(data, cap); - if(!data) { - close(fd); - return -1; - } - } - - memcpy(data + len, buf, n); - len += n; - } - data[len] = '\0'; - - *out = data; - *outlen = len; - - return 0; -} - -static int sslerr_to_curlerr(struct SessionHandle *data, int err) -{ - switch(err) { - case errSSLXCertChainInvalid: - failf(data, "SSL certificate problem: Invalid certificate chain"); - return CURLE_SSL_CACERT; - case errSSLUnknownRootCert: - failf(data, "SSL certificate problem: Untrusted root certificate"); - return CURLE_SSL_CACERT; - case errSSLNoRootCert: - failf(data, "SSL certificate problem: No root certificate"); - return CURLE_SSL_CACERT; - case errSSLCertExpired: - failf(data, "SSL certificate problem: Certificate chain had an " - "expired certificate"); - return CURLE_SSL_CACERT; - case errSSLBadCert: - failf(data, "SSL certificate problem: Couldn't understand the server " - "certificate format"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLHostNameMismatch: - failf(data, "SSL certificate peer hostname mismatch"); - return CURLE_PEER_FAILED_VERIFICATION; - default: - failf(data, "SSL unexpected certificate error %d", err); - return CURLE_SSL_CACERT; - } -} - -static int append_cert_to_array(struct SessionHandle *data, - unsigned char *buf, size_t buflen, - CFMutableArrayRef array) -{ - CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen); - if(!certdata) { - failf(data, "SSL: failed to allocate array for CA certificate"); - return CURLE_OUT_OF_MEMORY; - } - - SecCertificateRef cacert = - SecCertificateCreateWithData(kCFAllocatorDefault, certdata); - CFRelease(certdata); - if(!cacert) { - failf(data, "SSL: failed to create SecCertificate from CA certificate"); - return CURLE_SSL_CACERT; - } - - /* Check if cacert is valid. */ - CFStringRef subject = CopyCertSubject(cacert); - if(subject) { - char subject_cbuf[128]; - memset(subject_cbuf, 0, 128); - if(!CFStringGetCString(subject, - subject_cbuf, - 128, - kCFStringEncodingUTF8)) { - CFRelease(cacert); - failf(data, "SSL: invalid CA certificate subject"); - return CURLE_SSL_CACERT; - } - CFRelease(subject); - } - else { - CFRelease(cacert); - failf(data, "SSL: invalid CA certificate"); - return CURLE_SSL_CACERT; - } - - CFArrayAppendValue(array, cacert); - CFRelease(cacert); - - return CURLE_OK; -} - -static int verify_cert(const char *cafile, struct SessionHandle *data, - SSLContextRef ctx) -{ - int n = 0, rc; - long res; - unsigned char *certbuf, *der; - size_t buflen, derlen, offset = 0; - - if(read_cert(cafile, &certbuf, &buflen) < 0) { - failf(data, "SSL: failed to read or invalid CA certificate"); - return CURLE_SSL_CACERT; - } - - /* - * Certbuf now contains the contents of the certificate file, which can be - * - a single DER certificate, - * - a single PEM certificate or - * - a bunch of PEM certificates (certificate bundle). - * - * Go through certbuf, and convert any PEM certificate in it into DER - * format. - */ - CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeArrayCallBacks); - if(array == NULL) { - free(certbuf); - failf(data, "SSL: out of memory creating CA certificate array"); - return CURLE_OUT_OF_MEMORY; - } - - while(offset < buflen) { - n++; - - /* - * Check if the certificate is in PEM format, and convert it to DER. If - * this fails, we assume the certificate is in DER format. - */ - res = pem_to_der((const char *)certbuf + offset, &der, &derlen); - if(res < 0) { - free(certbuf); - CFRelease(array); - failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle", - n, offset); - return CURLE_SSL_CACERT; - } - offset += res; - - if(res == 0 && offset == 0) { - /* This is not a PEM file, probably a certificate in DER format. */ - rc = append_cert_to_array(data, certbuf, buflen, array); - free(certbuf); - if(rc != CURLE_OK) { - CFRelease(array); - return rc; - } - break; - } - else if(res == 0) { - /* No more certificates in the bundle. */ - free(certbuf); - break; - } - - rc = append_cert_to_array(data, der, derlen, array); - free(der); - if(rc != CURLE_OK) { - free(certbuf); - CFRelease(array); - return rc; - } - } - - SecTrustRef trust; - OSStatus ret = SSLCopyPeerTrust(ctx, &trust); - if(trust == NULL) { - failf(data, "SSL: error getting certificate chain"); - CFRelease(array); - return CURLE_OUT_OF_MEMORY; - } - else if(ret != noErr) { - CFRelease(array); - return sslerr_to_curlerr(data, ret); - } - - ret = SecTrustSetAnchorCertificates(trust, array); - if(ret != noErr) { - CFRelease(trust); - return sslerr_to_curlerr(data, ret); - } - ret = SecTrustSetAnchorCertificatesOnly(trust, true); - if(ret != noErr) { - CFRelease(trust); - return sslerr_to_curlerr(data, ret); - } - - SecTrustResultType trust_eval = 0; - ret = SecTrustEvaluate(trust, &trust_eval); - CFRelease(array); - CFRelease(trust); - if(ret != noErr) { - return sslerr_to_curlerr(data, ret); - } - - switch (trust_eval) { - case kSecTrustResultUnspecified: - case kSecTrustResultProceed: - return CURLE_OK; - - case kSecTrustResultRecoverableTrustFailure: - case kSecTrustResultDeny: - default: - failf(data, "SSL: certificate verification failed (result: %d)", - trust_eval); - return CURLE_PEER_FAILED_VERIFICATION; - } -} - -static CURLcode -darwinssl_connect_step2(struct connectdata *conn, int sockindex) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - OSStatus err; - SSLCipherSuite cipher; - SSLProtocol protocol = 0; - - DEBUGASSERT(ssl_connect_2 == connssl->connecting_state - || ssl_connect_2_reading == connssl->connecting_state - || ssl_connect_2_writing == connssl->connecting_state); - - /* Here goes nothing: */ - err = SSLHandshake(connssl->ssl_ctx); - - if(err != noErr) { - switch (err) { - case errSSLWouldBlock: /* they're not done with us yet */ - connssl->connecting_state = connssl->ssl_direction ? - ssl_connect_2_writing : ssl_connect_2_reading; - return CURLE_OK; - - /* The below is errSSLServerAuthCompleted; it's not defined in - Leopard's headers */ - case -9841: - if(data->set.str[STRING_SSL_CAFILE]) { - int res = verify_cert(data->set.str[STRING_SSL_CAFILE], data, - connssl->ssl_ctx); - if(res != CURLE_OK) - return res; - } - /* the documentation says we need to call SSLHandshake() again */ - return darwinssl_connect_step2(conn, sockindex); - - /* These are all certificate problems with the server: */ - case errSSLXCertChainInvalid: - failf(data, "SSL certificate problem: Invalid certificate chain"); - return CURLE_SSL_CACERT; - case errSSLUnknownRootCert: - failf(data, "SSL certificate problem: Untrusted root certificate"); - return CURLE_SSL_CACERT; - case errSSLNoRootCert: - failf(data, "SSL certificate problem: No root certificate"); - return CURLE_SSL_CACERT; - case errSSLCertExpired: - failf(data, "SSL certificate problem: Certificate chain had an " - "expired certificate"); - return CURLE_SSL_CACERT; - case errSSLBadCert: - failf(data, "SSL certificate problem: Couldn't understand the server " - "certificate format"); - return CURLE_SSL_CONNECT_ERROR; - - /* These are all certificate problems with the client: */ - case errSecAuthFailed: - failf(data, "SSL authentication failed"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLPeerHandshakeFail: - failf(data, "SSL peer handshake failed, the server most likely " - "requires a client certificate to connect"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLPeerUnknownCA: - failf(data, "SSL server rejected the client certificate due to " - "the certificate being signed by an unknown certificate " - "authority"); - return CURLE_SSL_CONNECT_ERROR; - - /* This error is raised if the server's cert didn't match the server's - host name: */ - case errSSLHostNameMismatch: - failf(data, "SSL certificate peer verification failed, the " - "certificate did not match \"%s\"\n", conn->host.dispname); - return CURLE_PEER_FAILED_VERIFICATION; - - /* Generic handshake errors: */ - case errSSLConnectionRefused: - failf(data, "Server dropped the connection during the SSL handshake"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLClosedAbort: - failf(data, "Server aborted the SSL handshake"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLNegotiation: - failf(data, "Could not negotiate an SSL cipher suite with the server"); - return CURLE_SSL_CONNECT_ERROR; - /* Sometimes paramErr happens with buggy ciphers: */ - case paramErr: case errSSLInternal: - failf(data, "Internal SSL engine error encountered during the " - "SSL handshake"); - return CURLE_SSL_CONNECT_ERROR; - case errSSLFatalAlert: - failf(data, "Fatal SSL engine error encountered during the SSL " - "handshake"); - return CURLE_SSL_CONNECT_ERROR; - default: - failf(data, "Unknown SSL protocol error in connection to %s:%d", - conn->host.name, err); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { - /* we have been connected fine, we're not waiting for anything else. */ - connssl->connecting_state = ssl_connect_3; - - /* Informational message */ - (void)SSLGetNegotiatedCipher(connssl->ssl_ctx, &cipher); - (void)SSLGetNegotiatedProtocolVersion(connssl->ssl_ctx, &protocol); - switch (protocol) { - case kSSLProtocol2: - infof(data, "SSL 2.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); - break; - case kSSLProtocol3: - infof(data, "SSL 3.0 connection using %s\n", - SSLCipherNameForNumber(cipher)); - break; - case kTLSProtocol1: - infof(data, "TLS 1.0 connection using %s\n", - TLSCipherNameForNumber(cipher)); - break; -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - case kTLSProtocol11: - infof(data, "TLS 1.1 connection using %s\n", - TLSCipherNameForNumber(cipher)); - break; - case kTLSProtocol12: - infof(data, "TLS 1.2 connection using %s\n", - TLSCipherNameForNumber(cipher)); - break; -#endif - default: - infof(data, "Unknown protocol connection\n"); - break; - } - - return CURLE_OK; - } -} - -static CURLcode -darwinssl_connect_step3(struct connectdata *conn, - int sockindex) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - CFStringRef server_cert_summary; - char server_cert_summary_c[128]; - CFArrayRef server_certs = NULL; - SecCertificateRef server_cert; - OSStatus err; - CFIndex i, count; - SecTrustRef trust = NULL; - - /* There is no step 3! - * Well, okay, if verbose mode is on, let's print the details of the - * server certificates. */ -#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS -#if CURL_BUILD_IOS -#pragma unused(server_certs) - err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust); - /* For some reason, SSLCopyPeerTrust() can return noErr and yet return - a null trust, so be on guard for that: */ - if(err == noErr && trust) { - count = SecTrustGetCertificateCount(trust); - for(i = 0L ; i < count ; i++) { - server_cert = SecTrustGetCertificateAtIndex(trust, i); - server_cert_summary = CopyCertSubject(server_cert); - memset(server_cert_summary_c, 0, 128); - if(CFStringGetCString(server_cert_summary, - server_cert_summary_c, - 128, - kCFStringEncodingUTF8)) { - infof(data, "Server certificate: %s\n", server_cert_summary_c); - } - CFRelease(server_cert_summary); - } - CFRelease(trust); - } -#else - /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion. - The function SecTrustGetCertificateAtIndex() is officially present - in Lion, but it is unfortunately also present in Snow Leopard as - private API and doesn't work as expected. So we have to look for - a different symbol to make sure this code is only executed under - Lion or later. */ - if(SecTrustEvaluateAsync != NULL) { -#pragma unused(server_certs) - err = SSLCopyPeerTrust(connssl->ssl_ctx, &trust); - /* For some reason, SSLCopyPeerTrust() can return noErr and yet return - a null trust, so be on guard for that: */ - if(err == noErr && trust) { - count = SecTrustGetCertificateCount(trust); - for(i = 0L ; i < count ; i++) { - server_cert = SecTrustGetCertificateAtIndex(trust, i); - server_cert_summary = CopyCertSubject(server_cert); - memset(server_cert_summary_c, 0, 128); - if(CFStringGetCString(server_cert_summary, - server_cert_summary_c, - 128, - kCFStringEncodingUTF8)) { - infof(data, "Server certificate: %s\n", server_cert_summary_c); - } - CFRelease(server_cert_summary); - } - CFRelease(trust); - } - } - else { -#if CURL_SUPPORT_MAC_10_8 - err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs); - /* Just in case SSLCopyPeerCertificates() returns null too... */ - if(err == noErr && server_certs) { - count = CFArrayGetCount(server_certs); - for(i = 0L ; i < count ; i++) { - server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, - i); - - server_cert_summary = CopyCertSubject(server_cert); - memset(server_cert_summary_c, 0, 128); - if(CFStringGetCString(server_cert_summary, - server_cert_summary_c, - 128, - kCFStringEncodingUTF8)) { - infof(data, "Server certificate: %s\n", server_cert_summary_c); - } - CFRelease(server_cert_summary); - } - CFRelease(server_certs); - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#endif /* CURL_BUILD_IOS */ -#else -#pragma unused(trust) - err = SSLCopyPeerCertificates(connssl->ssl_ctx, &server_certs); - if(err == noErr) { - count = CFArrayGetCount(server_certs); - for(i = 0L ; i < count ; i++) { - server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i); - server_cert_summary = CopyCertSubject(server_cert); - memset(server_cert_summary_c, 0, 128); - if(CFStringGetCString(server_cert_summary, - server_cert_summary_c, - 128, - kCFStringEncodingUTF8)) { - infof(data, "Server certificate: %s\n", server_cert_summary_c); - } - CFRelease(server_cert_summary); - } - CFRelease(server_certs); - } -#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */ - - connssl->connecting_state = ssl_connect_done; - return CURLE_OK; -} - -static Curl_recv darwinssl_recv; -static Curl_send darwinssl_send; - -static CURLcode -darwinssl_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - long timeout_ms; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1==connssl->connecting_state) { - /* Find out how much more time we're allowed */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - result = darwinssl_connect_step1(conn, sockindex); - if(result) - return result; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading || - connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading == - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if this - * connection is done nonblocking and this loop would execute again. This - * permits the owner of a multi handle to abort a connection attempt - * before step2 has completed while ensuring that a client using select() - * or epoll() will always have a valid fdset to wait on. - */ - result = darwinssl_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - - } /* repeat step2 until all transactions are done. */ - - - if(ssl_connect_3 == connssl->connecting_state) { - result = darwinssl_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = darwinssl_recv; - conn->send[sockindex] = darwinssl_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -CURLcode -Curl_darwinssl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done) -{ - return darwinssl_connect_common(conn, sockindex, TRUE, done); -} - -CURLcode -Curl_darwinssl_connect(struct connectdata *conn, - int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = darwinssl_connect_common(conn, sockindex, FALSE, &done); - - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -void Curl_darwinssl_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - if(connssl->ssl_ctx) { - (void)SSLClose(connssl->ssl_ctx); -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(SSLCreateContext != NULL) - CFRelease(connssl->ssl_ctx); -#if CURL_SUPPORT_MAC_10_8 - else - (void)SSLDisposeContext(connssl->ssl_ctx); -#endif /* CURL_SUPPORT_MAC_10_8 */ -#else - (void)SSLDisposeContext(connssl->ssl_ctx); -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - connssl->ssl_ctx = NULL; - } - connssl->ssl_sockfd = 0; -} - -int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - ssize_t nread; - int what; - int rc; - char buf[120]; - - if(!connssl->ssl_ctx) - return 0; - - if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) - return 0; - - Curl_darwinssl_close(conn, sockindex); - - rc = 0; - - what = Curl_socket_ready(conn->sock[sockindex], - CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); - - for(;;) { - if(what < 0) { - /* anything that gets here is fatally bad */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - rc = -1; - break; - } - - if(!what) { /* timeout */ - failf(data, "SSL shutdown timeout"); - break; - } - - /* Something to read, let's do it and hope that it is the close - notify alert from the server. No way to SSL_Read now, so use read(). */ - - nread = read(conn->sock[sockindex], buf, sizeof(buf)); - - if(nread < 0) { - failf(data, "read: %s", strerror(errno)); - rc = -1; - } - - if(nread <= 0) - break; - - what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0); - } - - return rc; -} - -void Curl_darwinssl_session_free(void *ptr) -{ - /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a - cached session ID inside the Security framework. There is a private - function that does this, but I don't want to have to explain to you why I - got your application rejected from the App Store due to the use of a - private API, so the best we can do is free up our own char array that we - created way back in darwinssl_connect_step1... */ - Curl_safefree(ptr); -} - -size_t Curl_darwinssl_version(char *buffer, size_t size) -{ - return snprintf(buffer, size, "SecureTransport"); -} - -/* - * This function uses SSLGetSessionState to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -int Curl_darwinssl_check_cxn(struct connectdata *conn) -{ - struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET]; - OSStatus err; - SSLSessionState state; - - if(connssl->ssl_ctx) { - err = SSLGetSessionState(connssl->ssl_ctx, &state); - if(err == noErr) - return state == kSSLConnected || state == kSSLHandshake; - return -1; - } - return 0; -} - -bool Curl_darwinssl_data_pending(const struct connectdata *conn, - int connindex) -{ - const struct ssl_connect_data *connssl = &conn->ssl[connindex]; - OSStatus err; - size_t buffer; - - if(connssl->ssl_ctx) { /* SSL is in use */ - err = SSLGetBufferedReadSize(connssl->ssl_ctx, &buffer); - if(err == noErr) - return buffer > 0UL; - return false; - } - else - return false; -} - -int Curl_darwinssl_random(unsigned char *entropy, - size_t length) -{ - /* arc4random_buf() isn't available on cats older than Lion, so let's - do this manually for the benefit of the older cats. */ - size_t i; - u_int32_t random_number = 0; - - for(i = 0 ; i < length ; i++) { - if(i % sizeof(u_int32_t) == 0) - random_number = arc4random(); - entropy[i] = random_number & 0xFF; - random_number >>= 8; - } - i = random_number = 0; - return 0; -} - -void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len) -{ - (void)md5len; - (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum); -} - -bool Curl_darwinssl_false_start(void) { -#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 - if(SSLSetSessionOption != NULL) - return TRUE; -#endif - return FALSE; -} - -static ssize_t darwinssl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - /*struct SessionHandle *data = conn->data;*/ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - size_t processed = 0UL; - OSStatus err; - - /* The SSLWrite() function works a little differently than expected. The - fourth argument (processed) is currently documented in Apple's - documentation as: "On return, the length, in bytes, of the data actually - written." - - Now, one could interpret that as "written to the socket," but actually, - it returns the amount of data that was written to a buffer internal to - the SSLContextRef instead. So it's possible for SSLWrite() to return - errSSLWouldBlock and a number of bytes "written" because those bytes were - encrypted and written to a buffer, not to the socket. - - So if this happens, then we need to keep calling SSLWrite() over and - over again with no new data until it quits returning errSSLWouldBlock. */ - - /* Do we have buffered data to write from the last time we were called? */ - if(connssl->ssl_write_buffered_length) { - /* Write the buffered data: */ - err = SSLWrite(connssl->ssl_ctx, NULL, 0UL, &processed); - switch (err) { - case noErr: - /* processed is always going to be 0 because we didn't write to - the buffer, so return how much was written to the socket */ - processed = connssl->ssl_write_buffered_length; - connssl->ssl_write_buffered_length = 0UL; - break; - case errSSLWouldBlock: /* argh, try again */ - *curlcode = CURLE_AGAIN; - return -1L; - default: - failf(conn->data, "SSLWrite() returned error %d", err); - *curlcode = CURLE_SEND_ERROR; - return -1L; - } - } - else { - /* We've got new data to write: */ - err = SSLWrite(connssl->ssl_ctx, mem, len, &processed); - if(err != noErr) { - switch (err) { - case errSSLWouldBlock: - /* Data was buffered but not sent, we have to tell the caller - to try sending again, and remember how much was buffered */ - connssl->ssl_write_buffered_length = len; - *curlcode = CURLE_AGAIN; - return -1L; - default: - failf(conn->data, "SSLWrite() returned error %d", err); - *curlcode = CURLE_SEND_ERROR; - return -1L; - } - } - } - return (ssize_t)processed; -} - -static ssize_t darwinssl_recv(struct connectdata *conn, - int num, - char *buf, - size_t buffersize, - CURLcode *curlcode) -{ - /*struct SessionHandle *data = conn->data;*/ - struct ssl_connect_data *connssl = &conn->ssl[num]; - size_t processed = 0UL; - OSStatus err = SSLRead(connssl->ssl_ctx, buf, buffersize, &processed); - - if(err != noErr) { - switch (err) { - case errSSLWouldBlock: /* return how much we read (if anything) */ - if(processed) - return (ssize_t)processed; - *curlcode = CURLE_AGAIN; - return -1L; - break; - - /* errSSLClosedGraceful - server gracefully shut down the SSL session - errSSLClosedNoNotify - server hung up on us instead of sending a - closure alert notice, read() is returning 0 - Either way, inform the caller that the server disconnected. */ - case errSSLClosedGraceful: - case errSSLClosedNoNotify: - *curlcode = CURLE_OK; - return -1L; - break; - - default: - failf(conn->data, "SSLRead() return error %d", err); - *curlcode = CURLE_RECV_ERROR; - return -1L; - break; - } - } - return (ssize_t)processed; -} - -#endif /* USE_DARWINSSL */ diff --git a/Externals/curl/lib/vtls/darwinssl.h b/Externals/curl/lib/vtls/darwinssl.h deleted file mode 100644 index 8b185b67fc..0000000000 --- a/Externals/curl/lib/vtls/darwinssl.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef HEADER_CURL_DARWINSSL_H -#define HEADER_CURL_DARWINSSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2014, Nick Zitzmann, . - * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_DARWINSSL - -CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex); - -CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); - -/* close a SSL connection */ -void Curl_darwinssl_close(struct connectdata *conn, int sockindex); - -void Curl_darwinssl_session_free(void *ptr); -size_t Curl_darwinssl_version(char *buffer, size_t size); -int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex); -int Curl_darwinssl_check_cxn(struct connectdata *conn); -bool Curl_darwinssl_data_pending(const struct connectdata *conn, - int connindex); - -int Curl_darwinssl_random(unsigned char *entropy, - size_t length); -void Curl_darwinssl_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len); -bool Curl_darwinssl_false_start(void); - -/* Set the API backend definition to SecureTransport */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_DARWINSSL - -/* API setup for SecureTransport */ -#define curlssl_init() (1) -#define curlssl_cleanup() Curl_nop_stmt -#define curlssl_connect Curl_darwinssl_connect -#define curlssl_connect_nonblocking Curl_darwinssl_connect_nonblocking -#define curlssl_session_free(x) Curl_darwinssl_session_free(x) -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_darwinssl_close -#define curlssl_shutdown(x,y) 0 -#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) -#define curlssl_version Curl_darwinssl_version -#define curlssl_check_cxn Curl_darwinssl_check_cxn -#define curlssl_data_pending(x,y) Curl_darwinssl_data_pending(x, y) -#define curlssl_random(x,y,z) ((void)x, Curl_darwinssl_random(y,z)) -#define curlssl_md5sum(a,b,c,d) Curl_darwinssl_md5sum(a,b,c,d) -#define curlssl_false_start() Curl_darwinssl_false_start() - -#endif /* USE_DARWINSSL */ -#endif /* HEADER_CURL_DARWINSSL_H */ diff --git a/Externals/curl/lib/vtls/gskit.c b/Externals/curl/lib/vtls/gskit.c deleted file mode 100644 index a9a8a91864..0000000000 --- a/Externals/curl/lib/vtls/gskit.c +++ /dev/null @@ -1,1069 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_GSKIT - -#include -#include - -/* Some symbols are undefined/unsupported on OS400 versions < V7R1. */ -#ifndef GSK_SSL_EXTN_SERVERNAME_REQUEST -#define GSK_SSL_EXTN_SERVERNAME_REQUEST 230 -#endif - -#ifndef GSK_TLSV10_CIPHER_SPECS -#define GSK_TLSV10_CIPHER_SPECS 236 -#endif - -#ifndef GSK_TLSV11_CIPHER_SPECS -#define GSK_TLSV11_CIPHER_SPECS 237 -#endif - -#ifndef GSK_TLSV12_CIPHER_SPECS -#define GSK_TLSV12_CIPHER_SPECS 238 -#endif - -#ifndef GSK_PROTOCOL_TLSV11 -#define GSK_PROTOCOL_TLSV11 437 -#endif - -#ifndef GSK_PROTOCOL_TLSV12 -#define GSK_PROTOCOL_TLSV12 438 -#endif - -#ifndef GSK_FALSE -#define GSK_FALSE 0 -#endif - -#ifndef GSK_TRUE -#define GSK_TRUE 1 -#endif - - -#ifdef HAVE_LIMITS_H -# include -#endif - -#include -#include "urldata.h" -#include "sendf.h" -#include "gskit.h" -#include "vtls.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "strequal.h" -#include "x509asn1.h" -#include "curl_printf.h" - -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - - -/* SSL version flags. */ -#define CURL_GSKPROTO_SSLV2 0 -#define CURL_GSKPROTO_SSLV2_MASK (1 << CURL_GSKPROTO_SSLV2) -#define CURL_GSKPROTO_SSLV3 1 -#define CURL_GSKPROTO_SSLV3_MASK (1 << CURL_GSKPROTO_SSLV3) -#define CURL_GSKPROTO_TLSV10 2 -#define CURL_GSKPROTO_TLSV10_MASK (1 << CURL_GSKPROTO_TLSV10) -#define CURL_GSKPROTO_TLSV11 3 -#define CURL_GSKPROTO_TLSV11_MASK (1 << CURL_GSKPROTO_TLSV11) -#define CURL_GSKPROTO_TLSV12 4 -#define CURL_GSKPROTO_TLSV12_MASK (1 << CURL_GSKPROTO_TLSV12) -#define CURL_GSKPROTO_LAST 5 - - -/* Supported ciphers. */ -typedef struct { - const char *name; /* Cipher name. */ - const char *gsktoken; /* Corresponding token for GSKit String. */ - unsigned int versions; /* SSL version flags. */ -} gskit_cipher; - -static const gskit_cipher ciphertable[] = { - { "null-md5", "01", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | - CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, - { "null-sha", "02", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | - CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, - { "exp-rc4-md5", "03", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK }, - { "rc4-md5", "04", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | - CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, - { "rc4-sha", "05", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | - CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, - { "exp-rc2-cbc-md5", "06", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK }, - { "exp-des-cbc-sha", "09", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | - CURL_GSKPROTO_TLSV11_MASK }, - { "des-cbc3-sha", "0A", - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK | - CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK }, - { "aes128-sha", "2F", - CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK | - CURL_GSKPROTO_TLSV12_MASK }, - { "aes256-sha", "35", - CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK | - CURL_GSKPROTO_TLSV12_MASK }, - { "null-sha256", "3B", CURL_GSKPROTO_TLSV12_MASK }, - { "aes128-sha256", "3C", CURL_GSKPROTO_TLSV12_MASK }, - { "aes256-sha256", "3D", CURL_GSKPROTO_TLSV12_MASK }, - { "aes128-gcm-sha256", - "9C", CURL_GSKPROTO_TLSV12_MASK }, - { "aes256-gcm-sha384", - "9D", CURL_GSKPROTO_TLSV12_MASK }, - { "rc4-md5", "1", CURL_GSKPROTO_SSLV2_MASK }, - { "exp-rc4-md5", "2", CURL_GSKPROTO_SSLV2_MASK }, - { "rc2-md5", "3", CURL_GSKPROTO_SSLV2_MASK }, - { "exp-rc2-md5", "4", CURL_GSKPROTO_SSLV2_MASK }, - { "des-cbc-md5", "6", CURL_GSKPROTO_SSLV2_MASK }, - { "des-cbc3-md5", "7", CURL_GSKPROTO_SSLV2_MASK }, - { (const char *) NULL, (const char *) NULL, 0 } -}; - - -static bool is_separator(char c) -{ - /* Return whether character is a cipher list separator. */ - switch (c) { - case ' ': - case '\t': - case ':': - case ',': - case ';': - return true; - } - return false; -} - - -static CURLcode gskit_status(struct SessionHandle *data, int rc, - const char *procname, CURLcode defcode) -{ - /* Process GSKit status and map it to a CURLcode. */ - switch (rc) { - case GSK_OK: - case GSK_OS400_ASYNCHRONOUS_SOC_INIT: - return CURLE_OK; - case GSK_KEYRING_OPEN_ERROR: - case GSK_OS400_ERROR_NO_ACCESS: - return CURLE_SSL_CACERT_BADFILE; - case GSK_INSUFFICIENT_STORAGE: - return CURLE_OUT_OF_MEMORY; - case GSK_ERROR_BAD_V2_CIPHER: - case GSK_ERROR_BAD_V3_CIPHER: - case GSK_ERROR_NO_CIPHERS: - return CURLE_SSL_CIPHER; - case GSK_OS400_ERROR_NOT_TRUSTED_ROOT: - case GSK_ERROR_CERT_VALIDATION: - return CURLE_PEER_FAILED_VERIFICATION; - case GSK_OS400_ERROR_TIMED_OUT: - return CURLE_OPERATION_TIMEDOUT; - case GSK_WOULD_BLOCK: - return CURLE_AGAIN; - case GSK_OS400_ERROR_NOT_REGISTERED: - break; - case GSK_ERROR_IO: - switch (errno) { - case ENOMEM: - return CURLE_OUT_OF_MEMORY; - default: - failf(data, "%s I/O error: %s", procname, strerror(errno)); - break; - } - break; - default: - failf(data, "%s: %s", procname, gsk_strerror(rc)); - break; - } - return defcode; -} - - -static CURLcode set_enum(struct SessionHandle *data, gsk_handle h, - GSK_ENUM_ID id, GSK_ENUM_VALUE value, bool unsupported_ok) -{ - int rc = gsk_attribute_set_enum(h, id, value); - - switch (rc) { - case GSK_OK: - return CURLE_OK; - case GSK_ERROR_IO: - failf(data, "gsk_attribute_set_enum() I/O error: %s", strerror(errno)); - break; - case GSK_ATTRIBUTE_INVALID_ID: - if(unsupported_ok) - return CURLE_UNSUPPORTED_PROTOCOL; - default: - failf(data, "gsk_attribute_set_enum(): %s", gsk_strerror(rc)); - break; - } - return CURLE_SSL_CONNECT_ERROR; -} - - -static CURLcode set_buffer(struct SessionHandle *data, gsk_handle h, - GSK_BUF_ID id, const char *buffer, bool unsupported_ok) -{ - int rc = gsk_attribute_set_buffer(h, id, buffer, 0); - - switch (rc) { - case GSK_OK: - return CURLE_OK; - case GSK_ERROR_IO: - failf(data, "gsk_attribute_set_buffer() I/O error: %s", strerror(errno)); - break; - case GSK_ATTRIBUTE_INVALID_ID: - if(unsupported_ok) - return CURLE_UNSUPPORTED_PROTOCOL; - default: - failf(data, "gsk_attribute_set_buffer(): %s", gsk_strerror(rc)); - break; - } - return CURLE_SSL_CONNECT_ERROR; -} - - -static CURLcode set_numeric(struct SessionHandle *data, - gsk_handle h, GSK_NUM_ID id, int value) -{ - int rc = gsk_attribute_set_numeric_value(h, id, value); - - switch (rc) { - case GSK_OK: - return CURLE_OK; - case GSK_ERROR_IO: - failf(data, "gsk_attribute_set_numeric_value() I/O error: %s", - strerror(errno)); - break; - default: - failf(data, "gsk_attribute_set_numeric_value(): %s", gsk_strerror(rc)); - break; - } - return CURLE_SSL_CONNECT_ERROR; -} - - -static CURLcode set_callback(struct SessionHandle *data, - gsk_handle h, GSK_CALLBACK_ID id, void *info) -{ - int rc = gsk_attribute_set_callback(h, id, info); - - switch (rc) { - case GSK_OK: - return CURLE_OK; - case GSK_ERROR_IO: - failf(data, "gsk_attribute_set_callback() I/O error: %s", strerror(errno)); - break; - default: - failf(data, "gsk_attribute_set_callback(): %s", gsk_strerror(rc)); - break; - } - return CURLE_SSL_CONNECT_ERROR; -} - - -static CURLcode set_ciphers(struct SessionHandle *data, - gsk_handle h, unsigned int *protoflags) -{ - const char *cipherlist = data->set.str[STRING_SSL_CIPHER_LIST]; - const char *clp; - const gskit_cipher *ctp; - int i; - int l; - bool unsupported; - CURLcode result; - struct { - char *buf; - char *ptr; - } ciphers[CURL_GSKPROTO_LAST]; - - /* Compile cipher list into GSKit-compatible cipher lists. */ - - if(!cipherlist) - return CURLE_OK; - while(is_separator(*cipherlist)) /* Skip initial separators. */ - cipherlist++; - if(!*cipherlist) - return CURLE_OK; - - /* We allocate GSKit buffers of the same size as the input string: since - GSKit tokens are always shorter than their cipher names, allocated buffers - will always be large enough to accomodate the result. */ - l = strlen(cipherlist) + 1; - memset((char *) ciphers, 0, sizeof ciphers); - for(i = 0; i < CURL_GSKPROTO_LAST; i++) { - ciphers[i].buf = malloc(l); - if(!ciphers[i].buf) { - while(i--) - free(ciphers[i].buf); - return CURLE_OUT_OF_MEMORY; - } - ciphers[i].ptr = ciphers[i].buf; - *ciphers[i].ptr = '\0'; - } - - /* Process each cipher in input string. */ - unsupported = FALSE; - result = CURLE_OK; - for(;;) { - for(clp = cipherlist; *cipherlist && !is_separator(*cipherlist);) - cipherlist++; - l = cipherlist - clp; - if(!l) - break; - /* Search the cipher in our table. */ - for(ctp = ciphertable; ctp->name; ctp++) - if(strnequal(ctp->name, clp, l) && !ctp->name[l]) - break; - if(!ctp->name) { - failf(data, "Unknown cipher %.*s", l, clp); - result = CURLE_SSL_CIPHER; - } - else { - unsupported |= !(ctp->versions & (CURL_GSKPROTO_SSLV2_MASK | - CURL_GSKPROTO_SSLV3_MASK | CURL_GSKPROTO_TLSV10_MASK)); - for(i = 0; i < CURL_GSKPROTO_LAST; i++) { - if(ctp->versions & (1 << i)) { - strcpy(ciphers[i].ptr, ctp->gsktoken); - ciphers[i].ptr += strlen(ctp->gsktoken); - } - } - } - - /* Advance to next cipher name or end of string. */ - while(is_separator(*cipherlist)) - cipherlist++; - } - - /* Disable protocols with empty cipher lists. */ - for(i = 0; i < CURL_GSKPROTO_LAST; i++) { - if(!(*protoflags & (1 << i)) || !ciphers[i].buf[0]) { - *protoflags &= ~(1 << i); - ciphers[i].buf[0] = '\0'; - } - } - - /* Try to set-up TLSv1.1 and TLSv2.1 ciphers. */ - if(*protoflags & CURL_GSKPROTO_TLSV11_MASK) { - result = set_buffer(data, h, GSK_TLSV11_CIPHER_SPECS, - ciphers[CURL_GSKPROTO_TLSV11].buf, TRUE); - if(result == CURLE_UNSUPPORTED_PROTOCOL) { - result = CURLE_OK; - if(unsupported) { - failf(data, "TLSv1.1-only ciphers are not yet supported"); - result = CURLE_SSL_CIPHER; - } - } - } - if(!result && (*protoflags & CURL_GSKPROTO_TLSV12_MASK)) { - result = set_buffer(data, h, GSK_TLSV12_CIPHER_SPECS, - ciphers[CURL_GSKPROTO_TLSV12].buf, TRUE); - if(result == CURLE_UNSUPPORTED_PROTOCOL) { - result = CURLE_OK; - if(unsupported) { - failf(data, "TLSv1.2-only ciphers are not yet supported"); - result = CURLE_SSL_CIPHER; - } - } - } - - /* Try to set-up TLSv1.0 ciphers. If not successful, concatenate them to - the SSLv3 ciphers. OS/400 prior to version 7.1 will understand it. */ - if(!result && (*protoflags & CURL_GSKPROTO_TLSV10_MASK)) { - result = set_buffer(data, h, GSK_TLSV10_CIPHER_SPECS, - ciphers[CURL_GSKPROTO_TLSV10].buf, TRUE); - if(result == CURLE_UNSUPPORTED_PROTOCOL) { - result = CURLE_OK; - strcpy(ciphers[CURL_GSKPROTO_SSLV3].ptr, - ciphers[CURL_GSKPROTO_TLSV10].ptr); - } - } - - /* Set-up other ciphers. */ - if(!result && (*protoflags & CURL_GSKPROTO_SSLV3_MASK)) - result = set_buffer(data, h, GSK_V3_CIPHER_SPECS, - ciphers[CURL_GSKPROTO_SSLV3].buf, FALSE); - if(!result && (*protoflags & CURL_GSKPROTO_SSLV2_MASK)) - result = set_buffer(data, h, GSK_V2_CIPHER_SPECS, - ciphers[CURL_GSKPROTO_SSLV2].buf, FALSE); - - /* Clean-up. */ - for(i = 0; i < CURL_GSKPROTO_LAST; i++) - free(ciphers[i].buf); - - return result; -} - - -int Curl_gskit_init(void) -{ - /* No initialisation needed. */ - - return 1; -} - - -void Curl_gskit_cleanup(void) -{ - /* Nothing to do. */ -} - - -static CURLcode init_environment(struct SessionHandle *data, - gsk_handle *envir, const char *appid, - const char *file, const char *label, - const char *password) -{ - int rc; - CURLcode result; - gsk_handle h; - - /* Creates the GSKit environment. */ - - rc = gsk_environment_open(&h); - switch (rc) { - case GSK_OK: - break; - case GSK_INSUFFICIENT_STORAGE: - return CURLE_OUT_OF_MEMORY; - default: - failf(data, "gsk_environment_open(): %s", gsk_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - - result = set_enum(data, h, GSK_SESSION_TYPE, GSK_CLIENT_SESSION, FALSE); - if(!result && appid) - result = set_buffer(data, h, GSK_OS400_APPLICATION_ID, appid, FALSE); - if(!result && file) - result = set_buffer(data, h, GSK_KEYRING_FILE, file, FALSE); - if(!result && label) - result = set_buffer(data, h, GSK_KEYRING_LABEL, label, FALSE); - if(!result && password) - result = set_buffer(data, h, GSK_KEYRING_PW, password, FALSE); - - if(!result) { - /* Locate CAs, Client certificate and key according to our settings. - Note: this call may be blocking for some tenths of seconds. */ - result = gskit_status(data, gsk_environment_init(h), - "gsk_environment_init()", CURLE_SSL_CERTPROBLEM); - if(!result) { - *envir = h; - return result; - } - } - /* Error: rollback. */ - gsk_environment_close(&h); - return result; -} - - -static void cancel_async_handshake(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - Qso_OverlappedIO_t cstat; - - if(QsoCancelOperation(conn->sock[sockindex], 0) > 0) - QsoWaitForIOCompletion(connssl->iocport, &cstat, (struct timeval *) NULL); -} - - -static void close_async_handshake(struct ssl_connect_data *connssl) -{ - QsoDestroyIOCompletionPort(connssl->iocport); - connssl->iocport = -1; -} - - -static void close_one(struct ssl_connect_data *conn, - struct SessionHandle *data) -{ - if(conn->handle) { - gskit_status(data, gsk_secure_soc_close(&conn->handle), - "gsk_secure_soc_close()", 0); - conn->handle = (gsk_handle) NULL; - } - if(conn->iocport >= 0) - close_async_handshake(conn); -} - - -static ssize_t gskit_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, CURLcode *curlcode) -{ - struct SessionHandle *data = conn->data; - CURLcode cc; - int written; - - cc = gskit_status(data, - gsk_secure_soc_write(conn->ssl[sockindex].handle, - (char *) mem, (int) len, &written), - "gsk_secure_soc_write()", CURLE_SEND_ERROR); - if(cc != CURLE_OK) { - *curlcode = cc; - written = -1; - } - return (ssize_t) written; /* number of bytes */ -} - - -static ssize_t gskit_recv(struct connectdata *conn, int num, char *buf, - size_t buffersize, CURLcode *curlcode) -{ - struct SessionHandle *data = conn->data; - int buffsize; - int nread; - CURLcode cc; - - buffsize = buffersize > (size_t) INT_MAX? INT_MAX: (int) buffersize; - cc = gskit_status(data, gsk_secure_soc_read(conn->ssl[num].handle, - buf, buffsize, &nread), - "gsk_secure_soc_read()", CURLE_RECV_ERROR); - if(cc != CURLE_OK) { - *curlcode = cc; - nread = -1; - } - return (ssize_t) nread; -} - - -static CURLcode gskit_connect_step1(struct connectdata *conn, int sockindex) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - gsk_handle envir; - CURLcode result; - int rc; - char *keyringfile; - char *keyringpwd; - char *keyringlabel; - char *sni; - unsigned int protoflags; - long timeout; - Qso_OverlappedIO_t commarea; - - /* Create SSL environment, start (preferably asynchronous) handshake. */ - - connssl->handle = (gsk_handle) NULL; - connssl->iocport = -1; - - /* GSKit supports two ways of specifying an SSL context: either by - * application identifier (that should have been defined at the system - * level) or by keyring file, password and certificate label. - * Local certificate name (CURLOPT_SSLCERT) is used to hold either the - * application identifier of the certificate label. - * Key password (CURLOPT_KEYPASSWD) holds the keyring password. - * It is not possible to have different keyrings for the CAs and the - * local certificate. We thus use the CA file (CURLOPT_CAINFO) to identify - * the keyring file. - * If no key password is given and the keyring is the system keyring, - * application identifier mode is tried first, as recommended in IBM doc. - */ - - keyringfile = data->set.str[STRING_SSL_CAFILE]; - keyringpwd = data->set.str[STRING_KEY_PASSWD]; - keyringlabel = data->set.str[STRING_CERT]; - envir = (gsk_handle) NULL; - - if(keyringlabel && *keyringlabel && !keyringpwd && - !strcmp(keyringfile, CURL_CA_BUNDLE)) { - /* Try application identifier mode. */ - init_environment(data, &envir, keyringlabel, (const char *) NULL, - (const char *) NULL, (const char *) NULL); - } - - if(!envir) { - /* Use keyring mode. */ - result = init_environment(data, &envir, (const char *) NULL, - keyringfile, keyringlabel, keyringpwd); - if(result) - return result; - } - - /* Create secure session. */ - result = gskit_status(data, gsk_secure_soc_open(envir, &connssl->handle), - "gsk_secure_soc_open()", CURLE_SSL_CONNECT_ERROR); - gsk_environment_close(&envir); - if(result) - return result; - - /* Determine which SSL/TLS version should be enabled. */ - protoflags = CURL_GSKPROTO_TLSV10_MASK | CURL_GSKPROTO_TLSV11_MASK | - CURL_GSKPROTO_TLSV12_MASK; - sni = conn->host.name; - switch (data->set.ssl.version) { - case CURL_SSLVERSION_SSLv2: - protoflags = CURL_GSKPROTO_SSLV2_MASK; - sni = (char *) NULL; - break; - case CURL_SSLVERSION_SSLv3: - protoflags = CURL_GSKPROTO_SSLV3_MASK; - sni = (char *) NULL; - break; - case CURL_SSLVERSION_TLSv1: - protoflags = CURL_GSKPROTO_TLSV10_MASK | - CURL_GSKPROTO_TLSV11_MASK | CURL_GSKPROTO_TLSV12_MASK; - break; - case CURL_SSLVERSION_TLSv1_0: - protoflags = CURL_GSKPROTO_TLSV10_MASK; - break; - case CURL_SSLVERSION_TLSv1_1: - protoflags = CURL_GSKPROTO_TLSV11_MASK; - break; - case CURL_SSLVERSION_TLSv1_2: - protoflags = CURL_GSKPROTO_TLSV12_MASK; - break; - } - - /* Process SNI. Ignore if not supported (on OS400 < V7R1). */ - if(sni) { - result = set_buffer(data, connssl->handle, - GSK_SSL_EXTN_SERVERNAME_REQUEST, sni, TRUE); - if(result == CURLE_UNSUPPORTED_PROTOCOL) - result = CURLE_OK; - } - - /* Set session parameters. */ - if(!result) { - /* Compute the handshake timeout. Since GSKit granularity is 1 second, - we round up the required value. */ - timeout = Curl_timeleft(data, NULL, TRUE); - if(timeout < 0) - result = CURLE_OPERATION_TIMEDOUT; - else - result = set_numeric(data, connssl->handle, GSK_HANDSHAKE_TIMEOUT, - (timeout + 999) / 1000); - } - if(!result) - result = set_numeric(data, connssl->handle, GSK_FD, conn->sock[sockindex]); - if(!result) - result = set_ciphers(data, connssl->handle, &protoflags); - if(!protoflags) { - failf(data, "No SSL protocol/cipher combination enabled"); - result = CURLE_SSL_CIPHER; - } - if(!result) - result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV2, - (protoflags & CURL_GSKPROTO_SSLV2_MASK)? - GSK_PROTOCOL_SSLV2_ON: GSK_PROTOCOL_SSLV2_OFF, FALSE); - if(!result) - result = set_enum(data, connssl->handle, GSK_PROTOCOL_SSLV3, - (protoflags & CURL_GSKPROTO_SSLV3_MASK)? - GSK_PROTOCOL_SSLV3_ON: GSK_PROTOCOL_SSLV3_OFF, FALSE); - if(!result) - result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV1, - (protoflags & CURL_GSKPROTO_TLSV10_MASK)? - GSK_PROTOCOL_TLSV1_ON: GSK_PROTOCOL_TLSV1_OFF, FALSE); - if(!result) { - result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV11, - (protoflags & CURL_GSKPROTO_TLSV11_MASK)? - GSK_TRUE: GSK_FALSE, TRUE); - if(result == CURLE_UNSUPPORTED_PROTOCOL) { - result = CURLE_OK; - if(protoflags == CURL_GSKPROTO_TLSV11_MASK) { - failf(data, "TLS 1.1 not yet supported"); - result = CURLE_SSL_CIPHER; - } - } - } - if(!result) { - result = set_enum(data, connssl->handle, GSK_PROTOCOL_TLSV12, - (protoflags & CURL_GSKPROTO_TLSV12_MASK)? - GSK_TRUE: GSK_FALSE, TRUE); - if(result == CURLE_UNSUPPORTED_PROTOCOL) { - result = CURLE_OK; - if(protoflags == CURL_GSKPROTO_TLSV12_MASK) { - failf(data, "TLS 1.2 not yet supported"); - result = CURLE_SSL_CIPHER; - } - } - } - if(!result) - result = set_enum(data, connssl->handle, GSK_SERVER_AUTH_TYPE, - data->set.ssl.verifypeer? GSK_SERVER_AUTH_FULL: - GSK_SERVER_AUTH_PASSTHRU, FALSE); - - if(!result) { - /* Start handshake. Try asynchronous first. */ - memset(&commarea, 0, sizeof commarea); - connssl->iocport = QsoCreateIOCompletionPort(); - if(connssl->iocport != -1) { - result = gskit_status(data, - gsk_secure_soc_startInit(connssl->handle, - connssl->iocport, - &commarea), - "gsk_secure_soc_startInit()", - CURLE_SSL_CONNECT_ERROR); - if(!result) { - connssl->connecting_state = ssl_connect_2; - return CURLE_OK; - } - else - close_async_handshake(connssl); - } - else if(errno != ENOBUFS) - result = gskit_status(data, GSK_ERROR_IO, - "QsoCreateIOCompletionPort()", 0); - else { - /* No more completion port available. Use synchronous IO. */ - result = gskit_status(data, gsk_secure_soc_init(connssl->handle), - "gsk_secure_soc_init()", CURLE_SSL_CONNECT_ERROR); - if(!result) { - connssl->connecting_state = ssl_connect_3; - return CURLE_OK; - } - } - } - - /* Error: rollback. */ - close_one(connssl, data); - return result; -} - - -static CURLcode gskit_connect_step2(struct connectdata *conn, int sockindex, - bool nonblocking) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - Qso_OverlappedIO_t cstat; - long timeout_ms; - struct timeval stmv; - CURLcode result; - - /* Poll or wait for end of SSL asynchronous handshake. */ - - for(;;) { - timeout_ms = nonblocking? 0: Curl_timeleft(data, NULL, TRUE); - if(timeout_ms < 0) - timeout_ms = 0; - stmv.tv_sec = timeout_ms / 1000; - stmv.tv_usec = (timeout_ms - stmv.tv_sec * 1000) * 1000; - switch (QsoWaitForIOCompletion(connssl->iocport, &cstat, &stmv)) { - case 1: /* Operation complete. */ - break; - case -1: /* An error occurred: handshake still in progress. */ - if(errno == EINTR) { - if(nonblocking) - return CURLE_OK; - continue; /* Retry. */ - } - if(errno != ETIME) { - failf(data, "QsoWaitForIOCompletion() I/O error: %s", strerror(errno)); - cancel_async_handshake(conn, sockindex); - close_async_handshake(connssl); - return CURLE_SSL_CONNECT_ERROR; - } - /* FALL INTO... */ - case 0: /* Handshake in progress, timeout occurred. */ - if(nonblocking) - return CURLE_OK; - cancel_async_handshake(conn, sockindex); - close_async_handshake(connssl); - return CURLE_OPERATION_TIMEDOUT; - } - break; - } - result = gskit_status(data, cstat.returnValue, "SSL handshake", - CURLE_SSL_CONNECT_ERROR); - if(!result) - connssl->connecting_state = ssl_connect_3; - close_async_handshake(connssl); - return result; -} - - -static CURLcode gskit_connect_step3(struct connectdata *conn, int sockindex) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - const gsk_cert_data_elem *cdev; - int cdec; - const gsk_cert_data_elem *p; - const char *cert = (const char *) NULL; - const char *certend; - const char *ptr; - int i; - CURLcode result; - - /* SSL handshake done: gather certificate info and verify host. */ - - if(gskit_status(data, gsk_attribute_get_cert_info(connssl->handle, - GSK_PARTNER_CERT_INFO, - &cdev, &cdec), - "gsk_attribute_get_cert_info()", CURLE_SSL_CONNECT_ERROR) == - CURLE_OK) { - infof(data, "Server certificate:\n"); - p = cdev; - for(i = 0; i++ < cdec; p++) - switch (p->cert_data_id) { - case CERT_BODY_DER: - cert = p->cert_data_p; - certend = cert + cdev->cert_data_l; - break; - case CERT_DN_PRINTABLE: - infof(data, "\t subject: %.*s\n", p->cert_data_l, p->cert_data_p); - break; - case CERT_ISSUER_DN_PRINTABLE: - infof(data, "\t issuer: %.*s\n", p->cert_data_l, p->cert_data_p); - break; - case CERT_VALID_FROM: - infof(data, "\t start date: %.*s\n", p->cert_data_l, p->cert_data_p); - break; - case CERT_VALID_TO: - infof(data, "\t expire date: %.*s\n", p->cert_data_l, p->cert_data_p); - break; - } - } - - /* Verify host. */ - result = Curl_verifyhost(conn, cert, certend); - if(result) - return result; - - /* The only place GSKit can get the whole CA chain is a validation - callback where no user data pointer is available. Therefore it's not - possible to copy this chain into our structures for CAINFO. - However the server certificate may be available, thus we can return - info about it. */ - if(data->set.ssl.certinfo) { - result = Curl_ssl_init_certinfo(data, 1); - if(result) - return result; - - if(cert) { - result = Curl_extract_certinfo(conn, 0, cert, certend); - if(result) - return result; - } - } - - /* Check pinned public key. */ - ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; - if(!result && ptr) { - curl_X509certificate x509; - curl_asn1Element *p; - - if(!cert) - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - Curl_parseX509(&x509, cert, certend); - p = &x509.subjectPublicKeyInfo; - result = Curl_pin_peer_pubkey(data, ptr, p->header, p->end - p->header); - if(result) { - failf(data, "SSL: public key does not match pinned public key!"); - return result; - } - } - - connssl->connecting_state = ssl_connect_done; - return CURLE_OK; -} - - -static CURLcode gskit_connect_common(struct connectdata *conn, int sockindex, - bool nonblocking, bool *done) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - long timeout_ms; - Qso_OverlappedIO_t cstat; - CURLcode result = CURLE_OK; - - *done = connssl->state == ssl_connection_complete; - if(*done) - return CURLE_OK; - - /* Step 1: create session, start handshake. */ - if(connssl->connecting_state == ssl_connect_1) { - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - result = CURLE_OPERATION_TIMEDOUT; - } - else - result = gskit_connect_step1(conn, sockindex); - } - - /* Step 2: check if handshake is over. */ - if(!result && connssl->connecting_state == ssl_connect_2) { - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - result = CURLE_OPERATION_TIMEDOUT; - } - else - result = gskit_connect_step2(conn, sockindex, nonblocking); - } - - /* Step 3: gather certificate info, verify host. */ - if(!result && connssl->connecting_state == ssl_connect_3) - result = gskit_connect_step3(conn, sockindex); - - if(result) - close_one(connssl, data); - else if(connssl->connecting_state == ssl_connect_done) { - connssl->state = ssl_connection_complete; - connssl->connecting_state = ssl_connect_1; - conn->recv[sockindex] = gskit_recv; - conn->send[sockindex] = gskit_send; - *done = TRUE; - } - - return result; -} - - -CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done) -{ - CURLcode result; - - result = gskit_connect_common(conn, sockindex, TRUE, done); - if(*done || result) - conn->ssl[sockindex].connecting_state = ssl_connect_1; - return result; -} - - -CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex) -{ - CURLcode result; - bool done; - - conn->ssl[sockindex].connecting_state = ssl_connect_1; - result = gskit_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - - -void Curl_gskit_close(struct connectdata *conn, int sockindex) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - if(connssl->use) - close_one(connssl, data); -} - - -int Curl_gskit_shutdown(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - ssize_t nread; - int what; - int rc; - char buf[120]; - - if(!connssl->handle) - return 0; - - if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE) - return 0; - - close_one(connssl, data); - rc = 0; - what = Curl_socket_ready(conn->sock[sockindex], - CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); - - for(;;) { - if(what < 0) { - /* anything that gets here is fatally bad */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - rc = -1; - break; - } - - if(!what) { /* timeout */ - failf(data, "SSL shutdown timeout"); - break; - } - - /* Something to read, let's do it and hope that it is the close - notify alert from the server. No way to gsk_secure_soc_read() now, so - use read(). */ - - nread = read(conn->sock[sockindex], buf, sizeof(buf)); - - if(nread < 0) { - failf(data, "read: %s", strerror(errno)); - rc = -1; - } - - if(nread <= 0) - break; - - what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, 0); - } - - return rc; -} - - -size_t Curl_gskit_version(char *buffer, size_t size) -{ - strncpy(buffer, "GSKit", size); - return strlen(buffer); -} - - -int Curl_gskit_check_cxn(struct connectdata *cxn) -{ - int err; - int errlen; - - /* The only thing that can be tested here is at the socket level. */ - - if(!cxn->ssl[FIRSTSOCKET].handle) - return 0; /* connection has been closed */ - - err = 0; - errlen = sizeof err; - - if(getsockopt(cxn->sock[FIRSTSOCKET], SOL_SOCKET, SO_ERROR, - (unsigned char *) &err, &errlen) || - errlen != sizeof err || err) - return 0; /* connection has been closed */ - - return -1; /* connection status unknown */ -} - -#endif /* USE_GSKIT */ diff --git a/Externals/curl/lib/vtls/gskit.h b/Externals/curl/lib/vtls/gskit.h deleted file mode 100644 index 41483cba62..0000000000 --- a/Externals/curl/lib/vtls/gskit.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef HEADER_CURL_GSKIT_H -#define HEADER_CURL_GSKIT_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -/* - * This header should only be needed to get included by vtls.c and gskit.c - */ - -#include "urldata.h" - -#ifdef USE_GSKIT -int Curl_gskit_init(void); -void Curl_gskit_cleanup(void); -CURLcode Curl_gskit_connect(struct connectdata *conn, int sockindex); -CURLcode Curl_gskit_connect_nonblocking(struct connectdata *conn, - int sockindex, bool *done); -void Curl_gskit_close(struct connectdata *conn, int sockindex); -int Curl_gskit_shutdown(struct connectdata *conn, int sockindex); - -size_t Curl_gskit_version(char *buffer, size_t size); -int Curl_gskit_check_cxn(struct connectdata *cxn); - -/* Set the API backend definition to GSKit */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_GSKIT - -/* this backend supports CURLOPT_CERTINFO */ -#define have_curlssl_certinfo 1 - -/* API setup for GSKit */ -#define curlssl_init Curl_gskit_init -#define curlssl_cleanup Curl_gskit_cleanup -#define curlssl_connect Curl_gskit_connect -#define curlssl_connect_nonblocking Curl_gskit_connect_nonblocking - -/* No session handling for GSKit */ -#define curlssl_session_free(x) Curl_nop_stmt -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_gskit_close -#define curlssl_shutdown(x,y) Curl_gskit_shutdown(x,y) -#define curlssl_set_engine(x,y) CURLE_NOT_BUILT_IN -#define curlssl_set_engine_default(x) CURLE_NOT_BUILT_IN -#define curlssl_engines_list(x) NULL -#define curlssl_version Curl_gskit_version -#define curlssl_check_cxn(x) Curl_gskit_check_cxn(x) -#define curlssl_data_pending(x,y) 0 -#define curlssl_random(x,y,z) -1 - -#endif /* USE_GSKIT */ - -#endif /* HEADER_CURL_GSKIT_H */ diff --git a/Externals/curl/lib/vtls/gtls.c b/Externals/curl/lib/vtls/gtls.c deleted file mode 100644 index 1b5a6a4d52..0000000000 --- a/Externals/curl/lib/vtls/gtls.c +++ /dev/null @@ -1,1627 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all GnuTLS-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - * Note: don't use the GnuTLS' *_t variable type names in this source code, - * since they were not present in 1.0.X. - */ - -#include "curl_setup.h" - -#ifdef USE_GNUTLS - -#include -#include -#include - -#ifdef USE_GNUTLS_NETTLE -#include -#include -#include -#else -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "gtls.h" -#include "vtls.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "rawstr.h" -#include "warnless.h" -#include "x509asn1.h" -#include "curl_printf.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* - Some hackish cast macros based on: - https://developer.gnome.org/glib/unstable/glib-Type-Conversion-Macros.html -*/ -#ifndef GNUTLS_POINTER_TO_INT_CAST -#define GNUTLS_POINTER_TO_INT_CAST(p) ((int) (long) (p)) -#endif -#ifndef GNUTLS_INT_TO_POINTER_CAST -#define GNUTLS_INT_TO_POINTER_CAST(i) ((void*) (long) (i)) -#endif - -/* Enable GnuTLS debugging by defining GTLSDEBUG */ -/*#define GTLSDEBUG */ - -#ifdef GTLSDEBUG -static void tls_log_func(int level, const char *str) -{ - fprintf(stderr, "|<%d>| %s", level, str); -} -#endif -static bool gtls_inited = FALSE; - -#if defined(GNUTLS_VERSION_NUMBER) -# if (GNUTLS_VERSION_NUMBER >= 0x020c00) -# undef gnutls_transport_set_lowat -# define gnutls_transport_set_lowat(A,B) Curl_nop_stmt -# define USE_GNUTLS_PRIORITY_SET_DIRECT 1 -# endif -# if (GNUTLS_VERSION_NUMBER >= 0x020c03) -# define GNUTLS_MAPS_WINSOCK_ERRORS 1 -# endif - -# if (GNUTLS_VERSION_NUMBER >= 0x030200) -# define HAS_ALPN -# endif - -# if (GNUTLS_VERSION_NUMBER >= 0x03020d) -# define HAS_OCSP -# endif - -# if (GNUTLS_VERSION_NUMBER >= 0x030306) -# define HAS_CAPATH -# endif -#endif - -#ifdef HAS_OCSP -# include -#endif - -/* - * Custom push and pull callback functions used by GNU TLS to read and write - * to the socket. These functions are simple wrappers to send() and recv() - * (although here using the sread/swrite macros as defined by - * curl_setup_once.h). - * We use custom functions rather than the GNU TLS defaults because it allows - * us to get specific about the fourth "flags" argument, and to use arbitrary - * private data with gnutls_transport_set_ptr if we wish. - * - * When these custom push and pull callbacks fail, GNU TLS checks its own - * session-specific error variable, and when not set also its own global - * errno variable, in order to take appropriate action. GNU TLS does not - * require that the transport is actually a socket. This implies that for - * Windows builds these callbacks should ideally set the session-specific - * error variable using function gnutls_transport_set_errno or as a last - * resort global errno variable using gnutls_transport_set_global_errno, - * with a transport agnostic error value. This implies that some winsock - * error translation must take place in these callbacks. - * - * Paragraph above applies to GNU TLS versions older than 2.12.3, since - * this version GNU TLS does its own internal winsock error translation - * using system_errno() function. - */ - -#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) -# define gtls_EINTR 4 -# define gtls_EIO 5 -# define gtls_EAGAIN 11 -static int gtls_mapped_sockerrno(void) -{ - switch(SOCKERRNO) { - case WSAEWOULDBLOCK: - return gtls_EAGAIN; - case WSAEINTR: - return gtls_EINTR; - default: - break; - } - return gtls_EIO; -} -#endif - -static ssize_t Curl_gtls_push(void *s, const void *buf, size_t len) -{ - ssize_t ret = swrite(GNUTLS_POINTER_TO_INT_CAST(s), buf, len); -#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) - if(ret < 0) - gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); -#endif - return ret; -} - -static ssize_t Curl_gtls_pull(void *s, void *buf, size_t len) -{ - ssize_t ret = sread(GNUTLS_POINTER_TO_INT_CAST(s), buf, len); -#if defined(USE_WINSOCK) && !defined(GNUTLS_MAPS_WINSOCK_ERRORS) - if(ret < 0) - gnutls_transport_set_global_errno(gtls_mapped_sockerrno()); -#endif - return ret; -} - -/* Curl_gtls_init() - * - * Global GnuTLS init, called from Curl_ssl_init(). This calls functions that - * are not thread-safe and thus this function itself is not thread-safe and - * must only be called from within curl_global_init() to keep the thread - * situation under control! - */ -int Curl_gtls_init(void) -{ - int ret = 1; - if(!gtls_inited) { - ret = gnutls_global_init()?0:1; -#ifdef GTLSDEBUG - gnutls_global_set_log_function(tls_log_func); - gnutls_global_set_log_level(2); -#endif - gtls_inited = TRUE; - } - return ret; -} - -int Curl_gtls_cleanup(void) -{ - if(gtls_inited) { - gnutls_global_deinit(); - gtls_inited = FALSE; - } - return 1; -} - -static void showtime(struct SessionHandle *data, - const char *text, - time_t stamp) -{ - struct tm buffer; - const struct tm *tm = &buffer; - CURLcode result = Curl_gmtime(stamp, &buffer); - if(result) - return; - - snprintf(data->state.buffer, - BUFSIZE, - "\t %s: %s, %02d %s %4d %02d:%02d:%02d GMT", - text, - Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], - tm->tm_mday, - Curl_month[tm->tm_mon], - tm->tm_year + 1900, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - infof(data, "%s\n", data->state.buffer); -} - -static gnutls_datum_t load_file (const char *file) -{ - FILE *f; - gnutls_datum_t loaded_file = { NULL, 0 }; - long filelen; - void *ptr; - - if(!(f = fopen(file, "rb"))) - return loaded_file; - if(fseek(f, 0, SEEK_END) != 0 - || (filelen = ftell(f)) < 0 - || fseek(f, 0, SEEK_SET) != 0 - || !(ptr = malloc((size_t)filelen))) - goto out; - if(fread(ptr, 1, (size_t)filelen, f) < (size_t)filelen) { - free(ptr); - goto out; - } - - loaded_file.data = ptr; - loaded_file.size = (unsigned int)filelen; -out: - fclose(f); - return loaded_file; -} - -static void unload_file(gnutls_datum_t data) { - free(data.data); -} - - -/* this function does a SSL/TLS (re-)handshake */ -static CURLcode handshake(struct connectdata *conn, - int sockindex, - bool duringconnect, - bool nonblocking) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - gnutls_session_t session = conn->ssl[sockindex].session; - curl_socket_t sockfd = conn->sock[sockindex]; - long timeout_ms; - int rc; - int what; - - for(;;) { - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, duringconnect); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading - || connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_ready(readfd, writefd, - nonblocking?0: - timeout_ms?timeout_ms:1000); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) - return CURLE_OK; - else if(timeout_ms) { - /* timeout */ - failf(data, "SSL connection timeout at %ld", timeout_ms); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - rc = gnutls_handshake(session); - - if((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) { - connssl->connecting_state = - gnutls_record_get_direction(session)? - ssl_connect_2_writing:ssl_connect_2_reading; - continue; - } - else if((rc < 0) && !gnutls_error_is_fatal(rc)) { - const char *strerr = NULL; - - if(rc == GNUTLS_E_WARNING_ALERT_RECEIVED) { - int alert = gnutls_alert_get(session); - strerr = gnutls_alert_get_name(alert); - } - - if(strerr == NULL) - strerr = gnutls_strerror(rc); - - infof(data, "gnutls_handshake() warning: %s\n", strerr); - continue; - } - else if(rc < 0) { - const char *strerr = NULL; - - if(rc == GNUTLS_E_FATAL_ALERT_RECEIVED) { - int alert = gnutls_alert_get(session); - strerr = gnutls_alert_get_name(alert); - } - - if(strerr == NULL) - strerr = gnutls_strerror(rc); - - failf(data, "gnutls_handshake() failed: %s", strerr); - return CURLE_SSL_CONNECT_ERROR; - } - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - return CURLE_OK; - } -} - -static gnutls_x509_crt_fmt_t do_file_type(const char *type) -{ - if(!type || !type[0]) - return GNUTLS_X509_FMT_PEM; - if(Curl_raw_equal(type, "PEM")) - return GNUTLS_X509_FMT_PEM; - if(Curl_raw_equal(type, "DER")) - return GNUTLS_X509_FMT_DER; - return -1; -} - -static CURLcode -gtls_connect_step1(struct connectdata *conn, - int sockindex) -{ - struct SessionHandle *data = conn->data; - gnutls_session_t session; - int rc; - void *ssl_sessionid; - size_t ssl_idsize; - bool sni = TRUE; /* default is SNI enabled */ -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif -#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT - static const int cipher_priority[] = { - /* These two ciphers were added to GnuTLS as late as ver. 3.0.1, - but this code path is only ever used for ver. < 2.12.0. - GNUTLS_CIPHER_AES_128_GCM, - GNUTLS_CIPHER_AES_256_GCM, - */ - GNUTLS_CIPHER_AES_128_CBC, - GNUTLS_CIPHER_AES_256_CBC, - GNUTLS_CIPHER_CAMELLIA_128_CBC, - GNUTLS_CIPHER_CAMELLIA_256_CBC, - GNUTLS_CIPHER_3DES_CBC, - }; - static const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 }; - static int protocol_priority[] = { 0, 0, 0, 0 }; -#else -#define GNUTLS_CIPHERS "NORMAL:-ARCFOUR-128:-CTYPE-ALL:+CTYPE-X509" -/* If GnuTLS was compiled without support for SRP it will error out if SRP is - requested in the priority string, so treat it specially - */ -#define GNUTLS_SRP "+SRP" - const char* prioritylist; - const char *err = NULL; -#endif - - if(conn->ssl[sockindex].state == ssl_connection_complete) - /* to make us tolerant against being called more than once for the - same connection */ - return CURLE_OK; - - if(!gtls_inited) - Curl_gtls_init(); - - /* GnuTLS only supports SSLv3 and TLSv1 */ - if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { - failf(data, "GnuTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) - sni = FALSE; /* SSLv3 has no SNI */ - - /* allocate a cred struct */ - rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef USE_TLS_SRP - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { - infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username); - - rc = gnutls_srp_allocate_client_credentials( - &conn->ssl[sockindex].srp_client_cred); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_srp_allocate_client_cred() failed: %s", - gnutls_strerror(rc)); - return CURLE_OUT_OF_MEMORY; - } - - rc = gnutls_srp_set_client_credentials(conn->ssl[sockindex]. - srp_client_cred, - data->set.ssl.username, - data->set.ssl.password); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_srp_set_client_cred() failed: %s", - gnutls_strerror(rc)); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - } -#endif - - if(data->set.ssl.CAfile) { - /* set the trusted CA cert bundle file */ - gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred, - GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); - - rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred, - data->set.ssl.CAfile, - GNUTLS_X509_FMT_PEM); - if(rc < 0) { - infof(data, "error reading ca cert file %s (%s)\n", - data->set.ssl.CAfile, gnutls_strerror(rc)); - if(data->set.ssl.verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } - else - infof(data, "found %d certificates in %s\n", - rc, data->set.ssl.CAfile); - } - -#ifdef HAS_CAPATH - if(data->set.ssl.CApath) { - /* set the trusted CA cert directory */ - rc = gnutls_certificate_set_x509_trust_dir(conn->ssl[sockindex].cred, - data->set.ssl.CApath, - GNUTLS_X509_FMT_PEM); - if(rc < 0) { - infof(data, "error reading ca cert file %s (%s)\n", - data->set.ssl.CAfile, gnutls_strerror(rc)); - if(data->set.ssl.verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } - else - infof(data, "found %d certificates in %s\n", - rc, data->set.ssl.CApath); - } -#endif - -#ifdef CURL_CA_FALLBACK - /* use system ca certificate store as fallback */ - if(data->set.ssl.verifypeer && - !(data->set.ssl.CAfile || data->set.ssl.CApath)) { - gnutls_certificate_set_x509_system_trust(conn->ssl[sockindex].cred); - } -#endif - - if(data->set.ssl.CRLfile) { - /* set the CRL list file */ - rc = gnutls_certificate_set_x509_crl_file(conn->ssl[sockindex].cred, - data->set.ssl.CRLfile, - GNUTLS_X509_FMT_PEM); - if(rc < 0) { - failf(data, "error reading crl file %s (%s)", - data->set.ssl.CRLfile, gnutls_strerror(rc)); - return CURLE_SSL_CRL_BADFILE; - } - else - infof(data, "found %d CRL in %s\n", - rc, data->set.ssl.CRLfile); - } - - /* Initialize TLS session as a client */ - rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_init() failed: %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - - /* convenient assign */ - session = conn->ssl[sockindex].session; - - if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) && -#ifdef ENABLE_IPV6 - (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) && -#endif - sni && - (gnutls_server_name_set(session, GNUTLS_NAME_DNS, conn->host.name, - strlen(conn->host.name)) < 0)) - infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension\n"); - - /* Use default priorities */ - rc = gnutls_set_default_priority(session); - if(rc != GNUTLS_E_SUCCESS) - return CURLE_SSL_CONNECT_ERROR; - -#ifndef USE_GNUTLS_PRIORITY_SET_DIRECT - rc = gnutls_cipher_set_priority(session, cipher_priority); - if(rc != GNUTLS_E_SUCCESS) - return CURLE_SSL_CONNECT_ERROR; - - /* Sets the priority on the certificate types supported by gnutls. Priority - is higher for types specified before others. After specifying the types - you want, you must append a 0. */ - rc = gnutls_certificate_type_set_priority(session, cert_type_priority); - if(rc != GNUTLS_E_SUCCESS) - return CURLE_SSL_CONNECT_ERROR; - - if(data->set.ssl.cipher_list != NULL) { - failf(data, "can't pass a custom cipher list to older GnuTLS" - " versions"); - return CURLE_SSL_CONNECT_ERROR; - } - - switch (data->set.ssl.version) { - case CURL_SSLVERSION_SSLv3: - protocol_priority[0] = GNUTLS_SSL3; - break; - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - protocol_priority[0] = GNUTLS_TLS1_0; - protocol_priority[1] = GNUTLS_TLS1_1; - protocol_priority[2] = GNUTLS_TLS1_2; - break; - case CURL_SSLVERSION_TLSv1_0: - protocol_priority[0] = GNUTLS_TLS1_0; - break; - case CURL_SSLVERSION_TLSv1_1: - protocol_priority[0] = GNUTLS_TLS1_1; - break; - case CURL_SSLVERSION_TLSv1_2: - protocol_priority[0] = GNUTLS_TLS1_2; - break; - case CURL_SSLVERSION_SSLv2: - default: - failf(data, "GnuTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - break; - } - rc = gnutls_protocol_set_priority(session, protocol_priority); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "Did you pass a valid GnuTLS cipher list?"); - return CURLE_SSL_CONNECT_ERROR; - } - -#else - /* Ensure +SRP comes at the *end* of all relevant strings so that it can be - * removed if a run-time error indicates that SRP is not supported by this - * GnuTLS version */ - switch (data->set.ssl.version) { - case CURL_SSLVERSION_SSLv3: - prioritylist = GNUTLS_CIPHERS ":-VERS-TLS-ALL:+VERS-SSL3.0"; - sni = false; - break; - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:" GNUTLS_SRP; - break; - case CURL_SSLVERSION_TLSv1_0: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.0:" GNUTLS_SRP; - break; - case CURL_SSLVERSION_TLSv1_1: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.1:" GNUTLS_SRP; - break; - case CURL_SSLVERSION_TLSv1_2: - prioritylist = GNUTLS_CIPHERS ":-VERS-SSL3.0:-VERS-TLS-ALL:" - "+VERS-TLS1.2:" GNUTLS_SRP; - break; - case CURL_SSLVERSION_SSLv2: - default: - failf(data, "GnuTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - break; - } - rc = gnutls_priority_set_direct(session, prioritylist, &err); - if((rc == GNUTLS_E_INVALID_REQUEST) && err) { - if(!strcmp(err, GNUTLS_SRP)) { - /* This GnuTLS was probably compiled without support for SRP. - * Note that fact and try again without it. */ - int validprioritylen = curlx_uztosi(err - prioritylist); - char *prioritycopy = strdup(prioritylist); - if(!prioritycopy) - return CURLE_OUT_OF_MEMORY; - - infof(data, "This GnuTLS does not support SRP\n"); - if(validprioritylen) - /* Remove the :+SRP */ - prioritycopy[validprioritylen - 1] = 0; - rc = gnutls_priority_set_direct(session, prioritycopy, &err); - free(prioritycopy); - } - } - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "Error %d setting GnuTLS cipher list starting with %s", - rc, err); - return CURLE_SSL_CONNECT_ERROR; - } -#endif - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - int cur = 0; - gnutls_datum_t protocols[2]; - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - protocols[cur].data = (unsigned char *)NGHTTP2_PROTO_VERSION_ID; - protocols[cur].size = NGHTTP2_PROTO_VERSION_ID_LEN; - cur++; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - protocols[cur].data = (unsigned char *)ALPN_HTTP_1_1; - protocols[cur].size = ALPN_HTTP_1_1_LENGTH; - cur++; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - gnutls_alpn_set_protocols(session, protocols, cur, 0); - } -#endif - - if(data->set.str[STRING_CERT]) { - if(data->set.str[STRING_KEY_PASSWD]) { -#if HAVE_GNUTLS_CERTIFICATE_SET_X509_KEY_FILE2 - const unsigned int supported_key_encryption_algorithms = - GNUTLS_PKCS_USE_PKCS12_3DES | GNUTLS_PKCS_USE_PKCS12_ARCFOUR | - GNUTLS_PKCS_USE_PKCS12_RC2_40 | GNUTLS_PKCS_USE_PBES2_3DES | - GNUTLS_PKCS_USE_PBES2_AES_128 | GNUTLS_PKCS_USE_PBES2_AES_192 | - GNUTLS_PKCS_USE_PBES2_AES_256; - rc = gnutls_certificate_set_x509_key_file2( - conn->ssl[sockindex].cred, - data->set.str[STRING_CERT], - data->set.str[STRING_KEY] ? - data->set.str[STRING_KEY] : data->set.str[STRING_CERT], - do_file_type(data->set.str[STRING_CERT_TYPE]), - data->set.str[STRING_KEY_PASSWD], - supported_key_encryption_algorithms); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, - "error reading X.509 potentially-encrypted key file: %s", - gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } -#else - failf(data, "gnutls lacks support for encrypted key files"); - return CURLE_SSL_CONNECT_ERROR; -#endif - } - else { - rc = gnutls_certificate_set_x509_key_file( - conn->ssl[sockindex].cred, - data->set.str[STRING_CERT], - data->set.str[STRING_KEY] ? - data->set.str[STRING_KEY] : data->set.str[STRING_CERT], - do_file_type(data->set.str[STRING_CERT_TYPE]) ); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "error reading X.509 key or certificate file: %s", - gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - } - -#ifdef USE_TLS_SRP - /* put the credentials to the current session */ - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { - rc = gnutls_credentials_set(session, GNUTLS_CRD_SRP, - conn->ssl[sockindex].srp_client_cred); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - else -#endif - { - rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, - conn->ssl[sockindex].cred); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_credentials_set() failed: %s", gnutls_strerror(rc)); - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* set the connection handle (file descriptor for the socket) */ - gnutls_transport_set_ptr(session, - GNUTLS_INT_TO_POINTER_CAST(conn->sock[sockindex])); - - /* register callback functions to send and receive data. */ - gnutls_transport_set_push_function(session, Curl_gtls_push); - gnutls_transport_set_pull_function(session, Curl_gtls_pull); - - /* lowat must be set to zero when using custom push and pull functions. */ - gnutls_transport_set_lowat(session, 0); - -#ifdef HAS_OCSP - if(data->set.ssl.verifystatus) { - rc = gnutls_ocsp_status_request_enable_client(session, NULL, 0, NULL); - if(rc != GNUTLS_E_SUCCESS) { - failf(data, "gnutls_ocsp_status_request_enable_client() failed: %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - } -#endif - - /* This might be a reconnect, so we check for a session ID in the cache - to speed up things */ - - if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) { - /* we got a session id, use it! */ - gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); - - /* Informational message */ - infof (data, "SSL re-using session ID\n"); - } - - return CURLE_OK; -} - -static CURLcode pkp_pin_peer_pubkey(struct SessionHandle *data, - gnutls_x509_crt_t cert, - const char *pinnedpubkey) -{ - /* Scratch */ - size_t len1 = 0, len2 = 0; - unsigned char *buff1 = NULL; - - gnutls_pubkey_t key = NULL; - - /* Result is returned to caller */ - int ret = 0; - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - /* if a path wasn't specified, don't pin */ - if(NULL == pinnedpubkey) - return CURLE_OK; - - if(NULL == cert) - return result; - - do { - /* Begin Gyrations to get the public key */ - gnutls_pubkey_init(&key); - - ret = gnutls_pubkey_import_x509(key, cert, 0); - if(ret < 0) - break; /* failed */ - - ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, NULL, &len1); - if(ret != GNUTLS_E_SHORT_MEMORY_BUFFER || len1 == 0) - break; /* failed */ - - buff1 = malloc(len1); - if(NULL == buff1) - break; /* failed */ - - len2 = len1; - - ret = gnutls_pubkey_export(key, GNUTLS_X509_FMT_DER, buff1, &len2); - if(ret < 0 || len1 != len2) - break; /* failed */ - - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); - } while(0); - - if(NULL != key) - gnutls_pubkey_deinit(key); - - Curl_safefree(buff1); - - return result; -} - -static Curl_recv gtls_recv; -static Curl_send gtls_send; - -static CURLcode -gtls_connect_step3(struct connectdata *conn, - int sockindex) -{ - unsigned int cert_list_size; - const gnutls_datum_t *chainp; - unsigned int verify_status = 0; - gnutls_x509_crt_t x509_cert, x509_issuer; - gnutls_datum_t issuerp; - char certbuf[256] = ""; /* big enough? */ - size_t size; - unsigned int algo; - unsigned int bits; - time_t certclock; - const char *ptr; - struct SessionHandle *data = conn->data; - gnutls_session_t session = conn->ssl[sockindex].session; - int rc; - bool incache; - void *ssl_sessionid; -#ifdef HAS_ALPN - gnutls_datum_t proto; -#endif - CURLcode result = CURLE_OK; - - gnutls_protocol_t version = gnutls_protocol_get_version(session); - - /* the name of the cipher suite used, e.g. ECDHE_RSA_AES_256_GCM_SHA384. */ - ptr = gnutls_cipher_suite_get_name(gnutls_kx_get(session), - gnutls_cipher_get(session), - gnutls_mac_get(session)); - - infof(data, "SSL connection using %s / %s\n", - gnutls_protocol_get_name(version), ptr); - - /* This function will return the peer's raw certificate (chain) as sent by - the peer. These certificates are in raw format (DER encoded for - X.509). In case of a X.509 then a certificate list may be present. The - first certificate in the list is the peer's certificate, following the - issuer's certificate, then the issuer's issuer etc. */ - - chainp = gnutls_certificate_get_peers(session, &cert_list_size); - if(!chainp) { - if(data->set.ssl.verifypeer || - data->set.ssl.verifyhost || - data->set.ssl.issuercert) { -#ifdef USE_TLS_SRP - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP - && data->set.ssl.username != NULL - && !data->set.ssl.verifypeer - && gnutls_cipher_get(session)) { - /* no peer cert, but auth is ok if we have SRP user and cipher and no - peer verify */ - } - else { -#endif - failf(data, "failed to get server cert"); - return CURLE_PEER_FAILED_VERIFICATION; -#ifdef USE_TLS_SRP - } -#endif - } - infof(data, "\t common name: WARNING couldn't obtain\n"); - } - - if(data->set.ssl.certinfo && chainp) { - unsigned int i; - - result = Curl_ssl_init_certinfo(data, cert_list_size); - if(result) - return result; - - for(i = 0; i < cert_list_size; i++) { - const char *beg = (const char *) chainp[i].data; - const char *end = beg + chainp[i].size; - - result = Curl_extract_certinfo(conn, i, beg, end); - if(result) - return result; - } - } - - if(data->set.ssl.verifypeer) { - /* This function will try to verify the peer's certificate and return its - status (trusted, invalid etc.). The value of status should be one or - more of the gnutls_certificate_status_t enumerated elements bitwise - or'd. To avoid denial of service attacks some default upper limits - regarding the certificate key size and chain size are set. To override - them use gnutls_certificate_set_verify_limits(). */ - - rc = gnutls_certificate_verify_peers2(session, &verify_status); - if(rc < 0) { - failf(data, "server cert verify failed: %d", rc); - return CURLE_SSL_CONNECT_ERROR; - } - - /* verify_status is a bitmask of gnutls_certificate_status bits */ - if(verify_status & GNUTLS_CERT_INVALID) { - if(data->set.ssl.verifypeer) { - failf(data, "server certificate verification failed. CAfile: %s " - "CRLfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none", - data->set.ssl.CRLfile?data->set.ssl.CRLfile:"none"); - return CURLE_SSL_CACERT; - } - else - infof(data, "\t server certificate verification FAILED\n"); - } - else - infof(data, "\t server certificate verification OK\n"); - } - else - infof(data, "\t server certificate verification SKIPPED\n"); - -#ifdef HAS_OCSP - if(data->set.ssl.verifystatus) { - if(gnutls_ocsp_status_request_is_checked(session, 0) == 0) { - gnutls_datum_t status_request; - gnutls_ocsp_resp_t ocsp_resp; - - gnutls_ocsp_cert_status_t status; - gnutls_x509_crl_reason_t reason; - - rc = gnutls_ocsp_status_request_get(session, &status_request); - - infof(data, "\t server certificate status verification FAILED\n"); - - if(rc == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { - failf(data, "No OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - gnutls_ocsp_resp_init(&ocsp_resp); - - rc = gnutls_ocsp_resp_import(ocsp_resp, &status_request); - if(rc < 0) { - failf(data, "Invalid OCSP response received"); - return CURLE_SSL_INVALIDCERTSTATUS; - } - - rc = gnutls_ocsp_resp_get_single(ocsp_resp, 0, NULL, NULL, NULL, NULL, - &status, NULL, NULL, NULL, &reason); - - switch(status) { - case GNUTLS_OCSP_CERT_GOOD: - break; - - case GNUTLS_OCSP_CERT_REVOKED: { - const char *crl_reason; - - switch(reason) { - default: - case GNUTLS_X509_CRLREASON_UNSPECIFIED: - crl_reason = "unspecified reason"; - break; - - case GNUTLS_X509_CRLREASON_KEYCOMPROMISE: - crl_reason = "private key compromised"; - break; - - case GNUTLS_X509_CRLREASON_CACOMPROMISE: - crl_reason = "CA compromised"; - break; - - case GNUTLS_X509_CRLREASON_AFFILIATIONCHANGED: - crl_reason = "affiliation has changed"; - break; - - case GNUTLS_X509_CRLREASON_SUPERSEDED: - crl_reason = "certificate superseded"; - break; - - case GNUTLS_X509_CRLREASON_CESSATIONOFOPERATION: - crl_reason = "operation has ceased"; - break; - - case GNUTLS_X509_CRLREASON_CERTIFICATEHOLD: - crl_reason = "certificate is on hold"; - break; - - case GNUTLS_X509_CRLREASON_REMOVEFROMCRL: - crl_reason = "will be removed from delta CRL"; - break; - - case GNUTLS_X509_CRLREASON_PRIVILEGEWITHDRAWN: - crl_reason = "privilege withdrawn"; - break; - - case GNUTLS_X509_CRLREASON_AACOMPROMISE: - crl_reason = "AA compromised"; - break; - } - - failf(data, "Server certificate was revoked: %s", crl_reason); - break; - } - - default: - case GNUTLS_OCSP_CERT_UNKNOWN: - failf(data, "Server certificate status is unknown"); - break; - } - - gnutls_ocsp_resp_deinit(ocsp_resp); - - return CURLE_SSL_INVALIDCERTSTATUS; - } - else - infof(data, "\t server certificate status verification OK\n"); - } - else - infof(data, "\t server certificate status verification SKIPPED\n"); -#endif - - /* initialize an X.509 certificate structure. */ - gnutls_x509_crt_init(&x509_cert); - - if(chainp) - /* convert the given DER or PEM encoded Certificate to the native - gnutls_x509_crt_t format */ - gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); - - if(data->set.ssl.issuercert) { - gnutls_x509_crt_init(&x509_issuer); - issuerp = load_file(data->set.ssl.issuercert); - gnutls_x509_crt_import(x509_issuer, &issuerp, GNUTLS_X509_FMT_PEM); - rc = gnutls_x509_crt_check_issuer(x509_cert, x509_issuer); - gnutls_x509_crt_deinit(x509_issuer); - unload_file(issuerp); - if(rc <= 0) { - failf(data, "server certificate issuer check failed (IssuerCert: %s)", - data->set.ssl.issuercert?data->set.ssl.issuercert:"none"); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_ISSUER_ERROR; - } - infof(data, "\t server certificate issuer check OK (Issuer Cert: %s)\n", - data->set.ssl.issuercert?data->set.ssl.issuercert:"none"); - } - - size=sizeof(certbuf); - rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, - 0, /* the first and only one */ - FALSE, - certbuf, - &size); - if(rc) { - infof(data, "error fetching CN from cert:%s\n", - gnutls_strerror(rc)); - } - - /* This function will check if the given certificate's subject matches the - given hostname. This is a basic implementation of the matching described - in RFC2818 (HTTPS), which takes into account wildcards, and the subject - alternative name PKIX extension. Returns non zero on success, and zero on - failure. */ - rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name); -#if GNUTLS_VERSION_NUMBER < 0x030306 - /* Before 3.3.6, gnutls_x509_crt_check_hostname() didn't check IP - addresses. */ - if(!rc) { -#ifdef ENABLE_IPV6 - #define use_addr in6_addr -#else - #define use_addr in_addr -#endif - unsigned char addrbuf[sizeof(struct use_addr)]; - unsigned char certaddr[sizeof(struct use_addr)]; - size_t addrlen = 0, certaddrlen; - int i; - int ret = 0; - - if(Curl_inet_pton(AF_INET, conn->host.name, addrbuf) > 0) - addrlen = 4; -#ifdef ENABLE_IPV6 - else if(Curl_inet_pton(AF_INET6, conn->host.name, addrbuf) > 0) - addrlen = 16; -#endif - - if(addrlen) { - for(i=0; ; i++) { - certaddrlen = sizeof(certaddr); - ret = gnutls_x509_crt_get_subject_alt_name(x509_cert, i, certaddr, - &certaddrlen, NULL); - /* If this happens, it wasn't an IP address. */ - if(ret == GNUTLS_E_SHORT_MEMORY_BUFFER) - continue; - if(ret < 0) - break; - if(ret != GNUTLS_SAN_IPADDRESS) - continue; - if(certaddrlen == addrlen && !memcmp(addrbuf, certaddr, addrlen)) { - rc = 1; - break; - } - } - } - } -#endif - if(!rc) { - if(data->set.ssl.verifyhost) { - failf(data, "SSL: certificate subject name (%s) does not match " - "target host name '%s'", certbuf, conn->host.dispname); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, "\t common name: %s (does not match '%s')\n", - certbuf, conn->host.dispname); - } - else - infof(data, "\t common name: %s (matched)\n", certbuf); - - /* Check for time-based validity */ - certclock = gnutls_x509_crt_get_expiration_time(x509_cert); - - if(certclock == (time_t)-1) { - if(data->set.ssl.verifypeer) { - failf(data, "server cert expiration date verify failed"); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_CONNECT_ERROR; - } - else - infof(data, "\t server certificate expiration date verify FAILED\n"); - } - else { - if(certclock < time(NULL)) { - if(data->set.ssl.verifypeer) { - failf(data, "server certificate expiration date has passed."); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, "\t server certificate expiration date FAILED\n"); - } - else - infof(data, "\t server certificate expiration date OK\n"); - } - - certclock = gnutls_x509_crt_get_activation_time(x509_cert); - - if(certclock == (time_t)-1) { - if(data->set.ssl.verifypeer) { - failf(data, "server cert activation date verify failed"); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_SSL_CONNECT_ERROR; - } - else - infof(data, "\t server certificate activation date verify FAILED\n"); - } - else { - if(certclock > time(NULL)) { - if(data->set.ssl.verifypeer) { - failf(data, "server certificate not activated yet."); - gnutls_x509_crt_deinit(x509_cert); - return CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, "\t server certificate activation date FAILED\n"); - } - else - infof(data, "\t server certificate activation date OK\n"); - } - - ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; - if(ptr) { - result = pkp_pin_peer_pubkey(data, x509_cert, ptr); - if(result != CURLE_OK) { - failf(data, "SSL: public key does not match pinned public key!"); - gnutls_x509_crt_deinit(x509_cert); - return result; - } - } - - /* Show: - - - subject - - start date - - expire date - - common name - - issuer - - */ - - /* public key algorithm's parameters */ - algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); - infof(data, "\t certificate public key: %s\n", - gnutls_pk_algorithm_get_name(algo)); - - /* version of the X.509 certificate. */ - infof(data, "\t certificate version: #%d\n", - gnutls_x509_crt_get_version(x509_cert)); - - - size = sizeof(certbuf); - gnutls_x509_crt_get_dn(x509_cert, certbuf, &size); - infof(data, "\t subject: %s\n", certbuf); - - certclock = gnutls_x509_crt_get_activation_time(x509_cert); - showtime(data, "start date", certclock); - - certclock = gnutls_x509_crt_get_expiration_time(x509_cert); - showtime(data, "expire date", certclock); - - size = sizeof(certbuf); - gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size); - infof(data, "\t issuer: %s\n", certbuf); - - gnutls_x509_crt_deinit(x509_cert); - - /* compression algorithm (if any) */ - ptr = gnutls_compression_get_name(gnutls_compression_get(session)); - /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */ - infof(data, "\t compression: %s\n", ptr); - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - rc = gnutls_alpn_get_selected_protocol(session, &proto); - if(rc == 0) { - infof(data, "ALPN, server accepted to use %.*s\n", proto.size, - proto.data); - -#ifdef USE_NGHTTP2 - if(proto.size == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, proto.data, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(proto.size == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, proto.data, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - } - else - infof(data, "ALPN, server did not agree to a protocol\n"); - } -#endif - - conn->ssl[sockindex].state = ssl_connection_complete; - conn->recv[sockindex] = gtls_recv; - conn->send[sockindex] = gtls_send; - - { - /* we always unconditionally get the session id here, as even if we - already got it from the cache and asked to use it in the connection, it - might've been rejected and then a new one is in use now and we need to - detect that. */ - void *connect_sessionid; - size_t connect_idsize = 0; - - /* get the session ID data size */ - gnutls_session_get_data(session, NULL, &connect_idsize); - connect_sessionid = malloc(connect_idsize); /* get a buffer for it */ - - if(connect_sessionid) { - /* extract session ID to the allocated buffer */ - gnutls_session_get_data(session, connect_sessionid, &connect_idsize); - - incache = !(Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)); - if(incache) { - /* there was one before in the cache, so instead of risking that the - previous one was rejected, we just kill that and store the new */ - Curl_ssl_delsessionid(conn, ssl_sessionid); - } - - /* store this session id */ - result = Curl_ssl_addsessionid(conn, connect_sessionid, connect_idsize); - if(result) { - free(connect_sessionid); - result = CURLE_OUT_OF_MEMORY; - } - } - else - result = CURLE_OUT_OF_MEMORY; - } - - return result; -} - - -/* - * This function is called after the TCP connect has completed. Setup the TLS - * layer and do all necessary magic. - */ -/* We use connssl->connecting_state to keep track of the connection status; - there are three states: 'ssl_connect_1' (not started yet or complete), - 'ssl_connect_2_reading' (waiting for data from server), and - 'ssl_connect_2_writing' (waiting to be able to write). - */ -static CURLcode -gtls_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - int rc; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - /* Initiate the connection, if not already done */ - if(ssl_connect_1==connssl->connecting_state) { - rc = gtls_connect_step1 (conn, sockindex); - if(rc) - return rc; - } - - rc = handshake(conn, sockindex, TRUE, nonblocking); - if(rc) - /* handshake() sets its own error message with failf() */ - return rc; - - /* Finish connecting once the handshake is done */ - if(ssl_connect_1==connssl->connecting_state) { - rc = gtls_connect_step3(conn, sockindex); - if(rc) - return rc; - } - - *done = ssl_connect_1==connssl->connecting_state; - - return CURLE_OK; -} - -CURLcode -Curl_gtls_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done) -{ - return gtls_connect_common(conn, sockindex, TRUE, done); -} - -CURLcode -Curl_gtls_connect(struct connectdata *conn, - int sockindex) - -{ - CURLcode result; - bool done = FALSE; - - result = gtls_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -static ssize_t gtls_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - ssize_t rc = gnutls_record_send(conn->ssl[sockindex].session, mem, len); - - if(rc < 0) { - *curlcode = (rc == GNUTLS_E_AGAIN) - ? CURLE_AGAIN - : CURLE_SEND_ERROR; - - rc = -1; - } - - return rc; -} - -static void close_one(struct connectdata *conn, - int idx) -{ - if(conn->ssl[idx].session) { - gnutls_bye(conn->ssl[idx].session, GNUTLS_SHUT_RDWR); - gnutls_deinit(conn->ssl[idx].session); - conn->ssl[idx].session = NULL; - } - if(conn->ssl[idx].cred) { - gnutls_certificate_free_credentials(conn->ssl[idx].cred); - conn->ssl[idx].cred = NULL; - } -#ifdef USE_TLS_SRP - if(conn->ssl[idx].srp_client_cred) { - gnutls_srp_free_client_credentials(conn->ssl[idx].srp_client_cred); - conn->ssl[idx].srp_client_cred = NULL; - } -#endif -} - -void Curl_gtls_close(struct connectdata *conn, int sockindex) -{ - close_one(conn, sockindex); -} - -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) -{ - ssize_t result; - int retval = 0; - struct SessionHandle *data = conn->data; - int done = 0; - char buf[120]; - - /* This has only been tested on the proftpd server, and the mod_tls code - sends a close notify alert without waiting for a close notify alert in - response. Thus we wait for a close notify alert from the server, but - we do not send one. Let's hope other servers do the same... */ - - if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) - gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR); - - if(conn->ssl[sockindex].session) { - while(!done) { - int what = Curl_socket_ready(conn->sock[sockindex], - CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); - if(what > 0) { - /* Something to read, let's do it and hope that it is the close - notify alert from the server */ - result = gnutls_record_recv(conn->ssl[sockindex].session, - buf, sizeof(buf)); - switch(result) { - case 0: - /* This is the expected response. There was no data but only - the close notify alert */ - done = 1; - break; - case GNUTLS_E_AGAIN: - case GNUTLS_E_INTERRUPTED: - infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n"); - break; - default: - retval = -1; - done = 1; - break; - } - } - else if(0 == what) { - /* timeout */ - failf(data, "SSL shutdown timeout"); - done = 1; - break; - } - else { - /* anything that gets here is fatally bad */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - retval = -1; - done = 1; - } - } - gnutls_deinit(conn->ssl[sockindex].session); - } - gnutls_certificate_free_credentials(conn->ssl[sockindex].cred); - -#ifdef USE_TLS_SRP - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP - && data->set.ssl.username != NULL) - gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred); -#endif - - conn->ssl[sockindex].cred = NULL; - conn->ssl[sockindex].session = NULL; - - return retval; -} - -static ssize_t gtls_recv(struct connectdata *conn, /* connection data */ - int num, /* socketindex */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - CURLcode *curlcode) -{ - ssize_t ret; - - ret = gnutls_record_recv(conn->ssl[num].session, buf, buffersize); - if((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)) { - *curlcode = CURLE_AGAIN; - return -1; - } - - if(ret == GNUTLS_E_REHANDSHAKE) { - /* BLOCKING call, this is bad but a work-around for now. Fixing this "the - proper way" takes a whole lot of work. */ - CURLcode result = handshake(conn, num, FALSE, FALSE); - if(result) - /* handshake() writes error message on its own */ - *curlcode = result; - else - *curlcode = CURLE_AGAIN; /* then return as if this was a wouldblock */ - return -1; - } - - if(ret < 0) { - failf(conn->data, "GnuTLS recv error (%d): %s", - (int)ret, gnutls_strerror((int)ret)); - *curlcode = CURLE_RECV_ERROR; - return -1; - } - - return ret; -} - -void Curl_gtls_session_free(void *ptr) -{ - free(ptr); -} - -size_t Curl_gtls_version(char *buffer, size_t size) -{ - return snprintf(buffer, size, "GnuTLS/%s", gnutls_check_version(NULL)); -} - -#ifndef USE_GNUTLS_NETTLE -static int Curl_gtls_seed(struct SessionHandle *data) -{ - /* we have the "SSL is seeded" boolean static to prevent multiple - time-consuming seedings in vain */ - static bool ssl_seeded = FALSE; - - /* Quickly add a bit of entropy */ - gcry_fast_random_poll(); - - if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] || - data->set.str[STRING_SSL_EGDSOCKET]) { - - /* TODO: to a good job seeding the RNG - This may involve the gcry_control function and these options: - GCRYCTL_SET_RANDOM_SEED_FILE - GCRYCTL_SET_RNDEGD_SOCKET - */ - ssl_seeded = TRUE; - } - return 0; -} -#endif - -/* data might be NULL! */ -int Curl_gtls_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) -{ -#if defined(USE_GNUTLS_NETTLE) - (void)data; - gnutls_rnd(GNUTLS_RND_RANDOM, entropy, length); -#elif defined(USE_GNUTLS) - if(data) - Curl_gtls_seed(data); /* Initiate the seed if not already done */ - gcry_randomize(entropy, length, GCRY_STRONG_RANDOM); -#endif - return 0; -} - -void Curl_gtls_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len) -{ -#if defined(USE_GNUTLS_NETTLE) - struct md5_ctx MD5pw; - md5_init(&MD5pw); - md5_update(&MD5pw, (unsigned int)tmplen, tmp); - md5_digest(&MD5pw, (unsigned int)md5len, md5sum); -#elif defined(USE_GNUTLS) - gcry_md_hd_t MD5pw; - gcry_md_open(&MD5pw, GCRY_MD_MD5, 0); - gcry_md_write(MD5pw, tmp, tmplen); - memcpy(md5sum, gcry_md_read (MD5pw, 0), md5len); - gcry_md_close(MD5pw); -#endif -} - -void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t sha256len) -{ -#if defined(USE_GNUTLS_NETTLE) - struct sha256_ctx SHA256pw; - sha256_init(&SHA256pw); - sha256_update(&SHA256pw, (unsigned int)tmplen, tmp); - sha256_digest(&SHA256pw, (unsigned int)sha256len, sha256sum); -#elif defined(USE_GNUTLS) - gcry_md_hd_t SHA256pw; - gcry_md_open(&SHA256pw, GCRY_MD_SHA256, 0); - gcry_md_write(SHA256pw, tmp, tmplen); - memcpy(sha256sum, gcry_md_read (SHA256pw, 0), sha256len); - gcry_md_close(SHA256pw); -#endif -} - -bool Curl_gtls_cert_status_request(void) -{ -#ifdef HAS_OCSP - return TRUE; -#else - return FALSE; -#endif -} - -#endif /* USE_GNUTLS */ diff --git a/Externals/curl/lib/vtls/gtls.h b/Externals/curl/lib/vtls/gtls.h deleted file mode 100644 index 611a2f47bb..0000000000 --- a/Externals/curl/lib/vtls/gtls.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef HEADER_CURL_GTLS_H -#define HEADER_CURL_GTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_GNUTLS - -#include "urldata.h" - -int Curl_gtls_init(void); -int Curl_gtls_cleanup(void); -CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex); -CURLcode Curl_gtls_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); - - /* close a SSL connection */ -void Curl_gtls_close(struct connectdata *conn, int sockindex); - -void Curl_gtls_session_free(void *ptr); -size_t Curl_gtls_version(char *buffer, size_t size); -int Curl_gtls_shutdown(struct connectdata *conn, int sockindex); -int Curl_gtls_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length); -void Curl_gtls_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len); -void Curl_gtls_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t sha256len); - -bool Curl_gtls_cert_status_request(void); - -/* Set the API backend definition to GnuTLS */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_GNUTLS - -/* this backend supports the CAPATH option */ -#define have_curlssl_ca_path 1 - -/* this backend supports CURLOPT_CERTINFO */ -#define have_curlssl_certinfo 1 - -/* this backend supports CURLOPT_PINNEDPUBLICKEY */ -#define have_curlssl_pinnedpubkey 1 - -/* API setup for GnuTLS */ -#define curlssl_init Curl_gtls_init -#define curlssl_cleanup Curl_gtls_cleanup -#define curlssl_connect Curl_gtls_connect -#define curlssl_connect_nonblocking Curl_gtls_connect_nonblocking -#define curlssl_session_free(x) Curl_gtls_session_free(x) -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_gtls_close -#define curlssl_shutdown(x,y) Curl_gtls_shutdown(x,y) -#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) -#define curlssl_version Curl_gtls_version -#define curlssl_check_cxn(x) ((void)x, -1) -#define curlssl_data_pending(x,y) ((void)x, (void)y, 0) -#define curlssl_random(x,y,z) Curl_gtls_random(x,y,z) -#define curlssl_md5sum(a,b,c,d) Curl_gtls_md5sum(a,b,c,d) -#define curlssl_sha256sum(a,b,c,d) Curl_gtls_sha256sum(a,b,c,d) -#define curlssl_cert_status_request() Curl_gtls_cert_status_request() - -#endif /* USE_GNUTLS */ -#endif /* HEADER_CURL_GTLS_H */ diff --git a/Externals/curl/lib/vtls/mbedtls.c b/Externals/curl/lib/vtls/mbedtls.c deleted file mode 100644 index ef0b9492ab..0000000000 --- a/Externals/curl/lib/vtls/mbedtls.c +++ /dev/null @@ -1,866 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010 - 2011, Hoi-Ho Chan, - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all mbedTLS-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ - -#include "curl_setup.h" - -#ifdef USE_MBEDTLS - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "mbedtls.h" -#include "vtls.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "rawstr.h" -#include "polarssl_threadlock.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -/* apply threading? */ -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) -#define THREADING_SUPPORT -#endif - -#if defined(THREADING_SUPPORT) -static mbedtls_entropy_context entropy; - -static int entropy_init_initialized = 0; - -/* start of entropy_init_mutex() */ -static void entropy_init_mutex(mbedtls_entropy_context *ctx) -{ - /* lock 0 = entropy_init_mutex() */ - Curl_polarsslthreadlock_lock_function(0); - if(entropy_init_initialized == 0) { - mbedtls_entropy_init(ctx); - entropy_init_initialized = 1; - } - Curl_polarsslthreadlock_unlock_function(0); -} -/* end of entropy_init_mutex() */ - -/* start of entropy_func_mutex() */ -static int entropy_func_mutex(void *data, unsigned char *output, size_t len) -{ - int ret; - /* lock 1 = entropy_func_mutex() */ - Curl_polarsslthreadlock_lock_function(1); - ret = mbedtls_entropy_func(data, output, len); - Curl_polarsslthreadlock_unlock_function(1); - - return ret; -} -/* end of entropy_func_mutex() */ - -#endif /* THREADING_SUPPORT */ - -/* Define this to enable lots of debugging for mbedTLS */ -#undef MBEDTLS_DEBUG - -#ifdef MBEDTLS_DEBUG -static void mbed_debug(void *context, int level, const char *f_name, - int line_nb, const char *line) -{ - struct SessionHandle *data = NULL; - - if(!context) - return; - - data = (struct SessionHandle *)context; - - infof(data, "%s", line); - (void) level; -} -#else -#endif - -/* ALPN for http2? */ -#ifdef USE_NGHTTP2 -# undef HAS_ALPN -# ifdef MBEDTLS_SSL_ALPN -# define HAS_ALPN -# endif -#endif - - -/* - * profile - */ -const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_fr = -{ - /* Hashes from SHA-1 and above */ - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA1) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_RIPEMD160) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA224) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA256) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA384) | - MBEDTLS_X509_ID_FLAG(MBEDTLS_MD_SHA512), - 0xFFFFFFF, /* Any PK alg */ - 0xFFFFFFF, /* Any curve */ - 1024, /* RSA min key len */ -}; - -/* See https://tls.mbed.org/discussions/generic/ - howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der -*/ -#define RSA_PUB_DER_MAX_BYTES (38 + 2 * MBEDTLS_MPI_MAX_SIZE) -#define ECP_PUB_DER_MAX_BYTES (30 + 2 * MBEDTLS_ECP_MAX_BYTES) - -#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ - RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) - -static Curl_recv mbed_recv; -static Curl_send mbed_send; - -static CURLcode -mbed_connect_step1(struct connectdata *conn, - int sockindex) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data* connssl = &conn->ssl[sockindex]; - - bool sni = TRUE; /* default is SNI enabled */ - int ret = -1; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - void *old_session = NULL; - char errorbuf[128]; - errorbuf[0]=0; - - /* mbedTLS only supports SSLv3 and TLSv1 */ - if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { - failf(data, "mbedTLS does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) - sni = FALSE; /* SSLv3 has no SNI */ - -#ifdef THREADING_SUPPORT - entropy_init_mutex(&entropy); - mbedtls_ctr_drbg_init(&connssl->ctr_drbg); - - ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex, - &entropy, NULL, 0); - if(ret) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", - -ret, errorbuf); - } -#else - mbedtls_entropy_init(&connssl->entropy); - mbedtls_ctr_drbg_init(&connssl->ctr_drbg); - - ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func, - &connssl->entropy, NULL, 0); - if(ret) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n", - -ret, errorbuf); - } -#endif /* THREADING_SUPPORT */ - - /* Load the trusted CA */ - mbedtls_x509_crt_init(&connssl->cacert); - - if(data->set.str[STRING_SSL_CAFILE]) { - ret = mbedtls_x509_crt_parse_file(&connssl->cacert, - data->set.str[STRING_SSL_CAFILE]); - - if(ret<0) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s", - data->set.str[STRING_SSL_CAFILE], -ret, errorbuf); - - if(data->set.ssl.verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } - } - - if(data->set.str[STRING_SSL_CAPATH]) { - ret = mbedtls_x509_crt_parse_path(&connssl->cacert, - data->set.str[STRING_SSL_CAPATH]); - - if(ret<0) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s", - data->set.str[STRING_SSL_CAPATH], -ret, errorbuf); - - if(data->set.ssl.verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } - } - - /* Load the client certificate */ - mbedtls_x509_crt_init(&connssl->clicert); - - if(data->set.str[STRING_CERT]) { - ret = mbedtls_x509_crt_parse_file(&connssl->clicert, - data->set.str[STRING_CERT]); - - if(ret) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s", - data->set.str[STRING_CERT], -ret, errorbuf); - - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Load the client private key */ - mbedtls_pk_init(&connssl->pk); - - if(data->set.str[STRING_KEY]) { - ret = mbedtls_pk_parse_keyfile(&connssl->pk, data->set.str[STRING_KEY], - data->set.str[STRING_KEY_PASSWD]); - if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA)) - ret = MBEDTLS_ERR_PK_TYPE_MISMATCH; - - if(ret) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s", - data->set.str[STRING_KEY], -ret, errorbuf); - - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Load the CRL */ - mbedtls_x509_crl_init(&connssl->crl); - - if(data->set.str[STRING_SSL_CRLFILE]) { - ret = mbedtls_x509_crl_parse_file(&connssl->crl, - data->set.str[STRING_SSL_CRLFILE]); - - if(ret) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s", - data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf); - - return CURLE_SSL_CRL_BADFILE; - } - } - - infof(data, "mbedTLS: Connecting to %s:%d\n", - conn->host.name, conn->remote_port); - - mbedtls_ssl_config_init(&connssl->config); - - mbedtls_ssl_init(&connssl->ssl); - if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) { - failf(data, "mbedTLS: ssl_init failed"); - return CURLE_SSL_CONNECT_ERROR; - } - ret = mbedtls_ssl_config_defaults(&connssl->config, - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT); - if(ret) { - failf(data, "mbedTLS: ssl_config failed"); - return CURLE_SSL_CONNECT_ERROR; - } - - /* new profile with RSA min key len = 1024 ... */ - mbedtls_ssl_conf_cert_profile(&connssl->config, - &mbedtls_x509_crt_profile_fr); - - switch(data->set.ssl.version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_1); - infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n"); - break; - case CURL_SSLVERSION_SSLv3: - mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_0); - mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_0); - infof(data, "mbedTLS: Set SSL version to SSLv3\n"); - break; - case CURL_SSLVERSION_TLSv1_0: - mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_1); - mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_1); - infof(data, "mbedTLS: Set SSL version to TLS 1.0\n"); - break; - case CURL_SSLVERSION_TLSv1_1: - mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_2); - mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_2); - infof(data, "mbedTLS: Set SSL version to TLS 1.1\n"); - break; - case CURL_SSLVERSION_TLSv1_2: - mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_3); - mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3, - MBEDTLS_SSL_MINOR_VERSION_3); - infof(data, "mbedTLS: Set SSL version to TLS 1.2\n"); - break; - default: - failf(data, "mbedTLS: Unsupported SSL protocol version"); - return CURLE_SSL_CONNECT_ERROR; - } - - mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL); - - mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random, - &connssl->ctr_drbg); - mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex], - mbedtls_net_send, - mbedtls_net_recv, - NULL /* rev_timeout() */); - - mbedtls_ssl_conf_ciphersuites(&connssl->config, - mbedtls_ssl_list_ciphersuites()); - if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) { - ret = mbedtls_ssl_set_session(&connssl->ssl, old_session); - if(ret) { - failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret); - return CURLE_SSL_CONNECT_ERROR; - } - infof(data, "mbedTLS re-using session\n"); - } - - mbedtls_ssl_conf_ca_chain(&connssl->config, - &connssl->cacert, - &connssl->crl); - - if(data->set.str[STRING_KEY]) { - mbedtls_ssl_conf_own_cert(&connssl->config, - &connssl->clicert, &connssl->pk); - } - if(mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) { - /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and* - the name to set in the SNI extension. So even if curl connects to a - host specified as an IP address, this function must be used. */ - failf(data, "couldn't set hostname in mbedTLS"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - const char **p = &connssl->protocols[0]; -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) - *p++ = NGHTTP2_PROTO_VERSION_ID; -#endif - *p++ = ALPN_HTTP_1_1; - *p = NULL; - /* this function doesn't clone the protocols array, which is why we need - to keep it around */ - if(mbedtls_ssl_conf_alpn_protocols(&connssl->config, - &connssl->protocols[0])) { - failf(data, "Failed setting ALPN protocols"); - return CURLE_SSL_CONNECT_ERROR; - } - for(p = &connssl->protocols[0]; *p; ++p) - infof(data, "ALPN, offering %s\n", *p); - } -#endif - -#ifdef MBEDTLS_DEBUG - mbedtls_ssl_conf_dbg(&connssl->config, mbedtls_debug, data); -#endif - - connssl->connecting_state = ssl_connect_2; - - return CURLE_OK; -} - -static CURLcode -mbed_connect_step2(struct connectdata *conn, - int sockindex) -{ - int ret; - struct SessionHandle *data = conn->data; - struct ssl_connect_data* connssl = &conn->ssl[sockindex]; - const mbedtls_x509_crt *peercert; - -#ifdef HAS_ALPN - const char* next_protocol; -#endif - - char errorbuf[128]; - errorbuf[0] = 0; - - conn->recv[sockindex] = mbed_recv; - conn->send[sockindex] = mbed_send; - - ret = mbedtls_ssl_handshake(&connssl->ssl); - - if(ret == MBEDTLS_ERR_SSL_WANT_READ) { - connssl->connecting_state = ssl_connect_2_reading; - return CURLE_OK; - } - else if(ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - connssl->connecting_state = ssl_connect_2_writing; - return CURLE_OK; - } - else if(ret) { -#ifdef MBEDTLS_ERROR_C - mbedtls_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* MBEDTLS_ERROR_C */ - failf(data, "ssl_handshake returned - mbedTLS: (-0x%04X) %s", - -ret, errorbuf); - return CURLE_SSL_CONNECT_ERROR; - } - - infof(data, "mbedTLS: Handshake complete, cipher is %s\n", - mbedtls_ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) - ); - - ret = mbedtls_ssl_get_verify_result(&conn->ssl[sockindex].ssl); - - if(ret && data->set.ssl.verifypeer) { - if(ret & MBEDTLS_X509_BADCERT_EXPIRED) - failf(data, "Cert verify failed: BADCERT_EXPIRED"); - - if(ret & MBEDTLS_X509_BADCERT_REVOKED) { - failf(data, "Cert verify failed: BADCERT_REVOKED"); - return CURLE_SSL_CACERT; - } - - if(ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) - failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); - - if(ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED) - failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); - - return CURLE_PEER_FAILED_VERIFICATION; - } - - peercert = mbedtls_ssl_get_peer_cert(&connssl->ssl); - - if(peercert && data->set.verbose) { - const size_t bufsize = 16384; - char *buffer = malloc(bufsize); - - if(!buffer) - return CURLE_OUT_OF_MEMORY; - - if(mbedtls_x509_crt_info(buffer, bufsize, "* ", peercert) > 0) - infof(data, "Dumping cert info:\n%s\n", buffer); - else - infof(data, "Unable to dump certificate information.\n"); - - free(buffer); - } - - if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { - int size; - CURLcode result; - mbedtls_x509_crt *p; - unsigned char pubkey[PUB_DER_MAX_BYTES]; - - if(!peercert || !peercert->raw.p || !peercert->raw.len) { - failf(data, "Failed due to missing peer certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - p = calloc(1, sizeof(*p)); - - if(!p) - return CURLE_OUT_OF_MEMORY; - - mbedtls_x509_crt_init(p); - - /* Make a copy of our const peercert because mbedtls_pk_write_pubkey_der - needs a non-const key, for now. - https://github.com/ARMmbed/mbedtls/issues/396 */ - if(mbedtls_x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { - failf(data, "Failed copying peer certificate"); - mbedtls_x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - size = mbedtls_pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); - - if(size <= 0) { - failf(data, "Failed copying public key from peer certificate"); - mbedtls_x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - /* mbedtls_pk_write_pubkey_der writes data at the end of the buffer. */ - result = Curl_pin_peer_pubkey(data, - data->set.str[STRING_SSL_PINNEDPUBLICKEY], - &pubkey[PUB_DER_MAX_BYTES - size], size); - if(result) { - mbedtls_x509_crt_free(p); - free(p); - return result; - } - - mbedtls_x509_crt_free(p); - free(p); - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - next_protocol = mbedtls_ssl_get_alpn_protocol(&connssl->ssl); - - if(next_protocol) { - infof(data, "ALPN, server accepted to use %s\n", next_protocol); -#ifdef USE_NGHTTP2 - if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN) && - !next_protocol[NGHTTP2_PROTO_VERSION_ID_LEN]) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH) && - !next_protocol[ALPN_HTTP_1_1_LENGTH]) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - } - else { - infof(data, "ALPN, server did not agree to a protocol\n"); - } - } -#endif - - connssl->connecting_state = ssl_connect_3; - infof(data, "SSL connected\n"); - - return CURLE_OK; -} - -static CURLcode -mbed_connect_step3(struct connectdata *conn, - int sockindex) -{ - CURLcode retcode = CURLE_OK; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - void *old_ssl_sessionid = NULL; - mbedtls_ssl_session *our_ssl_sessionid; - int ret; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - our_ssl_sessionid = malloc(sizeof(mbedtls_ssl_session)); - if(!our_ssl_sessionid) - return CURLE_OUT_OF_MEMORY; - - mbedtls_ssl_session_init(our_ssl_sessionid); - - ret = mbedtls_ssl_get_session(&connssl->ssl, our_ssl_sessionid); - if(ret) { - failf(data, "mbedtls_ssl_get_session returned -0x%x", -ret); - return CURLE_SSL_CONNECT_ERROR; - } - - /* If there's already a matching session in the cache, delete it */ - if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)) - Curl_ssl_delsessionid(conn, old_ssl_sessionid); - - retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0); - if(retcode) { - free(our_ssl_sessionid); - failf(data, "failed to store ssl session"); - return retcode; - } - - connssl->connecting_state = ssl_connect_done; - - return CURLE_OK; -} - -static ssize_t mbed_send(struct connectdata *conn, int sockindex, - const void *mem, size_t len, - CURLcode *curlcode) -{ - int ret = -1; - - ret = mbedtls_ssl_write(&conn->ssl[sockindex].ssl, - (unsigned char *)mem, len); - - if(ret < 0) { - *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_WRITE) ? - CURLE_AGAIN : CURLE_SEND_ERROR; - ret = -1; - } - - return ret; -} - -void Curl_mbedtls_close_all(struct SessionHandle *data) -{ - (void)data; -} - -void Curl_mbedtls_close(struct connectdata *conn, int sockindex) -{ - mbedtls_pk_free(&conn->ssl[sockindex].pk); - mbedtls_x509_crt_free(&conn->ssl[sockindex].clicert); - mbedtls_x509_crt_free(&conn->ssl[sockindex].cacert); - mbedtls_x509_crl_free(&conn->ssl[sockindex].crl); - mbedtls_ssl_config_free(&conn->ssl[sockindex].config); - mbedtls_ssl_free(&conn->ssl[sockindex].ssl); - mbedtls_ctr_drbg_free(&conn->ssl[sockindex].ctr_drbg); -#ifndef THREADING_SUPPORT - mbedtls_entropy_free(&conn->ssl[sockindex].entropy); -#endif /* THREADING_SUPPORT */ -} - -static ssize_t mbed_recv(struct connectdata *conn, int num, - char *buf, size_t buffersize, - CURLcode *curlcode) -{ - int ret = -1; - ssize_t len = -1; - - memset(buf, 0, buffersize); - ret = mbedtls_ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, - buffersize); - - if(ret <= 0) { - if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) - return 0; - - *curlcode = (ret == MBEDTLS_ERR_SSL_WANT_READ) ? - CURLE_AGAIN : CURLE_RECV_ERROR; - return -1; - } - - len = ret; - - return len; -} - -void Curl_mbedtls_session_free(void *ptr) -{ - mbedtls_ssl_session_free(ptr); - free(ptr); -} - -size_t Curl_mbedtls_version(char *buffer, size_t size) -{ - unsigned int version = mbedtls_version_get_number(); - return snprintf(buffer, size, "mbedTLS/%d.%d.%d", version>>24, - (version>>16)&0xff, (version>>8)&0xff); -} - -static CURLcode -mbed_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode retcode; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - long timeout_ms; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1==connssl->connecting_state) { - /* Find out how much more time we're allowed */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - retcode = mbed_connect_step1(conn, sockindex); - if(retcode) - return retcode; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading - || connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if - * this connection is part of a multi handle and this loop would - * execute again. This permits the owner of a multi handle to - * abort a connection attempt before step2 has completed while - * ensuring that a client using select() or epoll() will always - * have a valid fdset to wait on. - */ - retcode = mbed_connect_step2(conn, sockindex); - if(retcode || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return retcode; - - } /* repeat step2 until all transactions are done. */ - - if(ssl_connect_3==connssl->connecting_state) { - retcode = mbed_connect_step3(conn, sockindex); - if(retcode) - return retcode; - } - - if(ssl_connect_done==connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = mbed_recv; - conn->send[sockindex] = mbed_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -CURLcode -Curl_mbedtls_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done) -{ - return mbed_connect_common(conn, sockindex, TRUE, done); -} - - -CURLcode -Curl_mbedtls_connect(struct connectdata *conn, - int sockindex) -{ - CURLcode retcode; - bool done = FALSE; - - retcode = mbed_connect_common(conn, sockindex, FALSE, &done); - if(retcode) - return retcode; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -/* - * return 0 error initializing SSL - * return 1 SSL initialized successfully - */ -int Curl_mbedtls_init(void) -{ - return Curl_polarsslthreadlock_thread_setup(); -} - -void Curl_mbedtls_cleanup(void) -{ - (void)Curl_polarsslthreadlock_thread_cleanup(); -} - -int Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex) -{ - mbedtls_ssl_context *ssl = - (mbedtls_ssl_context *)&conn->ssl[sockindex].ssl; - return ssl->in_msglen != 0; -} - -#endif /* USE_MBEDTLS */ diff --git a/Externals/curl/lib/vtls/mbedtls.h b/Externals/curl/lib/vtls/mbedtls.h deleted file mode 100644 index 9117fff1c3..0000000000 --- a/Externals/curl/lib/vtls/mbedtls.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef HEADER_CURL_MBEDTLS_H -#define HEADER_CURL_MBEDTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * Copyright (C) 2010, Hoi-Ho Chan, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_MBEDTLS - -#include - -/* Called on first use mbedTLS, setup threading if supported */ -int Curl_mbedtls_init(void); -void Curl_mbedtls_cleanup(void); -int Curl_mbedtls_data_pending(const struct connectdata *conn, int sockindex); - -CURLcode Curl_mbedtls_connect(struct connectdata *conn, int sockindex); - -CURLcode Curl_mbedtls_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); - -/* tell mbedTLS to close down all open information regarding connections (and - thus session ID caching etc) */ -void Curl_mbedtls_close_all(struct SessionHandle *data); - - /* close a SSL connection */ -void Curl_mbedtls_close(struct connectdata *conn, int sockindex); - -void Curl_mbedtls_session_free(void *ptr); -size_t Curl_mbedtls_version(char *buffer, size_t size); -int Curl_mbedtls_shutdown(struct connectdata *conn, int sockindex); - -/* this backends supports CURLOPT_PINNEDPUBLICKEY */ -#define have_curlssl_pinnedpubkey 1 - -/* API setup for mbedTLS */ -#define curlssl_init() Curl_mbedtls_init() -#define curlssl_cleanup() Curl_mbedtls_cleanup() -#define curlssl_connect Curl_mbedtls_connect -#define curlssl_connect_nonblocking Curl_mbedtls_connect_nonblocking -#define curlssl_session_free(x) Curl_mbedtls_session_free(x) -#define curlssl_close_all Curl_mbedtls_close_all -#define curlssl_close Curl_mbedtls_close -#define curlssl_shutdown(x,y) 0 -#define curlssl_set_engine(x,y) (x=x, y=y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) (x=x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) (x=x, (struct curl_slist *)NULL) -#define curlssl_version Curl_mbedtls_version -#define curlssl_check_cxn(x) (x=x, -1) -#define curlssl_data_pending(x,y) Curl_mbedtls_data_pending(x, y) -#define CURL_SSL_BACKEND CURLSSLBACKEND_MBEDTLS -#define curlssl_sha256sum(a,b,c,d) mbedtls_sha256(a,b,c,0) - -/* This might cause libcurl to use a weeker random! - TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that -*/ -#define curlssl_random(x,y,z) (x=x, y=y, z=z, CURLE_NOT_BUILT_IN) - -#endif /* USE_MBEDTLS */ -#endif /* HEADER_CURL_MBEDTLS_H */ diff --git a/Externals/curl/lib/vtls/nss.c b/Externals/curl/lib/vtls/nss.c deleted file mode 100644 index 02c8727e44..0000000000 --- a/Externals/curl/lib/vtls/nss.c +++ /dev/null @@ -1,2081 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all NSS-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - */ - -#include "curl_setup.h" - -#ifdef USE_NSS - -#include "urldata.h" -#include "sendf.h" -#include "formdata.h" /* for the boundary function */ -#include "url.h" /* for the ssl config check function */ -#include "connect.h" -#include "strequal.h" -#include "select.h" -#include "vtls.h" -#include "llist.h" -#include "curl_printf.h" -#include "nssg.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for SECKEY_DestroyPublicKey() */ - -#define NSSVERNUM ((NSS_VMAJOR<<16)|(NSS_VMINOR<<8)|NSS_VPATCH) - -#if NSSVERNUM >= 0x030f00 /* 3.15.0 */ -#include -#endif - -#include "rawstr.h" -#include "warnless.h" -#include "x509asn1.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -#define SSL_DIR "/etc/pki/nssdb" - -/* enough to fit the string "PEM Token #[0|1]" */ -#define SLOTSIZE 13 - -PRFileDesc *PR_ImportTCPSocket(PRInt32 osfd); - -PRLock * nss_initlock = NULL; -PRLock * nss_crllock = NULL; -struct curl_llist *nss_crl_list = NULL; -NSSInitContext * nss_context = NULL; - -volatile int initialized = 0; - -typedef struct { - const char *name; - int num; -} cipher_s; - -#define PK11_SETATTRS(_attr, _idx, _type, _val, _len) do { \ - CK_ATTRIBUTE *ptr = (_attr) + ((_idx)++); \ - ptr->type = (_type); \ - ptr->pValue = (_val); \ - ptr->ulValueLen = (_len); \ -} WHILE_FALSE - -#define CERT_NewTempCertificate __CERT_NewTempCertificate - -#define NUM_OF_CIPHERS sizeof(cipherlist)/sizeof(cipherlist[0]) -static const cipher_s cipherlist[] = { - /* SSL2 cipher suites */ - {"rc4", SSL_EN_RC4_128_WITH_MD5}, - {"rc4-md5", SSL_EN_RC4_128_WITH_MD5}, - {"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5}, - {"rc2", SSL_EN_RC2_128_CBC_WITH_MD5}, - {"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5}, - {"des", SSL_EN_DES_64_CBC_WITH_MD5}, - {"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5}, - /* SSL3/TLS cipher suites */ - {"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5}, - {"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA}, - {"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA}, - {"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA}, - {"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5}, - {"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5}, - {"rsa_null_md5", SSL_RSA_WITH_NULL_MD5}, - {"rsa_null_sha", SSL_RSA_WITH_NULL_SHA}, - {"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA}, - {"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA}, - {"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA}, - {"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA}, - {"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA}, - /* TLS 1.0: Exportable 56-bit Cipher Suites. */ - {"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA}, - {"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, - /* AES ciphers. */ - {"dhe_dss_aes_128_cbc_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA}, - {"dhe_dss_aes_256_cbc_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA}, - {"dhe_rsa_aes_128_cbc_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA}, - {"dhe_rsa_aes_256_cbc_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA}, - {"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA}, - {"rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA}, - /* ECC ciphers. */ - {"ecdh_ecdsa_null_sha", TLS_ECDH_ECDSA_WITH_NULL_SHA}, - {"ecdh_ecdsa_rc4_128_sha", TLS_ECDH_ECDSA_WITH_RC4_128_SHA}, - {"ecdh_ecdsa_3des_sha", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA}, - {"ecdh_ecdsa_aes_128_sha", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA}, - {"ecdh_ecdsa_aes_256_sha", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA}, - {"ecdhe_ecdsa_null_sha", TLS_ECDHE_ECDSA_WITH_NULL_SHA}, - {"ecdhe_ecdsa_rc4_128_sha", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA}, - {"ecdhe_ecdsa_3des_sha", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA}, - {"ecdhe_ecdsa_aes_128_sha", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA}, - {"ecdhe_ecdsa_aes_256_sha", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}, - {"ecdh_rsa_null_sha", TLS_ECDH_RSA_WITH_NULL_SHA}, - {"ecdh_rsa_128_sha", TLS_ECDH_RSA_WITH_RC4_128_SHA}, - {"ecdh_rsa_3des_sha", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA}, - {"ecdh_rsa_aes_128_sha", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA}, - {"ecdh_rsa_aes_256_sha", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA}, - {"echde_rsa_null", TLS_ECDHE_RSA_WITH_NULL_SHA}, - {"ecdhe_rsa_rc4_128_sha", TLS_ECDHE_RSA_WITH_RC4_128_SHA}, - {"ecdhe_rsa_3des_sha", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA}, - {"ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA}, - {"ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, - {"ecdh_anon_null_sha", TLS_ECDH_anon_WITH_NULL_SHA}, - {"ecdh_anon_rc4_128sha", TLS_ECDH_anon_WITH_RC4_128_SHA}, - {"ecdh_anon_3des_sha", TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA}, - {"ecdh_anon_aes_128_sha", TLS_ECDH_anon_WITH_AES_128_CBC_SHA}, - {"ecdh_anon_aes_256_sha", TLS_ECDH_anon_WITH_AES_256_CBC_SHA}, -#ifdef TLS_RSA_WITH_NULL_SHA256 - /* new HMAC-SHA256 cipher suites specified in RFC */ - {"rsa_null_sha_256", TLS_RSA_WITH_NULL_SHA256}, - {"rsa_aes_128_cbc_sha_256", TLS_RSA_WITH_AES_128_CBC_SHA256}, - {"rsa_aes_256_cbc_sha_256", TLS_RSA_WITH_AES_256_CBC_SHA256}, - {"dhe_rsa_aes_128_cbc_sha_256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256}, - {"dhe_rsa_aes_256_cbc_sha_256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256}, - {"ecdhe_ecdsa_aes_128_cbc_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256}, - {"ecdhe_rsa_aes_128_cbc_sha_256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256}, -#endif -#ifdef TLS_RSA_WITH_AES_128_GCM_SHA256 - /* AES GCM cipher suites in RFC 5288 and RFC 5289 */ - {"rsa_aes_128_gcm_sha_256", TLS_RSA_WITH_AES_128_GCM_SHA256}, - {"dhe_rsa_aes_128_gcm_sha_256", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256}, - {"dhe_dss_aes_128_gcm_sha_256", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256}, - {"ecdhe_ecdsa_aes_128_gcm_sha_256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}, - {"ecdh_ecdsa_aes_128_gcm_sha_256", TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256}, - {"ecdhe_rsa_aes_128_gcm_sha_256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, - {"ecdh_rsa_aes_128_gcm_sha_256", TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256}, -#endif -}; - -static const char* pem_library = "libnsspem.so"; -SECMODModule* mod = NULL; - -/* NSPR I/O layer we use to detect blocking direction during SSL handshake */ -static PRDescIdentity nspr_io_identity = PR_INVALID_IO_LAYER; -static PRIOMethods nspr_io_methods; - -static const char* nss_error_to_name(PRErrorCode code) -{ - const char *name = PR_ErrorToName(code); - if(name) - return name; - - return "unknown error"; -} - -static void nss_print_error_message(struct SessionHandle *data, PRUint32 err) -{ - failf(data, "%s", PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT)); -} - -static SECStatus set_ciphers(struct SessionHandle *data, PRFileDesc * model, - char *cipher_list) -{ - unsigned int i; - PRBool cipher_state[NUM_OF_CIPHERS]; - PRBool found; - char *cipher; - - /* use accessors to avoid dynamic linking issues after an update of NSS */ - const PRUint16 num_implemented_ciphers = SSL_GetNumImplementedCiphers(); - const PRUint16 *implemented_ciphers = SSL_GetImplementedCiphers(); - if(!implemented_ciphers) - return SECFailure; - - /* First disable all ciphers. This uses a different max value in case - * NSS adds more ciphers later we don't want them available by - * accident - */ - for(i = 0; i < num_implemented_ciphers; i++) { - SSL_CipherPrefSet(model, implemented_ciphers[i], PR_FALSE); - } - - /* Set every entry in our list to false */ - for(i = 0; i < NUM_OF_CIPHERS; i++) { - cipher_state[i] = PR_FALSE; - } - - cipher = cipher_list; - - while(cipher_list && (cipher_list[0])) { - while((*cipher) && (ISSPACE(*cipher))) - ++cipher; - - if((cipher_list = strchr(cipher, ','))) { - *cipher_list++ = '\0'; - } - - found = PR_FALSE; - - for(i=0; iset.str[cert_kind]; - const char *n; - - if(!is_file(str)) - /* no such file exists, use the string as nickname */ - return strdup(str); - - /* search the first slash; we require at least one slash in a file name */ - n = strchr(str, '/'); - if(!n) { - infof(data, "warning: certificate file name \"%s\" handled as nickname; " - "please use \"./%s\" to force file name\n", str, str); - return strdup(str); - } - - /* we'll use the PEM reader to read the certificate from file */ - return NULL; -} - -/* Call PK11_CreateGenericObject() with the given obj_class and filename. If - * the call succeeds, append the object handle to the list of objects so that - * the object can be destroyed in Curl_nss_close(). */ -static CURLcode nss_create_object(struct ssl_connect_data *ssl, - CK_OBJECT_CLASS obj_class, - const char *filename, bool cacert) -{ - PK11SlotInfo *slot; - PK11GenericObject *obj; - CK_BBOOL cktrue = CK_TRUE; - CK_BBOOL ckfalse = CK_FALSE; - CK_ATTRIBUTE attrs[/* max count of attributes */ 4]; - int attr_cnt = 0; - CURLcode result = (cacert) - ? CURLE_SSL_CACERT_BADFILE - : CURLE_SSL_CERTPROBLEM; - - const int slot_id = (cacert) ? 0 : 1; - char *slot_name = aprintf("PEM Token #%d", slot_id); - if(!slot_name) - return CURLE_OUT_OF_MEMORY; - - slot = PK11_FindSlotByName(slot_name); - free(slot_name); - if(!slot) - return result; - - PK11_SETATTRS(attrs, attr_cnt, CKA_CLASS, &obj_class, sizeof(obj_class)); - PK11_SETATTRS(attrs, attr_cnt, CKA_TOKEN, &cktrue, sizeof(CK_BBOOL)); - PK11_SETATTRS(attrs, attr_cnt, CKA_LABEL, (unsigned char *)filename, - strlen(filename) + 1); - - if(CKO_CERTIFICATE == obj_class) { - CK_BBOOL *pval = (cacert) ? (&cktrue) : (&ckfalse); - PK11_SETATTRS(attrs, attr_cnt, CKA_TRUST, pval, sizeof(*pval)); - } - - obj = PK11_CreateGenericObject(slot, attrs, attr_cnt, PR_FALSE); - PK11_FreeSlot(slot); - if(!obj) - return result; - - if(!Curl_llist_insert_next(ssl->obj_list, ssl->obj_list->tail, obj)) { - PK11_DestroyGenericObject(obj); - return CURLE_OUT_OF_MEMORY; - } - - if(!cacert && CKO_CERTIFICATE == obj_class) - /* store reference to a client certificate */ - ssl->obj_clicert = obj; - - return CURLE_OK; -} - -/* Destroy the NSS object whose handle is given by ptr. This function is - * a callback of Curl_llist_alloc() used by Curl_llist_destroy() to destroy - * NSS objects in Curl_nss_close() */ -static void nss_destroy_object(void *user, void *ptr) -{ - PK11GenericObject *obj = (PK11GenericObject *)ptr; - (void) user; - PK11_DestroyGenericObject(obj); -} - -/* same as nss_destroy_object() but for CRL items */ -static void nss_destroy_crl_item(void *user, void *ptr) -{ - SECItem *crl_der = (SECItem *)ptr; - (void) user; - SECITEM_FreeItem(crl_der, PR_TRUE); -} - -static CURLcode nss_load_cert(struct ssl_connect_data *ssl, - const char *filename, PRBool cacert) -{ - CURLcode result = (cacert) - ? CURLE_SSL_CACERT_BADFILE - : CURLE_SSL_CERTPROBLEM; - - /* libnsspem.so leaks memory if the requested file does not exist. For more - * details, go to . */ - if(is_file(filename)) - result = nss_create_object(ssl, CKO_CERTIFICATE, filename, cacert); - - if(!result && !cacert) { - /* we have successfully loaded a client certificate */ - CERTCertificate *cert; - char *nickname = NULL; - char *n = strrchr(filename, '/'); - if(n) - n++; - - /* The following undocumented magic helps to avoid a SIGSEGV on call - * of PK11_ReadRawAttribute() from SelectClientCert() when using an - * immature version of libnsspem.so. For more details, go to - * . */ - nickname = aprintf("PEM Token #1:%s", n); - if(nickname) { - cert = PK11_FindCertFromNickname(nickname, NULL); - if(cert) - CERT_DestroyCertificate(cert); - - free(nickname); - } - } - - return result; -} - -/* add given CRL to cache if it is not already there */ -static CURLcode nss_cache_crl(SECItem *crl_der) -{ - CERTCertDBHandle *db = CERT_GetDefaultCertDB(); - CERTSignedCrl *crl = SEC_FindCrlByDERCert(db, crl_der, 0); - if(crl) { - /* CRL already cached */ - SEC_DestroyCrl(crl); - SECITEM_FreeItem(crl_der, PR_TRUE); - return CURLE_OK; - } - - /* acquire lock before call of CERT_CacheCRL() and accessing nss_crl_list */ - PR_Lock(nss_crllock); - - /* store the CRL item so that we can free it in Curl_nss_cleanup() */ - if(!Curl_llist_insert_next(nss_crl_list, nss_crl_list->tail, crl_der)) { - SECITEM_FreeItem(crl_der, PR_TRUE); - PR_Unlock(nss_crllock); - return CURLE_OUT_OF_MEMORY; - } - - if(SECSuccess != CERT_CacheCRL(db, crl_der)) { - /* unable to cache CRL */ - PR_Unlock(nss_crllock); - return CURLE_SSL_CRL_BADFILE; - } - - /* we need to clear session cache, so that the CRL could take effect */ - SSL_ClearSessionCache(); - PR_Unlock(nss_crllock); - return CURLE_OK; -} - -static CURLcode nss_load_crl(const char* crlfilename) -{ - PRFileDesc *infile; - PRFileInfo info; - SECItem filedata = { 0, NULL, 0 }; - SECItem *crl_der = NULL; - char *body; - - infile = PR_Open(crlfilename, PR_RDONLY, 0); - if(!infile) - return CURLE_SSL_CRL_BADFILE; - - if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info)) - goto fail; - - if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1)) - goto fail; - - if(info.size != PR_Read(infile, filedata.data, info.size)) - goto fail; - - crl_der = SECITEM_AllocItem(NULL, NULL, 0U); - if(!crl_der) - goto fail; - - /* place a trailing zero right after the visible data */ - body = (char*)filedata.data; - body[--filedata.len] = '\0'; - - body = strstr(body, "-----BEGIN"); - if(body) { - /* assume ASCII */ - char *trailer; - char *begin = PORT_Strchr(body, '\n'); - if(!begin) - begin = PORT_Strchr(body, '\r'); - if(!begin) - goto fail; - - trailer = strstr(++begin, "-----END"); - if(!trailer) - goto fail; - - /* retrieve DER from ASCII */ - *trailer = '\0'; - if(ATOB_ConvertAsciiToItem(crl_der, begin)) - goto fail; - - SECITEM_FreeItem(&filedata, PR_FALSE); - } - else - /* assume DER */ - *crl_der = filedata; - - PR_Close(infile); - return nss_cache_crl(crl_der); - -fail: - PR_Close(infile); - SECITEM_FreeItem(crl_der, PR_TRUE); - SECITEM_FreeItem(&filedata, PR_FALSE); - return CURLE_SSL_CRL_BADFILE; -} - -static CURLcode nss_load_key(struct connectdata *conn, int sockindex, - char *key_file) -{ - PK11SlotInfo *slot; - SECStatus status; - CURLcode result; - struct ssl_connect_data *ssl = conn->ssl; - - (void)sockindex; /* unused */ - - result = nss_create_object(ssl, CKO_PRIVATE_KEY, key_file, FALSE); - if(result) { - PR_SetError(SEC_ERROR_BAD_KEY, 0); - return result; - } - - slot = PK11_FindSlotByName("PEM Token #1"); - if(!slot) - return CURLE_SSL_CERTPROBLEM; - - /* This will force the token to be seen as re-inserted */ - SECMOD_WaitForAnyTokenEvent(mod, 0, 0); - PK11_IsPresent(slot); - - status = PK11_Authenticate(slot, PR_TRUE, - conn->data->set.str[STRING_KEY_PASSWD]); - PK11_FreeSlot(slot); - - return (SECSuccess == status) ? CURLE_OK : CURLE_SSL_CERTPROBLEM; -} - -static int display_error(struct connectdata *conn, PRInt32 err, - const char *filename) -{ - switch(err) { - case SEC_ERROR_BAD_PASSWORD: - failf(conn->data, "Unable to load client key: Incorrect password"); - return 1; - case SEC_ERROR_UNKNOWN_CERT: - failf(conn->data, "Unable to load certificate %s", filename); - return 1; - default: - break; - } - return 0; /* The caller will print a generic error */ -} - -static CURLcode cert_stuff(struct connectdata *conn, int sockindex, - char *cert_file, char *key_file) -{ - struct SessionHandle *data = conn->data; - CURLcode result; - - if(cert_file) { - result = nss_load_cert(&conn->ssl[sockindex], cert_file, PR_FALSE); - if(result) { - const PRErrorCode err = PR_GetError(); - if(!display_error(conn, err, cert_file)) { - const char *err_name = nss_error_to_name(err); - failf(data, "unable to load client cert: %d (%s)", err, err_name); - } - - return result; - } - } - - if(key_file || (is_file(cert_file))) { - if(key_file) - result = nss_load_key(conn, sockindex, key_file); - else - /* In case the cert file also has the key */ - result = nss_load_key(conn, sockindex, cert_file); - if(result) { - const PRErrorCode err = PR_GetError(); - if(!display_error(conn, err, key_file)) { - const char *err_name = nss_error_to_name(err); - failf(data, "unable to load client key: %d (%s)", err, err_name); - } - - return result; - } - } - - return CURLE_OK; -} - -static char * nss_get_password(PK11SlotInfo * slot, PRBool retry, void *arg) -{ - (void)slot; /* unused */ - - if(retry || NULL == arg) - return NULL; - else - return (char *)PORT_Strdup((char *)arg); -} - -/* bypass the default SSL_AuthCertificate() hook in case we do not want to - * verify peer */ -static SECStatus nss_auth_cert_hook(void *arg, PRFileDesc *fd, PRBool checksig, - PRBool isServer) -{ - struct connectdata *conn = (struct connectdata *)arg; - -#ifdef SSL_ENABLE_OCSP_STAPLING - if(conn->data->set.ssl.verifystatus) { - SECStatus cacheResult; - - const SECItemArray *csa = SSL_PeerStapledOCSPResponses(fd); - if(!csa) { - failf(conn->data, "Invalid OCSP response"); - return SECFailure; - } - - if(csa->len == 0) { - failf(conn->data, "No OCSP response received"); - return SECFailure; - } - - cacheResult = CERT_CacheOCSPResponseFromSideChannel( - CERT_GetDefaultCertDB(), SSL_PeerCertificate(fd), - PR_Now(), &csa->items[0], arg - ); - - if(cacheResult != SECSuccess) { - failf(conn->data, "Invalid OCSP response"); - return cacheResult; - } - } -#endif - - if(!conn->data->set.ssl.verifypeer) { - infof(conn->data, "skipping SSL peer certificate verification\n"); - return SECSuccess; - } - - return SSL_AuthCertificate(CERT_GetDefaultCertDB(), fd, checksig, isServer); -} - -/** - * Inform the application that the handshake is complete. - */ -static void HandshakeCallback(PRFileDesc *sock, void *arg) -{ - struct connectdata *conn = (struct connectdata*) arg; - unsigned int buflenmax = 50; - unsigned char buf[50]; - unsigned int buflen; - SSLNextProtoState state; - - if(!conn->bits.tls_enable_npn && !conn->bits.tls_enable_alpn) { - return; - } - - if(SSL_GetNextProto(sock, &state, buf, &buflen, buflenmax) == SECSuccess) { - - switch(state) { - case SSL_NEXT_PROTO_NO_SUPPORT: - case SSL_NEXT_PROTO_NO_OVERLAP: - infof(conn->data, "ALPN/NPN, server did not agree to a protocol\n"); - return; -#ifdef SSL_ENABLE_ALPN - case SSL_NEXT_PROTO_SELECTED: - infof(conn->data, "ALPN, server accepted to use %.*s\n", buflen, buf); - break; -#endif - case SSL_NEXT_PROTO_NEGOTIATED: - infof(conn->data, "NPN, server accepted to use %.*s\n", buflen, buf); - break; - } - -#ifdef USE_NGHTTP2 - if(buflen == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, buf, NGHTTP2_PROTO_VERSION_ID_LEN)) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(buflen == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, buf, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - } -} - -#if NSSVERNUM >= 0x030f04 /* 3.15.4 */ -static SECStatus CanFalseStartCallback(PRFileDesc *sock, void *client_data, - PRBool *canFalseStart) -{ - struct connectdata *conn = client_data; - struct SessionHandle *data = conn->data; - - SSLChannelInfo channelInfo; - SSLCipherSuiteInfo cipherInfo; - - SECStatus rv; - PRBool negotiatedExtension; - - *canFalseStart = PR_FALSE; - - if(SSL_GetChannelInfo(sock, &channelInfo, sizeof(channelInfo)) != SECSuccess) - return SECFailure; - - if(SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, - sizeof(cipherInfo)) != SECSuccess) - return SECFailure; - - /* Prevent version downgrade attacks from TLS 1.2, and avoid False Start for - * TLS 1.3 and later. See https://bugzilla.mozilla.org/show_bug.cgi?id=861310 - */ - if(channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2) - goto end; - - /* Only allow ECDHE key exchange algorithm. - * See https://bugzilla.mozilla.org/show_bug.cgi?id=952863 */ - if(cipherInfo.keaType != ssl_kea_ecdh) - goto end; - - /* Prevent downgrade attacks on the symmetric cipher. We do not allow CBC - * mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt - * design. See https://bugzilla.mozilla.org/show_bug.cgi?id=1109766 */ - if(cipherInfo.symCipher != ssl_calg_aes_gcm) - goto end; - - /* Enforce ALPN or NPN to do False Start, as an indicator of server - * compatibility. */ - rv = SSL_HandshakeNegotiatedExtension(sock, ssl_app_layer_protocol_xtn, - &negotiatedExtension); - if(rv != SECSuccess || !negotiatedExtension) { - rv = SSL_HandshakeNegotiatedExtension(sock, ssl_next_proto_nego_xtn, - &negotiatedExtension); - } - - if(rv != SECSuccess || !negotiatedExtension) - goto end; - - *canFalseStart = PR_TRUE; - - infof(data, "Trying TLS False Start\n"); - -end: - return SECSuccess; -} -#endif - -static void display_cert_info(struct SessionHandle *data, - CERTCertificate *cert) -{ - char *subject, *issuer, *common_name; - PRExplodedTime printableTime; - char timeString[256]; - PRTime notBefore, notAfter; - - subject = CERT_NameToAscii(&cert->subject); - issuer = CERT_NameToAscii(&cert->issuer); - common_name = CERT_GetCommonName(&cert->subject); - infof(data, "\tsubject: %s\n", subject); - - CERT_GetCertTimes(cert, ¬Before, ¬After); - PR_ExplodeTime(notBefore, PR_GMTParameters, &printableTime); - PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime); - infof(data, "\tstart date: %s\n", timeString); - PR_ExplodeTime(notAfter, PR_GMTParameters, &printableTime); - PR_FormatTime(timeString, 256, "%b %d %H:%M:%S %Y GMT", &printableTime); - infof(data, "\texpire date: %s\n", timeString); - infof(data, "\tcommon name: %s\n", common_name); - infof(data, "\tissuer: %s\n", issuer); - - PR_Free(subject); - PR_Free(issuer); - PR_Free(common_name); -} - -static CURLcode display_conn_info(struct connectdata *conn, PRFileDesc *sock) -{ - CURLcode result = CURLE_OK; - SSLChannelInfo channel; - SSLCipherSuiteInfo suite; - CERTCertificate *cert; - CERTCertificate *cert2; - CERTCertificate *cert3; - PRTime now; - int i; - - if(SSL_GetChannelInfo(sock, &channel, sizeof channel) == - SECSuccess && channel.length == sizeof channel && - channel.cipherSuite) { - if(SSL_GetCipherSuiteInfo(channel.cipherSuite, - &suite, sizeof suite) == SECSuccess) { - infof(conn->data, "SSL connection using %s\n", suite.cipherSuiteName); - } - } - - cert = SSL_PeerCertificate(sock); - if(cert) { - infof(conn->data, "Server certificate:\n"); - - if(!conn->data->set.ssl.certinfo) { - display_cert_info(conn->data, cert); - CERT_DestroyCertificate(cert); - } - else { - /* Count certificates in chain. */ - now = PR_Now(); - i = 1; - if(!cert->isRoot) { - cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA); - while(cert2) { - i++; - if(cert2->isRoot) { - CERT_DestroyCertificate(cert2); - break; - } - cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA); - CERT_DestroyCertificate(cert2); - cert2 = cert3; - } - } - - result = Curl_ssl_init_certinfo(conn->data, i); - if(!result) { - for(i = 0; cert; cert = cert2) { - result = Curl_extract_certinfo(conn, i++, (char *)cert->derCert.data, - (char *)cert->derCert.data + - cert->derCert.len); - if(result) - break; - - if(cert->isRoot) { - CERT_DestroyCertificate(cert); - break; - } - - cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA); - CERT_DestroyCertificate(cert); - } - } - } - } - - return result; -} - -static SECStatus BadCertHandler(void *arg, PRFileDesc *sock) -{ - struct connectdata *conn = (struct connectdata *)arg; - struct SessionHandle *data = conn->data; - PRErrorCode err = PR_GetError(); - CERTCertificate *cert; - - /* remember the cert verification result */ - data->set.ssl.certverifyresult = err; - - if(err == SSL_ERROR_BAD_CERT_DOMAIN && !data->set.ssl.verifyhost) - /* we are asked not to verify the host name */ - return SECSuccess; - - /* print only info about the cert, the error is printed off the callback */ - cert = SSL_PeerCertificate(sock); - if(cert) { - infof(data, "Server certificate:\n"); - display_cert_info(data, cert); - CERT_DestroyCertificate(cert); - } - - return SECFailure; -} - -/** - * - * Check that the Peer certificate's issuer certificate matches the one found - * by issuer_nickname. This is not exactly the way OpenSSL and GNU TLS do the - * issuer check, so we provide comments that mimic the OpenSSL - * X509_check_issued function (in x509v3/v3_purp.c) - */ -static SECStatus check_issuer_cert(PRFileDesc *sock, - char *issuer_nickname) -{ - CERTCertificate *cert, *cert_issuer, *issuer; - SECStatus res=SECSuccess; - void *proto_win = NULL; - - cert = SSL_PeerCertificate(sock); - cert_issuer = CERT_FindCertIssuer(cert, PR_Now(), certUsageObjectSigner); - - proto_win = SSL_RevealPinArg(sock); - issuer = PK11_FindCertFromNickname(issuer_nickname, proto_win); - - if((!cert_issuer) || (!issuer)) - res = SECFailure; - else if(SECITEM_CompareItem(&cert_issuer->derCert, - &issuer->derCert)!=SECEqual) - res = SECFailure; - - CERT_DestroyCertificate(cert); - CERT_DestroyCertificate(issuer); - CERT_DestroyCertificate(cert_issuer); - return res; -} - -static CURLcode cmp_peer_pubkey(struct ssl_connect_data *connssl, - const char *pinnedpubkey) -{ - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - struct SessionHandle *data = connssl->data; - CERTCertificate *cert; - - if(!pinnedpubkey) - /* no pinned public key specified */ - return CURLE_OK; - - /* get peer certificate */ - cert = SSL_PeerCertificate(connssl->handle); - if(cert) { - /* extract public key from peer certificate */ - SECKEYPublicKey *pubkey = CERT_ExtractPublicKey(cert); - if(pubkey) { - /* encode the public key as DER */ - SECItem *cert_der = PK11_DEREncodePublicKey(pubkey); - if(cert_der) { - /* compare the public key with the pinned public key */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, cert_der->data, - cert_der->len); - SECITEM_FreeItem(cert_der, PR_TRUE); - } - SECKEY_DestroyPublicKey(pubkey); - } - CERT_DestroyCertificate(cert); - } - - /* report the resulting status */ - switch(result) { - case CURLE_OK: - infof(data, "pinned public key verified successfully!\n"); - break; - case CURLE_SSL_PINNEDPUBKEYNOTMATCH: - failf(data, "failed to verify pinned public key"); - break; - default: - /* OOM, etc. */ - break; - } - - return result; -} - -/** - * - * Callback to pick the SSL client certificate. - */ -static SECStatus SelectClientCert(void *arg, PRFileDesc *sock, - struct CERTDistNamesStr *caNames, - struct CERTCertificateStr **pRetCert, - struct SECKEYPrivateKeyStr **pRetKey) -{ - struct ssl_connect_data *connssl = (struct ssl_connect_data *)arg; - struct SessionHandle *data = connssl->data; - const char *nickname = connssl->client_nickname; - - if(connssl->obj_clicert) { - /* use the cert/key provided by PEM reader */ - static const char pem_slotname[] = "PEM Token #1"; - SECItem cert_der = { 0, NULL, 0 }; - void *proto_win = SSL_RevealPinArg(sock); - struct CERTCertificateStr *cert; - struct SECKEYPrivateKeyStr *key; - - PK11SlotInfo *slot = PK11_FindSlotByName(pem_slotname); - if(NULL == slot) { - failf(data, "NSS: PK11 slot not found: %s", pem_slotname); - return SECFailure; - } - - if(PK11_ReadRawAttribute(PK11_TypeGeneric, connssl->obj_clicert, CKA_VALUE, - &cert_der) != SECSuccess) { - failf(data, "NSS: CKA_VALUE not found in PK11 generic object"); - PK11_FreeSlot(slot); - return SECFailure; - } - - cert = PK11_FindCertFromDERCertItem(slot, &cert_der, proto_win); - SECITEM_FreeItem(&cert_der, PR_FALSE); - if(NULL == cert) { - failf(data, "NSS: client certificate from file not found"); - PK11_FreeSlot(slot); - return SECFailure; - } - - key = PK11_FindPrivateKeyFromCert(slot, cert, NULL); - PK11_FreeSlot(slot); - if(NULL == key) { - failf(data, "NSS: private key from file not found"); - CERT_DestroyCertificate(cert); - return SECFailure; - } - - infof(data, "NSS: client certificate from file\n"); - display_cert_info(data, cert); - - *pRetCert = cert; - *pRetKey = key; - return SECSuccess; - } - - /* use the default NSS hook */ - if(SECSuccess != NSS_GetClientAuthData((void *)nickname, sock, caNames, - pRetCert, pRetKey) - || NULL == *pRetCert) { - - if(NULL == nickname) - failf(data, "NSS: client certificate not found (nickname not " - "specified)"); - else - failf(data, "NSS: client certificate not found: %s", nickname); - - return SECFailure; - } - - /* get certificate nickname if any */ - nickname = (*pRetCert)->nickname; - if(NULL == nickname) - nickname = "[unknown]"; - - if(NULL == *pRetKey) { - failf(data, "NSS: private key not found for certificate: %s", nickname); - return SECFailure; - } - - infof(data, "NSS: using client certificate: %s\n", nickname); - display_cert_info(data, *pRetCert); - return SECSuccess; -} - -/* update blocking direction in case of PR_WOULD_BLOCK_ERROR */ -static void nss_update_connecting_state(ssl_connect_state state, void *secret) -{ - struct ssl_connect_data *connssl = (struct ssl_connect_data *)secret; - if(PR_GetError() != PR_WOULD_BLOCK_ERROR) - /* an unrelated error is passing by */ - return; - - switch(connssl->connecting_state) { - case ssl_connect_2: - case ssl_connect_2_reading: - case ssl_connect_2_writing: - break; - default: - /* we are not called from an SSL handshake */ - return; - } - - /* update the state accordingly */ - connssl->connecting_state = state; -} - -/* recv() wrapper we use to detect blocking direction during SSL handshake */ -static PRInt32 nspr_io_recv(PRFileDesc *fd, void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - const PRRecvFN recv_fn = fd->lower->methods->recv; - const PRInt32 rv = recv_fn(fd->lower, buf, amount, flags, timeout); - if(rv < 0) - /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */ - nss_update_connecting_state(ssl_connect_2_reading, fd->secret); - return rv; -} - -/* send() wrapper we use to detect blocking direction during SSL handshake */ -static PRInt32 nspr_io_send(PRFileDesc *fd, const void *buf, PRInt32 amount, - PRIntn flags, PRIntervalTime timeout) -{ - const PRSendFN send_fn = fd->lower->methods->send; - const PRInt32 rv = send_fn(fd->lower, buf, amount, flags, timeout); - if(rv < 0) - /* check for PR_WOULD_BLOCK_ERROR and update blocking direction */ - nss_update_connecting_state(ssl_connect_2_writing, fd->secret); - return rv; -} - -/* close() wrapper to avoid assertion failure due to fd->secret != NULL */ -static PRStatus nspr_io_close(PRFileDesc *fd) -{ - const PRCloseFN close_fn = PR_GetDefaultIOMethods()->close; - fd->secret = NULL; - return close_fn(fd); -} - -/* data might be NULL */ -static CURLcode nss_init_core(struct SessionHandle *data, const char *cert_dir) -{ - NSSInitParameters initparams; - - if(nss_context != NULL) - return CURLE_OK; - - memset((void *) &initparams, '\0', sizeof(initparams)); - initparams.length = sizeof(initparams); - - if(cert_dir) { - char *certpath = aprintf("sql:%s", cert_dir); - if(!certpath) - return CURLE_OUT_OF_MEMORY; - - infof(data, "Initializing NSS with certpath: %s\n", certpath); - nss_context = NSS_InitContext(certpath, "", "", "", &initparams, - NSS_INIT_READONLY | NSS_INIT_PK11RELOAD); - free(certpath); - - if(nss_context != NULL) - return CURLE_OK; - - infof(data, "Unable to initialize NSS database\n"); - } - - infof(data, "Initializing NSS with certpath: none\n"); - nss_context = NSS_InitContext("", "", "", "", &initparams, NSS_INIT_READONLY - | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN - | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD); - if(nss_context != NULL) - return CURLE_OK; - - infof(data, "Unable to initialize NSS\n"); - return CURLE_SSL_CACERT_BADFILE; -} - -/* data might be NULL */ -static CURLcode nss_init(struct SessionHandle *data) -{ - char *cert_dir; - struct_stat st; - CURLcode result; - - if(initialized) - return CURLE_OK; - - /* list of all CRL items we need to destroy in Curl_nss_cleanup() */ - nss_crl_list = Curl_llist_alloc(nss_destroy_crl_item); - if(!nss_crl_list) - return CURLE_OUT_OF_MEMORY; - - /* First we check if $SSL_DIR points to a valid dir */ - cert_dir = getenv("SSL_DIR"); - if(cert_dir) { - if((stat(cert_dir, &st) != 0) || - (!S_ISDIR(st.st_mode))) { - cert_dir = NULL; - } - } - - /* Now we check if the default location is a valid dir */ - if(!cert_dir) { - if((stat(SSL_DIR, &st) == 0) && - (S_ISDIR(st.st_mode))) { - cert_dir = (char *)SSL_DIR; - } - } - - if(nspr_io_identity == PR_INVALID_IO_LAYER) { - /* allocate an identity for our own NSPR I/O layer */ - nspr_io_identity = PR_GetUniqueIdentity("libcurl"); - if(nspr_io_identity == PR_INVALID_IO_LAYER) - return CURLE_OUT_OF_MEMORY; - - /* the default methods just call down to the lower I/O layer */ - memcpy(&nspr_io_methods, PR_GetDefaultIOMethods(), sizeof nspr_io_methods); - - /* override certain methods in the table by our wrappers */ - nspr_io_methods.recv = nspr_io_recv; - nspr_io_methods.send = nspr_io_send; - nspr_io_methods.close = nspr_io_close; - } - - result = nss_init_core(data, cert_dir); - if(result) - return result; - - if(!any_cipher_enabled()) - NSS_SetDomesticPolicy(); - - initialized = 1; - - return CURLE_OK; -} - -/** - * Global SSL init - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ -int Curl_nss_init(void) -{ - /* curl_global_init() is not thread-safe so this test is ok */ - if(nss_initlock == NULL) { - PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 256); - nss_initlock = PR_NewLock(); - nss_crllock = PR_NewLock(); - } - - /* We will actually initialize NSS later */ - - return 1; -} - -/* data might be NULL */ -CURLcode Curl_nss_force_init(struct SessionHandle *data) -{ - CURLcode result; - if(!nss_initlock) { - if(data) - failf(data, "unable to initialize NSS, curl_global_init() should have " - "been called with CURL_GLOBAL_SSL or CURL_GLOBAL_ALL"); - return CURLE_FAILED_INIT; - } - - PR_Lock(nss_initlock); - result = nss_init(data); - PR_Unlock(nss_initlock); - - return result; -} - -/* Global cleanup */ -void Curl_nss_cleanup(void) -{ - /* This function isn't required to be threadsafe and this is only done - * as a safety feature. - */ - PR_Lock(nss_initlock); - if(initialized) { - /* Free references to client certificates held in the SSL session cache. - * Omitting this hampers destruction of the security module owning - * the certificates. */ - SSL_ClearSessionCache(); - - if(mod && SECSuccess == SECMOD_UnloadUserModule(mod)) { - SECMOD_DestroyModule(mod); - mod = NULL; - } - NSS_ShutdownContext(nss_context); - nss_context = NULL; - } - - /* destroy all CRL items */ - Curl_llist_destroy(nss_crl_list, NULL); - nss_crl_list = NULL; - - PR_Unlock(nss_initlock); - - PR_DestroyLock(nss_initlock); - PR_DestroyLock(nss_crllock); - nss_initlock = NULL; - - initialized = 0; -} - -/* - * This function uses SSL_peek to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -int -Curl_nss_check_cxn(struct connectdata *conn) -{ - int rc; - char buf; - - rc = - PR_Recv(conn->ssl[FIRSTSOCKET].handle, (void *)&buf, 1, PR_MSG_PEEK, - PR_SecondsToInterval(1)); - if(rc > 0) - return 1; /* connection still in place */ - - if(rc == 0) - return 0; /* connection has been closed */ - - return -1; /* connection status unknown */ -} - -/* - * This function is called when an SSL connection is closed. - */ -void Curl_nss_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - if(connssl->handle) { - /* NSS closes the socket we previously handed to it, so we must mark it - as closed to avoid double close */ - fake_sclose(conn->sock[sockindex]); - conn->sock[sockindex] = CURL_SOCKET_BAD; - - if((connssl->client_nickname != NULL) || (connssl->obj_clicert != NULL)) - /* A server might require different authentication based on the - * particular path being requested by the client. To support this - * scenario, we must ensure that a connection will never reuse the - * authentication data from a previous connection. */ - SSL_InvalidateSession(connssl->handle); - - free(connssl->client_nickname); - connssl->client_nickname = NULL; - /* destroy all NSS objects in order to avoid failure of NSS shutdown */ - Curl_llist_destroy(connssl->obj_list, NULL); - connssl->obj_list = NULL; - connssl->obj_clicert = NULL; - - PR_Close(connssl->handle); - connssl->handle = NULL; - } -} - -/* return true if NSS can provide error code (and possibly msg) for the - error */ -static bool is_nss_error(CURLcode err) -{ - switch(err) { - case CURLE_PEER_FAILED_VERIFICATION: - case CURLE_SSL_CACERT: - case CURLE_SSL_CERTPROBLEM: - case CURLE_SSL_CONNECT_ERROR: - case CURLE_SSL_ISSUER_ERROR: - return true; - - default: - return false; - } -} - -/* return true if the given error code is related to a client certificate */ -static bool is_cc_error(PRInt32 err) -{ - switch(err) { - case SSL_ERROR_BAD_CERT_ALERT: - case SSL_ERROR_EXPIRED_CERT_ALERT: - case SSL_ERROR_REVOKED_CERT_ALERT: - return true; - - default: - return false; - } -} - -static Curl_recv nss_recv; -static Curl_send nss_send; - -static CURLcode nss_load_ca_certificates(struct connectdata *conn, - int sockindex) -{ - struct SessionHandle *data = conn->data; - const char *cafile = data->set.ssl.CAfile; - const char *capath = data->set.ssl.CApath; - - if(cafile) { - CURLcode result = nss_load_cert(&conn->ssl[sockindex], cafile, PR_TRUE); - if(result) - return result; - } - - if(capath) { - struct_stat st; - if(stat(capath, &st) == -1) - return CURLE_SSL_CACERT_BADFILE; - - if(S_ISDIR(st.st_mode)) { - PRDirEntry *entry; - PRDir *dir = PR_OpenDir(capath); - if(!dir) - return CURLE_SSL_CACERT_BADFILE; - - while((entry = PR_ReadDir(dir, PR_SKIP_BOTH | PR_SKIP_HIDDEN))) { - char *fullpath = aprintf("%s/%s", capath, entry->name); - if(!fullpath) { - PR_CloseDir(dir); - return CURLE_OUT_OF_MEMORY; - } - - if(CURLE_OK != nss_load_cert(&conn->ssl[sockindex], fullpath, PR_TRUE)) - /* This is purposefully tolerant of errors so non-PEM files can - * be in the same directory */ - infof(data, "failed to load '%s' from CURLOPT_CAPATH\n", fullpath); - - free(fullpath); - } - - PR_CloseDir(dir); - } - else - infof(data, "warning: CURLOPT_CAPATH not a directory (%s)\n", capath); - } - - infof(data, " CAfile: %s\n CApath: %s\n", - cafile ? cafile : "none", - capath ? capath : "none"); - - return CURLE_OK; -} - -static CURLcode nss_init_sslver(SSLVersionRange *sslver, - struct SessionHandle *data) -{ - switch(data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; -#ifdef SSL_LIBRARY_VERSION_TLS_1_2 - sslver->max = SSL_LIBRARY_VERSION_TLS_1_2; -#elif defined SSL_LIBRARY_VERSION_TLS_1_1 - sslver->max = SSL_LIBRARY_VERSION_TLS_1_1; -#else - sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; -#endif - return CURLE_OK; - - case CURL_SSLVERSION_SSLv2: - sslver->min = SSL_LIBRARY_VERSION_2; - sslver->max = SSL_LIBRARY_VERSION_2; - return CURLE_OK; - - case CURL_SSLVERSION_SSLv3: - sslver->min = SSL_LIBRARY_VERSION_3_0; - sslver->max = SSL_LIBRARY_VERSION_3_0; - return CURLE_OK; - - case CURL_SSLVERSION_TLSv1_0: - sslver->min = SSL_LIBRARY_VERSION_TLS_1_0; - sslver->max = SSL_LIBRARY_VERSION_TLS_1_0; - return CURLE_OK; - - case CURL_SSLVERSION_TLSv1_1: -#ifdef SSL_LIBRARY_VERSION_TLS_1_1 - sslver->min = SSL_LIBRARY_VERSION_TLS_1_1; - sslver->max = SSL_LIBRARY_VERSION_TLS_1_1; - return CURLE_OK; -#endif - break; - - case CURL_SSLVERSION_TLSv1_2: -#ifdef SSL_LIBRARY_VERSION_TLS_1_2 - sslver->min = SSL_LIBRARY_VERSION_TLS_1_2; - sslver->max = SSL_LIBRARY_VERSION_TLS_1_2; - return CURLE_OK; -#endif - break; - } - - failf(data, "TLS minor version cannot be set"); - return CURLE_SSL_CONNECT_ERROR; -} - -static CURLcode nss_fail_connect(struct ssl_connect_data *connssl, - struct SessionHandle *data, - CURLcode curlerr) -{ - PRErrorCode err = 0; - - if(is_nss_error(curlerr)) { - /* read NSPR error code */ - err = PR_GetError(); - if(is_cc_error(err)) - curlerr = CURLE_SSL_CERTPROBLEM; - - /* print the error number and error string */ - infof(data, "NSS error %d (%s)\n", err, nss_error_to_name(err)); - - /* print a human-readable message describing the error if available */ - nss_print_error_message(data, err); - } - - /* cleanup on connection failure */ - Curl_llist_destroy(connssl->obj_list, NULL); - connssl->obj_list = NULL; - - return curlerr; -} - -/* Switch the SSL socket into non-blocking mode. */ -static CURLcode nss_set_nonblock(struct ssl_connect_data *connssl, - struct SessionHandle *data) -{ - static PRSocketOptionData sock_opt; - sock_opt.option = PR_SockOpt_Nonblocking; - sock_opt.value.non_blocking = PR_TRUE; - - if(PR_SetSocketOption(connssl->handle, &sock_opt) != PR_SUCCESS) - return nss_fail_connect(connssl, data, CURLE_SSL_CONNECT_ERROR); - - return CURLE_OK; -} - -static CURLcode nss_setup_connect(struct connectdata *conn, int sockindex) -{ - PRFileDesc *model = NULL; - PRFileDesc *nspr_io = NULL; - PRFileDesc *nspr_io_stub = NULL; - PRBool ssl_no_cache; - PRBool ssl_cbc_random_iv; - struct SessionHandle *data = conn->data; - curl_socket_t sockfd = conn->sock[sockindex]; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - CURLcode result; - - SSLVersionRange sslver = { - SSL_LIBRARY_VERSION_TLS_1_0, /* min */ - SSL_LIBRARY_VERSION_TLS_1_0 /* max */ - }; - - connssl->data = data; - - /* list of all NSS objects we need to destroy in Curl_nss_close() */ - connssl->obj_list = Curl_llist_alloc(nss_destroy_object); - if(!connssl->obj_list) - return CURLE_OUT_OF_MEMORY; - - /* FIXME. NSS doesn't support multiple databases open at the same time. */ - PR_Lock(nss_initlock); - result = nss_init(conn->data); - if(result) { - PR_Unlock(nss_initlock); - goto error; - } - - result = CURLE_SSL_CONNECT_ERROR; - - if(!mod) { - char *configstring = aprintf("library=%s name=PEM", pem_library); - if(!configstring) { - PR_Unlock(nss_initlock); - goto error; - } - mod = SECMOD_LoadUserModule(configstring, NULL, PR_FALSE); - free(configstring); - - if(!mod || !mod->loaded) { - if(mod) { - SECMOD_DestroyModule(mod); - mod = NULL; - } - infof(data, "WARNING: failed to load NSS PEM library %s. Using " - "OpenSSL PEM certificates will not work.\n", pem_library); - } - } - - PK11_SetPasswordFunc(nss_get_password); - PR_Unlock(nss_initlock); - - model = PR_NewTCPSocket(); - if(!model) - goto error; - model = SSL_ImportFD(NULL, model); - - if(SSL_OptionSet(model, SSL_SECURITY, PR_TRUE) != SECSuccess) - goto error; - if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_SERVER, PR_FALSE) != SECSuccess) - goto error; - if(SSL_OptionSet(model, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE) != SECSuccess) - goto error; - - /* do not use SSL cache if disabled or we are not going to verify peer */ - ssl_no_cache = (conn->ssl_config.sessionid && data->set.ssl.verifypeer) ? - PR_FALSE : PR_TRUE; - if(SSL_OptionSet(model, SSL_NO_CACHE, ssl_no_cache) != SECSuccess) - goto error; - - /* enable/disable the requested SSL version(s) */ - if(nss_init_sslver(&sslver, data) != CURLE_OK) - goto error; - if(SSL_VersionRangeSet(model, &sslver) != SECSuccess) - goto error; - - ssl_cbc_random_iv = !data->set.ssl_enable_beast; -#ifdef SSL_CBC_RANDOM_IV - /* unless the user explicitly asks to allow the protocol vulnerability, we - use the work-around */ - if(SSL_OptionSet(model, SSL_CBC_RANDOM_IV, ssl_cbc_random_iv) != SECSuccess) - infof(data, "warning: failed to set SSL_CBC_RANDOM_IV = %d\n", - ssl_cbc_random_iv); -#else - if(ssl_cbc_random_iv) - infof(data, "warning: support for SSL_CBC_RANDOM_IV not compiled in\n"); -#endif - - if(data->set.ssl.cipher_list) { - if(set_ciphers(data, model, data->set.ssl.cipher_list) != SECSuccess) { - result = CURLE_SSL_CIPHER; - goto error; - } - } - - if(!data->set.ssl.verifypeer && data->set.ssl.verifyhost) - infof(data, "warning: ignoring value of ssl.verifyhost\n"); - - /* bypass the default SSL_AuthCertificate() hook in case we do not want to - * verify peer */ - if(SSL_AuthCertificateHook(model, nss_auth_cert_hook, conn) != SECSuccess) - goto error; - - data->set.ssl.certverifyresult=0; /* not checked yet */ - if(SSL_BadCertHook(model, BadCertHandler, conn) != SECSuccess) - goto error; - - if(SSL_HandshakeCallback(model, HandshakeCallback, conn) != SECSuccess) - goto error; - - if(data->set.ssl.verifypeer) { - const CURLcode rv = nss_load_ca_certificates(conn, sockindex); - if(rv) { - result = rv; - goto error; - } - } - - if(data->set.ssl.CRLfile) { - const CURLcode rv = nss_load_crl(data->set.ssl.CRLfile); - if(rv) { - result = rv; - goto error; - } - infof(data, " CRLfile: %s\n", data->set.ssl.CRLfile); - } - - if(data->set.str[STRING_CERT]) { - char *nickname = dup_nickname(data, STRING_CERT); - if(nickname) { - /* we are not going to use libnsspem.so to read the client cert */ - connssl->obj_clicert = NULL; - } - else { - CURLcode rv = cert_stuff(conn, sockindex, data->set.str[STRING_CERT], - data->set.str[STRING_KEY]); - if(rv) { - /* failf() is already done in cert_stuff() */ - result = rv; - goto error; - } - } - - /* store the nickname for SelectClientCert() called during handshake */ - connssl->client_nickname = nickname; - } - else - connssl->client_nickname = NULL; - - if(SSL_GetClientAuthDataHook(model, SelectClientCert, - (void *)connssl) != SECSuccess) { - result = CURLE_SSL_CERTPROBLEM; - goto error; - } - - /* wrap OS file descriptor by NSPR's file descriptor abstraction */ - nspr_io = PR_ImportTCPSocket(sockfd); - if(!nspr_io) - goto error; - - /* create our own NSPR I/O layer */ - nspr_io_stub = PR_CreateIOLayerStub(nspr_io_identity, &nspr_io_methods); - if(!nspr_io_stub) { - PR_Close(nspr_io); - goto error; - } - - /* make the per-connection data accessible from NSPR I/O callbacks */ - nspr_io_stub->secret = (void *)connssl; - - /* push our new layer to the NSPR I/O stack */ - if(PR_PushIOLayer(nspr_io, PR_TOP_IO_LAYER, nspr_io_stub) != PR_SUCCESS) { - PR_Close(nspr_io); - PR_Close(nspr_io_stub); - goto error; - } - - /* import our model socket onto the current I/O stack */ - connssl->handle = SSL_ImportFD(model, nspr_io); - if(!connssl->handle) { - PR_Close(nspr_io); - goto error; - } - - PR_Close(model); /* We don't need this any more */ - model = NULL; - - /* This is the password associated with the cert that we're using */ - if(data->set.str[STRING_KEY_PASSWD]) { - SSL_SetPKCS11PinArg(connssl->handle, data->set.str[STRING_KEY_PASSWD]); - } - -#ifdef SSL_ENABLE_OCSP_STAPLING - if(data->set.ssl.verifystatus) { - if(SSL_OptionSet(connssl->handle, SSL_ENABLE_OCSP_STAPLING, PR_TRUE) - != SECSuccess) - goto error; - } -#endif - -#ifdef SSL_ENABLE_NPN - if(SSL_OptionSet(connssl->handle, SSL_ENABLE_NPN, conn->bits.tls_enable_npn - ? PR_TRUE : PR_FALSE) != SECSuccess) - goto error; -#endif - -#ifdef SSL_ENABLE_ALPN - if(SSL_OptionSet(connssl->handle, SSL_ENABLE_ALPN, conn->bits.tls_enable_alpn - ? PR_TRUE : PR_FALSE) != SECSuccess) - goto error; -#endif - -#if NSSVERNUM >= 0x030f04 /* 3.15.4 */ - if(data->set.ssl.falsestart) { - if(SSL_OptionSet(connssl->handle, SSL_ENABLE_FALSE_START, PR_TRUE) - != SECSuccess) - goto error; - - if(SSL_SetCanFalseStartCallback(connssl->handle, CanFalseStartCallback, - conn) != SECSuccess) - goto error; - } -#endif - -#if defined(SSL_ENABLE_NPN) || defined(SSL_ENABLE_ALPN) - if(conn->bits.tls_enable_npn || conn->bits.tls_enable_alpn) { - int cur = 0; - unsigned char protocols[128]; - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; - memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN); - cur += NGHTTP2_PROTO_VERSION_ID_LEN; - } -#endif - protocols[cur++] = ALPN_HTTP_1_1_LENGTH; - memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); - cur += ALPN_HTTP_1_1_LENGTH; - - if(SSL_SetNextProtoNego(connssl->handle, protocols, cur) != SECSuccess) - goto error; - } -#endif - - - /* Force handshake on next I/O */ - if(SSL_ResetHandshake(connssl->handle, /* asServer */ PR_FALSE) - != SECSuccess) - goto error; - - /* propagate hostname to the TLS layer */ - if(SSL_SetURL(connssl->handle, conn->host.name) != SECSuccess) - goto error; - - /* prevent NSS from re-using the session for a different hostname */ - if(SSL_SetSockPeerID(connssl->handle, conn->host.name) != SECSuccess) - goto error; - - return CURLE_OK; - -error: - if(model) - PR_Close(model); - - return nss_fail_connect(connssl, data, result); -} - -static CURLcode nss_do_connect(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - CURLcode result = CURLE_SSL_CONNECT_ERROR; - PRUint32 timeout; - - /* check timeout situation */ - const long time_left = Curl_timeleft(data, NULL, TRUE); - if(time_left < 0L) { - failf(data, "timed out before SSL handshake"); - result = CURLE_OPERATION_TIMEDOUT; - goto error; - } - - /* Force the handshake now */ - timeout = PR_MillisecondsToInterval((PRUint32) time_left); - if(SSL_ForceHandshakeWithTimeout(connssl->handle, timeout) != SECSuccess) { - if(PR_GetError() == PR_WOULD_BLOCK_ERROR) - /* blocking direction is updated by nss_update_connecting_state() */ - return CURLE_AGAIN; - else if(conn->data->set.ssl.certverifyresult == SSL_ERROR_BAD_CERT_DOMAIN) - result = CURLE_PEER_FAILED_VERIFICATION; - else if(conn->data->set.ssl.certverifyresult!=0) - result = CURLE_SSL_CACERT; - goto error; - } - - result = display_conn_info(conn, connssl->handle); - if(result) - goto error; - - if(data->set.str[STRING_SSL_ISSUERCERT]) { - SECStatus ret = SECFailure; - char *nickname = dup_nickname(data, STRING_SSL_ISSUERCERT); - if(nickname) { - /* we support only nicknames in case of STRING_SSL_ISSUERCERT for now */ - ret = check_issuer_cert(connssl->handle, nickname); - free(nickname); - } - - if(SECFailure == ret) { - infof(data, "SSL certificate issuer check failed\n"); - result = CURLE_SSL_ISSUER_ERROR; - goto error; - } - else { - infof(data, "SSL certificate issuer check ok\n"); - } - } - - result = cmp_peer_pubkey(connssl, data->set.str[STRING_SSL_PINNEDPUBLICKEY]); - if(result) - /* status already printed */ - goto error; - - return CURLE_OK; - -error: - return nss_fail_connect(connssl, data, result); -} - -static CURLcode nss_connect_common(struct connectdata *conn, int sockindex, - bool *done) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - const bool blocking = (done == NULL); - CURLcode result; - - if(connssl->state == ssl_connection_complete) - return CURLE_OK; - - if(connssl->connecting_state == ssl_connect_1) { - result = nss_setup_connect(conn, sockindex); - if(result) - /* we do not expect CURLE_AGAIN from nss_setup_connect() */ - return result; - - if(!blocking) { - /* in non-blocking mode, set NSS non-blocking mode before handshake */ - result = nss_set_nonblock(connssl, data); - if(result) - return result; - } - - connssl->connecting_state = ssl_connect_2; - } - - result = nss_do_connect(conn, sockindex); - switch(result) { - case CURLE_OK: - break; - case CURLE_AGAIN: - if(!blocking) - /* CURLE_AGAIN in non-blocking mode is not an error */ - return CURLE_OK; - /* fall through */ - default: - return result; - } - - if(blocking) { - /* in blocking mode, set NSS non-blocking mode _after_ SSL handshake */ - result = nss_set_nonblock(connssl, data); - if(result) - return result; - } - else - /* signal completed SSL handshake */ - *done = TRUE; - - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = nss_recv; - conn->send[sockindex] = nss_send; - - /* ssl_connect_done is never used outside, go back to the initial state */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex) -{ - return nss_connect_common(conn, sockindex, /* blocking */ NULL); -} - -CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn, - int sockindex, bool *done) -{ - return nss_connect_common(conn, sockindex, done); -} - -static ssize_t nss_send(struct connectdata *conn, /* connection data */ - int sockindex, /* socketindex */ - const void *mem, /* send this data */ - size_t len, /* amount to write */ - CURLcode *curlcode) -{ - ssize_t rc = PR_Send(conn->ssl[sockindex].handle, mem, (int)len, 0, - PR_INTERVAL_NO_WAIT); - if(rc < 0) { - PRInt32 err = PR_GetError(); - if(err == PR_WOULD_BLOCK_ERROR) - *curlcode = CURLE_AGAIN; - else { - /* print the error number and error string */ - const char *err_name = nss_error_to_name(err); - infof(conn->data, "SSL write: error %d (%s)\n", err, err_name); - - /* print a human-readable message describing the error if available */ - nss_print_error_message(conn->data, err); - - *curlcode = (is_cc_error(err)) - ? CURLE_SSL_CERTPROBLEM - : CURLE_SEND_ERROR; - } - - return -1; - } - - return rc; /* number of bytes */ -} - -static ssize_t nss_recv(struct connectdata * conn, /* connection data */ - int num, /* socketindex */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - CURLcode *curlcode) -{ - ssize_t nread = PR_Recv(conn->ssl[num].handle, buf, (int)buffersize, 0, - PR_INTERVAL_NO_WAIT); - if(nread < 0) { - /* failed SSL read */ - PRInt32 err = PR_GetError(); - - if(err == PR_WOULD_BLOCK_ERROR) - *curlcode = CURLE_AGAIN; - else { - /* print the error number and error string */ - const char *err_name = nss_error_to_name(err); - infof(conn->data, "SSL read: errno %d (%s)\n", err, err_name); - - /* print a human-readable message describing the error if available */ - nss_print_error_message(conn->data, err); - - *curlcode = (is_cc_error(err)) - ? CURLE_SSL_CERTPROBLEM - : CURLE_RECV_ERROR; - } - - return -1; - } - - return nread; -} - -size_t Curl_nss_version(char *buffer, size_t size) -{ - return snprintf(buffer, size, "NSS/%s", NSS_VERSION); -} - -/* data might be NULL */ -int Curl_nss_seed(struct SessionHandle *data) -{ - /* make sure that NSS is initialized */ - return !!Curl_nss_force_init(data); -} - -/* data might be NULL */ -int Curl_nss_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) -{ - Curl_nss_seed(data); /* Initiate the seed if not already done */ - - if(SECSuccess != PK11_GenerateRandom(entropy, curlx_uztosi(length))) - /* signal a failure */ - return -1; - - return 0; -} - -void Curl_nss_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len) -{ - PK11Context *MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); - unsigned int MD5out; - - PK11_DigestOp(MD5pw, tmp, curlx_uztoui(tmplen)); - PK11_DigestFinal(MD5pw, md5sum, &MD5out, curlx_uztoui(md5len)); - PK11_DestroyContext(MD5pw, PR_TRUE); -} - -void Curl_nss_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t sha256len) -{ - PK11Context *SHA256pw = PK11_CreateDigestContext(SEC_OID_SHA256); - unsigned int SHA256out; - - PK11_DigestOp(SHA256pw, tmp, curlx_uztoui(tmplen)); - PK11_DigestFinal(SHA256pw, sha256sum, &SHA256out, curlx_uztoui(sha256len)); - PK11_DestroyContext(SHA256pw, PR_TRUE); -} - -bool Curl_nss_cert_status_request(void) -{ -#ifdef SSL_ENABLE_OCSP_STAPLING - return TRUE; -#else - return FALSE; -#endif -} - -bool Curl_nss_false_start(void) { -#if NSSVERNUM >= 0x030f04 /* 3.15.4 */ - return TRUE; -#else - return FALSE; -#endif -} - -#endif /* USE_NSS */ diff --git a/Externals/curl/lib/vtls/nssg.h b/Externals/curl/lib/vtls/nssg.h deleted file mode 100644 index e388ec0ff7..0000000000 --- a/Externals/curl/lib/vtls/nssg.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef HEADER_CURL_NSSG_H -#define HEADER_CURL_NSSG_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_NSS -/* - * This header should only be needed to get included by vtls.c and nss.c - */ - -#include "urldata.h" - -CURLcode Curl_nss_connect(struct connectdata *conn, int sockindex); -CURLcode Curl_nss_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); -/* close a SSL connection */ -void Curl_nss_close(struct connectdata *conn, int sockindex); - -int Curl_nss_init(void); -void Curl_nss_cleanup(void); - -size_t Curl_nss_version(char *buffer, size_t size); -int Curl_nss_check_cxn(struct connectdata *cxn); -int Curl_nss_seed(struct SessionHandle *data); - -/* initialize NSS library if not already */ -CURLcode Curl_nss_force_init(struct SessionHandle *data); - -int Curl_nss_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length); - -void Curl_nss_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len); - -void Curl_nss_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum, /* output */ - size_t sha256len); - -bool Curl_nss_cert_status_request(void); - -bool Curl_nss_false_start(void); - -/* Set the API backend definition to NSS */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_NSS - -/* this backend supports the CAPATH option */ -#define have_curlssl_ca_path 1 - -/* this backend supports CURLOPT_CERTINFO */ -#define have_curlssl_certinfo 1 - -/* this backends supports CURLOPT_PINNEDPUBLICKEY */ -#define have_curlssl_pinnedpubkey 1 - -/* API setup for NSS */ -#define curlssl_init Curl_nss_init -#define curlssl_cleanup Curl_nss_cleanup -#define curlssl_connect Curl_nss_connect -#define curlssl_connect_nonblocking Curl_nss_connect_nonblocking - -/* NSS has its own session ID cache */ -#define curlssl_session_free(x) Curl_nop_stmt -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_nss_close -/* NSS has no shutdown function provided and thus always fail */ -#define curlssl_shutdown(x,y) ((void)x, (void)y, 1) -#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) -#define curlssl_version Curl_nss_version -#define curlssl_check_cxn(x) Curl_nss_check_cxn(x) -#define curlssl_data_pending(x,y) ((void)x, (void)y, 0) -#define curlssl_random(x,y,z) Curl_nss_random(x,y,z) -#define curlssl_md5sum(a,b,c,d) Curl_nss_md5sum(a,b,c,d) -#define curlssl_sha256sum(a,b,c,d) Curl_nss_sha256sum(a,b,c,d) -#define curlssl_cert_status_request() Curl_nss_cert_status_request() -#define curlssl_false_start() Curl_nss_false_start() - -#endif /* USE_NSS */ -#endif /* HEADER_CURL_NSSG_H */ diff --git a/Externals/curl/lib/vtls/openssl.c b/Externals/curl/lib/vtls/openssl.c deleted file mode 100644 index 3a4bde5b34..0000000000 --- a/Externals/curl/lib/vtls/openssl.c +++ /dev/null @@ -1,3188 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - */ - -/* - * The original SSLeay-using code for curl was written by Linas Vepstas and - * Sampo Kellomaki 1998. - */ - -#include "curl_setup.h" - -#ifdef USE_OPENSSL - -#ifdef HAVE_LIMITS_H -#include -#endif - -#include "urldata.h" -#include "sendf.h" -#include "formdata.h" /* for the boundary function */ -#include "url.h" /* for the ssl config check function */ -#include "inet_pton.h" -#include "openssl.h" -#include "connect.h" -#include "slist.h" -#include "strequal.h" -#include "select.h" -#include "vtls.h" -#include "rawstr.h" -#include "hostcheck.h" -#include "curl_printf.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_OPENSSL_PKCS12_H -#include -#endif - -#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_OCSP) -#include -#endif - -#include "warnless.h" -#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */ - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -#ifndef OPENSSL_VERSION_NUMBER -#error "OPENSSL_VERSION_NUMBER not defined" -#endif - -#if defined(HAVE_OPENSSL_ENGINE_H) -#include -#endif - -#if OPENSSL_VERSION_NUMBER >= 0x00909000L -#define SSL_METHOD_QUAL const -#else -#define SSL_METHOD_QUAL -#endif - -#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) -#define HAVE_ERR_REMOVE_THREAD_STATE 1 -#if (OPENSSL_VERSION_NUMBER >= 0x10100004L) && \ - !defined(LIBRESSL_VERSION_NUMBER) -/* OpenSSL 1.1.0 deprecates the function */ -#define HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED 1 -#endif -#endif - -#if !defined(HAVE_SSLV2_CLIENT_METHOD) || \ - OPENSSL_VERSION_NUMBER >= 0x10100000L /* 1.1.0+ has no SSLv2 */ -#undef OPENSSL_NO_SSL2 /* undef first to avoid compiler warnings */ -#define OPENSSL_NO_SSL2 -#endif - -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && /* OpenSSL 1.1.0+ */ \ - !defined(LIBRESSL_VERSION_NUMBER) -#define SSLeay_add_ssl_algorithms() SSL_library_init() -#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER -#define HAVE_X509_GET0_EXTENSIONS 1 /* added in 1.1.0 -pre1 */ -#define HAVE_OPAQUE_EVP_PKEY 1 /* since 1.1.0 -pre3 */ -#define HAVE_OPAQUE_RSA_DSA_DH 1 /* since 1.1.0 -pre5 */ -#endif - -#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL) && /* 1.0.2 or later */ \ - !defined(LIBRESSL_VERSION_NUMBER) -#define HAVE_X509_GET0_SIGNATURE 1 -#endif - -#if (OPENSSL_VERSION_NUMBER < 0x0090808fL) -/* not present in older OpenSSL */ -#define OPENSSL_load_builtin_modules(x) -#endif - -#if defined(LIBRESSL_VERSION_NUMBER) -#define OSSL_PACKAGE "LibreSSL" -#elif defined(OPENSSL_IS_BORINGSSL) -#define OSSL_PACKAGE "BoringSSL" -#else -#define OSSL_PACKAGE "OpenSSL" -#endif - -/* - * Number of bytes to read from the random number seed file. This must be - * a finite value (because some entropy "files" like /dev/urandom have - * an infinite length), but must be large enough to provide enough - * entopy to properly seed OpenSSL's PRNG. - */ -#define RAND_LOAD_LENGTH 1024 - -static int passwd_callback(char *buf, int num, int encrypting, - void *global_passwd) -{ - DEBUGASSERT(0 == encrypting); - - if(!encrypting) { - int klen = curlx_uztosi(strlen((char *)global_passwd)); - if(num > klen) { - memcpy(buf, global_passwd, klen+1); - return klen; - } - } - return 0; -} - -/* - * rand_enough() is a function that returns TRUE if we have seeded the random - * engine properly. We use some preprocessor magic to provide a seed_enough() - * macro to use, just to prevent a compiler warning on this function if we - * pass in an argument that is never used. - */ - -#ifdef HAVE_RAND_STATUS -#define seed_enough(x) rand_enough() -static bool rand_enough(void) -{ - return (0 != RAND_status()) ? TRUE : FALSE; -} -#else -#define seed_enough(x) rand_enough(x) -static bool rand_enough(int nread) -{ - /* this is a very silly decision to make */ - return (nread > 500) ? TRUE : FALSE; -} -#endif - -static int ossl_seed(struct SessionHandle *data) -{ - char *buf = data->state.buffer; /* point to the big buffer */ - int nread=0; - - /* Q: should we add support for a random file name as a libcurl option? - A: Yes, it is here */ - -#ifndef RANDOM_FILE - /* if RANDOM_FILE isn't defined, we only perform this if an option tells - us to! */ - if(data->set.ssl.random_file) -#define RANDOM_FILE "" /* doesn't matter won't be used */ -#endif - { - /* let the option override the define */ - nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]? - data->set.str[STRING_SSL_RANDOM_FILE]: - RANDOM_FILE), - RAND_LOAD_LENGTH); - if(seed_enough(nread)) - return nread; - } - -#if defined(HAVE_RAND_EGD) - /* only available in OpenSSL 0.9.5 and later */ - /* EGD_SOCKET is set at configure time or not at all */ -#ifndef EGD_SOCKET - /* If we don't have the define set, we only do this if the egd-option - is set */ - if(data->set.str[STRING_SSL_EGDSOCKET]) -#define EGD_SOCKET "" /* doesn't matter won't be used */ -#endif - { - /* If there's an option and a define, the option overrides the - define */ - int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]? - data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET); - if(-1 != ret) { - nread += ret; - if(seed_enough(nread)) - return nread; - } - } -#endif - - /* If we get here, it means we need to seed the PRNG using a "silly" - approach! */ - do { - unsigned char randb[64]; - int len = sizeof(randb); - RAND_bytes(randb, len); - RAND_add(randb, len, (len >> 1)); - } while(!RAND_status()); - - /* generates a default path for the random seed file */ - buf[0]=0; /* blank it first */ - RAND_file_name(buf, BUFSIZE); - if(buf[0]) { - /* we got a file name to try */ - nread += RAND_load_file(buf, RAND_LOAD_LENGTH); - if(seed_enough(nread)) - return nread; - } - - infof(data, "libcurl is now using a weak random seed!\n"); - return nread; -} - -static void Curl_ossl_seed(struct SessionHandle *data) -{ - /* we have the "SSL is seeded" boolean static to prevent multiple - time-consuming seedings in vain */ - static bool ssl_seeded = FALSE; - - if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] || - data->set.str[STRING_SSL_EGDSOCKET]) { - ossl_seed(data); - ssl_seeded = TRUE; - } -} - -#ifndef SSL_FILETYPE_ENGINE -#define SSL_FILETYPE_ENGINE 42 -#endif -#ifndef SSL_FILETYPE_PKCS12 -#define SSL_FILETYPE_PKCS12 43 -#endif -static int do_file_type(const char *type) -{ - if(!type || !type[0]) - return SSL_FILETYPE_PEM; - if(Curl_raw_equal(type, "PEM")) - return SSL_FILETYPE_PEM; - if(Curl_raw_equal(type, "DER")) - return SSL_FILETYPE_ASN1; - if(Curl_raw_equal(type, "ENG")) - return SSL_FILETYPE_ENGINE; - if(Curl_raw_equal(type, "P12")) - return SSL_FILETYPE_PKCS12; - return -1; -} - -#if defined(HAVE_OPENSSL_ENGINE_H) -/* - * Supply default password to the engine user interface conversation. - * The password is passed by OpenSSL engine from ENGINE_load_private_key() - * last argument to the ui and can be obtained by UI_get0_user_data(ui) here. - */ -static int ssl_ui_reader(UI *ui, UI_STRING *uis) -{ - const char *password; - switch(UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - password = (const char*)UI_get0_user_data(ui); - if(password && (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { - UI_set_result(ui, uis, password); - return 1; - } - default: - break; - } - return (UI_method_get_reader(UI_OpenSSL()))(ui, uis); -} - -/* - * Suppress interactive request for a default password if available. - */ -static int ssl_ui_writer(UI *ui, UI_STRING *uis) -{ - switch(UI_get_string_type(uis)) { - case UIT_PROMPT: - case UIT_VERIFY: - if(UI_get0_user_data(ui) && - (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD)) { - return 1; - } - default: - break; - } - return (UI_method_get_writer(UI_OpenSSL()))(ui, uis); -} -#endif - -static -int cert_stuff(struct connectdata *conn, - SSL_CTX* ctx, - char *cert_file, - const char *cert_type, - char *key_file, - const char *key_type) -{ - struct SessionHandle *data = conn->data; - - int file_type = do_file_type(cert_type); - - if(cert_file || (file_type == SSL_FILETYPE_ENGINE)) { - SSL *ssl; - X509 *x509; - int cert_done = 0; - - if(data->set.str[STRING_KEY_PASSWD]) { - /* set the password in the callback userdata */ - SSL_CTX_set_default_passwd_cb_userdata(ctx, - data->set.str[STRING_KEY_PASSWD]); - /* Set passwd callback: */ - SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); - } - - - switch(file_type) { - case SSL_FILETYPE_PEM: - /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ - if(SSL_CTX_use_certificate_chain_file(ctx, - cert_file) != 1) { - failf(data, - "could not load PEM client certificate, " OSSL_PACKAGE - " error %s, " - "(no key found, wrong pass phrase, or wrong file format?)", - ERR_error_string(ERR_get_error(), NULL) ); - return 0; - } - break; - - case SSL_FILETYPE_ASN1: - /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but - we use the case above for PEM so this can only be performed with - ASN1 files. */ - if(SSL_CTX_use_certificate_file(ctx, - cert_file, - file_type) != 1) { - failf(data, - "could not load ASN1 client certificate, " OSSL_PACKAGE - " error %s, " - "(no key found, wrong pass phrase, or wrong file format?)", - ERR_error_string(ERR_get_error(), NULL) ); - return 0; - } - break; - case SSL_FILETYPE_ENGINE: -#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) - { - if(data->state.engine) { - const char *cmd_name = "LOAD_CERT_CTRL"; - struct { - const char *cert_id; - X509 *cert; - } params; - - params.cert_id = cert_file; - params.cert = NULL; - - /* Does the engine supports LOAD_CERT_CTRL ? */ - if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME, - 0, (void *)cmd_name, NULL)) { - failf(data, "ssl engine does not support loading certificates"); - return 0; - } - - /* Load the certificate from the engine */ - if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name, - 0, ¶ms, NULL, 1)) { - failf(data, "ssl engine cannot load client cert with id" - " '%s' [%s]", cert_file, - ERR_error_string(ERR_get_error(), NULL)); - return 0; - } - - if(!params.cert) { - failf(data, "ssl engine didn't initialized the certificate " - "properly."); - return 0; - } - - if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { - failf(data, "unable to set client certificate"); - X509_free(params.cert); - return 0; - } - X509_free(params.cert); /* we don't need the handle any more... */ - } - else { - failf(data, "crypto engine not set, can't load certificate"); - return 0; - } - } - break; -#else - failf(data, "file type ENG for certificate not implemented"); - return 0; -#endif - - case SSL_FILETYPE_PKCS12: - { -#ifdef HAVE_OPENSSL_PKCS12_H - FILE *f; - PKCS12 *p12; - EVP_PKEY *pri; - STACK_OF(X509) *ca = NULL; - - f = fopen(cert_file, "rb"); - if(!f) { - failf(data, "could not open PKCS12 file '%s'", cert_file); - return 0; - } - p12 = d2i_PKCS12_fp(f, NULL); - fclose(f); - - if(!p12) { - failf(data, "error reading PKCS12 file '%s'", cert_file); - return 0; - } - - PKCS12_PBE_add(); - - if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509, - &ca)) { - failf(data, - "could not parse PKCS12 file, check password, " OSSL_PACKAGE - " error %s", - ERR_error_string(ERR_get_error(), NULL) ); - PKCS12_free(p12); - return 0; - } - - PKCS12_free(p12); - - if(SSL_CTX_use_certificate(ctx, x509) != 1) { - failf(data, - "could not load PKCS12 client certificate, " OSSL_PACKAGE - " error %s", - ERR_error_string(ERR_get_error(), NULL) ); - goto fail; - } - - if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) { - failf(data, "unable to use private key from PKCS12 file '%s'", - cert_file); - goto fail; - } - - if(!SSL_CTX_check_private_key (ctx)) { - failf(data, "private key from PKCS12 file '%s' " - "does not match certificate in same file", cert_file); - goto fail; - } - /* Set Certificate Verification chain */ - if(ca) { - while(sk_X509_num(ca)) { - /* - * Note that sk_X509_pop() is used below to make sure the cert is - * removed from the stack properly before getting passed to - * SSL_CTX_add_extra_chain_cert(). Previously we used - * sk_X509_value() instead, but then we'd clean it in the subsequent - * sk_X509_pop_free() call. - */ - X509 *x = sk_X509_pop(ca); - if(!SSL_CTX_add_extra_chain_cert(ctx, x)) { - X509_free(x); - failf(data, "cannot add certificate to certificate chain"); - goto fail; - } - /* SSL_CTX_add_client_CA() seems to work with either sk_* function, - * presumably because it duplicates what we pass to it. - */ - if(!SSL_CTX_add_client_CA(ctx, x)) { - failf(data, "cannot add certificate to client CA list"); - goto fail; - } - } - } - - cert_done = 1; - fail: - EVP_PKEY_free(pri); - X509_free(x509); - sk_X509_pop_free(ca, X509_free); - - if(!cert_done) - return 0; /* failure! */ - break; -#else - failf(data, "file type P12 for certificate not supported"); - return 0; -#endif - } - default: - failf(data, "not supported file type '%s' for certificate", cert_type); - return 0; - } - - file_type = do_file_type(key_type); - - switch(file_type) { - case SSL_FILETYPE_PEM: - if(cert_done) - break; - if(!key_file) - /* cert & key can only be in PEM case in the same file */ - key_file=cert_file; - case SSL_FILETYPE_ASN1: - if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) { - failf(data, "unable to set private key file: '%s' type %s", - key_file, key_type?key_type:"PEM"); - return 0; - } - break; - case SSL_FILETYPE_ENGINE: -#ifdef HAVE_OPENSSL_ENGINE_H - { /* XXXX still needs some work */ - EVP_PKEY *priv_key = NULL; - if(data->state.engine) { - UI_METHOD *ui_method = - UI_create_method((char *)"cURL user interface"); - if(!ui_method) { - failf(data, "unable do create " OSSL_PACKAGE - " user-interface method"); - return 0; - } - UI_method_set_opener(ui_method, UI_method_get_opener(UI_OpenSSL())); - UI_method_set_closer(ui_method, UI_method_get_closer(UI_OpenSSL())); - UI_method_set_reader(ui_method, ssl_ui_reader); - UI_method_set_writer(ui_method, ssl_ui_writer); - /* the typecast below was added to please mingw32 */ - priv_key = (EVP_PKEY *) - ENGINE_load_private_key(data->state.engine, key_file, - ui_method, - data->set.str[STRING_KEY_PASSWD]); - UI_destroy_method(ui_method); - if(!priv_key) { - failf(data, "failed to load private key from crypto engine"); - return 0; - } - if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { - failf(data, "unable to set private key"); - EVP_PKEY_free(priv_key); - return 0; - } - EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ - } - else { - failf(data, "crypto engine not set, can't load private key"); - return 0; - } - } - break; -#else - failf(data, "file type ENG for private key not supported"); - return 0; -#endif - case SSL_FILETYPE_PKCS12: - if(!cert_done) { - failf(data, "file type P12 for private key not supported"); - return 0; - } - break; - default: - failf(data, "not supported file type for private key"); - return 0; - } - - ssl=SSL_new(ctx); - if(!ssl) { - failf(data, "unable to create an SSL structure"); - return 0; - } - - x509=SSL_get_certificate(ssl); - - /* This version was provided by Evan Jordan and is supposed to not - leak memory as the previous version: */ - if(x509) { - EVP_PKEY *pktmp = X509_get_pubkey(x509); - EVP_PKEY_copy_parameters(pktmp, SSL_get_privatekey(ssl)); - EVP_PKEY_free(pktmp); - } - - SSL_free(ssl); - - /* If we are using DSA, we can copy the parameters from - * the private key */ - - - /* Now we know that a key and cert have been set against - * the SSL context */ - if(!SSL_CTX_check_private_key(ctx)) { - failf(data, "Private key does not match the certificate public key"); - return 0; - } - } - return 1; -} - -/* returns non-zero on failure */ -static int x509_name_oneline(X509_NAME *a, char *buf, size_t size) -{ -#if 0 - return X509_NAME_oneline(a, buf, size); -#else - BIO *bio_out = BIO_new(BIO_s_mem()); - BUF_MEM *biomem; - int rc; - - if(!bio_out) - return 1; /* alloc failed! */ - - rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC); - BIO_get_mem_ptr(bio_out, &biomem); - - if((size_t)biomem->length < size) - size = biomem->length; - else - size--; /* don't overwrite the buffer end */ - - memcpy(buf, biomem->data, size); - buf[size]=0; - - BIO_free(bio_out); - - return !rc; -#endif -} - -/* Return error string for last OpenSSL error - */ -static char *SSL_strerror(unsigned long error, char *buf, size_t size) -{ - /* OpenSSL 0.9.6 and later has a function named - ERR_error_string_n() that takes the size of the buffer as a - third argument */ - ERR_error_string_n(error, buf, size); - return buf; -} - -/** - * Global SSL init - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ -int Curl_ossl_init(void) -{ - OPENSSL_load_builtin_modules(); - -#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES - ENGINE_load_builtin_engines(); -#endif - - /* OPENSSL_config(NULL); is "strongly recommended" to use but unfortunately - that function makes an exit() call on wrongly formatted config files - which makes it hard to use in some situations. OPENSSL_config() itself - calls CONF_modules_load_file() and we use that instead and we ignore - its return code! */ - - /* CONF_MFLAGS_DEFAULT_SECTION introduced some time between 0.9.8b and - 0.9.8e */ -#ifndef CONF_MFLAGS_DEFAULT_SECTION -#define CONF_MFLAGS_DEFAULT_SECTION 0x0 -#endif - - CONF_modules_load_file(NULL, NULL, - CONF_MFLAGS_DEFAULT_SECTION| - CONF_MFLAGS_IGNORE_MISSING_FILE); - - /* Lets get nice error messages */ - SSL_load_error_strings(); - - /* Init the global ciphers and digests */ - if(!SSLeay_add_ssl_algorithms()) - return 0; - - OpenSSL_add_all_algorithms(); - - return 1; -} - -/* Global cleanup */ -void Curl_ossl_cleanup(void) -{ - /* Free ciphers and digests lists */ - EVP_cleanup(); - -#ifdef HAVE_ENGINE_CLEANUP - /* Free engine list */ - ENGINE_cleanup(); -#endif - -#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA - /* Free OpenSSL ex_data table */ - CRYPTO_cleanup_all_ex_data(); -#endif - - /* Free OpenSSL error strings */ - ERR_free_strings(); - - /* Free thread local error state, destroying hash upon zero refcount */ -#ifdef HAVE_ERR_REMOVE_THREAD_STATE_DEPRECATED - -#elif defined(HAVE_ERR_REMOVE_THREAD_STATE) - ERR_remove_thread_state(NULL); -#else - ERR_remove_state(0); -#endif - - /* Free all memory allocated by all configuration modules */ - CONF_modules_free(); - -#if OPENSSL_VERSION_NUMBER >= 0x10002003L && \ - OPENSSL_VERSION_NUMBER <= 0x10002FFFL - SSL_COMP_free_compression_methods(); -#endif -} - -/* - * This function is used to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -int Curl_ossl_check_cxn(struct connectdata *conn) -{ - /* SSL_peek takes data out of the raw recv buffer without peeking so we use - recv MSG_PEEK instead. Bug #795 */ -#ifdef MSG_PEEK - char buf; - ssize_t nread; - nread = recv((RECV_TYPE_ARG1)conn->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf, - (RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK); - if(nread == 0) - return 0; /* connection has been closed */ - else if(nread == 1) - return 1; /* connection still in place */ - else if(nread == -1) { - int err = SOCKERRNO; - if(err == EINPROGRESS || -#if defined(EAGAIN) && (EAGAIN != EWOULDBLOCK) - err == EAGAIN || -#endif - err == EWOULDBLOCK) - return 1; /* connection still in place */ - if(err == ECONNRESET || -#ifdef ECONNABORTED - err == ECONNABORTED || -#endif -#ifdef ENETDOWN - err == ENETDOWN || -#endif -#ifdef ENETRESET - err == ENETRESET || -#endif -#ifdef ESHUTDOWN - err == ESHUTDOWN || -#endif -#ifdef ETIMEDOUT - err == ETIMEDOUT || -#endif - err == ENOTCONN) - return 0; /* connection has been closed */ - } -#endif - return -1; /* connection status unknown */ -} - -/* Selects an OpenSSL crypto engine - */ -CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine) -{ -#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H) - ENGINE *e; - -#if OPENSSL_VERSION_NUMBER >= 0x00909000L - e = ENGINE_by_id(engine); -#else - /* avoid memory leak */ - for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { - const char *e_id = ENGINE_get_id(e); - if(!strcmp(engine, e_id)) - break; - } -#endif - - if(!e) { - failf(data, "SSL Engine '%s' not found", engine); - return CURLE_SSL_ENGINE_NOTFOUND; - } - - if(data->state.engine) { - ENGINE_finish(data->state.engine); - ENGINE_free(data->state.engine); - data->state.engine = NULL; - } - if(!ENGINE_init(e)) { - char buf[256]; - - ENGINE_free(e); - failf(data, "Failed to initialise SSL Engine '%s':\n%s", - engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf))); - return CURLE_SSL_ENGINE_INITFAILED; - } - data->state.engine = e; - return CURLE_OK; -#else - (void)engine; - failf(data, "SSL Engine not supported"); - return CURLE_SSL_ENGINE_NOTFOUND; -#endif -} - -/* Sets engine as default for all SSL operations - */ -CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data) -{ -#ifdef HAVE_OPENSSL_ENGINE_H - if(data->state.engine) { - if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) { - infof(data, "set default crypto engine '%s'\n", - ENGINE_get_id(data->state.engine)); - } - else { - failf(data, "set default crypto engine '%s' failed", - ENGINE_get_id(data->state.engine)); - return CURLE_SSL_ENGINE_SETFAILED; - } - } -#else - (void) data; -#endif - return CURLE_OK; -} - -/* Return list of OpenSSL crypto engine names. - */ -struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data) -{ - struct curl_slist *list = NULL; -#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H) - struct curl_slist *beg; - ENGINE *e; - - for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { - beg = curl_slist_append(list, ENGINE_get_id(e)); - if(!beg) { - curl_slist_free_all(list); - return NULL; - } - list = beg; - } -#endif - (void) data; - return list; -} - - -/* - * This function is called when an SSL connection is closed. - */ -void Curl_ossl_close(struct connectdata *conn, int sockindex) -{ - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - if(connssl->handle) { - (void)SSL_shutdown(connssl->handle); - SSL_set_connect_state(connssl->handle); - - SSL_free (connssl->handle); - connssl->handle = NULL; - } - if(connssl->ctx) { - SSL_CTX_free (connssl->ctx); - connssl->ctx = NULL; - } -} - -/* - * This function is called to shut down the SSL layer but keep the - * socket open (CCC - Clear Command Channel) - */ -int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) -{ - int retval = 0; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - char buf[120]; /* We will use this for the OpenSSL error buffer, so it has - to be at least 120 bytes long. */ - unsigned long sslerror; - ssize_t nread; - int buffsize; - int err; - int done = 0; - - /* This has only been tested on the proftpd server, and the mod_tls code - sends a close notify alert without waiting for a close notify alert in - response. Thus we wait for a close notify alert from the server, but - we do not send one. Let's hope other servers do the same... */ - - if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) - (void)SSL_shutdown(connssl->handle); - - if(connssl->handle) { - buffsize = (int)sizeof(buf); - while(!done) { - int what = Curl_socket_ready(conn->sock[sockindex], - CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); - if(what > 0) { - ERR_clear_error(); - - /* Something to read, let's do it and hope that it is the close - notify alert from the server */ - nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf, - buffsize); - err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread); - - switch(err) { - case SSL_ERROR_NONE: /* this is not an error */ - case SSL_ERROR_ZERO_RETURN: /* no more data */ - /* This is the expected response. There was no data but only - the close notify alert */ - done = 1; - break; - case SSL_ERROR_WANT_READ: - /* there's data pending, re-invoke SSL_read() */ - infof(data, "SSL_ERROR_WANT_READ\n"); - break; - case SSL_ERROR_WANT_WRITE: - /* SSL wants a write. Really odd. Let's bail out. */ - infof(data, "SSL_ERROR_WANT_WRITE\n"); - done = 1; - break; - default: - /* openssl/ssl.h says "look at error stack/return value/errno" */ - sslerror = ERR_get_error(); - failf(conn->data, OSSL_PACKAGE " SSL read: %s, errno %d", - ERR_error_string(sslerror, buf), - SOCKERRNO); - done = 1; - break; - } - } - else if(0 == what) { - /* timeout */ - failf(data, "SSL shutdown timeout"); - done = 1; - } - else { - /* anything that gets here is fatally bad */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - retval = -1; - done = 1; - } - } /* while()-loop for the select() */ - - if(data->set.verbose) { -#ifdef HAVE_SSL_GET_SHUTDOWN - switch(SSL_get_shutdown(connssl->handle)) { - case SSL_SENT_SHUTDOWN: - infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n"); - break; - case SSL_RECEIVED_SHUTDOWN: - infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n"); - break; - case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN: - infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|" - "SSL_RECEIVED__SHUTDOWN\n"); - break; - } -#endif - } - - SSL_free (connssl->handle); - connssl->handle = NULL; - } - return retval; -} - -void Curl_ossl_session_free(void *ptr) -{ - /* free the ID */ - SSL_SESSION_free(ptr); -} - -/* - * This function is called when the 'data' struct is going away. Close - * down everything and free all resources! - */ -void Curl_ossl_close_all(struct SessionHandle *data) -{ -#ifdef HAVE_OPENSSL_ENGINE_H - if(data->state.engine) { - ENGINE_finish(data->state.engine); - ENGINE_free(data->state.engine); - data->state.engine = NULL; - } -#else - (void)data; -#endif -} - -/* ====================================================== */ - - -/* Quote from RFC2818 section 3.1 "Server Identity" - - If a subjectAltName extension of type dNSName is present, that MUST - be used as the identity. Otherwise, the (most specific) Common Name - field in the Subject field of the certificate MUST be used. Although - the use of the Common Name is existing practice, it is deprecated and - Certification Authorities are encouraged to use the dNSName instead. - - Matching is performed using the matching rules specified by - [RFC2459]. If more than one identity of a given type is present in - the certificate (e.g., more than one dNSName name, a match in any one - of the set is considered acceptable.) Names may contain the wildcard - character * which is considered to match any single domain name - component or component fragment. E.g., *.a.com matches foo.a.com but - not bar.foo.a.com. f*.com matches foo.com but not bar.com. - - In some cases, the URI is specified as an IP address rather than a - hostname. In this case, the iPAddress subjectAltName must be present - in the certificate and must exactly match the IP in the URI. - -*/ -static CURLcode verifyhost(struct connectdata *conn, X509 *server_cert) -{ - bool matched = FALSE; - int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */ - size_t addrlen = 0; - struct SessionHandle *data = conn->data; - STACK_OF(GENERAL_NAME) *altnames; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - CURLcode result = CURLE_OK; - -#ifdef ENABLE_IPV6 - if(conn->bits.ipv6_ip && - Curl_inet_pton(AF_INET6, conn->host.name, &addr)) { - target = GEN_IPADD; - addrlen = sizeof(struct in6_addr); - } - else -#endif - if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) { - target = GEN_IPADD; - addrlen = sizeof(struct in_addr); - } - - /* get a "list" of alternative names */ - altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); - - if(altnames) { - int numalts; - int i; - - /* get amount of alternatives, RFC2459 claims there MUST be at least - one, but we don't depend on it... */ - numalts = sk_GENERAL_NAME_num(altnames); - - /* loop through all alternatives while none has matched */ - for(i=0; (itype == target) { - /* get data and length */ - const char *altptr = (char *)ASN1_STRING_data(check->d.ia5); - size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5); - - switch(target) { - case GEN_DNS: /* name/pattern comparison */ - /* The OpenSSL man page explicitly says: "In general it cannot be - assumed that the data returned by ASN1_STRING_data() is null - terminated or does not contain embedded nulls." But also that - "The actual format of the data will depend on the actual string - type itself: for example for and IA5String the data will be ASCII" - - Gisle researched the OpenSSL sources: - "I checked the 0.9.6 and 0.9.8 sources before my patch and - it always 0-terminates an IA5String." - */ - if((altlen == strlen(altptr)) && - /* if this isn't true, there was an embedded zero in the name - string and we cannot match it. */ - Curl_cert_hostcheck(altptr, conn->host.name)) { - matched = TRUE; - infof(data, - " subjectAltName: host \"%s\" matched cert's \"%s\"\n", - conn->host.dispname, altptr); - } - break; - - case GEN_IPADD: /* IP address comparison */ - /* compare alternative IP address if the data chunk is the same size - our server IP address is */ - if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) { - matched = TRUE; - infof(data, - " subjectAltName: host \"%s\" matched cert's IP address!\n", - conn->host.dispname); - } - break; - } - } - } - GENERAL_NAMES_free(altnames); - } - - if(matched) - /* an alternative name matched */ - ; - else if(altnames) { - /* an alternative name field existed, but didn't match and then we MUST - fail */ - infof(data, " subjectAltName does not match %s\n", conn->host.dispname); - failf(data, "SSL: no alternative certificate subject name matches " - "target host name '%s'", conn->host.dispname); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else { - /* we have to look to the last occurrence of a commonName in the - distinguished one to get the most significant one. */ - int j, i=-1; - - /* The following is done because of a bug in 0.9.6b */ - - unsigned char *nulstr = (unsigned char *)""; - unsigned char *peer_CN = nulstr; - - X509_NAME *name = X509_get_subject_name(server_cert); - if(name) - while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0) - i=j; - - /* we have the name entry and we will now convert this to a string - that we can use for comparison. Doing this we support BMPstring, - UTF8 etc. */ - - if(i>=0) { - ASN1_STRING *tmp = - X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); - - /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input - is already UTF-8 encoded. We check for this case and copy the raw - string manually to avoid the problem. This code can be made - conditional in the future when OpenSSL has been fixed. Work-around - brought by Alexis S. L. Carvalho. */ - if(tmp) { - if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) { - j = ASN1_STRING_length(tmp); - if(j >= 0) { - peer_CN = OPENSSL_malloc(j+1); - if(peer_CN) { - memcpy(peer_CN, ASN1_STRING_data(tmp), j); - peer_CN[j] = '\0'; - } - } - } - else /* not a UTF8 name */ - j = ASN1_STRING_to_UTF8(&peer_CN, tmp); - - if(peer_CN && (curlx_uztosi(strlen((char *)peer_CN)) != j)) { - /* there was a terminating zero before the end of string, this - cannot match and we return failure! */ - failf(data, "SSL: illegal cert name field"); - result = CURLE_PEER_FAILED_VERIFICATION; - } - } - } - - if(peer_CN == nulstr) - peer_CN = NULL; - else { - /* convert peer_CN from UTF8 */ - CURLcode rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN)); - /* Curl_convert_from_utf8 calls failf if unsuccessful */ - if(rc) { - OPENSSL_free(peer_CN); - return rc; - } - } - - if(result) - /* error already detected, pass through */ - ; - else if(!peer_CN) { - failf(data, - "SSL: unable to obtain common name from peer certificate"); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else if(!Curl_cert_hostcheck((const char *)peer_CN, conn->host.name)) { - failf(data, "SSL: certificate subject name '%s' does not match " - "target host name '%s'", peer_CN, conn->host.dispname); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else { - infof(data, " common name: %s (matched)\n", peer_CN); - } - if(peer_CN) - OPENSSL_free(peer_CN); - } - - return result; -} - -#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ - !defined(OPENSSL_NO_OCSP) -static CURLcode verifystatus(struct connectdata *conn, - struct ssl_connect_data *connssl) -{ - int i, ocsp_status; - const unsigned char *p; - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - - OCSP_RESPONSE *rsp = NULL; - OCSP_BASICRESP *br = NULL; - X509_STORE *st = NULL; - STACK_OF(X509) *ch = NULL; - - long len = SSL_get_tlsext_status_ocsp_resp(connssl->handle, &p); - - if(!p) { - failf(data, "No OCSP response received"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - rsp = d2i_OCSP_RESPONSE(NULL, &p, len); - if(!rsp) { - failf(data, "Invalid OCSP response"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - ocsp_status = OCSP_response_status(rsp); - if(ocsp_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { - failf(data, "Invalid OCSP response status: %s (%d)", - OCSP_response_status_str(ocsp_status), ocsp_status); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - br = OCSP_response_get1_basic(rsp); - if(!br) { - failf(data, "Invalid OCSP response"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - ch = SSL_get_peer_cert_chain(connssl->handle); - st = SSL_CTX_get_cert_store(connssl->ctx); - -#if ((OPENSSL_VERSION_NUMBER <= 0x1000201fL) /* Fixed after 1.0.2a */ || \ - defined(LIBRESSL_VERSION_NUMBER)) - /* The authorized responder cert in the OCSP response MUST be signed by the - peer cert's issuer (see RFC6960 section 4.2.2.2). If that's a root cert, - no problem, but if it's an intermediate cert OpenSSL has a bug where it - expects this issuer to be present in the chain embedded in the OCSP - response. So we add it if necessary. */ - - /* First make sure the peer cert chain includes both a peer and an issuer, - and the OCSP response contains a responder cert. */ - if(sk_X509_num(ch) >= 2 && sk_X509_num(br->certs) >= 1) { - X509 *responder = sk_X509_value(br->certs, sk_X509_num(br->certs) - 1); - - /* Find issuer of responder cert and add it to the OCSP response chain */ - for(i = 0; i < sk_X509_num(ch); i++) { - X509 *issuer = sk_X509_value(ch, i); - if(X509_check_issued(issuer, responder) == X509_V_OK) { - if(!OCSP_basic_add1_cert(br, issuer)) { - failf(data, "Could not add issuer cert to OCSP response"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - } - } - } -#endif - - if(OCSP_basic_verify(br, ch, st, 0) <= 0) { - failf(data, "OCSP response verification failed"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - for(i = 0; i < OCSP_resp_count(br); i++) { - int cert_status, crl_reason; - OCSP_SINGLERESP *single = NULL; - - ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd; - - single = OCSP_resp_get0(br, i); - if(!single) - continue; - - cert_status = OCSP_single_get0_status(single, &crl_reason, &rev, - &thisupd, &nextupd); - - if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) { - failf(data, "OCSP response has expired"); - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - - infof(data, "SSL certificate status: %s (%d)\n", - OCSP_cert_status_str(cert_status), cert_status); - - switch(cert_status) { - case V_OCSP_CERTSTATUS_GOOD: - break; - - case V_OCSP_CERTSTATUS_REVOKED: - result = CURLE_SSL_INVALIDCERTSTATUS; - - failf(data, "SSL certificate revocation reason: %s (%d)", - OCSP_crl_reason_str(crl_reason), crl_reason); - goto end; - - case V_OCSP_CERTSTATUS_UNKNOWN: - result = CURLE_SSL_INVALIDCERTSTATUS; - goto end; - } - } - -end: - if(br) OCSP_BASICRESP_free(br); - OCSP_RESPONSE_free(rsp); - - return result; -} -#endif - -#endif /* USE_OPENSSL */ - -/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions - and thus this cannot be done there. */ -#ifdef SSL_CTRL_SET_MSG_CALLBACK - -static const char *ssl_msg_type(int ssl_ver, int msg) -{ -#ifdef SSL2_VERSION_MAJOR - if(ssl_ver == SSL2_VERSION_MAJOR) { - switch (msg) { - case SSL2_MT_ERROR: - return "Error"; - case SSL2_MT_CLIENT_HELLO: - return "Client hello"; - case SSL2_MT_CLIENT_MASTER_KEY: - return "Client key"; - case SSL2_MT_CLIENT_FINISHED: - return "Client finished"; - case SSL2_MT_SERVER_HELLO: - return "Server hello"; - case SSL2_MT_SERVER_VERIFY: - return "Server verify"; - case SSL2_MT_SERVER_FINISHED: - return "Server finished"; - case SSL2_MT_REQUEST_CERTIFICATE: - return "Request CERT"; - case SSL2_MT_CLIENT_CERTIFICATE: - return "Client CERT"; - } - } - else -#endif - if(ssl_ver == SSL3_VERSION_MAJOR) { - switch (msg) { - case SSL3_MT_HELLO_REQUEST: - return "Hello request"; - case SSL3_MT_CLIENT_HELLO: - return "Client hello"; - case SSL3_MT_SERVER_HELLO: - return "Server hello"; -#ifdef SSL3_MT_NEWSESSION_TICKET - case SSL3_MT_NEWSESSION_TICKET: - return "Newsession Ticket"; -#endif - case SSL3_MT_CERTIFICATE: - return "Certificate"; - case SSL3_MT_SERVER_KEY_EXCHANGE: - return "Server key exchange"; - case SSL3_MT_CLIENT_KEY_EXCHANGE: - return "Client key exchange"; - case SSL3_MT_CERTIFICATE_REQUEST: - return "Request CERT"; - case SSL3_MT_SERVER_DONE: - return "Server finished"; - case SSL3_MT_CERTIFICATE_VERIFY: - return "CERT verify"; - case SSL3_MT_FINISHED: - return "Finished"; -#ifdef SSL3_MT_CERTIFICATE_STATUS - case SSL3_MT_CERTIFICATE_STATUS: - return "Certificate Status"; -#endif - } - } - return "Unknown"; -} - -static const char *tls_rt_type(int type) -{ - switch(type) { -#ifdef SSL3_RT_HEADER - case SSL3_RT_HEADER: - return "TLS header"; -#endif - case SSL3_RT_CHANGE_CIPHER_SPEC: - return "TLS change cipher"; - case SSL3_RT_ALERT: - return "TLS alert"; - case SSL3_RT_HANDSHAKE: - return "TLS handshake"; - case SSL3_RT_APPLICATION_DATA: - return "TLS app data"; - default: - return "TLS Unknown"; - } -} - - -/* - * Our callback from the SSL/TLS layers. - */ -static void ssl_tls_trace(int direction, int ssl_ver, int content_type, - const void *buf, size_t len, SSL *ssl, - void *userp) -{ - struct SessionHandle *data; - const char *msg_name, *tls_rt_name; - char ssl_buf[1024]; - char unknown[32]; - int msg_type, txt_len; - const char *verstr = NULL; - struct connectdata *conn = userp; - - if(!conn || !conn->data || !conn->data->set.fdebug || - (direction != 0 && direction != 1)) - return; - - data = conn->data; - - switch(ssl_ver) { -#ifdef SSL2_VERSION /* removed in recent versions */ - case SSL2_VERSION: - verstr = "SSLv2"; - break; -#endif -#ifdef SSL3_VERSION - case SSL3_VERSION: - verstr = "SSLv3"; - break; -#endif - case TLS1_VERSION: - verstr = "TLSv1.0"; - break; -#ifdef TLS1_1_VERSION - case TLS1_1_VERSION: - verstr = "TLSv1.1"; - break; -#endif -#ifdef TLS1_2_VERSION - case TLS1_2_VERSION: - verstr = "TLSv1.2"; - break; -#endif - case 0: - break; - default: - snprintf(unknown, sizeof(unknown), "(%x)", ssl_ver); - verstr = unknown; - break; - } - - if(ssl_ver) { - /* the info given when the version is zero is not that useful for us */ - - ssl_ver >>= 8; /* check the upper 8 bits only below */ - - /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL - * always pass-up content-type as 0. But the interesting message-type - * is at 'buf[0]'. - */ - if(ssl_ver == SSL3_VERSION_MAJOR && content_type) - tls_rt_name = tls_rt_type(content_type); - else - tls_rt_name = ""; - - msg_type = *(char*)buf; - msg_name = ssl_msg_type(ssl_ver, msg_type); - - txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "%s (%s), %s, %s (%d):\n", - verstr, direction?"OUT":"IN", - tls_rt_name, msg_name, msg_type); - Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL); - } - - Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : - CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL); - (void) ssl; -} -#endif - -#ifdef USE_OPENSSL -/* ====================================================== */ - -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME -# define use_sni(x) sni = (x) -#else -# define use_sni(x) Curl_nop_stmt -#endif - -/* Check for OpenSSL 1.0.2 which has ALPN support. */ -#undef HAS_ALPN -#if OPENSSL_VERSION_NUMBER >= 0x10002000L \ - && !defined(OPENSSL_NO_TLSEXT) -# define HAS_ALPN 1 -#endif - -/* Check for OpenSSL 1.0.1 which has NPN support. */ -#undef HAS_NPN -#if OPENSSL_VERSION_NUMBER >= 0x10001000L \ - && !defined(OPENSSL_NO_TLSEXT) \ - && !defined(OPENSSL_NO_NEXTPROTONEG) -# define HAS_NPN 1 -#endif - -#ifdef HAS_NPN - -/* - * in is a list of lenght prefixed strings. this function has to select - * the protocol we want to use from the list and write its string into out. - */ - -static int -select_next_protocol(unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - const char *key, unsigned int keylen) -{ - unsigned int i; - for(i = 0; i + keylen <= inlen; i += in[i] + 1) { - if(memcmp(&in[i + 1], key, keylen) == 0) { - *out = (unsigned char *) &in[i + 1]; - *outlen = in[i]; - return 0; - } - } - return -1; -} - -static int -select_next_proto_cb(SSL *ssl, - unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - void *arg) -{ - struct connectdata *conn = (struct connectdata*) arg; - - (void)ssl; - -#ifdef USE_NGHTTP2 - if(conn->data->set.httpversion >= CURL_HTTP_VERSION_2 && - !select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - infof(conn->data, "NPN, negotiated HTTP2 (%s)\n", - NGHTTP2_PROTO_VERSION_ID); - conn->negnpn = CURL_HTTP_VERSION_2; - return SSL_TLSEXT_ERR_OK; - } -#endif - - if(!select_next_protocol(out, outlen, in, inlen, ALPN_HTTP_1_1, - ALPN_HTTP_1_1_LENGTH)) { - infof(conn->data, "NPN, negotiated HTTP1.1\n"); - conn->negnpn = CURL_HTTP_VERSION_1_1; - return SSL_TLSEXT_ERR_OK; - } - - infof(conn->data, "NPN, no overlap, use HTTP1.1\n"); - *out = (unsigned char *)ALPN_HTTP_1_1; - *outlen = ALPN_HTTP_1_1_LENGTH; - conn->negnpn = CURL_HTTP_VERSION_1_1; - - return SSL_TLSEXT_ERR_OK; -} -#endif /* HAS_NPN */ - -static const char * -get_ssl_version_txt(SSL *ssl) -{ - if(!ssl) - return ""; - - switch(SSL_version(ssl)) { -#if OPENSSL_VERSION_NUMBER >= 0x1000100FL - case TLS1_2_VERSION: - return "TLSv1.2"; - case TLS1_1_VERSION: - return "TLSv1.1"; -#endif - case TLS1_VERSION: - return "TLSv1.0"; - case SSL3_VERSION: - return "SSLv3"; - case SSL2_VERSION: - return "SSLv2"; - } - return "unknown"; -} - -static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex) -{ - CURLcode result = CURLE_OK; - char *ciphers; - struct SessionHandle *data = conn->data; - SSL_METHOD_QUAL SSL_METHOD *req_method = NULL; - void *ssl_sessionid = NULL; - X509_LOOKUP *lookup = NULL; - curl_socket_t sockfd = conn->sock[sockindex]; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - long ctx_options; -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - bool sni; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif -#endif - - DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); - - /* Make funny stuff to get random input */ - Curl_ossl_seed(data); - - data->set.ssl.certverifyresult = !X509_V_OK; - - /* check to see if we've been told to use an explicit SSL/TLS version */ - - switch(data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - /* it will be handled later with the context options */ -#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && \ - !defined(LIBRESSL_VERSION_NUMBER) - req_method = TLS_client_method(); -#else - req_method = SSLv23_client_method(); -#endif - use_sni(TRUE); - break; - case CURL_SSLVERSION_SSLv2: -#ifdef OPENSSL_NO_SSL2 - failf(data, OSSL_PACKAGE " was built without SSLv2 support"); - return CURLE_NOT_BUILT_IN; -#else -#ifdef USE_TLS_SRP - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) - return CURLE_SSL_CONNECT_ERROR; -#endif - req_method = SSLv2_client_method(); - use_sni(FALSE); - break; -#endif - case CURL_SSLVERSION_SSLv3: -#ifdef OPENSSL_NO_SSL3_METHOD - failf(data, OSSL_PACKAGE " was built without SSLv3 support"); - return CURLE_NOT_BUILT_IN; -#else -#ifdef USE_TLS_SRP - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) - return CURLE_SSL_CONNECT_ERROR; -#endif - req_method = SSLv3_client_method(); - use_sni(FALSE); - break; -#endif - } - - if(connssl->ctx) - SSL_CTX_free(connssl->ctx); - connssl->ctx = SSL_CTX_new(req_method); - - if(!connssl->ctx) { - failf(data, "SSL: couldn't create a context: %s", - ERR_error_string(ERR_peek_error(), NULL)); - return CURLE_OUT_OF_MEMORY; - } - -#ifdef SSL_MODE_RELEASE_BUFFERS - SSL_CTX_set_mode(connssl->ctx, SSL_MODE_RELEASE_BUFFERS); -#endif - -#ifdef SSL_CTRL_SET_MSG_CALLBACK - if(data->set.fdebug && data->set.verbose) { - /* the SSL trace callback is only used for verbose logging */ - SSL_CTX_set_msg_callback(connssl->ctx, ssl_tls_trace); - SSL_CTX_set_msg_callback_arg(connssl->ctx, conn); - } -#endif - - /* OpenSSL contains code to work-around lots of bugs and flaws in various - SSL-implementations. SSL_CTX_set_options() is used to enabled those - work-arounds. The man page for this option states that SSL_OP_ALL enables - all the work-arounds and that "It is usually safe to use SSL_OP_ALL to - enable the bug workaround options if compatibility with somewhat broken - implementations is desired." - - The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to - disable "rfc4507bis session ticket support". rfc4507bis was later turned - into the proper RFC5077 it seems: https://tools.ietf.org/html/rfc5077 - - The enabled extension concerns the session management. I wonder how often - libcurl stops a connection and then resumes a TLS session. also, sending - the session data is some overhead. .I suggest that you just use your - proposed patch (which explicitly disables TICKET). - - If someone writes an application with libcurl and openssl who wants to - enable the feature, one can do this in the SSL callback. - - SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG option enabling allowed proper - interoperability with web server Netscape Enterprise Server 2.0.1 which - was released back in 1996. - - Due to CVE-2010-4180, option SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG has - become ineffective as of OpenSSL 0.9.8q and 1.0.0c. In order to mitigate - CVE-2010-4180 when using previous OpenSSL versions we no longer enable - this option regardless of OpenSSL version and SSL_OP_ALL definition. - - OpenSSL added a work-around for a SSL 3.0/TLS 1.0 CBC vulnerability - (https://www.openssl.org/~bodo/tls-cbc.txt). In 0.9.6e they added a bit to - SSL_OP_ALL that _disables_ that work-around despite the fact that - SSL_OP_ALL is documented to do "rather harmless" workarounds. In order to - keep the secure work-around, the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS bit - must not be set. - */ - - ctx_options = SSL_OP_ALL; - -#ifdef SSL_OP_NO_TICKET - ctx_options |= SSL_OP_NO_TICKET; -#endif - -#ifdef SSL_OP_NO_COMPRESSION - ctx_options |= SSL_OP_NO_COMPRESSION; -#endif - -#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG - /* mitigate CVE-2010-4180 */ - ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; -#endif - -#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS - /* unless the user explicitly ask to allow the protocol vulnerability we - use the work-around */ - if(!conn->data->set.ssl_enable_beast) - ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; -#endif - - switch(data->set.ssl.version) { - case CURL_SSLVERSION_SSLv3: -#ifdef USE_TLS_SRP - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { - infof(data, "Set version TLSv1.x for SRP authorisation\n"); - } -#endif - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_TLSv1; -#if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -#endif - break; - - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_SSLv3; - break; - - case CURL_SSLVERSION_TLSv1_0: - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_SSLv3; -#if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -#endif - break; - -#if OPENSSL_VERSION_NUMBER >= 0x1000100FL - case CURL_SSLVERSION_TLSv1_1: - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_SSLv3; - ctx_options |= SSL_OP_NO_TLSv1; - ctx_options |= SSL_OP_NO_TLSv1_2; - break; - - case CURL_SSLVERSION_TLSv1_2: - ctx_options |= SSL_OP_NO_SSLv2; - ctx_options |= SSL_OP_NO_SSLv3; - ctx_options |= SSL_OP_NO_TLSv1; - ctx_options |= SSL_OP_NO_TLSv1_1; - break; -#endif - -#ifndef OPENSSL_NO_SSL2 - case CURL_SSLVERSION_SSLv2: - ctx_options |= SSL_OP_NO_SSLv3; - ctx_options |= SSL_OP_NO_TLSv1; -#if OPENSSL_VERSION_NUMBER >= 0x1000100FL - ctx_options |= SSL_OP_NO_TLSv1_1; - ctx_options |= SSL_OP_NO_TLSv1_2; -#endif - break; -#endif - - default: - failf(data, "Unsupported SSL protocol version"); - return CURLE_SSL_CONNECT_ERROR; - } - - SSL_CTX_set_options(connssl->ctx, ctx_options); - -#ifdef HAS_NPN - if(conn->bits.tls_enable_npn) - SSL_CTX_set_next_proto_select_cb(connssl->ctx, select_next_proto_cb, conn); -#endif - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - int cur = 0; - unsigned char protocols[128]; - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID_LEN; - - memcpy(&protocols[cur], NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN); - cur += NGHTTP2_PROTO_VERSION_ID_LEN; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - protocols[cur++] = ALPN_HTTP_1_1_LENGTH; - memcpy(&protocols[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); - cur += ALPN_HTTP_1_1_LENGTH; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - /* expects length prefixed preference ordered list of protocols in wire - * format - */ - SSL_CTX_set_alpn_protos(connssl->ctx, protocols, cur); - } -#endif - - if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) { - if(!cert_stuff(conn, - connssl->ctx, - data->set.str[STRING_CERT], - data->set.str[STRING_CERT_TYPE], - data->set.str[STRING_KEY], - data->set.str[STRING_KEY_TYPE])) { - /* failf() is already done in cert_stuff() */ - return CURLE_SSL_CERTPROBLEM; - } - } - - ciphers = data->set.str[STRING_SSL_CIPHER_LIST]; - if(!ciphers) - ciphers = (char *)DEFAULT_CIPHER_SELECTION; - if(!SSL_CTX_set_cipher_list(connssl->ctx, ciphers)) { - failf(data, "failed setting cipher list: %s", ciphers); - return CURLE_SSL_CIPHER; - } - infof(data, "Cipher selection: %s\n", ciphers); - -#ifdef USE_TLS_SRP - if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { - infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username); - - if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) { - failf(data, "Unable to set SRP user name"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(!SSL_CTX_set_srp_password(connssl->ctx, data->set.ssl.password)) { - failf(data, "failed setting SRP password"); - return CURLE_BAD_FUNCTION_ARGUMENT; - } - if(!data->set.str[STRING_SSL_CIPHER_LIST]) { - infof(data, "Setting cipher list SRP\n"); - - if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) { - failf(data, "failed setting SRP cipher list"); - return CURLE_SSL_CIPHER; - } - } - } -#endif - if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) { - /* tell SSL where to find CA certificates that are used to verify - the servers certificate. */ - if(!SSL_CTX_load_verify_locations(connssl->ctx, - data->set.str[STRING_SSL_CAFILE], - data->set.str[STRING_SSL_CAPATH])) { - if(data->set.ssl.verifypeer) { - /* Fail if we insist on successfully verifying the server. */ - failf(data, "error setting certificate verify locations:\n" - " CAfile: %s\n CApath: %s", - data->set.str[STRING_SSL_CAFILE]? - data->set.str[STRING_SSL_CAFILE]: "none", - data->set.str[STRING_SSL_CAPATH]? - data->set.str[STRING_SSL_CAPATH] : "none"); - return CURLE_SSL_CACERT_BADFILE; - } - else { - /* Just continue with a warning if no strict certificate verification - is required. */ - infof(data, "error setting certificate verify locations," - " continuing anyway:\n"); - } - } - else { - /* Everything is fine. */ - infof(data, "successfully set certificate verify locations:\n"); - } - infof(data, - " CAfile: %s\n" - " CApath: %s\n", - data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]: - "none", - data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]: - "none"); - } -#ifdef CURL_CA_FALLBACK - else if(data->set.ssl.verifypeer) { - /* verfying the peer without any CA certificates won't - work so use openssl's built in default as fallback */ - SSL_CTX_set_default_verify_paths(connssl->ctx); - } -#endif - - if(data->set.str[STRING_SSL_CRLFILE]) { - /* tell SSL where to find CRL file that is used to check certificate - * revocation */ - lookup=X509_STORE_add_lookup(SSL_CTX_get_cert_store(connssl->ctx), - X509_LOOKUP_file()); - if(!lookup || - (!X509_load_crl_file(lookup, data->set.str[STRING_SSL_CRLFILE], - X509_FILETYPE_PEM)) ) { - failf(data, "error loading CRL file: %s", - data->set.str[STRING_SSL_CRLFILE]); - return CURLE_SSL_CRL_BADFILE; - } - else { - /* Everything is fine. */ - infof(data, "successfully load CRL file:\n"); - X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx), - X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); - } - infof(data, - " CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ? - data->set.str[STRING_SSL_CRLFILE]: "none"); - } - - /* Try building a chain using issuers in the trusted store first to avoid - problems with server-sent legacy intermediates. - Newer versions of OpenSSL do alternate chain checking by default which - gives us the same fix without as much of a performance hit (slight), so we - prefer that if available. - https://rt.openssl.org/Ticket/Display.html?id=3621&user=guest&pass=guest - */ -#if defined(X509_V_FLAG_TRUSTED_FIRST) && !defined(X509_V_FLAG_NO_ALT_CHAINS) - if(data->set.ssl.verifypeer) { - X509_STORE_set_flags(SSL_CTX_get_cert_store(connssl->ctx), - X509_V_FLAG_TRUSTED_FIRST); - } -#endif - - /* SSL always tries to verify the peer, this only says whether it should - * fail to connect if the verification fails, or if it should continue - * anyway. In the latter case the result of the verification is checked with - * SSL_get_verify_result() below. */ - SSL_CTX_set_verify(connssl->ctx, - data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE, - NULL); - - /* give application a chance to interfere with SSL set up. */ - if(data->set.ssl.fsslctx) { - result = (*data->set.ssl.fsslctx)(data, connssl->ctx, - data->set.ssl.fsslctxp); - if(result) { - failf(data, "error signaled by ssl ctx callback"); - return result; - } - } - - /* Lets make an SSL structure */ - if(connssl->handle) - SSL_free(connssl->handle); - connssl->handle = SSL_new(connssl->ctx); - if(!connssl->handle) { - failf(data, "SSL: couldn't create a context (handle)!"); - return CURLE_OUT_OF_MEMORY; - } - -#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ - !defined(OPENSSL_NO_OCSP) - if(data->set.ssl.verifystatus) - SSL_set_tlsext_status_type(connssl->handle, TLSEXT_STATUSTYPE_ocsp); -#endif - - SSL_set_connect_state(connssl->handle); - - connssl->server_cert = 0x0; - -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) && -#ifdef ENABLE_IPV6 - (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) && -#endif - sni && - !SSL_set_tlsext_host_name(connssl->handle, conn->host.name)) - infof(data, "WARNING: failed to configure server name indication (SNI) " - "TLS extension\n"); -#endif - - /* Check if there's a cached ID we can/should use here! */ - if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { - /* we got a session id, use it! */ - if(!SSL_set_session(connssl->handle, ssl_sessionid)) { - failf(data, "SSL: SSL_set_session failed: %s", - ERR_error_string(ERR_get_error(), NULL)); - return CURLE_SSL_CONNECT_ERROR; - } - /* Informational message */ - infof (data, "SSL re-using session ID\n"); - } - - /* pass the raw socket into the SSL layers */ - if(!SSL_set_fd(connssl->handle, (int)sockfd)) { - failf(data, "SSL: SSL_set_fd failed: %s", - ERR_error_string(ERR_get_error(), NULL)); - return CURLE_SSL_CONNECT_ERROR; - } - - connssl->connecting_state = ssl_connect_2; - - return CURLE_OK; -} - -static CURLcode ossl_connect_step2(struct connectdata *conn, int sockindex) -{ - struct SessionHandle *data = conn->data; - int err; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - DEBUGASSERT(ssl_connect_2 == connssl->connecting_state - || ssl_connect_2_reading == connssl->connecting_state - || ssl_connect_2_writing == connssl->connecting_state); - - ERR_clear_error(); - - err = SSL_connect(connssl->handle); - - /* 1 is fine - 0 is "not successful but was shut down controlled" - <0 is "handshake was not successful, because a fatal error occurred" */ - if(1 != err) { - int detail = SSL_get_error(connssl->handle, err); - - if(SSL_ERROR_WANT_READ == detail) { - connssl->connecting_state = ssl_connect_2_reading; - return CURLE_OK; - } - else if(SSL_ERROR_WANT_WRITE == detail) { - connssl->connecting_state = ssl_connect_2_writing; - return CURLE_OK; - } - else { - /* untreated error */ - unsigned long errdetail; - char error_buffer[256]=""; /* OpenSSL documents that this must be at - least 256 bytes long. */ - CURLcode result; - long lerr; - int lib; - int reason; - - /* the connection failed, we're not waiting for anything else. */ - connssl->connecting_state = ssl_connect_2; - - /* Get the earliest error code from the thread's error queue and removes - the entry. */ - errdetail = ERR_get_error(); - - /* Extract which lib and reason */ - lib = ERR_GET_LIB(errdetail); - reason = ERR_GET_REASON(errdetail); - - if((lib == ERR_LIB_SSL) && - (reason == SSL_R_CERTIFICATE_VERIFY_FAILED)) { - result = CURLE_SSL_CACERT; - - lerr = SSL_get_verify_result(connssl->handle); - if(lerr != X509_V_OK) { - snprintf(error_buffer, sizeof(error_buffer), - "SSL certificate problem: %s", - X509_verify_cert_error_string(lerr)); - } - else - /* strcpy() is fine here as long as the string fits within - error_buffer */ - strcpy(error_buffer, "SSL certificate verification failed"); - } - else { - result = CURLE_SSL_CONNECT_ERROR; - SSL_strerror(errdetail, error_buffer, sizeof(error_buffer)); - } - - /* detail is already set to the SSL error above */ - - /* If we e.g. use SSLv2 request-method and the server doesn't like us - * (RST connection etc.), OpenSSL gives no explanation whatsoever and - * the SO_ERROR is also lost. - */ - if(CURLE_SSL_CONNECT_ERROR == result && errdetail == 0) { - failf(data, "Unknown SSL protocol error in connection to %s:%ld ", - conn->host.name, conn->remote_port); - return result; - } - - /* Could be a CERT problem */ - failf(data, "%s", error_buffer); - - return result; - } - } - else { - /* we have been connected fine, we're not waiting for anything else. */ - connssl->connecting_state = ssl_connect_3; - - /* Informational message */ - infof(data, "SSL connection using %s / %s\n", - get_ssl_version_txt(connssl->handle), - SSL_get_cipher(connssl->handle)); - -#ifdef HAS_ALPN - /* Sets data and len to negotiated protocol, len is 0 if no protocol was - * negotiated - */ - if(conn->bits.tls_enable_alpn) { - const unsigned char* neg_protocol; - unsigned int len; - SSL_get0_alpn_selected(connssl->handle, &neg_protocol, &len); - if(len != 0) { - infof(data, "ALPN, server accepted to use %.*s\n", len, neg_protocol); - -#ifdef USE_NGHTTP2 - if(len == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, neg_protocol, len)) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(len == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, neg_protocol, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - } - else - infof(data, "ALPN, server did not agree to a protocol\n"); - } -#endif - - return CURLE_OK; - } -} - -static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len) -{ - int i, ilen; - - if((ilen = (int)len) < 0) - return 1; /* buffer too big */ - - i = i2t_ASN1_OBJECT(buf, ilen, a); - - if(i >= ilen) - return 1; /* buffer too small */ - - return 0; -} - -#define push_certinfo(_label, _num) \ -do { \ - long info_len = BIO_get_mem_data(mem, &ptr); \ - Curl_ssl_push_certinfo_len(data, _num, _label, ptr, info_len); \ - if(1!=BIO_reset(mem)) \ - break; \ -} WHILE_FALSE - -static void pubkey_show(struct SessionHandle *data, - BIO *mem, - int num, - const char *type, - const char *name, - BIGNUM *bn) -{ - char *ptr; - char namebuf[32]; - - snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); - - if(bn) - BN_print(mem, bn); - push_certinfo(namebuf, num); -} - -#ifdef HAVE_OPAQUE_RSA_DSA_DH -#define print_pubkey_BN(_type, _name, _num) \ - pubkey_show(data, mem, _num, #_type, #_name, _name) - -#else -#define print_pubkey_BN(_type, _name, _num) \ -do { \ - if(_type->_name) { \ - pubkey_show(data, mem, _num, #_type, #_name, _type->_name); \ - } \ -} WHILE_FALSE -#endif - -static int X509V3_ext(struct SessionHandle *data, - int certnum, - STACK_OF(X509_EXTENSION) *exts) -{ - int i; - size_t j; - - if((int)sk_X509_EXTENSION_num(exts) <= 0) - /* no extensions, bail out */ - return 1; - - for(i=0; i < (int)sk_X509_EXTENSION_num(exts); i++) { - ASN1_OBJECT *obj; - X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); - BUF_MEM *biomem; - char buf[512]; - char *ptr=buf; - char namebuf[128]; - BIO *bio_out = BIO_new(BIO_s_mem()); - - if(!bio_out) - return 1; - - obj = X509_EXTENSION_get_object(ext); - - asn1_object_dump(obj, namebuf, sizeof(namebuf)); - - if(!X509V3_EXT_print(bio_out, ext, 0, 0)) - ASN1_STRING_print(bio_out, (ASN1_STRING *)X509_EXTENSION_get_data(ext)); - - BIO_get_mem_ptr(bio_out, &biomem); - - for(j = 0; j < (size_t)biomem->length; j++) { - const char *sep=""; - if(biomem->data[j] == '\n') { - sep=", "; - j++; /* skip the newline */ - }; - while((j<(size_t)biomem->length) && (biomem->data[j] == ' ')) - j++; - if(j<(size_t)biomem->length) - ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep, - biomem->data[j]); - } - - Curl_ssl_push_certinfo(data, certnum, namebuf, buf); - - BIO_free(bio_out); - - } - return 0; /* all is fine */ -} - -static CURLcode get_cert_chain(struct connectdata *conn, - struct ssl_connect_data *connssl) - -{ - CURLcode result; - STACK_OF(X509) *sk; - int i; - struct SessionHandle *data = conn->data; - int numcerts; - BIO *mem; - - sk = SSL_get_peer_cert_chain(connssl->handle); - if(!sk) { - return CURLE_OUT_OF_MEMORY; - } - - numcerts = sk_X509_num(sk); - - result = Curl_ssl_init_certinfo(data, numcerts); - if(result) { - return result; - } - - mem = BIO_new(BIO_s_mem()); - - for(i = 0; i < numcerts; i++) { - ASN1_INTEGER *num; - X509 *x = sk_X509_value(sk, i); - EVP_PKEY *pubkey=NULL; - int j; - char *ptr; - ASN1_BIT_STRING *psig = NULL; - - X509_NAME_print_ex(mem, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); - push_certinfo("Subject", i); - - X509_NAME_print_ex(mem, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); - push_certinfo("Issuer", i); - - BIO_printf(mem, "%lx", X509_get_version(x)); - push_certinfo("Version", i); - - num = X509_get_serialNumber(x); - if(num->type == V_ASN1_NEG_INTEGER) - BIO_puts(mem, "-"); - for(j = 0; j < num->length; j++) - BIO_printf(mem, "%02x", num->data[j]); - push_certinfo("Serial Number", i); - -#if defined(HAVE_X509_GET0_SIGNATURE) && defined(HAVE_X509_GET0_EXTENSIONS) - { - X509_ALGOR *palg = NULL; - ASN1_STRING *a = ASN1_STRING_new(); - if(a) { - X509_get0_signature(&psig, &palg, x); - X509_signature_print(mem, palg, a); - ASN1_STRING_free(a); - - if(palg) { - i2a_ASN1_OBJECT(mem, palg->algorithm); - push_certinfo("Public Key Algorithm", i); - } - } - X509V3_ext(data, i, X509_get0_extensions(x)); - } -#else - { - /* before OpenSSL 1.0.2 */ - X509_CINF *cinf = x->cert_info; - - i2a_ASN1_OBJECT(mem, cinf->signature->algorithm); - push_certinfo("Signature Algorithm", i); - - i2a_ASN1_OBJECT(mem, cinf->key->algor->algorithm); - push_certinfo("Public Key Algorithm", i); - - X509V3_ext(data, i, cinf->extensions); - - psig = x->signature; - } -#endif - - ASN1_TIME_print(mem, X509_get_notBefore(x)); - push_certinfo("Start date", i); - - ASN1_TIME_print(mem, X509_get_notAfter(x)); - push_certinfo("Expire date", i); - - pubkey = X509_get_pubkey(x); - if(!pubkey) - infof(data, " Unable to load public key\n"); - else { - int pktype; -#ifdef HAVE_OPAQUE_EVP_PKEY - pktype = EVP_PKEY_id(pubkey); -#else - pktype = pubkey->type; -#endif - switch(pktype) { - case EVP_PKEY_RSA: - { - RSA *rsa; -#ifdef HAVE_OPAQUE_EVP_PKEY - rsa = EVP_PKEY_get0_RSA(pubkey); -#else - rsa = pubkey->pkey.rsa; -#endif - -#ifdef HAVE_OPAQUE_RSA_DSA_DH - { - BIGNUM *n; - BIGNUM *e; - BIGNUM *d; - BIGNUM *p; - BIGNUM *q; - BIGNUM *dmp1; - BIGNUM *dmq1; - BIGNUM *iqmp; - - RSA_get0_key(rsa, &n, &e, &d); - RSA_get0_factors(rsa, &p, &q); - RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); - BN_print(mem, n); - push_certinfo("RSA Public Key", i); - print_pubkey_BN(rsa, n, i); - print_pubkey_BN(rsa, e, i); - print_pubkey_BN(rsa, d, i); - print_pubkey_BN(rsa, p, i); - print_pubkey_BN(rsa, q, i); - print_pubkey_BN(rsa, dmp1, i); - print_pubkey_BN(rsa, dmq1, i); - print_pubkey_BN(rsa, iqmp, i); - } -#else - BIO_printf(mem, "%d", BN_num_bits(rsa->n)); - push_certinfo("RSA Public Key", i); - print_pubkey_BN(rsa, n, i); - print_pubkey_BN(rsa, e, i); - print_pubkey_BN(rsa, d, i); - print_pubkey_BN(rsa, p, i); - print_pubkey_BN(rsa, q, i); - print_pubkey_BN(rsa, dmp1, i); - print_pubkey_BN(rsa, dmq1, i); - print_pubkey_BN(rsa, iqmp, i); -#endif - - break; - } - case EVP_PKEY_DSA: - { - DSA *dsa; -#ifdef HAVE_OPAQUE_EVP_PKEY - dsa = EVP_PKEY_get0_DSA(pubkey); -#else - dsa = pubkey->pkey.dsa; -#endif -#ifdef HAVE_OPAQUE_RSA_DSA_DH - { - BIGNUM *p; - BIGNUM *q; - BIGNUM *g; - BIGNUM *priv_key; - BIGNUM *pub_key; - - DSA_get0_pqg(dsa, &p, &q, &g); - DSA_get0_key(dsa, &pub_key, &priv_key); - - print_pubkey_BN(dsa, p, i); - print_pubkey_BN(dsa, q, i); - print_pubkey_BN(dsa, g, i); - print_pubkey_BN(dsa, priv_key, i); - print_pubkey_BN(dsa, pub_key, i); - } -#else - print_pubkey_BN(dsa, p, i); - print_pubkey_BN(dsa, q, i); - print_pubkey_BN(dsa, g, i); - print_pubkey_BN(dsa, priv_key, i); - print_pubkey_BN(dsa, pub_key, i); -#endif - break; - } - case EVP_PKEY_DH: - { - DH *dh; -#ifdef HAVE_OPAQUE_EVP_PKEY - dh = EVP_PKEY_get0_DH(pubkey); -#else - dh = pubkey->pkey.dh; -#endif -#ifdef HAVE_OPAQUE_RSA_DSA_DH - { - BIGNUM *p; - BIGNUM *q; - BIGNUM *g; - BIGNUM *priv_key; - BIGNUM *pub_key; - DH_get0_pqg(dh, &p, &q, &g); - DH_get0_key(dh, &pub_key, &priv_key); - print_pubkey_BN(dh, p, i); - print_pubkey_BN(dh, q, i); - print_pubkey_BN(dh, g, i); - print_pubkey_BN(dh, priv_key, i); - print_pubkey_BN(dh, pub_key, i); - } -#else - print_pubkey_BN(dh, p, i); - print_pubkey_BN(dh, g, i); - print_pubkey_BN(dh, priv_key, i); - print_pubkey_BN(dh, pub_key, i); -#endif - break; - } -#if 0 - case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */ - /* left TODO */ - break; -#endif - } - EVP_PKEY_free(pubkey); - } - - if(psig) { - for(j = 0; j < psig->length; j++) - BIO_printf(mem, "%02x:", psig->data[j]); - push_certinfo("Signature", i); - } - - PEM_write_bio_X509(mem, x); - push_certinfo("Cert", i); - } - - BIO_free(mem); - - return CURLE_OK; -} - -/* - * Heavily modified from: - * https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#OpenSSL - */ -static CURLcode pkp_pin_peer_pubkey(struct SessionHandle *data, X509* cert, - const char *pinnedpubkey) -{ - /* Scratch */ - int len1 = 0, len2 = 0; - unsigned char *buff1 = NULL, *temp = NULL; - - /* Result is returned to caller */ - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; - - /* if a path wasn't specified, don't pin */ - if(!pinnedpubkey) - return CURLE_OK; - - if(!cert) - return result; - - do { - /* Begin Gyrations to get the subjectPublicKeyInfo */ - /* Thanks to Viktor Dukhovni on the OpenSSL mailing list */ - - /* https://groups.google.com/group/mailing.openssl.users/browse_thread - /thread/d61858dae102c6c7 */ - len1 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL); - if(len1 < 1) - break; /* failed */ - - /* https://www.openssl.org/docs/crypto/buffer.html */ - buff1 = temp = OPENSSL_malloc(len1); - if(!buff1) - break; /* failed */ - - /* https://www.openssl.org/docs/crypto/d2i_X509.html */ - len2 = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &temp); - - /* - * These checks are verifying we got back the same values as when we - * sized the buffer. It's pretty weak since they should always be the - * same. But it gives us something to test. - */ - if((len1 != len2) || !temp || ((temp - buff1) != len1)) - break; /* failed */ - - /* End Gyrations */ - - /* The one good exit point */ - result = Curl_pin_peer_pubkey(data, pinnedpubkey, buff1, len1); - } while(0); - - /* https://www.openssl.org/docs/crypto/buffer.html */ - if(buff1) - OPENSSL_free(buff1); - - return result; -} - -/* - * Get the server cert, verify it and show it etc, only call failf() if the - * 'strict' argument is TRUE as otherwise all this is for informational - * purposes only! - * - * We check certificates to authenticate the server; otherwise we risk - * man-in-the-middle attack. - */ -static CURLcode servercert(struct connectdata *conn, - struct ssl_connect_data *connssl, - bool strict) -{ - CURLcode result = CURLE_OK; - int rc; - long lerr, len; - struct SessionHandle *data = conn->data; - X509 *issuer; - FILE *fp; - char *buffer = data->state.buffer; - const char *ptr; - BIO *mem = BIO_new(BIO_s_mem()); - - if(data->set.ssl.certinfo) - /* we've been asked to gather certificate info! */ - (void)get_cert_chain(conn, connssl); - - connssl->server_cert = SSL_get_peer_certificate(connssl->handle); - if(!connssl->server_cert) { - if(!strict) - return CURLE_OK; - - failf(data, "SSL: couldn't get peer certificate!"); - return CURLE_PEER_FAILED_VERIFICATION; - } - - infof(data, "Server certificate:\n"); - - rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert), - buffer, BUFSIZE); - infof(data, " subject: %s\n", rc?"[NONE]":buffer); - - ASN1_TIME_print(mem, X509_get_notBefore(connssl->server_cert)); - len = BIO_get_mem_data(mem, (char **) &ptr); - infof(data, " start date: %.*s\n", len, ptr); - rc = BIO_reset(mem); - - ASN1_TIME_print(mem, X509_get_notAfter(connssl->server_cert)); - len = BIO_get_mem_data(mem, (char **) &ptr); - infof(data, " expire date: %.*s\n", len, ptr); - rc = BIO_reset(mem); - - BIO_free(mem); - - if(data->set.ssl.verifyhost) { - result = verifyhost(conn, connssl->server_cert); - if(result) { - X509_free(connssl->server_cert); - connssl->server_cert = NULL; - return result; - } - } - - rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert), - buffer, BUFSIZE); - if(rc) { - if(strict) - failf(data, "SSL: couldn't get X509-issuer name!"); - result = CURLE_SSL_CONNECT_ERROR; - } - else { - infof(data, " issuer: %s\n", buffer); - - /* We could do all sorts of certificate verification stuff here before - deallocating the certificate. */ - - /* e.g. match issuer name with provided issuer certificate */ - if(data->set.str[STRING_SSL_ISSUERCERT]) { - fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT); - if(!fp) { - if(strict) - failf(data, "SSL: Unable to open issuer cert (%s)", - data->set.str[STRING_SSL_ISSUERCERT]); - X509_free(connssl->server_cert); - connssl->server_cert = NULL; - return CURLE_SSL_ISSUER_ERROR; - } - - issuer = PEM_read_X509(fp, NULL, ZERO_NULL, NULL); - if(!issuer) { - if(strict) - failf(data, "SSL: Unable to read issuer cert (%s)", - data->set.str[STRING_SSL_ISSUERCERT]); - X509_free(connssl->server_cert); - X509_free(issuer); - fclose(fp); - return CURLE_SSL_ISSUER_ERROR; - } - - fclose(fp); - - if(X509_check_issued(issuer, connssl->server_cert) != X509_V_OK) { - if(strict) - failf(data, "SSL: Certificate issuer check failed (%s)", - data->set.str[STRING_SSL_ISSUERCERT]); - X509_free(connssl->server_cert); - X509_free(issuer); - connssl->server_cert = NULL; - return CURLE_SSL_ISSUER_ERROR; - } - - infof(data, " SSL certificate issuer check ok (%s)\n", - data->set.str[STRING_SSL_ISSUERCERT]); - X509_free(issuer); - } - - lerr = data->set.ssl.certverifyresult = - SSL_get_verify_result(connssl->handle); - - if(data->set.ssl.certverifyresult != X509_V_OK) { - if(data->set.ssl.verifypeer) { - /* We probably never reach this, because SSL_connect() will fail - and we return earlier if verifypeer is set? */ - if(strict) - failf(data, "SSL certificate verify result: %s (%ld)", - X509_verify_cert_error_string(lerr), lerr); - result = CURLE_PEER_FAILED_VERIFICATION; - } - else - infof(data, " SSL certificate verify result: %s (%ld)," - " continuing anyway.\n", - X509_verify_cert_error_string(lerr), lerr); - } - else - infof(data, " SSL certificate verify ok.\n"); - } - -#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ - !defined(OPENSSL_NO_OCSP) - if(data->set.ssl.verifystatus) { - result = verifystatus(conn, connssl); - if(result) { - X509_free(connssl->server_cert); - connssl->server_cert = NULL; - return result; - } - } -#endif - - if(!strict) - /* when not strict, we don't bother about the verify cert problems */ - result = CURLE_OK; - - ptr = data->set.str[STRING_SSL_PINNEDPUBLICKEY]; - if(!result && ptr) { - result = pkp_pin_peer_pubkey(data, connssl->server_cert, ptr); - if(result) - failf(data, "SSL: public key does not match pinned public key!"); - } - - X509_free(connssl->server_cert); - connssl->server_cert = NULL; - connssl->connecting_state = ssl_connect_done; - - return result; -} - -static CURLcode ossl_connect_step3(struct connectdata *conn, int sockindex) -{ - CURLcode result = CURLE_OK; - void *old_ssl_sessionid = NULL; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - bool incache; - SSL_SESSION *our_ssl_sessionid; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - our_ssl_sessionid = SSL_get1_session(connssl->handle); - - /* SSL_get1_session() will increment the reference count and the session - will stay in memory until explicitly freed with SSL_SESSION_free(3), - regardless of its state. */ - - incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)); - if(incache) { - if(old_ssl_sessionid != our_ssl_sessionid) { - infof(data, "old SSL session ID is stale, removing\n"); - Curl_ssl_delsessionid(conn, old_ssl_sessionid); - incache = FALSE; - } - } - - if(!incache) { - result = Curl_ssl_addsessionid(conn, our_ssl_sessionid, - 0 /* unknown size */); - if(result) { - failf(data, "failed to store ssl session"); - return result; - } - } - else { - /* Session was incache, so refcount already incremented earlier. - * Avoid further increments with each SSL_get1_session() call. - * This does not free the session as refcount remains > 0 - */ - SSL_SESSION_free(our_ssl_sessionid); - } - - /* - * We check certificates to authenticate the server; otherwise we risk - * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to - * verify the peer ignore faults and failures from the server cert - * operations. - */ - - result = servercert(conn, connssl, - (data->set.ssl.verifypeer || data->set.ssl.verifyhost)); - - if(!result) - connssl->connecting_state = ssl_connect_done; - - return result; -} - -static Curl_recv ossl_recv; -static Curl_send ossl_send; - -static CURLcode ossl_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - long timeout_ms; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1 == connssl->connecting_state) { - /* Find out how much more time we're allowed */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - result = ossl_connect_step1(conn, sockindex); - if(result) - return result; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading || - connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if this - * connection is done nonblocking and this loop would execute again. This - * permits the owner of a multi handle to abort a connection attempt - * before step2 has completed while ensuring that a client using select() - * or epoll() will always have a valid fdset to wait on. - */ - result = ossl_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - - } /* repeat step2 until all transactions are done. */ - - if(ssl_connect_3 == connssl->connecting_state) { - result = ossl_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = ossl_recv; - conn->send[sockindex] = ossl_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done) -{ - return ossl_connect_common(conn, sockindex, TRUE, done); -} - -CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = ossl_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -bool Curl_ossl_data_pending(const struct connectdata *conn, int connindex) -{ - if(conn->ssl[connindex].handle) - /* SSL is in use */ - return (0 != SSL_pending(conn->ssl[connindex].handle)) ? TRUE : FALSE; - else - return FALSE; -} - -static ssize_t ossl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - /* SSL_write() is said to return 'int' while write() and send() returns - 'size_t' */ - int err; - char error_buffer[120]; /* OpenSSL documents that this must be at least 120 - bytes long. */ - unsigned long sslerror; - int memlen; - int rc; - - ERR_clear_error(); - - memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; - rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen); - - if(rc <= 0) { - err = SSL_get_error(conn->ssl[sockindex].handle, rc); - - switch(err) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* The operation did not complete; the same TLS/SSL I/O function - should be called again later. This is basically an EWOULDBLOCK - equivalent. */ - *curlcode = CURLE_AGAIN; - return -1; - case SSL_ERROR_SYSCALL: - failf(conn->data, "SSL_write() returned SYSCALL, errno = %d", - SOCKERRNO); - *curlcode = CURLE_SEND_ERROR; - return -1; - case SSL_ERROR_SSL: - /* A failure in the SSL library occurred, usually a protocol error. - The OpenSSL error queue contains more information on the error. */ - sslerror = ERR_get_error(); - failf(conn->data, "SSL_write() error: %s", - ERR_error_string(sslerror, error_buffer)); - *curlcode = CURLE_SEND_ERROR; - return -1; - } - /* a true error */ - failf(conn->data, "SSL_write() return error %d", err); - *curlcode = CURLE_SEND_ERROR; - return -1; - } - *curlcode = CURLE_OK; - return (ssize_t)rc; /* number of bytes */ -} - -static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ - int num, /* socketindex */ - char *buf, /* store read data here */ - size_t buffersize, /* max amount to read */ - CURLcode *curlcode) -{ - char error_buffer[120]; /* OpenSSL documents that this must be at - least 120 bytes long. */ - unsigned long sslerror; - ssize_t nread; - int buffsize; - - ERR_clear_error(); - - buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; - nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize); - if(nread <= 0) { - /* failed SSL_read */ - int err = SSL_get_error(conn->ssl[num].handle, (int)nread); - - switch(err) { - case SSL_ERROR_NONE: /* this is not an error */ - case SSL_ERROR_ZERO_RETURN: /* no more data */ - break; - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - /* there's data pending, re-invoke SSL_read() */ - *curlcode = CURLE_AGAIN; - return -1; - default: - /* openssl/ssl.h for SSL_ERROR_SYSCALL says "look at error stack/return - value/errno" */ - /* https://www.openssl.org/docs/crypto/ERR_get_error.html */ - sslerror = ERR_get_error(); - if((nread < 0) || sslerror) { - /* If the return code was negative or there actually is an error in the - queue */ - failf(conn->data, "SSL read: %s, errno %d", - ERR_error_string(sslerror, error_buffer), - SOCKERRNO); - *curlcode = CURLE_RECV_ERROR; - return -1; - } - } - } - return nread; -} - -size_t Curl_ossl_version(char *buffer, size_t size) -{ -#ifdef OPENSSL_IS_BORINGSSL - return snprintf(buffer, size, OSSL_PACKAGE); -#else /* OPENSSL_IS_BORINGSSL */ - char sub[3]; - unsigned long ssleay_value; - sub[2]='\0'; - sub[1]='\0'; - ssleay_value=SSLeay(); - if(ssleay_value < 0x906000) { - ssleay_value=SSLEAY_VERSION_NUMBER; - sub[0]='\0'; - } - else { - if(ssleay_value&0xff0) { - int minor_ver = (ssleay_value >> 4) & 0xff; - if(minor_ver > 26) { - /* handle extended version introduced for 0.9.8za */ - sub[1] = (char) ((minor_ver - 1) % 26 + 'a' + 1); - sub[0] = 'z'; - } - else { - sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1); - } - } - else - sub[0]='\0'; - } - - return snprintf(buffer, size, "%s/%lx.%lx.%lx%s", - OSSL_PACKAGE, - (ssleay_value>>28)&0xf, - (ssleay_value>>20)&0xff, - (ssleay_value>>12)&0xff, - sub); -#endif /* OPENSSL_IS_BORINGSSL */ -} - -/* can be called with data == NULL */ -int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy, - size_t length) -{ - if(data) { - Curl_ossl_seed(data); /* Initiate the seed if not already done */ - } - RAND_bytes(entropy, curlx_uztosi(length)); - return 0; /* 0 as in no problem */ -} - -void Curl_ossl_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum /* output */, - size_t unused) -{ - MD5_CTX MD5pw; - (void)unused; - MD5_Init(&MD5pw); - MD5_Update(&MD5pw, tmp, tmplen); - MD5_Final(md5sum, &MD5pw); -} - -#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) -void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum /* output */, - size_t unused) -{ - SHA256_CTX SHA256pw; - (void)unused; - SHA256_Init(&SHA256pw); - SHA256_Update(&SHA256pw, tmp, tmplen); - SHA256_Final(sha256sum, &SHA256pw); -} -#endif - -bool Curl_ossl_cert_status_request(void) -{ -#if (OPENSSL_VERSION_NUMBER >= 0x0090808fL) && !defined(OPENSSL_NO_TLSEXT) && \ - !defined(OPENSSL_NO_OCSP) - return TRUE; -#else - return FALSE; -#endif -} -#endif /* USE_OPENSSL */ diff --git a/Externals/curl/lib/vtls/openssl.h b/Externals/curl/lib/vtls/openssl.h deleted file mode 100644 index 74f128ed10..0000000000 --- a/Externals/curl/lib/vtls/openssl.h +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef HEADER_CURL_SSLUSE_H -#define HEADER_CURL_SSLUSE_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#ifdef USE_OPENSSL -/* - * This header should only be needed to get included by vtls.c and openssl.c - */ - -#include "urldata.h" - -CURLcode Curl_ossl_connect(struct connectdata *conn, int sockindex); -CURLcode Curl_ossl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); - -/* close a SSL connection */ -void Curl_ossl_close(struct connectdata *conn, int sockindex); - -/* tell OpenSSL to close down all open information regarding connections (and - thus session ID caching etc) */ -void Curl_ossl_close_all(struct SessionHandle *data); - -/* Sets an OpenSSL engine */ -CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine); - -/* function provided for the generic SSL-layer, called when a session id - should be freed */ -void Curl_ossl_session_free(void *ptr); - -/* Sets engine as default for all SSL operations */ -CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data); - -/* Build list of OpenSSL engines */ -struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data); - -int Curl_ossl_init(void); -void Curl_ossl_cleanup(void); - -size_t Curl_ossl_version(char *buffer, size_t size); -int Curl_ossl_check_cxn(struct connectdata *cxn); -int Curl_ossl_shutdown(struct connectdata *conn, int sockindex); -bool Curl_ossl_data_pending(const struct connectdata *conn, - int connindex); - -/* return 0 if a find random is filled in */ -int Curl_ossl_random(struct SessionHandle *data, unsigned char *entropy, - size_t length); -void Curl_ossl_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum /* output */, - size_t unused); -void Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *sha256sum /* output */, - size_t unused); - -bool Curl_ossl_cert_status_request(void); - -/* Set the API backend definition to OpenSSL */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_OPENSSL - -/* this backend supports the CAPATH option */ -#define have_curlssl_ca_path 1 - -/* this backend supports CURLOPT_CERTINFO */ -#define have_curlssl_certinfo 1 - -/* this backend supports CURLOPT_SSL_CTX_* */ -#define have_curlssl_ssl_ctx 1 - -/* this backend supports CURLOPT_PINNEDPUBLICKEY */ -#define have_curlssl_pinnedpubkey 1 - -/* API setup for OpenSSL */ -#define curlssl_init Curl_ossl_init -#define curlssl_cleanup Curl_ossl_cleanup -#define curlssl_connect Curl_ossl_connect -#define curlssl_connect_nonblocking Curl_ossl_connect_nonblocking -#define curlssl_session_free(x) Curl_ossl_session_free(x) -#define curlssl_close_all Curl_ossl_close_all -#define curlssl_close Curl_ossl_close -#define curlssl_shutdown(x,y) Curl_ossl_shutdown(x,y) -#define curlssl_set_engine(x,y) Curl_ossl_set_engine(x,y) -#define curlssl_set_engine_default(x) Curl_ossl_set_engine_default(x) -#define curlssl_engines_list(x) Curl_ossl_engines_list(x) -#define curlssl_version Curl_ossl_version -#define curlssl_check_cxn Curl_ossl_check_cxn -#define curlssl_data_pending(x,y) Curl_ossl_data_pending(x,y) -#define curlssl_random(x,y,z) Curl_ossl_random(x,y,z) -#define curlssl_md5sum(a,b,c,d) Curl_ossl_md5sum(a,b,c,d) -#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && !defined(OPENSSL_NO_SHA256) -#define curlssl_sha256sum(a,b,c,d) Curl_ossl_sha256sum(a,b,c,d) -#endif -#define curlssl_cert_status_request() Curl_ossl_cert_status_request() - -#define DEFAULT_CIPHER_SELECTION \ - "ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH" - -#endif /* USE_OPENSSL */ -#endif /* HEADER_CURL_SSLUSE_H */ diff --git a/Externals/curl/lib/vtls/polarssl.c b/Externals/curl/lib/vtls/polarssl.c deleted file mode 100644 index 0e8b0f500d..0000000000 --- a/Externals/curl/lib/vtls/polarssl.c +++ /dev/null @@ -1,814 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * Copyright (C) 2010 - 2011, Hoi-Ho Chan, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all PolarSSL-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ - -#include "curl_setup.h" - -#ifdef USE_POLARSSL - -#include -#include -#include -#include -#include -#include - -#if POLARSSL_VERSION_NUMBER < 0x01030000 -#error too old PolarSSL -#endif - -#include -#include -#include - -#include "urldata.h" -#include "sendf.h" -#include "inet_pton.h" -#include "polarssl.h" -#include "vtls.h" -#include "parsedate.h" -#include "connect.h" /* for the connect timeout */ -#include "select.h" -#include "rawstr.h" -#include "polarssl_threadlock.h" -#include "curl_printf.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* See https://tls.mbed.org/discussions/generic/ - howto-determine-exact-buffer-len-for-mbedtls_pk_write_pubkey_der -*/ -#define RSA_PUB_DER_MAX_BYTES (38 + 2 * POLARSSL_MPI_MAX_SIZE) -#define ECP_PUB_DER_MAX_BYTES (30 + 2 * POLARSSL_ECP_MAX_BYTES) - -#define PUB_DER_MAX_BYTES (RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ - RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES) - -/* apply threading? */ -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) -#define THREADING_SUPPORT -#endif - -#if defined(THREADING_SUPPORT) -static entropy_context entropy; - -static int entropy_init_initialized = 0; - -/* start of entropy_init_mutex() */ -static void entropy_init_mutex(entropy_context *ctx) -{ - /* lock 0 = entropy_init_mutex() */ - Curl_polarsslthreadlock_lock_function(0); - if(entropy_init_initialized == 0) { - entropy_init(ctx); - entropy_init_initialized = 1; - } - Curl_polarsslthreadlock_unlock_function(0); -} -/* end of entropy_init_mutex() */ - -/* start of entropy_func_mutex() */ -static int entropy_func_mutex(void *data, unsigned char *output, size_t len) -{ - int ret; - /* lock 1 = entropy_func_mutex() */ - Curl_polarsslthreadlock_lock_function(1); - ret = entropy_func(data, output, len); - Curl_polarsslthreadlock_unlock_function(1); - - return ret; -} -/* end of entropy_func_mutex() */ - -#endif /* THREADING_SUPPORT */ - -/* Define this to enable lots of debugging for PolarSSL */ -#undef POLARSSL_DEBUG - -#ifdef POLARSSL_DEBUG -static void polarssl_debug(void *context, int level, const char *line) -{ - struct SessionHandle *data = NULL; - - if(!context) - return; - - data = (struct SessionHandle *)context; - - infof(data, "%s", line); - (void) level; -} -#else -#endif - -/* ALPN for http2? */ -#ifdef POLARSSL_SSL_ALPN -# define HAS_ALPN -#endif - -static Curl_recv polarssl_recv; -static Curl_send polarssl_send; - - -static CURLcode -polarssl_connect_step1(struct connectdata *conn, - int sockindex) -{ - struct SessionHandle *data = conn->data; - struct ssl_connect_data* connssl = &conn->ssl[sockindex]; - - bool sni = TRUE; /* default is SNI enabled */ - int ret = -1; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - void *old_session = NULL; - char errorbuf[128]; - errorbuf[0]=0; - - /* PolarSSL only supports SSLv3 and TLSv1 */ - if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { - failf(data, "PolarSSL does not support SSLv2"); - return CURLE_SSL_CONNECT_ERROR; - } - else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3) - sni = FALSE; /* SSLv3 has no SNI */ - -#ifdef THREADING_SUPPORT - entropy_init_mutex(&entropy); - - if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func_mutex, &entropy, - NULL, 0)) != 0) { -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", - -ret, errorbuf); - } -#else - entropy_init(&connssl->entropy); - - if((ret = ctr_drbg_init(&connssl->ctr_drbg, entropy_func, &connssl->entropy, - NULL, 0)) != 0) { -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "Failed - PolarSSL: ctr_drbg_init returned (-0x%04X) %s\n", - -ret, errorbuf); - } -#endif /* THREADING_SUPPORT */ - - /* Load the trusted CA */ - memset(&connssl->cacert, 0, sizeof(x509_crt)); - - if(data->set.str[STRING_SSL_CAFILE]) { - ret = x509_crt_parse_file(&connssl->cacert, - data->set.str[STRING_SSL_CAFILE]); - - if(ret<0) { -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "Error reading ca cert file %s - PolarSSL: (-0x%04X) %s", - data->set.str[STRING_SSL_CAFILE], -ret, errorbuf); - - if(data->set.ssl.verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } - } - - if(data->set.str[STRING_SSL_CAPATH]) { - ret = x509_crt_parse_path(&connssl->cacert, - data->set.str[STRING_SSL_CAPATH]); - - if(ret<0) { -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "Error reading ca cert path %s - PolarSSL: (-0x%04X) %s", - data->set.str[STRING_SSL_CAPATH], -ret, errorbuf); - - if(data->set.ssl.verifypeer) - return CURLE_SSL_CACERT_BADFILE; - } - } - - /* Load the client certificate */ - memset(&connssl->clicert, 0, sizeof(x509_crt)); - - if(data->set.str[STRING_CERT]) { - ret = x509_crt_parse_file(&connssl->clicert, - data->set.str[STRING_CERT]); - - if(ret) { -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "Error reading client cert file %s - PolarSSL: (-0x%04X) %s", - data->set.str[STRING_CERT], -ret, errorbuf); - - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Load the client private key */ - if(data->set.str[STRING_KEY]) { - pk_context pk; - pk_init(&pk); - ret = pk_parse_keyfile(&pk, data->set.str[STRING_KEY], - data->set.str[STRING_KEY_PASSWD]); - if(ret == 0 && !pk_can_do(&pk, POLARSSL_PK_RSA)) - ret = POLARSSL_ERR_PK_TYPE_MISMATCH; - if(ret == 0) - rsa_copy(&connssl->rsa, pk_rsa(pk)); - else - rsa_free(&connssl->rsa); - pk_free(&pk); - - if(ret) { -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "Error reading private key %s - PolarSSL: (-0x%04X) %s", - data->set.str[STRING_KEY], -ret, errorbuf); - - return CURLE_SSL_CERTPROBLEM; - } - } - - /* Load the CRL */ - memset(&connssl->crl, 0, sizeof(x509_crl)); - - if(data->set.str[STRING_SSL_CRLFILE]) { - ret = x509_crl_parse_file(&connssl->crl, - data->set.str[STRING_SSL_CRLFILE]); - - if(ret) { -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "Error reading CRL file %s - PolarSSL: (-0x%04X) %s", - data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf); - - return CURLE_SSL_CRL_BADFILE; - } - } - - infof(data, "PolarSSL: Connecting to %s:%d\n", - conn->host.name, conn->remote_port); - - if(ssl_init(&connssl->ssl)) { - failf(data, "PolarSSL: ssl_init failed"); - return CURLE_SSL_CONNECT_ERROR; - } - - switch(data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_1); - break; - case CURL_SSLVERSION_SSLv3: - ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_0); - ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_0); - infof(data, "PolarSSL: Forced min. SSL Version to be SSLv3\n"); - break; - case CURL_SSLVERSION_TLSv1_0: - ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_1); - ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_1); - infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.0\n"); - break; - case CURL_SSLVERSION_TLSv1_1: - ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_2); - ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_2); - infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.1\n"); - break; - case CURL_SSLVERSION_TLSv1_2: - ssl_set_min_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_3); - ssl_set_max_version(&connssl->ssl, SSL_MAJOR_VERSION_3, - SSL_MINOR_VERSION_3); - infof(data, "PolarSSL: Forced min. SSL Version to be TLS 1.2\n"); - break; - } - - ssl_set_endpoint(&connssl->ssl, SSL_IS_CLIENT); - ssl_set_authmode(&connssl->ssl, SSL_VERIFY_OPTIONAL); - - ssl_set_rng(&connssl->ssl, ctr_drbg_random, - &connssl->ctr_drbg); - ssl_set_bio(&connssl->ssl, - net_recv, &conn->sock[sockindex], - net_send, &conn->sock[sockindex]); - - ssl_set_ciphersuites(&connssl->ssl, ssl_list_ciphersuites()); - if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) { - ret = ssl_set_session(&connssl->ssl, old_session); - if(ret) { - failf(data, "ssl_set_session returned -0x%x", -ret); - return CURLE_SSL_CONNECT_ERROR; - } - infof(data, "PolarSSL re-using session\n"); - } - - ssl_set_ca_chain(&connssl->ssl, - &connssl->cacert, - &connssl->crl, - conn->host.name); - - ssl_set_own_cert_rsa(&connssl->ssl, - &connssl->clicert, &connssl->rsa); - - if(ssl_set_hostname(&connssl->ssl, conn->host.name)) { - /* ssl_set_hostname() sets the name to use in CN/SAN checks *and* the name - to set in the SNI extension. So even if curl connects to a host - specified as an IP address, this function must be used. */ - failf(data, "couldn't set hostname in PolarSSL"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - static const char* protocols[3]; - int cur = 0; - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - protocols[cur++] = NGHTTP2_PROTO_VERSION_ID; - infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - protocols[cur++] = ALPN_HTTP_1_1; - infof(data, "ALPN, offering %s\n", ALPN_HTTP_1_1); - - protocols[cur] = NULL; - - ssl_set_alpn_protocols(&connssl->ssl, protocols); - } -#endif - -#ifdef POLARSSL_DEBUG - ssl_set_dbg(&connssl->ssl, polarssl_debug, data); -#endif - - connssl->connecting_state = ssl_connect_2; - - return CURLE_OK; -} - -static CURLcode -polarssl_connect_step2(struct connectdata *conn, - int sockindex) -{ - int ret; - struct SessionHandle *data = conn->data; - struct ssl_connect_data* connssl = &conn->ssl[sockindex]; - char buffer[1024]; - - char errorbuf[128]; - errorbuf[0] = 0; - - conn->recv[sockindex] = polarssl_recv; - conn->send[sockindex] = polarssl_send; - - ret = ssl_handshake(&connssl->ssl); - - switch(ret) { - case 0: - break; - - case POLARSSL_ERR_NET_WANT_READ: - connssl->connecting_state = ssl_connect_2_reading; - return CURLE_OK; - - case POLARSSL_ERR_NET_WANT_WRITE: - connssl->connecting_state = ssl_connect_2_writing; - return CURLE_OK; - - default: -#ifdef POLARSSL_ERROR_C - error_strerror(ret, errorbuf, sizeof(errorbuf)); -#endif /* POLARSSL_ERROR_C */ - failf(data, "ssl_handshake returned - PolarSSL: (-0x%04X) %s", - -ret, errorbuf); - return CURLE_SSL_CONNECT_ERROR; - } - - infof(data, "PolarSSL: Handshake complete, cipher is %s\n", - ssl_get_ciphersuite(&conn->ssl[sockindex].ssl) ); - - ret = ssl_get_verify_result(&conn->ssl[sockindex].ssl); - - if(ret && data->set.ssl.verifypeer) { - if(ret & BADCERT_EXPIRED) - failf(data, "Cert verify failed: BADCERT_EXPIRED"); - - if(ret & BADCERT_REVOKED) { - failf(data, "Cert verify failed: BADCERT_REVOKED"); - return CURLE_SSL_CACERT; - } - - if(ret & BADCERT_CN_MISMATCH) - failf(data, "Cert verify failed: BADCERT_CN_MISMATCH"); - - if(ret & BADCERT_NOT_TRUSTED) - failf(data, "Cert verify failed: BADCERT_NOT_TRUSTED"); - - return CURLE_PEER_FAILED_VERIFICATION; - } - - if(ssl_get_peer_cert(&(connssl->ssl))) { - /* If the session was resumed, there will be no peer certs */ - memset(buffer, 0, sizeof(buffer)); - - if(x509_crt_info(buffer, sizeof(buffer), (char *)"* ", - ssl_get_peer_cert(&(connssl->ssl))) != -1) - infof(data, "Dumping cert info:\n%s\n", buffer); - } - - /* adapted from mbedtls.c */ - if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) { - int size; - CURLcode result; - x509_crt *p; - unsigned char pubkey[PUB_DER_MAX_BYTES]; - const x509_crt *peercert; - - peercert = ssl_get_peer_cert(&connssl->ssl); - - if(!peercert || !peercert->raw.p || !peercert->raw.len) { - failf(data, "Failed due to missing peer certificate"); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - p = calloc(1, sizeof(*p)); - - if(!p) - return CURLE_OUT_OF_MEMORY; - - x509_crt_init(p); - - /* Make a copy of our const peercert because pk_write_pubkey_der - needs a non-const key, for now. - https://github.com/ARMmbed/mbedtls/issues/396 */ - if(x509_crt_parse_der(p, peercert->raw.p, peercert->raw.len)) { - failf(data, "Failed copying peer certificate"); - x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - size = pk_write_pubkey_der(&p->pk, pubkey, PUB_DER_MAX_BYTES); - - if(size <= 0) { - failf(data, "Failed copying public key from peer certificate"); - x509_crt_free(p); - free(p); - return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - } - - /* pk_write_pubkey_der writes data at the end of the buffer. */ - result = Curl_pin_peer_pubkey(data, - data->set.str[STRING_SSL_PINNEDPUBLICKEY], - &pubkey[PUB_DER_MAX_BYTES - size], size); - if(result) { - x509_crt_free(p); - free(p); - return result; - } - - x509_crt_free(p); - free(p); - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - const char *next_protocol = ssl_get_alpn_protocol(&connssl->ssl); - - if(next_protocol != NULL) { - infof(data, "ALPN, server accepted to use %s\n", next_protocol); - -#ifdef USE_NGHTTP2 - if(!strncmp(next_protocol, NGHTTP2_PROTO_VERSION_ID, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(!strncmp(next_protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - } - else - infof(data, "ALPN, server did not agree to a protocol\n"); - } -#endif - - connssl->connecting_state = ssl_connect_3; - infof(data, "SSL connected\n"); - - return CURLE_OK; -} - -static CURLcode -polarssl_connect_step3(struct connectdata *conn, - int sockindex) -{ - CURLcode retcode = CURLE_OK; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct SessionHandle *data = conn->data; - void *old_ssl_sessionid = NULL; - ssl_session *our_ssl_sessionid; - int ret; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - our_ssl_sessionid = malloc(sizeof(ssl_session)); - if(!our_ssl_sessionid) - return CURLE_OUT_OF_MEMORY; - - ssl_session_init(our_ssl_sessionid); - - ret = ssl_get_session(&connssl->ssl, our_ssl_sessionid); - if(ret) { - failf(data, "ssl_get_session returned -0x%x", -ret); - return CURLE_SSL_CONNECT_ERROR; - } - - /* If there's already a matching session in the cache, delete it */ - if(!Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)) - Curl_ssl_delsessionid(conn, old_ssl_sessionid); - - retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 0); - if(retcode) { - free(our_ssl_sessionid); - failf(data, "failed to store ssl session"); - return retcode; - } - - connssl->connecting_state = ssl_connect_done; - - return CURLE_OK; -} - -static ssize_t polarssl_send(struct connectdata *conn, - int sockindex, - const void *mem, - size_t len, - CURLcode *curlcode) -{ - int ret = -1; - - ret = ssl_write(&conn->ssl[sockindex].ssl, - (unsigned char *)mem, len); - - if(ret < 0) { - *curlcode = (ret == POLARSSL_ERR_NET_WANT_WRITE) ? - CURLE_AGAIN : CURLE_SEND_ERROR; - ret = -1; - } - - return ret; -} - -void Curl_polarssl_close(struct connectdata *conn, int sockindex) -{ - rsa_free(&conn->ssl[sockindex].rsa); - x509_crt_free(&conn->ssl[sockindex].clicert); - x509_crt_free(&conn->ssl[sockindex].cacert); - x509_crl_free(&conn->ssl[sockindex].crl); - ssl_free(&conn->ssl[sockindex].ssl); -} - -static ssize_t polarssl_recv(struct connectdata *conn, - int num, - char *buf, - size_t buffersize, - CURLcode *curlcode) -{ - int ret = -1; - ssize_t len = -1; - - memset(buf, 0, buffersize); - ret = ssl_read(&conn->ssl[num].ssl, (unsigned char *)buf, buffersize); - - if(ret <= 0) { - if(ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY) - return 0; - - *curlcode = (ret == POLARSSL_ERR_NET_WANT_READ) ? - CURLE_AGAIN : CURLE_RECV_ERROR; - return -1; - } - - len = ret; - - return len; -} - -void Curl_polarssl_session_free(void *ptr) -{ - ssl_session_free(ptr); - free(ptr); -} - -/* 1.3.10 was the first rebranded version. All new releases (in 1.3 branch and - higher) will be mbed TLS branded.. */ - -size_t Curl_polarssl_version(char *buffer, size_t size) -{ - unsigned int version = version_get_number(); - return snprintf(buffer, size, "%s/%d.%d.%d", - version >= 0x01030A00?"mbedTLS":"PolarSSL", - version>>24, (version>>16)&0xff, (version>>8)&0xff); -} - -static CURLcode -polarssl_connect_common(struct connectdata *conn, - int sockindex, - bool nonblocking, - bool *done) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - long timeout_ms; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1 == connssl->connecting_state) { - /* Find out how much more time we're allowed */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - result = polarssl_connect_step1(conn, sockindex); - if(result) - return result; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check allowed time left */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading || - connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading== - connssl->connecting_state?sockfd:CURL_SOCKET_BAD; - - what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if - * this connection is part of a multi handle and this loop would - * execute again. This permits the owner of a multi handle to - * abort a connection attempt before step2 has completed while - * ensuring that a client using select() or epoll() will always - * have a valid fdset to wait on. - */ - result = polarssl_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - - } /* repeat step2 until all transactions are done. */ - - if(ssl_connect_3 == connssl->connecting_state) { - result = polarssl_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = polarssl_recv; - conn->send[sockindex] = polarssl_send; - *done = TRUE; - } - else - *done = FALSE; - - /* Reset our connect state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -CURLcode -Curl_polarssl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done) -{ - return polarssl_connect_common(conn, sockindex, TRUE, done); -} - - -CURLcode -Curl_polarssl_connect(struct connectdata *conn, - int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = polarssl_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -/* - * return 0 error initializing SSL - * return 1 SSL initialized successfully - */ -int Curl_polarssl_init(void) -{ - return Curl_polarsslthreadlock_thread_setup(); -} - -void Curl_polarssl_cleanup(void) -{ - (void)Curl_polarsslthreadlock_thread_cleanup(); -} - -#endif /* USE_POLARSSL */ diff --git a/Externals/curl/lib/vtls/polarssl.h b/Externals/curl/lib/vtls/polarssl.h deleted file mode 100644 index 7098b24a42..0000000000 --- a/Externals/curl/lib/vtls/polarssl.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef HEADER_CURL_POLARSSL_H -#define HEADER_CURL_POLARSSL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * Copyright (C) 2010, Hoi-Ho Chan, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_POLARSSL - -#include - -/* Called on first use PolarSSL, setup threading if supported */ -int Curl_polarssl_init(void); -void Curl_polarssl_cleanup(void); - - -CURLcode Curl_polarssl_connect(struct connectdata *conn, int sockindex); - -CURLcode Curl_polarssl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); - - /* close a SSL connection */ -void Curl_polarssl_close(struct connectdata *conn, int sockindex); - -void Curl_polarssl_session_free(void *ptr); -size_t Curl_polarssl_version(char *buffer, size_t size); -int Curl_polarssl_shutdown(struct connectdata *conn, int sockindex); - -/* Set the API backend definition to PolarSSL */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_POLARSSL - -/* this backend supports the CAPATH option */ -#define have_curlssl_ca_path 1 - -/* this backends supports CURLOPT_PINNEDPUBLICKEY */ -#define have_curlssl_pinnedpubkey 1 - -/* API setup for PolarSSL */ -#define curlssl_init() Curl_polarssl_init() -#define curlssl_cleanup() Curl_polarssl_cleanup() -#define curlssl_connect Curl_polarssl_connect -#define curlssl_connect_nonblocking Curl_polarssl_connect_nonblocking -#define curlssl_session_free(x) Curl_polarssl_session_free(x) -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_polarssl_close -#define curlssl_shutdown(x,y) 0 -#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) -#define curlssl_version Curl_polarssl_version -#define curlssl_check_cxn(x) ((void)x, -1) -#define curlssl_data_pending(x,y) ((void)x, (void)y, 0) -#define curlssl_sha256sum(a,b,c,d) sha256(a,b,c,0) - -/* This might cause libcurl to use a weeker random! - TODO: implement proper use of Polarssl's CTR-DRBG or HMAC-DRBG and use that -*/ -#define curlssl_random(x,y,z) ((void)x, (void)y, (void)z, CURLE_NOT_BUILT_IN) - -#endif /* USE_POLARSSL */ -#endif /* HEADER_CURL_POLARSSL_H */ diff --git a/Externals/curl/lib/vtls/polarssl_threadlock.c b/Externals/curl/lib/vtls/polarssl_threadlock.c deleted file mode 100644 index 3b0ebf8866..0000000000 --- a/Externals/curl/lib/vtls/polarssl_threadlock.c +++ /dev/null @@ -1,153 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2013-2015, Daniel Stenberg, , et al. - * Copyright (C) 2010, 2011, Hoi-Ho Chan, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#if (defined(USE_POLARSSL) || defined(USE_MBEDTLS)) && \ - (defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)) - -#if defined(USE_THREADS_POSIX) -# ifdef HAVE_PTHREAD_H -# include -# endif -#elif defined(USE_THREADS_WIN32) -# ifdef HAVE_PROCESS_H -# include -# endif -#endif - -#include "polarssl_threadlock.h" -#include "curl_printf.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* number of thread locks */ -#define NUMT 2 - -/* This array will store all of the mutexes available to PolarSSL. */ -static POLARSSL_MUTEX_T *mutex_buf = NULL; - -int Curl_polarsslthreadlock_thread_setup(void) -{ - int i; - int ret; - - mutex_buf = malloc(NUMT * sizeof(POLARSSL_MUTEX_T)); - if(!mutex_buf) - return 0; /* error, no number of threads defined */ - -#ifdef HAVE_PTHREAD_H - for(i = 0; i < NUMT; i++) { - ret = pthread_mutex_init(&mutex_buf[i], NULL); - if(ret) - return 0; /* pthread_mutex_init failed */ - } -#elif defined(HAVE_PROCESS_H) - for(i = 0; i < NUMT; i++) { - mutex_buf[i] = CreateMutex(0, FALSE, 0); - if(mutex_buf[i] == 0) - return 0; /* CreateMutex failed */ - } -#endif /* HAVE_PTHREAD_H */ - - return 1; /* OK */ -} - -int Curl_polarsslthreadlock_thread_cleanup(void) -{ - int i; - int ret; - - if(!mutex_buf) - return 0; /* error, no threads locks defined */ - -#ifdef HAVE_PTHREAD_H - for(i = 0; i < NUMT; i++) { - ret = pthread_mutex_destroy(&mutex_buf[i]); - if(ret) - return 0; /* pthread_mutex_destroy failed */ - } -#elif defined(HAVE_PROCESS_H) - for(i = 0; i < NUMT; i++) { - ret = CloseHandle(mutex_buf[i]); - if(!ret) - return 0; /* CloseHandle failed */ - } -#endif /* HAVE_PTHREAD_H */ - free(mutex_buf); - mutex_buf = NULL; - - return 1; /* OK */ -} - -int Curl_polarsslthreadlock_lock_function(int n) -{ - int ret; -#ifdef HAVE_PTHREAD_H - if(n < NUMT) { - ret = pthread_mutex_lock(&mutex_buf[n]); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_lock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } - } -#elif defined(HAVE_PROCESS_H) - if(n < NUMT) { - ret = (WaitForSingleObject(mutex_buf[n], INFINITE)==WAIT_FAILED?1:0); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_lock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } - } -#endif /* HAVE_PTHREAD_H */ - return 1; /* OK */ -} - -int Curl_polarsslthreadlock_unlock_function(int n) -{ - int ret; -#ifdef HAVE_PTHREAD_H - if(n < NUMT) { - ret = pthread_mutex_unlock(&mutex_buf[n]); - if(ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_unlock_function failed\n")); - return 0; /* pthread_mutex_unlock failed */ - } - } -#elif defined(HAVE_PROCESS_H) - if(n < NUMT) { - ret = ReleaseMutex(mutex_buf[n]); - if(!ret) { - DEBUGF(fprintf(stderr, - "Error: polarsslthreadlock_unlock_function failed\n")); - return 0; /* pthread_mutex_lock failed */ - } - } -#endif /* HAVE_PTHREAD_H */ - return 1; /* OK */ -} - -#endif /* USE_POLARSSL || USE_MBEDTLS */ diff --git a/Externals/curl/lib/vtls/polarssl_threadlock.h b/Externals/curl/lib/vtls/polarssl_threadlock.h deleted file mode 100644 index dda5359b81..0000000000 --- a/Externals/curl/lib/vtls/polarssl_threadlock.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef HEADER_CURL_POLARSSL_THREADLOCK_H -#define HEADER_CURL_POLARSSL_THREADLOCK_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2013-2015, Daniel Stenberg, , et al. - * Copyright (C) 2010, Hoi-Ho Chan, - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#if (defined USE_POLARSSL) || (defined USE_MBEDTLS) - -#if defined(USE_THREADS_POSIX) -# define POLARSSL_MUTEX_T pthread_mutex_t -#elif defined(USE_THREADS_WIN32) -# define POLARSSL_MUTEX_T HANDLE -#endif - -#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32) - -int Curl_polarsslthreadlock_thread_setup(void); -int Curl_polarsslthreadlock_thread_cleanup(void); -int Curl_polarsslthreadlock_lock_function(int n); -int Curl_polarsslthreadlock_unlock_function(int n); - -#else - -#define Curl_polarsslthreadlock_thread_setup() 1 -#define Curl_polarsslthreadlock_thread_cleanup() 1 -#define Curl_polarsslthreadlock_lock_function(x) 1 -#define Curl_polarsslthreadlock_unlock_function(x) 1 - -#endif /* USE_THREADS_POSIX || USE_THREADS_WIN32 */ - -#endif /* USE_POLARSSL */ - -#endif /* HEADER_CURL_POLARSSL_THREADLOCK_H */ diff --git a/Externals/curl/lib/vtls/schannel.c b/Externals/curl/lib/vtls/schannel.c deleted file mode 100644 index b2e9265638..0000000000 --- a/Externals/curl/lib/vtls/schannel.c +++ /dev/null @@ -1,1623 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012 - 2016, Marc Hoersken, - * Copyright (C) 2012, Mark Salisbury, - * Copyright (C) 2012 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * Source file for all SChannel-specific code for the TLS/SSL layer. No code - * but vtls.c should ever call or use these functions. - * - */ - -/* - * Based upon the PolarSSL implementation in polarssl.c and polarssl.h: - * Copyright (C) 2010, 2011, Hoi-Ho Chan, - * - * Based upon the CyaSSL implementation in cyassl.c and cyassl.h: - * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. - * - * Thanks for code and inspiration! - */ - -#include "curl_setup.h" - -#ifdef USE_SCHANNEL - -#ifndef USE_WINDOWS_SSPI -# error "Can't compile SCHANNEL support without SSPI." -#endif - -#include "curl_sspi.h" -#include "schannel.h" -#include "vtls.h" -#include "sendf.h" -#include "connect.h" /* for the connect timeout */ -#include "strerror.h" -#include "select.h" /* for the socket readyness */ -#include "inet_pton.h" /* for IP addr SNI check */ -#include "curl_multibyte.h" -#include "warnless.h" -#include "curl_printf.h" -#include "curl_memory.h" -/* The last #include file should be: */ -#include "memdebug.h" - -/* ALPN requires version 8.1 of the Windows SDK, which was - shipped with Visual Studio 2013, aka _MSC_VER 1800*/ -#if defined(_MSC_VER) && (_MSC_VER >= 1800) && !defined(_USING_V110_SDK71_) -# define HAS_ALPN 1 -#endif - -/* Uncomment to force verbose output - * #define infof(x, y, ...) printf(y, __VA_ARGS__) - * #define failf(x, y, ...) printf(y, __VA_ARGS__) - */ - -static Curl_recv schannel_recv; -static Curl_send schannel_send; - -#ifdef _WIN32_WCE -static CURLcode verify_certificate(struct connectdata *conn, int sockindex); -#endif - -static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType, - void *BufDataPtr, unsigned long BufByteSize) -{ - buffer->cbBuffer = BufByteSize; - buffer->BufferType = BufType; - buffer->pvBuffer = BufDataPtr; -} - -static void InitSecBufferDesc(SecBufferDesc *desc, SecBuffer *BufArr, - unsigned long NumArrElem) -{ - desc->ulVersion = SECBUFFER_VERSION; - desc->pBuffers = BufArr; - desc->cBuffers = NumArrElem; -} - -static CURLcode -schannel_connect_step1(struct connectdata *conn, int sockindex) -{ - ssize_t written = -1; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - SecBuffer outbuf; - SecBufferDesc outbuf_desc; - SecBuffer inbuf; - SecBufferDesc inbuf_desc; -#ifdef HAS_ALPN - unsigned char alpn_buffer[128]; -#endif - SCHANNEL_CRED schannel_cred; - SECURITY_STATUS sspi_status = SEC_E_OK; - struct curl_schannel_cred *old_cred = NULL; - struct in_addr addr; -#ifdef ENABLE_IPV6 - struct in6_addr addr6; -#endif - TCHAR *host_name; - CURLcode result; - - infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n", - conn->host.name, conn->remote_port); - - /* check for an existing re-usable credential handle */ - if(!Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL)) { - connssl->cred = old_cred; - infof(data, "schannel: re-using existing credential handle\n"); - } - else { - /* setup Schannel API options */ - memset(&schannel_cred, 0, sizeof(schannel_cred)); - schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; - - if(data->set.ssl.verifypeer) { -#ifdef _WIN32_WCE - /* certificate validation on CE doesn't seem to work right; we'll - do it following a more manual process. */ - schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | - SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; -#else - schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; - if(data->set.ssl_no_revoke) - schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - else - schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN; -#endif - if(data->set.ssl_no_revoke) - infof(data, "schannel: disabled server certificate revocation " - "checks\n"); - else - infof(data, "schannel: checking server certificate revocation\n"); - } - else { - schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | - SCH_CRED_IGNORE_NO_REVOCATION_CHECK | - SCH_CRED_IGNORE_REVOCATION_OFFLINE; - infof(data, "schannel: disabled server certificate revocation checks\n"); - } - - if(!data->set.ssl.verifyhost) { - schannel_cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK; - infof(data, "schannel: verifyhost setting prevents Schannel from " - "comparing the supplied target name with the subject " - "names in server certificates. Also disables SNI.\n"); - } - - switch(data->set.ssl.version) { - default: - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT | - SP_PROT_TLS1_1_CLIENT | - SP_PROT_TLS1_2_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_0: - schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_0_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_1: - schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_1_CLIENT; - break; - case CURL_SSLVERSION_TLSv1_2: - schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT; - break; - case CURL_SSLVERSION_SSLv3: - schannel_cred.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT; - break; - case CURL_SSLVERSION_SSLv2: - schannel_cred.grbitEnabledProtocols = SP_PROT_SSL2_CLIENT; - break; - } - - /* allocate memory for the re-usable credential handle */ - connssl->cred = (struct curl_schannel_cred *) - malloc(sizeof(struct curl_schannel_cred)); - if(!connssl->cred) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - memset(connssl->cred, 0, sizeof(struct curl_schannel_cred)); - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa374716.aspx - */ - sspi_status = - s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *)UNISP_NAME, - SECPKG_CRED_OUTBOUND, NULL, - &schannel_cred, NULL, NULL, - &connssl->cred->cred_handle, - &connssl->cred->time_stamp); - - if(sspi_status != SEC_E_OK) { - if(sspi_status == SEC_E_WRONG_PRINCIPAL) - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - else - failf(data, "schannel: AcquireCredentialsHandle failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - Curl_safefree(connssl->cred); - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* Warn if SNI is disabled due to use of an IP address */ - if(Curl_inet_pton(AF_INET, conn->host.name, &addr) -#ifdef ENABLE_IPV6 - || Curl_inet_pton(AF_INET6, conn->host.name, &addr6) -#endif - ) { - infof(data, "schannel: using IP address, SNI is not supported by OS.\n"); - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - int cur = 0; - int list_start_index = 0; - unsigned int* extension_len = NULL; - unsigned short* list_len = NULL; - - /* The first four bytes will be an unsigned int indicating number - of bytes of data in the rest of the the buffer. */ - extension_len = (unsigned int*)(&alpn_buffer[cur]); - cur += sizeof(unsigned int); - - /* The next four bytes are an indicator that this buffer will contain - ALPN data, as opposed to NPN, for example. */ - *(unsigned int*)&alpn_buffer[cur] = - SecApplicationProtocolNegotiationExt_ALPN; - cur += sizeof(unsigned int); - - /* The next two bytes will be an unsigned short indicating the number - of bytes used to list the preferred protocols. */ - list_len = (unsigned short*)(&alpn_buffer[cur]); - cur += sizeof(unsigned short); - - list_start_index = cur; - -#ifdef USE_NGHTTP2 - if(data->set.httpversion >= CURL_HTTP_VERSION_2) { - memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN); - cur += NGHTTP2_PROTO_ALPN_LEN; - infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID); - } -#endif - - alpn_buffer[cur++] = ALPN_HTTP_1_1_LENGTH; - memcpy(&alpn_buffer[cur], ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH); - cur += ALPN_HTTP_1_1_LENGTH; - infof(data, "schannel: ALPN, offering %s\n", ALPN_HTTP_1_1); - - *list_len = curlx_uitous(cur - list_start_index); - *extension_len = *list_len + sizeof(unsigned int) + sizeof(unsigned short); - - InitSecBuffer(&inbuf, SECBUFFER_APPLICATION_PROTOCOLS, alpn_buffer, cur); - InitSecBufferDesc(&inbuf_desc, &inbuf, 1); - } - else - { - InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, &inbuf, 1); - } -#else /* HAS_ALPN */ - InitSecBuffer(&inbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, &inbuf, 1); -#endif - - /* setup output buffer */ - InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, &outbuf, 1); - - /* setup request flags */ - connssl->req_flags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONFIDENTIALITY | ISC_REQ_ALLOCATE_MEMORY | - ISC_REQ_STREAM; - - /* allocate memory for the security context handle */ - connssl->ctxt = (struct curl_schannel_ctxt *) - malloc(sizeof(struct curl_schannel_ctxt)); - if(!connssl->ctxt) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - memset(connssl->ctxt, 0, sizeof(struct curl_schannel_ctxt)); - - host_name = Curl_convert_UTF8_to_tchar(conn->host.name); - if(!host_name) - return CURLE_OUT_OF_MEMORY; - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */ - - sspi_status = s_pSecFn->InitializeSecurityContext( - &connssl->cred->cred_handle, NULL, host_name, - connssl->req_flags, 0, 0, &inbuf_desc, 0, &connssl->ctxt->ctxt_handle, - &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp); - - Curl_unicodefree(host_name); - - if(sspi_status != SEC_I_CONTINUE_NEEDED) { - if(sspi_status == SEC_E_WRONG_PRINCIPAL) - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - else - failf(data, "schannel: initial InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - Curl_safefree(connssl->ctxt); - return CURLE_SSL_CONNECT_ERROR; - } - - infof(data, "schannel: sending initial handshake data: " - "sending %lu bytes...\n", outbuf.cbBuffer); - - /* send initial handshake data which is now stored in output buffer */ - result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer, - outbuf.cbBuffer, &written); - s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); - if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { - failf(data, "schannel: failed to send initial handshake data: " - "sent %zd of %lu bytes", written, outbuf.cbBuffer); - return CURLE_SSL_CONNECT_ERROR; - } - - infof(data, "schannel: sent initial handshake data: " - "sent %zd bytes\n", written); - - connssl->recv_unrecoverable_err = CURLE_OK; - connssl->recv_sspi_close_notify = false; - connssl->recv_connection_closed = false; - - /* continue to second handshake step */ - connssl->connecting_state = ssl_connect_2; - - return CURLE_OK; -} - -static CURLcode -schannel_connect_step2(struct connectdata *conn, int sockindex) -{ - int i; - ssize_t nread = -1, written = -1; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - unsigned char *reallocated_buffer; - size_t reallocated_length; - SecBuffer outbuf[3]; - SecBufferDesc outbuf_desc; - SecBuffer inbuf[2]; - SecBufferDesc inbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - TCHAR *host_name; - CURLcode result; - bool doread; - - doread = (connssl->connecting_state != ssl_connect_2_writing) ? TRUE : FALSE; - - infof(data, "schannel: SSL/TLS connection with %s port %hu (step 2/3)\n", - conn->host.name, conn->remote_port); - - if(!connssl->cred || !connssl->ctxt) - return CURLE_SSL_CONNECT_ERROR; - - /* buffer to store previously received and decrypted data */ - if(connssl->decdata_buffer == NULL) { - connssl->decdata_offset = 0; - connssl->decdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; - connssl->decdata_buffer = malloc(connssl->decdata_length); - if(connssl->decdata_buffer == NULL) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - } - - /* buffer to store previously received and encrypted data */ - if(connssl->encdata_buffer == NULL) { - connssl->encdata_offset = 0; - connssl->encdata_length = CURL_SCHANNEL_BUFFER_INIT_SIZE; - connssl->encdata_buffer = malloc(connssl->encdata_length); - if(connssl->encdata_buffer == NULL) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - } - - /* if we need a bigger buffer to read a full message, increase buffer now */ - if(connssl->encdata_length - connssl->encdata_offset < - CURL_SCHANNEL_BUFFER_FREE_SIZE) { - /* increase internal encrypted data buffer */ - reallocated_length = connssl->encdata_offset + - CURL_SCHANNEL_BUFFER_FREE_SIZE; - reallocated_buffer = realloc(connssl->encdata_buffer, - reallocated_length); - - if(reallocated_buffer == NULL) { - failf(data, "schannel: unable to re-allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - else { - connssl->encdata_buffer = reallocated_buffer; - connssl->encdata_length = reallocated_length; - } - } - - for(;;) { - if(doread) { - /* read encrypted handshake data from socket */ - result = Curl_read_plain(conn->sock[sockindex], - (char *) (connssl->encdata_buffer + - connssl->encdata_offset), - connssl->encdata_length - - connssl->encdata_offset, - &nread); - if(result == CURLE_AGAIN) { - if(connssl->connecting_state != ssl_connect_2_writing) - connssl->connecting_state = ssl_connect_2_reading; - infof(data, "schannel: failed to receive handshake, " - "need more data\n"); - return CURLE_OK; - } - else if((result != CURLE_OK) || (nread == 0)) { - failf(data, "schannel: failed to receive handshake, " - "SSL/TLS connection failed"); - return CURLE_SSL_CONNECT_ERROR; - } - - /* increase encrypted data buffer offset */ - connssl->encdata_offset += nread; - } - - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - connssl->encdata_offset, connssl->encdata_length); - - /* setup input buffers */ - InitSecBuffer(&inbuf[0], SECBUFFER_TOKEN, malloc(connssl->encdata_offset), - curlx_uztoul(connssl->encdata_offset)); - InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, inbuf, 2); - - /* setup output buffers */ - InitSecBuffer(&outbuf[0], SECBUFFER_TOKEN, NULL, 0); - InitSecBuffer(&outbuf[1], SECBUFFER_ALERT, NULL, 0); - InitSecBuffer(&outbuf[2], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, outbuf, 3); - - if(inbuf[0].pvBuffer == NULL) { - failf(data, "schannel: unable to allocate memory"); - return CURLE_OUT_OF_MEMORY; - } - - /* copy received handshake data into input buffer */ - memcpy(inbuf[0].pvBuffer, connssl->encdata_buffer, - connssl->encdata_offset); - - host_name = Curl_convert_UTF8_to_tchar(conn->host.name); - if(!host_name) - return CURLE_OUT_OF_MEMORY; - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx - */ - sspi_status = s_pSecFn->InitializeSecurityContext( - &connssl->cred->cred_handle, &connssl->ctxt->ctxt_handle, - host_name, connssl->req_flags, 0, 0, &inbuf_desc, 0, NULL, - &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp); - - Curl_unicodefree(host_name); - - /* free buffer for received handshake data */ - Curl_safefree(inbuf[0].pvBuffer); - - /* check if the handshake was incomplete */ - if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { - connssl->connecting_state = ssl_connect_2_reading; - infof(data, "schannel: received incomplete message, need more data\n"); - return CURLE_OK; - } - - /* If the server has requested a client certificate, attempt to continue - the handshake without one. This will allow connections to servers which - request a client certificate but do not require it. */ - if(sspi_status == SEC_I_INCOMPLETE_CREDENTIALS && - !(connssl->req_flags & ISC_REQ_USE_SUPPLIED_CREDS)) { - connssl->req_flags |= ISC_REQ_USE_SUPPLIED_CREDS; - connssl->connecting_state = ssl_connect_2_writing; - infof(data, "schannel: a client certificate has been requested\n"); - return CURLE_OK; - } - - /* check if the handshake needs to be continued */ - if(sspi_status == SEC_I_CONTINUE_NEEDED || sspi_status == SEC_E_OK) { - for(i = 0; i < 3; i++) { - /* search for handshake tokens that need to be send */ - if(outbuf[i].BufferType == SECBUFFER_TOKEN && outbuf[i].cbBuffer > 0) { - infof(data, "schannel: sending next handshake data: " - "sending %lu bytes...\n", outbuf[i].cbBuffer); - - /* send handshake token to server */ - result = Curl_write_plain(conn, conn->sock[sockindex], - outbuf[i].pvBuffer, outbuf[i].cbBuffer, - &written); - if((result != CURLE_OK) || - (outbuf[i].cbBuffer != (size_t) written)) { - failf(data, "schannel: failed to send next handshake data: " - "sent %zd of %lu bytes", written, outbuf[i].cbBuffer); - return CURLE_SSL_CONNECT_ERROR; - } - } - - /* free obsolete buffer */ - if(outbuf[i].pvBuffer != NULL) { - s_pSecFn->FreeContextBuffer(outbuf[i].pvBuffer); - } - } - } - else { - if(sspi_status == SEC_E_WRONG_PRINCIPAL) - failf(data, "schannel: SNI or certificate check failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - else - failf(data, "schannel: next InitializeSecurityContext failed: %s", - Curl_sspi_strerror(conn, sspi_status)); - return CURLE_SSL_CONNECT_ERROR; - } - - /* check if there was additional remaining encrypted data */ - if(inbuf[1].BufferType == SECBUFFER_EXTRA && inbuf[1].cbBuffer > 0) { - infof(data, "schannel: encrypted data length: %lu\n", inbuf[1].cbBuffer); - /* - There are two cases where we could be getting extra data here: - 1) If we're renegotiating a connection and the handshake is already - complete (from the server perspective), it can encrypted app data - (not handshake data) in an extra buffer at this point. - 2) (sspi_status == SEC_I_CONTINUE_NEEDED) We are negotiating a - connection and this extra data is part of the handshake. - We should process the data immediately; waiting for the socket to - be ready may fail since the server is done sending handshake data. - */ - /* check if the remaining data is less than the total amount - and therefore begins after the already processed data */ - if(connssl->encdata_offset > inbuf[1].cbBuffer) { - memmove(connssl->encdata_buffer, - (connssl->encdata_buffer + connssl->encdata_offset) - - inbuf[1].cbBuffer, inbuf[1].cbBuffer); - connssl->encdata_offset = inbuf[1].cbBuffer; - if(sspi_status == SEC_I_CONTINUE_NEEDED) { - doread = FALSE; - continue; - } - } - } - else { - connssl->encdata_offset = 0; - } - break; - } - - /* check if the handshake needs to be continued */ - if(sspi_status == SEC_I_CONTINUE_NEEDED) { - connssl->connecting_state = ssl_connect_2_reading; - return CURLE_OK; - } - - /* check if the handshake is complete */ - if(sspi_status == SEC_E_OK) { - connssl->connecting_state = ssl_connect_3; - infof(data, "schannel: SSL/TLS handshake complete\n"); - } - -#ifdef _WIN32_WCE - /* Windows CE doesn't do any server certificate validation. - We have to do it manually. */ - if(data->set.ssl.verifypeer) - return verify_certificate(conn, sockindex); -#endif - - return CURLE_OK; -} - -static CURLcode -schannel_connect_step3(struct connectdata *conn, int sockindex) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - struct curl_schannel_cred *old_cred = NULL; -#ifdef HAS_ALPN - SECURITY_STATUS sspi_status = SEC_E_OK; - SecPkgContext_ApplicationProtocol alpn_result; -#endif - bool incache; - - DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); - - infof(data, "schannel: SSL/TLS connection with %s port %hu (step 3/3)\n", - conn->host.name, conn->remote_port); - - if(!connssl->cred) - return CURLE_SSL_CONNECT_ERROR; - - /* check if the required context attributes are met */ - if(connssl->ret_flags != connssl->req_flags) { - if(!(connssl->ret_flags & ISC_RET_SEQUENCE_DETECT)) - failf(data, "schannel: failed to setup sequence detection"); - if(!(connssl->ret_flags & ISC_RET_REPLAY_DETECT)) - failf(data, "schannel: failed to setup replay detection"); - if(!(connssl->ret_flags & ISC_RET_CONFIDENTIALITY)) - failf(data, "schannel: failed to setup confidentiality"); - if(!(connssl->ret_flags & ISC_RET_ALLOCATED_MEMORY)) - failf(data, "schannel: failed to setup memory allocation"); - if(!(connssl->ret_flags & ISC_RET_STREAM)) - failf(data, "schannel: failed to setup stream orientation"); - return CURLE_SSL_CONNECT_ERROR; - } - -#ifdef HAS_ALPN - if(conn->bits.tls_enable_alpn) { - sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle, - SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result); - - if(sspi_status != SEC_E_OK) { - failf(data, "schannel: failed to retrieve ALPN result"); - return CURLE_SSL_CONNECT_ERROR; - } - - if(alpn_result.ProtoNegoStatus == - SecApplicationProtocolNegotiationStatus_Success) { - - infof(data, "schannel: ALPN, server accepted to use %.*s\n", - alpn_result.ProtocolIdSize, alpn_result.ProtocolId); - -#ifdef USE_NGHTTP2 - if(alpn_result.ProtocolIdSize == NGHTTP2_PROTO_VERSION_ID_LEN && - !memcmp(NGHTTP2_PROTO_VERSION_ID, alpn_result.ProtocolId, - NGHTTP2_PROTO_VERSION_ID_LEN)) { - conn->negnpn = CURL_HTTP_VERSION_2; - } - else -#endif - if(alpn_result.ProtocolIdSize == ALPN_HTTP_1_1_LENGTH && - !memcmp(ALPN_HTTP_1_1, alpn_result.ProtocolId, - ALPN_HTTP_1_1_LENGTH)) { - conn->negnpn = CURL_HTTP_VERSION_1_1; - } - } - else - infof(data, "ALPN, server did not agree to a protocol\n"); - } -#endif - - /* increment the reference counter of the credential/session handle */ - if(connssl->cred && connssl->ctxt) { - connssl->cred->refcount++; - infof(data, "schannel: incremented credential handle refcount = %d\n", - connssl->cred->refcount); - } - - /* save the current session data for possible re-use */ - incache = !(Curl_ssl_getsessionid(conn, (void **)&old_cred, NULL)); - if(incache) { - if(old_cred != connssl->cred) { - infof(data, "schannel: old credential handle is stale, removing\n"); - Curl_ssl_delsessionid(conn, (void *)old_cred); - incache = FALSE; - } - } - - if(!incache) { - result = Curl_ssl_addsessionid(conn, (void *)connssl->cred, - sizeof(struct curl_schannel_cred)); - if(result) { - failf(data, "schannel: failed to store credential handle"); - return result; - } - else { - connssl->cred->cached = TRUE; - infof(data, "schannel: stored credential handle in session cache\n"); - } - } - - connssl->connecting_state = ssl_connect_done; - - return CURLE_OK; -} - -static CURLcode -schannel_connect_common(struct connectdata *conn, int sockindex, - bool nonblocking, bool *done) -{ - CURLcode result; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - curl_socket_t sockfd = conn->sock[sockindex]; - long timeout_ms; - int what; - - /* check if the connection has already been established */ - if(ssl_connection_complete == connssl->state) { - *done = TRUE; - return CURLE_OK; - } - - if(ssl_connect_1 == connssl->connecting_state) { - /* check out how much more time we're allowed */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL/TLS connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - result = schannel_connect_step1(conn, sockindex); - if(result) - return result; - } - - while(ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state) { - - /* check out how much more time we're allowed */ - timeout_ms = Curl_timeleft(data, NULL, TRUE); - - if(timeout_ms < 0) { - /* no need to continue if time already is up */ - failf(data, "SSL/TLS connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - - /* if ssl is expecting something, check if it's available. */ - if(connssl->connecting_state == ssl_connect_2_reading - || connssl->connecting_state == ssl_connect_2_writing) { - - curl_socket_t writefd = ssl_connect_2_writing == - connssl->connecting_state ? sockfd : CURL_SOCKET_BAD; - curl_socket_t readfd = ssl_connect_2_reading == - connssl->connecting_state ? sockfd : CURL_SOCKET_BAD; - - what = Curl_socket_ready(readfd, writefd, nonblocking ? 0 : timeout_ms); - if(what < 0) { - /* fatal error */ - failf(data, "select/poll on SSL/TLS socket, errno: %d", SOCKERRNO); - return CURLE_SSL_CONNECT_ERROR; - } - else if(0 == what) { - if(nonblocking) { - *done = FALSE; - return CURLE_OK; - } - else { - /* timeout */ - failf(data, "SSL/TLS connection timeout"); - return CURLE_OPERATION_TIMEDOUT; - } - } - /* socket is readable or writable */ - } - - /* Run transaction, and return to the caller if it failed or if - * this connection is part of a multi handle and this loop would - * execute again. This permits the owner of a multi handle to - * abort a connection attempt before step2 has completed while - * ensuring that a client using select() or epoll() will always - * have a valid fdset to wait on. - */ - result = schannel_connect_step2(conn, sockindex); - if(result || (nonblocking && - (ssl_connect_2 == connssl->connecting_state || - ssl_connect_2_reading == connssl->connecting_state || - ssl_connect_2_writing == connssl->connecting_state))) - return result; - - } /* repeat step2 until all transactions are done. */ - - if(ssl_connect_3 == connssl->connecting_state) { - result = schannel_connect_step3(conn, sockindex); - if(result) - return result; - } - - if(ssl_connect_done == connssl->connecting_state) { - connssl->state = ssl_connection_complete; - conn->recv[sockindex] = schannel_recv; - conn->send[sockindex] = schannel_send; - *done = TRUE; - } - else - *done = FALSE; - - /* reset our connection state machine */ - connssl->connecting_state = ssl_connect_1; - - return CURLE_OK; -} - -static ssize_t -schannel_send(struct connectdata *conn, int sockindex, - const void *buf, size_t len, CURLcode *err) -{ - ssize_t written = -1; - size_t data_len = 0; - unsigned char *data = NULL; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - SecBuffer outbuf[4]; - SecBufferDesc outbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - CURLcode result; - - /* check if the maximum stream sizes were queried */ - if(connssl->stream_sizes.cbMaximumMessage == 0) { - sspi_status = s_pSecFn->QueryContextAttributes( - &connssl->ctxt->ctxt_handle, - SECPKG_ATTR_STREAM_SIZES, - &connssl->stream_sizes); - if(sspi_status != SEC_E_OK) { - *err = CURLE_SEND_ERROR; - return -1; - } - } - - /* check if the buffer is longer than the maximum message length */ - if(len > connssl->stream_sizes.cbMaximumMessage) { - *err = CURLE_SEND_ERROR; - return -1; - } - - /* calculate the complete message length and allocate a buffer for it */ - data_len = connssl->stream_sizes.cbHeader + len + - connssl->stream_sizes.cbTrailer; - data = (unsigned char *) malloc(data_len); - if(data == NULL) { - *err = CURLE_OUT_OF_MEMORY; - return -1; - } - - /* setup output buffers (header, data, trailer, empty) */ - InitSecBuffer(&outbuf[0], SECBUFFER_STREAM_HEADER, - data, connssl->stream_sizes.cbHeader); - InitSecBuffer(&outbuf[1], SECBUFFER_DATA, - data + connssl->stream_sizes.cbHeader, curlx_uztoul(len)); - InitSecBuffer(&outbuf[2], SECBUFFER_STREAM_TRAILER, - data + connssl->stream_sizes.cbHeader + len, - connssl->stream_sizes.cbTrailer); - InitSecBuffer(&outbuf[3], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, outbuf, 4); - - /* copy data into output buffer */ - memcpy(outbuf[1].pvBuffer, buf, len); - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375390.aspx */ - sspi_status = s_pSecFn->EncryptMessage(&connssl->ctxt->ctxt_handle, 0, - &outbuf_desc, 0); - - /* check if the message was encrypted */ - if(sspi_status == SEC_E_OK) { - written = 0; - - /* send the encrypted message including header, data and trailer */ - len = outbuf[0].cbBuffer + outbuf[1].cbBuffer + outbuf[2].cbBuffer; - - /* - It's important to send the full message which includes the header, - encrypted payload, and trailer. Until the client receives all the - data a coherent message has not been delivered and the client - can't read any of it. - - If we wanted to buffer the unwritten encrypted bytes, we would - tell the client that all data it has requested to be sent has been - sent. The unwritten encrypted bytes would be the first bytes to - send on the next invocation. - Here's the catch with this - if we tell the client that all the - bytes have been sent, will the client call this method again to - send the buffered data? Looking at who calls this function, it - seems the answer is NO. - */ - - /* send entire message or fail */ - while(len > (size_t)written) { - ssize_t this_write; - long timeleft; - int what; - - this_write = 0; - - timeleft = Curl_timeleft(conn->data, NULL, FALSE); - if(timeleft < 0) { - /* we already got the timeout */ - failf(conn->data, "schannel: timed out sending data " - "(bytes sent: %zd)", written); - *err = CURLE_OPERATION_TIMEDOUT; - written = -1; - break; - } - - what = Curl_socket_ready(CURL_SOCKET_BAD, conn->sock[sockindex], - timeleft); - if(what < 0) { - /* fatal error */ - failf(conn->data, "select/poll on SSL socket, errno: %d", SOCKERRNO); - *err = CURLE_SEND_ERROR; - written = -1; - break; - } - else if(0 == what) { - failf(conn->data, "schannel: timed out sending data " - "(bytes sent: %zd)", written); - *err = CURLE_OPERATION_TIMEDOUT; - written = -1; - break; - } - /* socket is writable */ - - result = Curl_write_plain(conn, conn->sock[sockindex], data + written, - len - written, &this_write); - if(result == CURLE_AGAIN) - continue; - else if(result != CURLE_OK) { - *err = result; - written = -1; - break; - } - - written += this_write; - } - } - else if(sspi_status == SEC_E_INSUFFICIENT_MEMORY) { - *err = CURLE_OUT_OF_MEMORY; - } - else{ - *err = CURLE_SEND_ERROR; - } - - Curl_safefree(data); - - if(len == (size_t)written) - /* Encrypted message including header, data and trailer entirely sent. - The return value is the number of unencrypted bytes that were sent. */ - written = outbuf[1].cbBuffer; - - return written; -} - -static ssize_t -schannel_recv(struct connectdata *conn, int sockindex, - char *buf, size_t len, CURLcode *err) -{ - size_t size = 0; - ssize_t nread = -1; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - unsigned char *reallocated_buffer; - size_t reallocated_length; - bool done = FALSE; - SecBuffer inbuf[4]; - SecBufferDesc inbuf_desc; - SECURITY_STATUS sspi_status = SEC_E_OK; - /* we want the length of the encrypted buffer to be at least large enough - that it can hold all the bytes requested and some TLS record overhead. */ - size_t min_encdata_length = len + CURL_SCHANNEL_BUFFER_FREE_SIZE; - - /**************************************************************************** - * Don't return or set connssl->recv_unrecoverable_err unless in the cleanup. - * The pattern for return error is set *err, optional infof, goto cleanup. - * - * Our priority is to always return as much decrypted data to the caller as - * possible, even if an error occurs. The state of the decrypted buffer must - * always be valid. Transfer of decrypted data to the caller's buffer is - * handled in the cleanup. - */ - - infof(data, "schannel: client wants to read %zu bytes\n", len); - *err = CURLE_OK; - - if(len && len <= connssl->decdata_offset) { - infof(data, "schannel: enough decrypted data is already available\n"); - goto cleanup; - } - else if(connssl->recv_unrecoverable_err) { - *err = connssl->recv_unrecoverable_err; - infof(data, "schannel: an unrecoverable error occurred in a prior call\n"); - goto cleanup; - } - else if(connssl->recv_sspi_close_notify) { - /* once a server has indicated shutdown there is no more encrypted data */ - infof(data, "schannel: server indicated shutdown in a prior call\n"); - goto cleanup; - } - else if(!len) { - /* It's debatable what to return when !len. Regardless we can't return - immediately because there may be data to decrypt (in the case we want to - decrypt all encrypted cached data) so handle !len later in cleanup. - */ - ; /* do nothing */ - } - else if(!connssl->recv_connection_closed) { - /* increase enc buffer in order to fit the requested amount of data */ - size = connssl->encdata_length - connssl->encdata_offset; - if(size < CURL_SCHANNEL_BUFFER_FREE_SIZE || - connssl->encdata_length < min_encdata_length) { - reallocated_length = connssl->encdata_offset + - CURL_SCHANNEL_BUFFER_FREE_SIZE; - if(reallocated_length < min_encdata_length) { - reallocated_length = min_encdata_length; - } - reallocated_buffer = realloc(connssl->encdata_buffer, - reallocated_length); - if(reallocated_buffer == NULL) { - *err = CURLE_OUT_OF_MEMORY; - failf(data, "schannel: unable to re-allocate memory"); - goto cleanup; - } - - connssl->encdata_buffer = reallocated_buffer; - connssl->encdata_length = reallocated_length; - size = connssl->encdata_length - connssl->encdata_offset; - infof(data, "schannel: encdata_buffer resized %zu\n", - connssl->encdata_length); - } - - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - connssl->encdata_offset, connssl->encdata_length); - - /* read encrypted data from socket */ - *err = Curl_read_plain(conn->sock[sockindex], - (char *)(connssl->encdata_buffer + - connssl->encdata_offset), - size, &nread); - if(*err) { - nread = -1; - if(*err == CURLE_AGAIN) - infof(data, "schannel: Curl_read_plain returned CURLE_AGAIN\n"); - else if(*err == CURLE_RECV_ERROR) - infof(data, "schannel: Curl_read_plain returned CURLE_RECV_ERROR\n"); - else - infof(data, "schannel: Curl_read_plain returned error %d\n", *err); - } - else if(nread == 0) { - connssl->recv_connection_closed = true; - infof(data, "schannel: server closed the connection\n"); - } - else if(nread > 0) { - connssl->encdata_offset += (size_t)nread; - infof(data, "schannel: encrypted data got %zd\n", nread); - } - } - - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - connssl->encdata_offset, connssl->encdata_length); - - /* decrypt loop */ - while(connssl->encdata_offset > 0 && sspi_status == SEC_E_OK && - (!len || connssl->decdata_offset < len || - connssl->recv_connection_closed)) { - /* prepare data buffer for DecryptMessage call */ - InitSecBuffer(&inbuf[0], SECBUFFER_DATA, connssl->encdata_buffer, - curlx_uztoul(connssl->encdata_offset)); - - /* we need 3 more empty input buffers for possible output */ - InitSecBuffer(&inbuf[1], SECBUFFER_EMPTY, NULL, 0); - InitSecBuffer(&inbuf[2], SECBUFFER_EMPTY, NULL, 0); - InitSecBuffer(&inbuf[3], SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&inbuf_desc, inbuf, 4); - - /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375348.aspx - */ - sspi_status = s_pSecFn->DecryptMessage(&connssl->ctxt->ctxt_handle, - &inbuf_desc, 0, NULL); - - /* check if everything went fine (server may want to renegotiate - or shutdown the connection context) */ - if(sspi_status == SEC_E_OK || sspi_status == SEC_I_RENEGOTIATE || - sspi_status == SEC_I_CONTEXT_EXPIRED) { - /* check for successfully decrypted data, even before actual - renegotiation or shutdown of the connection context */ - if(inbuf[1].BufferType == SECBUFFER_DATA) { - infof(data, "schannel: decrypted data length: %lu\n", - inbuf[1].cbBuffer); - - /* increase buffer in order to fit the received amount of data */ - size = inbuf[1].cbBuffer > CURL_SCHANNEL_BUFFER_FREE_SIZE ? - inbuf[1].cbBuffer : CURL_SCHANNEL_BUFFER_FREE_SIZE; - if(connssl->decdata_length - connssl->decdata_offset < size || - connssl->decdata_length < len) { - /* increase internal decrypted data buffer */ - reallocated_length = connssl->decdata_offset + size; - /* make sure that the requested amount of data fits */ - if(reallocated_length < len) { - reallocated_length = len; - } - reallocated_buffer = realloc(connssl->decdata_buffer, - reallocated_length); - if(reallocated_buffer == NULL) { - *err = CURLE_OUT_OF_MEMORY; - failf(data, "schannel: unable to re-allocate memory"); - goto cleanup; - } - connssl->decdata_buffer = reallocated_buffer; - connssl->decdata_length = reallocated_length; - } - - /* copy decrypted data to internal buffer */ - size = inbuf[1].cbBuffer; - if(size) { - memcpy(connssl->decdata_buffer + connssl->decdata_offset, - inbuf[1].pvBuffer, size); - connssl->decdata_offset += size; - } - - infof(data, "schannel: decrypted data added: %zu\n", size); - infof(data, "schannel: decrypted data cached: offset %zu length %zu\n", - connssl->decdata_offset, connssl->decdata_length); - } - - /* check for remaining encrypted data */ - if(inbuf[3].BufferType == SECBUFFER_EXTRA && inbuf[3].cbBuffer > 0) { - infof(data, "schannel: encrypted data length: %lu\n", - inbuf[3].cbBuffer); - - /* check if the remaining data is less than the total amount - * and therefore begins after the already processed data - */ - if(connssl->encdata_offset > inbuf[3].cbBuffer) { - /* move remaining encrypted data forward to the beginning of - buffer */ - memmove(connssl->encdata_buffer, - (connssl->encdata_buffer + connssl->encdata_offset) - - inbuf[3].cbBuffer, inbuf[3].cbBuffer); - connssl->encdata_offset = inbuf[3].cbBuffer; - } - - infof(data, "schannel: encrypted data cached: offset %zu length %zu\n", - connssl->encdata_offset, connssl->encdata_length); - } - else { - /* reset encrypted buffer offset, because there is no data remaining */ - connssl->encdata_offset = 0; - } - - /* check if server wants to renegotiate the connection context */ - if(sspi_status == SEC_I_RENEGOTIATE) { - infof(data, "schannel: remote party requests renegotiation\n"); - if(*err && *err != CURLE_AGAIN) { - infof(data, "schannel: can't renogotiate, an error is pending\n"); - goto cleanup; - } - if(connssl->encdata_offset) { - *err = CURLE_RECV_ERROR; - infof(data, "schannel: can't renogotiate, " - "encrypted data available\n"); - goto cleanup; - } - /* begin renegotiation */ - infof(data, "schannel: renegotiating SSL/TLS connection\n"); - connssl->state = ssl_connection_negotiating; - connssl->connecting_state = ssl_connect_2_writing; - *err = schannel_connect_common(conn, sockindex, FALSE, &done); - if(*err) { - infof(data, "schannel: renegotiation failed\n"); - goto cleanup; - } - /* now retry receiving data */ - sspi_status = SEC_E_OK; - infof(data, "schannel: SSL/TLS connection renegotiated\n"); - continue; - } - /* check if the server closed the connection */ - else if(sspi_status == SEC_I_CONTEXT_EXPIRED) { - /* In Windows 2000 SEC_I_CONTEXT_EXPIRED (close_notify) is not - returned so we have to work around that in cleanup. */ - connssl->recv_sspi_close_notify = true; - if(!connssl->recv_connection_closed) { - connssl->recv_connection_closed = true; - infof(data, "schannel: server closed the connection\n"); - } - goto cleanup; - } - } - else if(sspi_status == SEC_E_INCOMPLETE_MESSAGE) { - if(!*err) - *err = CURLE_AGAIN; - infof(data, "schannel: failed to decrypt data, need more data\n"); - goto cleanup; - } - else { - *err = CURLE_RECV_ERROR; - infof(data, "schannel: failed to read data from server: %s\n", - Curl_sspi_strerror(conn, sspi_status)); - goto cleanup; - } - } - - infof(data, "schannel: encrypted data buffer: offset %zu length %zu\n", - connssl->encdata_offset, connssl->encdata_length); - - infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n", - connssl->decdata_offset, connssl->decdata_length); - -cleanup: - /* Warning- there is no guarantee the encdata state is valid at this point */ - infof(data, "schannel: schannel_recv cleanup\n"); - - /* Error if the connection has closed without a close_notify. - Behavior here is a matter of debate. We don't want to be vulnerable to a - truncation attack however there's some browser precedent for ignoring the - close_notify for compatibility reasons. - Additionally, Windows 2000 (v5.0) is a special case since it seems it doesn't - return close_notify. In that case if the connection was closed we assume it - was graceful (close_notify) since there doesn't seem to be a way to tell. - */ - if(len && !connssl->decdata_offset && connssl->recv_connection_closed && - !connssl->recv_sspi_close_notify) { - bool isWin2k = FALSE; - -#if !defined(_WIN32_WINNT) || !defined(_WIN32_WINNT_WIN2K) || \ - (_WIN32_WINNT < _WIN32_WINNT_WIN2K) - OSVERSIONINFO osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - - /* Find out the Windows version */ - if(GetVersionEx(&osver)) { - /* Verify the version number is 5.0 */ - if(osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0) - isWin2k = TRUE; - } -#else - ULONGLONG cm; - OSVERSIONINFOEX osver; - - memset(&osver, 0, sizeof(osver)); - osver.dwOSVersionInfoSize = sizeof(osver); - osver.dwMajorVersion = 5; - - cm = VerSetConditionMask(0, VER_MAJORVERSION, VER_EQUAL); - cm = VerSetConditionMask(cm, VER_MINORVERSION, VER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - cm = VerSetConditionMask(cm, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL); - - if(VerifyVersionInfo(&osver, (VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR), - cm)) - isWin2k = TRUE; -#endif - - if(isWin2k && sspi_status == SEC_E_OK) - connssl->recv_sspi_close_notify = true; - else { - *err = CURLE_RECV_ERROR; - infof(data, "schannel: server closed abruptly (missing close_notify)\n"); - } - } - - /* Any error other than CURLE_AGAIN is an unrecoverable error. */ - if(*err && *err != CURLE_AGAIN) - connssl->recv_unrecoverable_err = *err; - - size = len < connssl->decdata_offset ? len : connssl->decdata_offset; - if(size) { - memcpy(buf, connssl->decdata_buffer, size); - memmove(connssl->decdata_buffer, connssl->decdata_buffer + size, - connssl->decdata_offset - size); - connssl->decdata_offset -= size; - - infof(data, "schannel: decrypted data returned %zu\n", size); - infof(data, "schannel: decrypted data buffer: offset %zu length %zu\n", - connssl->decdata_offset, connssl->decdata_length); - *err = CURLE_OK; - return (ssize_t)size; - } - - if(!*err && !connssl->recv_connection_closed) - *err = CURLE_AGAIN; - - /* It's debatable what to return when !len. We could return whatever error we - got from decryption but instead we override here so the return is consistent. - */ - if(!len) - *err = CURLE_OK; - - return *err ? -1 : 0; -} - -CURLcode -Curl_schannel_connect_nonblocking(struct connectdata *conn, int sockindex, - bool *done) -{ - return schannel_connect_common(conn, sockindex, TRUE, done); -} - -CURLcode -Curl_schannel_connect(struct connectdata *conn, int sockindex) -{ - CURLcode result; - bool done = FALSE; - - result = schannel_connect_common(conn, sockindex, FALSE, &done); - if(result) - return result; - - DEBUGASSERT(done); - - return CURLE_OK; -} - -bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex) -{ - const struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - if(connssl->use) /* SSL/TLS is in use */ - return (connssl->encdata_offset > 0 || - connssl->decdata_offset > 0) ? TRUE : FALSE; - else - return FALSE; -} - -void Curl_schannel_close(struct connectdata *conn, int sockindex) -{ - if(conn->ssl[sockindex].use) - /* if the SSL/TLS channel hasn't been shut down yet, do that now. */ - Curl_ssl_shutdown(conn, sockindex); -} - -int Curl_schannel_shutdown(struct connectdata *conn, int sockindex) -{ - /* See https://msdn.microsoft.com/en-us/library/windows/desktop/aa380138.aspx - * Shutting Down an Schannel Connection - */ - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - - infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n", - conn->host.name, conn->remote_port); - - if(connssl->cred && connssl->ctxt) { - SecBufferDesc BuffDesc; - SecBuffer Buffer; - SECURITY_STATUS sspi_status; - SecBuffer outbuf; - SecBufferDesc outbuf_desc; - CURLcode result; - TCHAR *host_name; - DWORD dwshut = SCHANNEL_SHUTDOWN; - - InitSecBuffer(&Buffer, SECBUFFER_TOKEN, &dwshut, sizeof(dwshut)); - InitSecBufferDesc(&BuffDesc, &Buffer, 1); - - sspi_status = s_pSecFn->ApplyControlToken(&connssl->ctxt->ctxt_handle, - &BuffDesc); - - if(sspi_status != SEC_E_OK) - failf(data, "schannel: ApplyControlToken failure: %s", - Curl_sspi_strerror(conn, sspi_status)); - - host_name = Curl_convert_UTF8_to_tchar(conn->host.name); - if(!host_name) - return CURLE_OUT_OF_MEMORY; - - /* setup output buffer */ - InitSecBuffer(&outbuf, SECBUFFER_EMPTY, NULL, 0); - InitSecBufferDesc(&outbuf_desc, &outbuf, 1); - - sspi_status = s_pSecFn->InitializeSecurityContext( - &connssl->cred->cred_handle, - &connssl->ctxt->ctxt_handle, - host_name, - connssl->req_flags, - 0, - 0, - NULL, - 0, - &connssl->ctxt->ctxt_handle, - &outbuf_desc, - &connssl->ret_flags, - &connssl->ctxt->time_stamp); - - Curl_unicodefree(host_name); - - if((sspi_status == SEC_E_OK) || (sspi_status == SEC_I_CONTEXT_EXPIRED)) { - /* send close message which is in output buffer */ - ssize_t written; - result = Curl_write_plain(conn, conn->sock[sockindex], outbuf.pvBuffer, - outbuf.cbBuffer, &written); - - s_pSecFn->FreeContextBuffer(outbuf.pvBuffer); - if((result != CURLE_OK) || (outbuf.cbBuffer != (size_t) written)) { - infof(data, "schannel: failed to send close msg: %s" - " (bytes written: %zd)\n", curl_easy_strerror(result), written); - } - } - } - - /* free SSPI Schannel API security context handle */ - if(connssl->ctxt) { - infof(data, "schannel: clear security context handle\n"); - s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle); - Curl_safefree(connssl->ctxt); - } - - /* free SSPI Schannel API credential handle */ - if(connssl->cred) { - /* decrement the reference counter of the credential/session handle */ - if(connssl->cred->refcount > 0) { - connssl->cred->refcount--; - infof(data, "schannel: decremented credential handle refcount = %d\n", - connssl->cred->refcount); - } - - /* if the handle was not cached and the refcount is zero */ - if(!connssl->cred->cached && connssl->cred->refcount == 0) { - infof(data, "schannel: clear credential handle\n"); - s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle); - Curl_safefree(connssl->cred); - } - } - - /* free internal buffer for received encrypted data */ - if(connssl->encdata_buffer != NULL) { - Curl_safefree(connssl->encdata_buffer); - connssl->encdata_length = 0; - connssl->encdata_offset = 0; - } - - /* free internal buffer for received decrypted data */ - if(connssl->decdata_buffer != NULL) { - Curl_safefree(connssl->decdata_buffer); - connssl->decdata_length = 0; - connssl->decdata_offset = 0; - } - - return CURLE_OK; -} - -void Curl_schannel_session_free(void *ptr) -{ - struct curl_schannel_cred *cred = ptr; - - if(cred && cred->cached) { - if(cred->refcount == 0) { - s_pSecFn->FreeCredentialsHandle(&cred->cred_handle); - Curl_safefree(cred); - } - else { - cred->cached = FALSE; - } - } -} - -int Curl_schannel_init(void) -{ - return (Curl_sspi_global_init() == CURLE_OK ? 1 : 0); -} - -void Curl_schannel_cleanup(void) -{ - Curl_sspi_global_cleanup(); -} - -size_t Curl_schannel_version(char *buffer, size_t size) -{ - size = snprintf(buffer, size, "WinSSL"); - - return size; -} - -int Curl_schannel_random(unsigned char *entropy, size_t length) -{ - HCRYPTPROV hCryptProv = 0; - - if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - return 1; - - if(!CryptGenRandom(hCryptProv, (DWORD)length, entropy)) { - CryptReleaseContext(hCryptProv, 0UL); - return 1; - } - - CryptReleaseContext(hCryptProv, 0UL); - return 0; -} - -#ifdef _WIN32_WCE -static CURLcode verify_certificate(struct connectdata *conn, int sockindex) -{ - SECURITY_STATUS status; - struct SessionHandle *data = conn->data; - struct ssl_connect_data *connssl = &conn->ssl[sockindex]; - CURLcode result = CURLE_OK; - CERT_CONTEXT *pCertContextServer = NULL; - const CERT_CHAIN_CONTEXT *pChainContext = NULL; - - status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle, - SECPKG_ATTR_REMOTE_CERT_CONTEXT, - &pCertContextServer); - - if((status != SEC_E_OK) || (pCertContextServer == NULL)) { - failf(data, "schannel: Failed to read remote certificate context: %s", - Curl_sspi_strerror(conn, status)); - result = CURLE_PEER_FAILED_VERIFICATION; - } - - if(result == CURLE_OK) { - CERT_CHAIN_PARA ChainPara; - memset(&ChainPara, 0, sizeof(ChainPara)); - ChainPara.cbSize = sizeof(ChainPara); - - if(!CertGetCertificateChain(NULL, - pCertContextServer, - NULL, - pCertContextServer->hCertStore, - &ChainPara, - (data->set.ssl_no_revoke ? 0 : - CERT_CHAIN_REVOCATION_CHECK_CHAIN), - NULL, - &pChainContext)) { - failf(data, "schannel: CertGetCertificateChain failed: %s", - Curl_sspi_strerror(conn, GetLastError())); - pChainContext = NULL; - result = CURLE_PEER_FAILED_VERIFICATION; - } - - if(result == CURLE_OK) { - CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0]; - DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED); - dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus; - if(dwTrustErrorMask) { - if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_REVOKED"); - else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_PARTIAL_CHAIN"); - else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_UNTRUSTED_ROOT"); - else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID) - failf(data, "schannel: CertGetCertificateChain trust error" - " CERT_TRUST_IS_NOT_TIME_VALID"); - else - failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x", - dwTrustErrorMask); - result = CURLE_PEER_FAILED_VERIFICATION; - } - } - } - - if(result == CURLE_OK) { - if(data->set.ssl.verifyhost) { - TCHAR cert_hostname_buff[128]; - xcharp_u hostname; - xcharp_u cert_hostname; - DWORD len; - - cert_hostname.const_tchar_ptr = cert_hostname_buff; - hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name); - - /* TODO: Fix this for certificates with multiple alternative names. - Right now we're only asking for the first preferred alternative name. - Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG - (if WinCE supports that?) and run this section in a loop for each. - https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx - curl: (51) schannel: CertGetNameString() certificate hostname - (.google.com) did not match connection (google.com) - */ - len = CertGetNameString(pCertContextServer, - CERT_NAME_DNS_TYPE, - 0, - NULL, - cert_hostname.tchar_ptr, - 128); - if(len > 0 && *cert_hostname.tchar_ptr == '*') { - /* this is a wildcard cert. try matching the last len - 1 chars */ - int hostname_len = strlen(conn->host.name); - cert_hostname.tchar_ptr++; - if(_tcsicmp(cert_hostname.const_tchar_ptr, - hostname.const_tchar_ptr + hostname_len - len + 2) != 0) - result = CURLE_PEER_FAILED_VERIFICATION; - } - else if(len == 0 || _tcsicmp(hostname.const_tchar_ptr, - cert_hostname.const_tchar_ptr) != 0) { - result = CURLE_PEER_FAILED_VERIFICATION; - } - if(result == CURLE_PEER_FAILED_VERIFICATION) { - char *_cert_hostname; - _cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname.tchar_ptr); - failf(data, "schannel: CertGetNameString() certificate hostname " - "(%s) did not match connection (%s)", - _cert_hostname, conn->host.name); - Curl_unicodefree(_cert_hostname); - } - Curl_unicodefree(hostname.tchar_ptr); - } - } - - if(pChainContext) - CertFreeCertificateChain(pChainContext); - - if(pCertContextServer) - CertFreeCertificateContext(pCertContextServer); - - return result; -} -#endif /* _WIN32_WCE */ - -#endif /* USE_SCHANNEL */ diff --git a/Externals/curl/lib/vtls/schannel.h b/Externals/curl/lib/vtls/schannel.h deleted file mode 100644 index a314b34f9a..0000000000 --- a/Externals/curl/lib/vtls/schannel.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef HEADER_CURL_SCHANNEL_H -#define HEADER_CURL_SCHANNEL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2012, Marc Hoersken, , et al. - * Copyright (C) 2012 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#ifdef USE_SCHANNEL - -#include "urldata.h" - -#ifndef UNISP_NAME_A -#define UNISP_NAME_A "Microsoft Unified Security Protocol Provider" -#endif - -#ifndef UNISP_NAME_W -#define UNISP_NAME_W L"Microsoft Unified Security Protocol Provider" -#endif - -#ifndef UNISP_NAME -#ifdef UNICODE -#define UNISP_NAME UNISP_NAME_W -#else -#define UNISP_NAME UNISP_NAME_A -#endif -#endif - -#ifndef SP_PROT_SSL2_CLIENT -#define SP_PROT_SSL2_CLIENT 0x00000008 -#endif - -#ifndef SP_PROT_SSL3_CLIENT -#define SP_PROT_SSL3_CLIENT 0x00000008 -#endif - -#ifndef SP_PROT_TLS1_CLIENT -#define SP_PROT_TLS1_CLIENT 0x00000080 -#endif - -#ifndef SP_PROT_TLS1_0_CLIENT -#define SP_PROT_TLS1_0_CLIENT SP_PROT_TLS1_CLIENT -#endif - -#ifndef SP_PROT_TLS1_1_CLIENT -#define SP_PROT_TLS1_1_CLIENT 0x00000200 -#endif - -#ifndef SP_PROT_TLS1_2_CLIENT -#define SP_PROT_TLS1_2_CLIENT 0x00000800 -#endif - -#ifndef SECBUFFER_ALERT -#define SECBUFFER_ALERT 17 -#endif - -/* Both schannel buffer sizes must be > 0 */ -#define CURL_SCHANNEL_BUFFER_INIT_SIZE 4096 -#define CURL_SCHANNEL_BUFFER_FREE_SIZE 1024 - - -CURLcode Curl_schannel_connect(struct connectdata *conn, int sockindex); - -CURLcode Curl_schannel_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); - -bool Curl_schannel_data_pending(const struct connectdata *conn, int sockindex); -void Curl_schannel_close(struct connectdata *conn, int sockindex); -int Curl_schannel_shutdown(struct connectdata *conn, int sockindex); -void Curl_schannel_session_free(void *ptr); - -int Curl_schannel_init(void); -void Curl_schannel_cleanup(void); -size_t Curl_schannel_version(char *buffer, size_t size); - -int Curl_schannel_random(unsigned char *entropy, size_t length); - -/* Set the API backend definition to Schannel */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_SCHANNEL - -/* API setup for Schannel */ -#define curlssl_init Curl_schannel_init -#define curlssl_cleanup Curl_schannel_cleanup -#define curlssl_connect Curl_schannel_connect -#define curlssl_connect_nonblocking Curl_schannel_connect_nonblocking -#define curlssl_session_free Curl_schannel_session_free -#define curlssl_close_all(x) ((void)x) -#define curlssl_close Curl_schannel_close -#define curlssl_shutdown Curl_schannel_shutdown -#define curlssl_set_engine(x,y) ((void)x, (void)y, CURLE_NOT_BUILT_IN) -#define curlssl_set_engine_default(x) ((void)x, CURLE_NOT_BUILT_IN) -#define curlssl_engines_list(x) ((void)x, (struct curl_slist *)NULL) -#define curlssl_version Curl_schannel_version -#define curlssl_check_cxn(x) ((void)x, -1) -#define curlssl_data_pending Curl_schannel_data_pending -#define curlssl_random(x,y,z) ((void)x, Curl_schannel_random(y,z)) - -#endif /* USE_SCHANNEL */ -#endif /* HEADER_CURL_SCHANNEL_H */ diff --git a/Externals/curl/lib/vtls/vtls.c b/Externals/curl/lib/vtls/vtls.c deleted file mode 100644 index ca505a71ca..0000000000 --- a/Externals/curl/lib/vtls/vtls.c +++ /dev/null @@ -1,993 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* This file is for implementing all "generic" SSL functions that all libcurl - internals should use. It is then responsible for calling the proper - "backend" function. - - SSL-functions in libcurl should call functions in this source file, and not - to any specific SSL-layer. - - Curl_ssl_ - prefix for generic ones - Curl_ossl_ - prefix for OpenSSL ones - Curl_gtls_ - prefix for GnuTLS ones - Curl_nss_ - prefix for NSS ones - Curl_gskit_ - prefix for GSKit ones - Curl_polarssl_ - prefix for PolarSSL ones - Curl_cyassl_ - prefix for CyaSSL ones - Curl_schannel_ - prefix for Schannel SSPI ones - Curl_darwinssl_ - prefix for SecureTransport (Darwin) ones - - Note that this source code uses curlssl_* functions, and they are all - defines/macros #defined by the lib-specific header files. - - "SSL/TLS Strong Encryption: An Introduction" - https://httpd.apache.org/docs/2.0/ssl/ssl_intro.html -*/ - -#include "curl_setup.h" - -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_FCNTL_H -#include -#endif - -#include "urldata.h" - -#include "vtls.h" /* generic SSL protos etc */ -#include "slist.h" -#include "sendf.h" -#include "rawstr.h" -#include "url.h" -#include "progress.h" -#include "share.h" -#include "timeval.h" -#include "curl_md5.h" -#include "warnless.h" -#include "curl_base64.h" -#include "curl_printf.h" - -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" - -/* convenience macro to check if this handle is using a shared SSL session */ -#define SSLSESSION_SHARED(data) (data->share && \ - (data->share->specifier & \ - (1<version == needle->version) && - (data->verifypeer == needle->verifypeer) && - (data->verifyhost == needle->verifyhost) && - safe_strequal(data->CApath, needle->CApath) && - safe_strequal(data->CAfile, needle->CAfile) && - safe_strequal(data->random_file, needle->random_file) && - safe_strequal(data->egdsocket, needle->egdsocket) && - safe_strequal(data->cipher_list, needle->cipher_list)) - return TRUE; - - return FALSE; -} - -bool -Curl_clone_ssl_config(struct ssl_config_data *source, - struct ssl_config_data *dest) -{ - dest->sessionid = source->sessionid; - dest->verifyhost = source->verifyhost; - dest->verifypeer = source->verifypeer; - dest->version = source->version; - - if(source->CAfile) { - dest->CAfile = strdup(source->CAfile); - if(!dest->CAfile) - return FALSE; - } - else - dest->CAfile = NULL; - - if(source->CApath) { - dest->CApath = strdup(source->CApath); - if(!dest->CApath) - return FALSE; - } - else - dest->CApath = NULL; - - if(source->cipher_list) { - dest->cipher_list = strdup(source->cipher_list); - if(!dest->cipher_list) - return FALSE; - } - else - dest->cipher_list = NULL; - - if(source->egdsocket) { - dest->egdsocket = strdup(source->egdsocket); - if(!dest->egdsocket) - return FALSE; - } - else - dest->egdsocket = NULL; - - if(source->random_file) { - dest->random_file = strdup(source->random_file); - if(!dest->random_file) - return FALSE; - } - else - dest->random_file = NULL; - - return TRUE; -} - -void Curl_free_ssl_config(struct ssl_config_data* sslc) -{ - Curl_safefree(sslc->CAfile); - Curl_safefree(sslc->CApath); - Curl_safefree(sslc->cipher_list); - Curl_safefree(sslc->egdsocket); - Curl_safefree(sslc->random_file); -} - - -/* - * Curl_rand() returns a random unsigned integer, 32bit. - * - * This non-SSL function is put here only because this file is the only one - * with knowledge of what the underlying SSL libraries provide in terms of - * randomizers. - * - * NOTE: 'data' may be passed in as NULL when coming from external API without - * easy handle! - * - */ - -unsigned int Curl_rand(struct SessionHandle *data) -{ - unsigned int r = 0; - static unsigned int randseed; - static bool seeded = FALSE; - -#ifdef CURLDEBUG - char *force_entropy = getenv("CURL_ENTROPY"); - if(force_entropy) { - if(!seeded) { - size_t elen = strlen(force_entropy); - size_t clen = sizeof(randseed); - size_t min = elen < clen ? elen : clen; - memcpy((char *)&randseed, force_entropy, min); - seeded = TRUE; - } - else - randseed++; - return randseed; - } -#endif - - /* data may be NULL! */ - if(!Curl_ssl_random(data, (unsigned char *)&r, sizeof(r))) - return r; - - /* If Curl_ssl_random() returns non-zero it couldn't offer randomness and we - instead perform a "best effort" */ - -#ifdef RANDOM_FILE - if(!seeded) { - /* if there's a random file to read a seed from, use it */ - int fd = open(RANDOM_FILE, O_RDONLY); - if(fd > -1) { - /* read random data into the randseed variable */ - ssize_t nread = read(fd, &randseed, sizeof(randseed)); - if(nread == sizeof(randseed)) - seeded = TRUE; - close(fd); - } - } -#endif - - if(!seeded) { - struct timeval now = curlx_tvnow(); - infof(data, "WARNING: Using weak random seed\n"); - randseed += (unsigned int)now.tv_usec + (unsigned int)now.tv_sec; - randseed = randseed * 1103515245 + 12345; - randseed = randseed * 1103515245 + 12345; - randseed = randseed * 1103515245 + 12345; - seeded = TRUE; - } - - /* Return an unsigned 32-bit pseudo-random number. */ - r = randseed = randseed * 1103515245 + 12345; - return (r << 16) | ((r >> 16) & 0xFFFF); -} - -int Curl_ssl_backend(void) -{ - return (int)CURL_SSL_BACKEND; -} - -#ifdef USE_SSL - -/* "global" init done? */ -static bool init_ssl=FALSE; - -/** - * Global SSL init - * - * @retval 0 error initializing SSL - * @retval 1 SSL initialized successfully - */ -int Curl_ssl_init(void) -{ - /* make sure this is only done once */ - if(init_ssl) - return 1; - init_ssl = TRUE; /* never again */ - - return curlssl_init(); -} - - -/* Global cleanup */ -void Curl_ssl_cleanup(void) -{ - if(init_ssl) { - /* only cleanup if we did a previous init */ - curlssl_cleanup(); - init_ssl = FALSE; - } -} - -static bool ssl_prefs_check(struct SessionHandle *data) -{ - /* check for CURLOPT_SSLVERSION invalid parameter value */ - if((data->set.ssl.version < 0) - || (data->set.ssl.version >= CURL_SSLVERSION_LAST)) { - failf(data, "Unrecognized parameter value passed via CURLOPT_SSLVERSION"); - return FALSE; - } - return TRUE; -} - -CURLcode -Curl_ssl_connect(struct connectdata *conn, int sockindex) -{ - CURLcode result; - - if(!ssl_prefs_check(conn->data)) - return CURLE_SSL_CONNECT_ERROR; - - /* mark this is being ssl-enabled from here on. */ - conn->ssl[sockindex].use = TRUE; - conn->ssl[sockindex].state = ssl_connection_negotiating; - - result = curlssl_connect(conn, sockindex); - - if(!result) - Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */ - - return result; -} - -CURLcode -Curl_ssl_connect_nonblocking(struct connectdata *conn, int sockindex, - bool *done) -{ - CURLcode result; - - if(!ssl_prefs_check(conn->data)) - return CURLE_SSL_CONNECT_ERROR; - - /* mark this is being ssl requested from here on. */ - conn->ssl[sockindex].use = TRUE; -#ifdef curlssl_connect_nonblocking - result = curlssl_connect_nonblocking(conn, sockindex, done); -#else - *done = TRUE; /* fallback to BLOCKING */ - result = curlssl_connect(conn, sockindex); -#endif /* non-blocking connect support */ - if(!result && *done) - Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSL is connected */ - return result; -} - -/* - * Check if there's a session ID for the given connection in the cache, and if - * there's one suitable, it is provided. Returns TRUE when no entry matched. - */ -bool Curl_ssl_getsessionid(struct connectdata *conn, - void **ssl_sessionid, - size_t *idsize) /* set 0 if unknown */ -{ - struct curl_ssl_session *check; - struct SessionHandle *data = conn->data; - size_t i; - long *general_age; - bool no_match = TRUE; - - *ssl_sessionid = NULL; - - if(!conn->ssl_config.sessionid) - /* session ID re-use is disabled */ - return TRUE; - - /* Lock if shared */ - if(SSLSESSION_SHARED(data)) { - Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); - general_age = &data->share->sessionage; - } - else - general_age = &data->state.sessionage; - - for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) { - check = &data->state.session[i]; - if(!check->sessionid) - /* not session ID means blank entry */ - continue; - if(Curl_raw_equal(conn->host.name, check->name) && - ((!conn->bits.conn_to_host && !check->conn_to_host) || - (conn->bits.conn_to_host && check->conn_to_host && - Curl_raw_equal(conn->conn_to_host.name, check->conn_to_host))) && - ((!conn->bits.conn_to_port && check->conn_to_port == -1) || - (conn->bits.conn_to_port && check->conn_to_port != -1 && - conn->conn_to_port == check->conn_to_port)) && - (conn->remote_port == check->remote_port) && - Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) { - /* yes, we have a session ID! */ - (*general_age)++; /* increase general age */ - check->age = *general_age; /* set this as used in this age */ - *ssl_sessionid = check->sessionid; - if(idsize) - *idsize = check->idsize; - no_match = FALSE; - break; - } - } - - /* Unlock */ - if(SSLSESSION_SHARED(data)) - Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); - - return no_match; -} - -/* - * Kill a single session ID entry in the cache. - */ -void Curl_ssl_kill_session(struct curl_ssl_session *session) -{ - if(session->sessionid) { - /* defensive check */ - - /* free the ID the SSL-layer specific way */ - curlssl_session_free(session->sessionid); - - session->sessionid = NULL; - session->age = 0; /* fresh */ - - Curl_free_ssl_config(&session->ssl_config); - - Curl_safefree(session->name); - Curl_safefree(session->conn_to_host); - } -} - -/* - * Delete the given session ID from the cache. - */ -void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid) -{ - size_t i; - struct SessionHandle *data=conn->data; - - if(SSLSESSION_SHARED(data)) - Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); - - for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) { - struct curl_ssl_session *check = &data->state.session[i]; - - if(check->sessionid == ssl_sessionid) { - Curl_ssl_kill_session(check); - break; - } - } - - if(SSLSESSION_SHARED(data)) - Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); -} - -/* - * Store session id in the session cache. The ID passed on to this function - * must already have been extracted and allocated the proper way for the SSL - * layer. Curl_XXXX_session_free() will be called to free/kill the session ID - * later on. - */ -CURLcode Curl_ssl_addsessionid(struct connectdata *conn, - void *ssl_sessionid, - size_t idsize) -{ - size_t i; - struct SessionHandle *data=conn->data; /* the mother of all structs */ - struct curl_ssl_session *store = &data->state.session[0]; - long oldest_age=data->state.session[0].age; /* zero if unused */ - char *clone_host; - char *clone_conn_to_host; - int conn_to_port; - long *general_age; - - /* Even though session ID re-use might be disabled, that only disables USING - IT. We still store it here in case the re-using is again enabled for an - upcoming transfer */ - - clone_host = strdup(conn->host.name); - if(!clone_host) - return CURLE_OUT_OF_MEMORY; /* bail out */ - - if(conn->bits.conn_to_host) { - clone_conn_to_host = strdup(conn->conn_to_host.name); - if(!clone_conn_to_host) { - free(clone_host); - return CURLE_OUT_OF_MEMORY; /* bail out */ - } - } - else - clone_conn_to_host = NULL; - - if(conn->bits.conn_to_port) - conn_to_port = conn->conn_to_port; - else - conn_to_port = -1; - - /* Now we should add the session ID and the host name to the cache, (remove - the oldest if necessary) */ - - /* If using shared SSL session, lock! */ - if(SSLSESSION_SHARED(data)) { - Curl_share_lock(data, CURL_LOCK_DATA_SSL_SESSION, CURL_LOCK_ACCESS_SINGLE); - general_age = &data->share->sessionage; - } - else { - general_age = &data->state.sessionage; - } - - /* find an empty slot for us, or find the oldest */ - for(i = 1; (i < data->set.ssl.max_ssl_sessions) && - data->state.session[i].sessionid; i++) { - if(data->state.session[i].age < oldest_age) { - oldest_age = data->state.session[i].age; - store = &data->state.session[i]; - } - } - if(i == data->set.ssl.max_ssl_sessions) - /* cache is full, we must "kill" the oldest entry! */ - Curl_ssl_kill_session(store); - else - store = &data->state.session[i]; /* use this slot */ - - /* now init the session struct wisely */ - store->sessionid = ssl_sessionid; - store->idsize = idsize; - store->age = *general_age; /* set current age */ - /* free it if there's one already present */ - free(store->name); - free(store->conn_to_host); - store->name = clone_host; /* clone host name */ - store->conn_to_host = clone_conn_to_host; /* clone connect to host name */ - store->conn_to_port = conn_to_port; /* connect to port number */ - store->remote_port = conn->remote_port; /* port number */ - - /* Unlock */ - if(SSLSESSION_SHARED(data)) - Curl_share_unlock(data, CURL_LOCK_DATA_SSL_SESSION); - - if(!Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config)) { - store->sessionid = NULL; /* let caller free sessionid */ - free(clone_host); - free(clone_conn_to_host); - return CURLE_OUT_OF_MEMORY; - } - - return CURLE_OK; -} - - -void Curl_ssl_close_all(struct SessionHandle *data) -{ - size_t i; - /* kill the session ID cache if not shared */ - if(data->state.session && !SSLSESSION_SHARED(data)) { - for(i = 0; i < data->set.ssl.max_ssl_sessions; i++) - /* the single-killer function handles empty table slots */ - Curl_ssl_kill_session(&data->state.session[i]); - - /* free the cache data */ - Curl_safefree(data->state.session); - } - - curlssl_close_all(data); -} - -void Curl_ssl_close(struct connectdata *conn, int sockindex) -{ - DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); - curlssl_close(conn, sockindex); -} - -CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex) -{ - if(curlssl_shutdown(conn, sockindex)) - return CURLE_SSL_SHUTDOWN_FAILED; - - conn->ssl[sockindex].use = FALSE; /* get back to ordinary socket usage */ - conn->ssl[sockindex].state = ssl_connection_none; - - conn->recv[sockindex] = Curl_recv_plain; - conn->send[sockindex] = Curl_send_plain; - - return CURLE_OK; -} - -/* Selects an SSL crypto engine - */ -CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine) -{ - return curlssl_set_engine(data, engine); -} - -/* Selects the default SSL crypto engine - */ -CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data) -{ - return curlssl_set_engine_default(data); -} - -/* Return list of OpenSSL crypto engine names. */ -struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data) -{ - return curlssl_engines_list(data); -} - -/* - * This sets up a session ID cache to the specified size. Make sure this code - * is agnostic to what underlying SSL technology we use. - */ -CURLcode Curl_ssl_initsessions(struct SessionHandle *data, size_t amount) -{ - struct curl_ssl_session *session; - - if(data->state.session) - /* this is just a precaution to prevent multiple inits */ - return CURLE_OK; - - session = calloc(amount, sizeof(struct curl_ssl_session)); - if(!session) - return CURLE_OUT_OF_MEMORY; - - /* store the info in the SSL section */ - data->set.ssl.max_ssl_sessions = amount; - data->state.session = session; - data->state.sessionage = 1; /* this is brand new */ - return CURLE_OK; -} - -size_t Curl_ssl_version(char *buffer, size_t size) -{ - return curlssl_version(buffer, size); -} - -/* - * This function tries to determine connection status. - * - * Return codes: - * 1 means the connection is still in place - * 0 means the connection has been closed - * -1 means the connection status is unknown - */ -int Curl_ssl_check_cxn(struct connectdata *conn) -{ - return curlssl_check_cxn(conn); -} - -bool Curl_ssl_data_pending(const struct connectdata *conn, - int connindex) -{ - return curlssl_data_pending(conn, connindex); -} - -void Curl_ssl_free_certinfo(struct SessionHandle *data) -{ - int i; - struct curl_certinfo *ci = &data->info.certs; - - if(ci->num_of_certs) { - /* free all individual lists used */ - for(i=0; inum_of_certs; i++) { - curl_slist_free_all(ci->certinfo[i]); - ci->certinfo[i] = NULL; - } - - free(ci->certinfo); /* free the actual array too */ - ci->certinfo = NULL; - ci->num_of_certs = 0; - } -} - -CURLcode Curl_ssl_init_certinfo(struct SessionHandle *data, int num) -{ - struct curl_certinfo *ci = &data->info.certs; - struct curl_slist **table; - - /* Free any previous certificate information structures */ - Curl_ssl_free_certinfo(data); - - /* Allocate the required certificate information structures */ - table = calloc((size_t) num, sizeof(struct curl_slist *)); - if(!table) - return CURLE_OUT_OF_MEMORY; - - ci->num_of_certs = num; - ci->certinfo = table; - - return CURLE_OK; -} - -/* - * 'value' is NOT a zero terminated string - */ -CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle *data, - int certnum, - const char *label, - const char *value, - size_t valuelen) -{ - struct curl_certinfo * ci = &data->info.certs; - char * output; - struct curl_slist * nl; - CURLcode result = CURLE_OK; - size_t labellen = strlen(label); - size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */ - - output = malloc(outlen); - if(!output) - return CURLE_OUT_OF_MEMORY; - - /* sprintf the label and colon */ - snprintf(output, outlen, "%s:", label); - - /* memcpy the value (it might not be zero terminated) */ - memcpy(&output[labellen+1], value, valuelen); - - /* zero terminate the output */ - output[labellen + 1 + valuelen] = 0; - - nl = Curl_slist_append_nodup(ci->certinfo[certnum], output); - if(!nl) { - free(output); - curl_slist_free_all(ci->certinfo[certnum]); - result = CURLE_OUT_OF_MEMORY; - } - - ci->certinfo[certnum] = nl; - return result; -} - -/* - * This is a convenience function for push_certinfo_len that takes a zero - * terminated value. - */ -CURLcode Curl_ssl_push_certinfo(struct SessionHandle *data, - int certnum, - const char *label, - const char *value) -{ - size_t valuelen = strlen(value); - - return Curl_ssl_push_certinfo_len(data, certnum, label, value, valuelen); -} - -int Curl_ssl_random(struct SessionHandle *data, - unsigned char *entropy, - size_t length) -{ - return curlssl_random(data, entropy, length); -} - -/* - * Public key pem to der conversion - */ - -static CURLcode pubkey_pem_to_der(const char *pem, - unsigned char **der, size_t *der_len) -{ - char *stripped_pem, *begin_pos, *end_pos; - size_t pem_count, stripped_pem_count = 0, pem_len; - CURLcode result; - - /* if no pem, exit. */ - if(!pem) - return CURLE_BAD_CONTENT_ENCODING; - - begin_pos = strstr(pem, "-----BEGIN PUBLIC KEY-----"); - if(!begin_pos) - return CURLE_BAD_CONTENT_ENCODING; - - pem_count = begin_pos - pem; - /* Invalid if not at beginning AND not directly following \n */ - if(0 != pem_count && '\n' != pem[pem_count - 1]) - return CURLE_BAD_CONTENT_ENCODING; - - /* 26 is length of "-----BEGIN PUBLIC KEY-----" */ - pem_count += 26; - - /* Invalid if not directly following \n */ - end_pos = strstr(pem + pem_count, "\n-----END PUBLIC KEY-----"); - if(!end_pos) - return CURLE_BAD_CONTENT_ENCODING; - - pem_len = end_pos - pem; - - stripped_pem = malloc(pem_len - pem_count + 1); - if(!stripped_pem) - return CURLE_OUT_OF_MEMORY; - - /* - * Here we loop through the pem array one character at a time between the - * correct indices, and place each character that is not '\n' or '\r' - * into the stripped_pem array, which should represent the raw base64 string - */ - while(pem_count < pem_len) { - if('\n' != pem[pem_count] && '\r' != pem[pem_count]) - stripped_pem[stripped_pem_count++] = pem[pem_count]; - ++pem_count; - } - /* Place the null terminator in the correct place */ - stripped_pem[stripped_pem_count] = '\0'; - - result = Curl_base64_decode(stripped_pem, der, der_len); - - Curl_safefree(stripped_pem); - - return result; -} - -/* - * Generic pinned public key check. - */ - -CURLcode Curl_pin_peer_pubkey(struct SessionHandle *data, - const char *pinnedpubkey, - const unsigned char *pubkey, size_t pubkeylen) -{ - FILE *fp; - unsigned char *buf = NULL, *pem_ptr = NULL; - long filesize; - size_t size, pem_len; - CURLcode pem_read; - CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH; -#ifdef curlssl_sha256sum - CURLcode encode; - size_t encodedlen, pinkeylen; - char *encoded, *pinkeycopy, *begin_pos, *end_pos; - unsigned char *sha256sumdigest = NULL; -#endif - - /* if a path wasn't specified, don't pin */ - if(!pinnedpubkey) - return CURLE_OK; - if(!pubkey || !pubkeylen) - return result; - - /* only do this if pinnedpubkey starts with "sha256//", length 8 */ - if(strncmp(pinnedpubkey, "sha256//", 8) == 0) { -#ifdef curlssl_sha256sum - /* compute sha256sum of public key */ - sha256sumdigest = malloc(SHA256_DIGEST_LENGTH); - if(!sha256sumdigest) - return CURLE_OUT_OF_MEMORY; - curlssl_sha256sum(pubkey, pubkeylen, - sha256sumdigest, SHA256_DIGEST_LENGTH); - encode = Curl_base64_encode(data, (char *)sha256sumdigest, - SHA256_DIGEST_LENGTH, &encoded, &encodedlen); - Curl_safefree(sha256sumdigest); - - if(encode) - return encode; - - infof(data, "\t public key hash: sha256//%s\n", encoded); - - /* it starts with sha256//, copy so we can modify it */ - pinkeylen = strlen(pinnedpubkey) + 1; - pinkeycopy = malloc(pinkeylen); - if(!pinkeycopy) { - Curl_safefree(encoded); - return CURLE_OUT_OF_MEMORY; - } - memcpy(pinkeycopy, pinnedpubkey, pinkeylen); - /* point begin_pos to the copy, and start extracting keys */ - begin_pos = pinkeycopy; - do { - end_pos = strstr(begin_pos, ";sha256//"); - /* - * if there is an end_pos, null terminate, - * otherwise it'll go to the end of the original string - */ - if(end_pos) - end_pos[0] = '\0'; - - /* compare base64 sha256 digests, 8 is the length of "sha256//" */ - if(encodedlen == strlen(begin_pos + 8) && - !memcmp(encoded, begin_pos + 8, encodedlen)) { - result = CURLE_OK; - break; - } - - /* - * change back the null-terminator we changed earlier, - * and look for next begin - */ - if(end_pos) { - end_pos[0] = ';'; - begin_pos = strstr(end_pos, "sha256//"); - } - } while(end_pos && begin_pos); - Curl_safefree(encoded); - Curl_safefree(pinkeycopy); -#else - /* without sha256 support, this cannot match */ - (void)data; -#endif - return result; - } - - fp = fopen(pinnedpubkey, "rb"); - if(!fp) - return result; - - do { - /* Determine the file's size */ - if(fseek(fp, 0, SEEK_END)) - break; - filesize = ftell(fp); - if(fseek(fp, 0, SEEK_SET)) - break; - if(filesize < 0 || filesize > MAX_PINNED_PUBKEY_SIZE) - break; - - /* - * if the size of our certificate is bigger than the file - * size then it can't match - */ - size = curlx_sotouz((curl_off_t) filesize); - if(pubkeylen > size) - break; - - /* - * Allocate buffer for the pinned key - * With 1 additional byte for null terminator in case of PEM key - */ - buf = malloc(size + 1); - if(!buf) - break; - - /* Returns number of elements read, which should be 1 */ - if((int) fread(buf, size, 1, fp) != 1) - break; - - /* If the sizes are the same, it can't be base64 encoded, must be der */ - if(pubkeylen == size) { - if(!memcmp(pubkey, buf, pubkeylen)) - result = CURLE_OK; - break; - } - - /* - * Otherwise we will assume it's PEM and try to decode it - * after placing null terminator - */ - buf[size] = '\0'; - pem_read = pubkey_pem_to_der((const char *)buf, &pem_ptr, &pem_len); - /* if it wasn't read successfully, exit */ - if(pem_read) - break; - - /* - * if the size of our certificate doesn't match the size of - * the decoded file, they can't be the same, otherwise compare - */ - if(pubkeylen == pem_len && !memcmp(pubkey, pem_ptr, pubkeylen)) - result = CURLE_OK; - } while(0); - - Curl_safefree(buf); - Curl_safefree(pem_ptr); - fclose(fp); - - return result; -} - -#ifndef CURL_DISABLE_CRYPTO_AUTH -CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len) -{ -#ifdef curlssl_md5sum - curlssl_md5sum(tmp, tmplen, md5sum, md5len); -#else - MD5_context *MD5pw; - - (void) md5len; - - MD5pw = Curl_MD5_init(Curl_DIGEST_MD5); - if(!MD5pw) - return CURLE_OUT_OF_MEMORY; - Curl_MD5_update(MD5pw, tmp, curlx_uztoui(tmplen)); - Curl_MD5_final(MD5pw, md5sum); -#endif - return CURLE_OK; -} -#endif - -/* - * Check whether the SSL backend supports the status_request extension. - */ -bool Curl_ssl_cert_status_request(void) -{ -#ifdef curlssl_cert_status_request - return curlssl_cert_status_request(); -#else - return FALSE; -#endif -} - -/* - * Check whether the SSL backend supports false start. - */ -bool Curl_ssl_false_start(void) -{ -#ifdef curlssl_false_start - return curlssl_false_start(); -#else - return FALSE; -#endif -} - -#endif /* USE_SSL */ diff --git a/Externals/curl/lib/vtls/vtls.h b/Externals/curl/lib/vtls/vtls.h deleted file mode 100644 index 31ba9fc503..0000000000 --- a/Externals/curl/lib/vtls/vtls.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef HEADER_CURL_VTLS_H -#define HEADER_CURL_VTLS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#include "curl_setup.h" - -#include "openssl.h" /* OpenSSL versions */ -#include "gtls.h" /* GnuTLS versions */ -#include "nssg.h" /* NSS versions */ -#include "gskit.h" /* Global Secure ToolKit versions */ -#include "polarssl.h" /* PolarSSL versions */ -#include "axtls.h" /* axTLS versions */ -#include "cyassl.h" /* CyaSSL versions */ -#include "schannel.h" /* Schannel SSPI version */ -#include "darwinssl.h" /* SecureTransport (Darwin) version */ -#include "mbedtls.h" /* mbedTLS versions */ - -#ifndef MAX_PINNED_PUBKEY_SIZE -#define MAX_PINNED_PUBKEY_SIZE 1048576 /* 1MB */ -#endif - -#ifndef MD5_DIGEST_LENGTH -#define MD5_DIGEST_LENGTH 16 /* fixed size */ -#endif - -#ifndef SHA256_DIGEST_LENGTH -#define SHA256_DIGEST_LENGTH 32 /* fixed size */ -#endif - -/* see https://tools.ietf.org/html/draft-ietf-tls-applayerprotoneg-04 */ -#define ALPN_HTTP_1_1_LENGTH 8 -#define ALPN_HTTP_1_1 "http/1.1" - -bool Curl_ssl_config_matches(struct ssl_config_data* data, - struct ssl_config_data* needle); -bool Curl_clone_ssl_config(struct ssl_config_data* source, - struct ssl_config_data* dest); -void Curl_free_ssl_config(struct ssl_config_data* sslc); - -unsigned int Curl_rand(struct SessionHandle *); - -int Curl_ssl_backend(void); - -#ifdef USE_SSL -int Curl_ssl_init(void); -void Curl_ssl_cleanup(void); -CURLcode Curl_ssl_connect(struct connectdata *conn, int sockindex); -CURLcode Curl_ssl_connect_nonblocking(struct connectdata *conn, - int sockindex, - bool *done); -/* tell the SSL stuff to close down all open information regarding - connections (and thus session ID caching etc) */ -void Curl_ssl_close_all(struct SessionHandle *data); -void Curl_ssl_close(struct connectdata *conn, int sockindex); -CURLcode Curl_ssl_shutdown(struct connectdata *conn, int sockindex); -CURLcode Curl_ssl_set_engine(struct SessionHandle *data, const char *engine); -/* Sets engine as default for all SSL operations */ -CURLcode Curl_ssl_set_engine_default(struct SessionHandle *data); -struct curl_slist *Curl_ssl_engines_list(struct SessionHandle *data); - -/* init the SSL session ID cache */ -CURLcode Curl_ssl_initsessions(struct SessionHandle *, size_t); -size_t Curl_ssl_version(char *buffer, size_t size); -bool Curl_ssl_data_pending(const struct connectdata *conn, - int connindex); -int Curl_ssl_check_cxn(struct connectdata *conn); - -/* Certificate information list handling. */ - -void Curl_ssl_free_certinfo(struct SessionHandle *data); -CURLcode Curl_ssl_init_certinfo(struct SessionHandle * data, int num); -CURLcode Curl_ssl_push_certinfo_len(struct SessionHandle * data, int certnum, - const char * label, const char * value, - size_t valuelen); -CURLcode Curl_ssl_push_certinfo(struct SessionHandle * data, int certnum, - const char * label, const char * value); - -/* Functions to be used by SSL library adaptation functions */ - -/* extract a session ID */ -bool Curl_ssl_getsessionid(struct connectdata *conn, - void **ssl_sessionid, - size_t *idsize); /* set 0 if unknown */ -/* add a new session ID */ -CURLcode Curl_ssl_addsessionid(struct connectdata *conn, - void *ssl_sessionid, - size_t idsize); -/* Kill a single session ID entry in the cache */ -void Curl_ssl_kill_session(struct curl_ssl_session *session); -/* delete a session from the cache */ -void Curl_ssl_delsessionid(struct connectdata *conn, void *ssl_sessionid); - -/* get N random bytes into the buffer, return 0 if a find random is filled - in */ -int Curl_ssl_random(struct SessionHandle *data, unsigned char *buffer, - size_t length); -CURLcode Curl_ssl_md5sum(unsigned char *tmp, /* input */ - size_t tmplen, - unsigned char *md5sum, /* output */ - size_t md5len); -/* Check pinned public key. */ -CURLcode Curl_pin_peer_pubkey(struct SessionHandle *data, - const char *pinnedpubkey, - const unsigned char *pubkey, size_t pubkeylen); - -bool Curl_ssl_cert_status_request(void); - -bool Curl_ssl_false_start(void); - -#define SSL_SHUTDOWN_TIMEOUT 10000 /* ms */ - -#else -/* Set the API backend definition to none */ -#define CURL_SSL_BACKEND CURLSSLBACKEND_NONE - -/* When SSL support is not present, just define away these function calls */ -#define Curl_ssl_init() 1 -#define Curl_ssl_cleanup() Curl_nop_stmt -#define Curl_ssl_connect(x,y) CURLE_NOT_BUILT_IN -#define Curl_ssl_close_all(x) Curl_nop_stmt -#define Curl_ssl_close(x,y) Curl_nop_stmt -#define Curl_ssl_shutdown(x,y) CURLE_NOT_BUILT_IN -#define Curl_ssl_set_engine(x,y) CURLE_NOT_BUILT_IN -#define Curl_ssl_set_engine_default(x) CURLE_NOT_BUILT_IN -#define Curl_ssl_engines_list(x) NULL -#define Curl_ssl_send(a,b,c,d,e) -1 -#define Curl_ssl_recv(a,b,c,d,e) -1 -#define Curl_ssl_initsessions(x,y) CURLE_OK -#define Curl_ssl_version(x,y) 0 -#define Curl_ssl_data_pending(x,y) 0 -#define Curl_ssl_check_cxn(x) 0 -#define Curl_ssl_free_certinfo(x) Curl_nop_stmt -#define Curl_ssl_connect_nonblocking(x,y,z) CURLE_NOT_BUILT_IN -#define Curl_ssl_kill_session(x) Curl_nop_stmt -#define Curl_ssl_random(x,y,z) ((void)x, CURLE_NOT_BUILT_IN) -#define Curl_ssl_cert_status_request() FALSE -#define Curl_ssl_false_start() FALSE -#endif - -#endif /* HEADER_CURL_VTLS_H */ diff --git a/Externals/curl/lib/warnless.c b/Externals/curl/lib/warnless.c deleted file mode 100644 index 0c4472e4a9..0000000000 --- a/Externals/curl/lib/warnless.c +++ /dev/null @@ -1,543 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(__INTEL_COMPILER) && defined(__unix__) - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#endif /* __INTEL_COMPILER && __unix__ */ - -#define BUILDING_WARNLESS_C 1 - -#include "warnless.h" - -#define CURL_MASK_SCHAR 0x7F -#define CURL_MASK_UCHAR 0xFF - -#if (SIZEOF_SHORT == 2) -# define CURL_MASK_SSHORT 0x7FFF -# define CURL_MASK_USHORT 0xFFFF -#elif (SIZEOF_SHORT == 4) -# define CURL_MASK_SSHORT 0x7FFFFFFF -# define CURL_MASK_USHORT 0xFFFFFFFF -#elif (SIZEOF_SHORT == 8) -# define CURL_MASK_SSHORT 0x7FFFFFFFFFFFFFFF -# define CURL_MASK_USHORT 0xFFFFFFFFFFFFFFFF -#else -# error "SIZEOF_SHORT not defined" -#endif - -#if (SIZEOF_INT == 2) -# define CURL_MASK_SINT 0x7FFF -# define CURL_MASK_UINT 0xFFFF -#elif (SIZEOF_INT == 4) -# define CURL_MASK_SINT 0x7FFFFFFF -# define CURL_MASK_UINT 0xFFFFFFFF -#elif (SIZEOF_INT == 8) -# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFF -# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFF -#elif (SIZEOF_INT == 16) -# define CURL_MASK_SINT 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -# define CURL_MASK_UINT 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -#else -# error "SIZEOF_INT not defined" -#endif - -#if (CURL_SIZEOF_LONG == 2) -# define CURL_MASK_SLONG 0x7FFFL -# define CURL_MASK_ULONG 0xFFFFUL -#elif (CURL_SIZEOF_LONG == 4) -# define CURL_MASK_SLONG 0x7FFFFFFFL -# define CURL_MASK_ULONG 0xFFFFFFFFUL -#elif (CURL_SIZEOF_LONG == 8) -# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFL -# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFUL -#elif (CURL_SIZEOF_LONG == 16) -# define CURL_MASK_SLONG 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL -# define CURL_MASK_ULONG 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFUL -#else -# error "CURL_SIZEOF_LONG not defined" -#endif - -#if (CURL_SIZEOF_CURL_OFF_T == 2) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFF) -#elif (CURL_SIZEOF_CURL_OFF_T == 4) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFF) -#elif (CURL_SIZEOF_CURL_OFF_T == 8) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFF) -#elif (CURL_SIZEOF_CURL_OFF_T == 16) -# define CURL_MASK_SCOFFT CURL_OFF_T_C(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -# define CURL_MASK_UCOFFT CURL_OFF_TU_C(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -#else -# error "CURL_SIZEOF_CURL_OFF_T not defined" -#endif - -#if (SIZEOF_SIZE_T == SIZEOF_SHORT) -# define CURL_MASK_SSIZE_T CURL_MASK_SSHORT -# define CURL_MASK_USIZE_T CURL_MASK_USHORT -#elif (SIZEOF_SIZE_T == SIZEOF_INT) -# define CURL_MASK_SSIZE_T CURL_MASK_SINT -# define CURL_MASK_USIZE_T CURL_MASK_UINT -#elif (SIZEOF_SIZE_T == CURL_SIZEOF_LONG) -# define CURL_MASK_SSIZE_T CURL_MASK_SLONG -# define CURL_MASK_USIZE_T CURL_MASK_ULONG -#elif (SIZEOF_SIZE_T == CURL_SIZEOF_CURL_OFF_T) -# define CURL_MASK_SSIZE_T CURL_MASK_SCOFFT -# define CURL_MASK_USIZE_T CURL_MASK_UCOFFT -#else -# error "SIZEOF_SIZE_T not defined" -#endif - -/* -** unsigned long to unsigned short -*/ - -unsigned short curlx_ultous(unsigned long ulnum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_USHORT); - return (unsigned short)(ulnum & (unsigned long) CURL_MASK_USHORT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned long to unsigned char -*/ - -unsigned char curlx_ultouc(unsigned long ulnum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_UCHAR); - return (unsigned char)(ulnum & (unsigned long) CURL_MASK_UCHAR); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned long to signed int -*/ - -int curlx_ultosi(unsigned long ulnum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(ulnum <= (unsigned long) CURL_MASK_SINT); - return (int)(ulnum & (unsigned long) CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned size_t to signed curl_off_t -*/ - -curl_off_t curlx_uztoso(size_t uznum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uznum <= (size_t) CURL_MASK_SCOFFT); - return (curl_off_t)(uznum & (size_t) CURL_MASK_SCOFFT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned size_t to signed int -*/ - -int curlx_uztosi(size_t uznum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uznum <= (size_t) CURL_MASK_SINT); - return (int)(uznum & (size_t) CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned size_t to unsigned long -*/ - -unsigned long curlx_uztoul(size_t uznum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - -#if (CURL_SIZEOF_LONG < SIZEOF_SIZE_T) - DEBUGASSERT(uznum <= (size_t) CURL_MASK_ULONG); -#endif - return (unsigned long)(uznum & (size_t) CURL_MASK_ULONG); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned size_t to unsigned int -*/ - -unsigned int curlx_uztoui(size_t uznum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - -#if (SIZEOF_INT < SIZEOF_SIZE_T) - DEBUGASSERT(uznum <= (size_t) CURL_MASK_UINT); -#endif - return (unsigned int)(uznum & (size_t) CURL_MASK_UINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** signed long to signed int -*/ - -int curlx_sltosi(long slnum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(slnum >= 0); -#if (SIZEOF_INT < CURL_SIZEOF_LONG) - DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_SINT); -#endif - return (int)(slnum & (long) CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** signed long to unsigned int -*/ - -unsigned int curlx_sltoui(long slnum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(slnum >= 0); -#if (SIZEOF_INT < CURL_SIZEOF_LONG) - DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_UINT); -#endif - return (unsigned int)(slnum & (long) CURL_MASK_UINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** signed long to unsigned short -*/ - -unsigned short curlx_sltous(long slnum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(slnum >= 0); - DEBUGASSERT((unsigned long) slnum <= (unsigned long) CURL_MASK_USHORT); - return (unsigned short)(slnum & (long) CURL_MASK_USHORT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned size_t to signed ssize_t -*/ - -ssize_t curlx_uztosz(size_t uznum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uznum <= (size_t) CURL_MASK_SSIZE_T); - return (ssize_t)(uznum & (size_t) CURL_MASK_SSIZE_T); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** signed curl_off_t to unsigned size_t -*/ - -size_t curlx_sotouz(curl_off_t sonum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(sonum >= 0); - return (size_t)(sonum & (curl_off_t) CURL_MASK_USIZE_T); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** signed ssize_t to signed int -*/ - -int curlx_sztosi(ssize_t sznum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(sznum >= 0); -#if (SIZEOF_INT < SIZEOF_SIZE_T) - DEBUGASSERT((size_t) sznum <= (size_t) CURL_MASK_SINT); -#endif - return (int)(sznum & (ssize_t) CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned int to unsigned short -*/ - -unsigned short curlx_uitous(unsigned int uinum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_USHORT); - return (unsigned short) (uinum & (unsigned int) CURL_MASK_USHORT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned int to unsigned char -*/ - -unsigned char curlx_uitouc(unsigned int uinum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_UCHAR); - return (unsigned char) (uinum & (unsigned int) CURL_MASK_UCHAR); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** unsigned int to signed int -*/ - -int curlx_uitosi(unsigned int uinum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(uinum <= (unsigned int) CURL_MASK_SINT); - return (int) (uinum & (unsigned int) CURL_MASK_SINT); - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -/* -** signed int to unsigned size_t -*/ - -size_t curlx_sitouz(int sinum) -{ -#ifdef __INTEL_COMPILER -# pragma warning(push) -# pragma warning(disable:810) /* conversion may lose significant bits */ -#endif - - DEBUGASSERT(sinum >= 0); - return (size_t) sinum; - -#ifdef __INTEL_COMPILER -# pragma warning(pop) -#endif -} - -#ifdef USE_WINSOCK - -/* -** curl_socket_t to signed int -*/ - -int curlx_sktosi(curl_socket_t s) -{ - return (int)((ssize_t) s); -} - -/* -** signed int to curl_socket_t -*/ - -curl_socket_t curlx_sitosk(int i) -{ - return (curl_socket_t)((ssize_t) i); -} - -#endif /* USE_WINSOCK */ - -#if defined(WIN32) || defined(_WIN32) - -ssize_t curlx_read(int fd, void *buf, size_t count) -{ - return (ssize_t)read(fd, buf, curlx_uztoui(count)); -} - -ssize_t curlx_write(int fd, const void *buf, size_t count) -{ - return (ssize_t)write(fd, buf, curlx_uztoui(count)); -} - -#endif /* WIN32 || _WIN32 */ - -#if defined(__INTEL_COMPILER) && defined(__unix__) - -int curlx_FD_ISSET(int fd, fd_set *fdset) -{ - #pragma warning(push) - #pragma warning(disable:1469) /* clobber ignored */ - return FD_ISSET(fd, fdset); - #pragma warning(pop) -} - -void curlx_FD_SET(int fd, fd_set *fdset) -{ - #pragma warning(push) - #pragma warning(disable:1469) /* clobber ignored */ - FD_SET(fd, fdset); - #pragma warning(pop) -} - -void curlx_FD_ZERO(fd_set *fdset) -{ - #pragma warning(push) - #pragma warning(disable:593) /* variable was set but never used */ - FD_ZERO(fdset); - #pragma warning(pop) -} - -unsigned short curlx_htons(unsigned short usnum) -{ -#if (__INTEL_COMPILER == 910) && defined(__i386__) - return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF)); -#else - #pragma warning(push) - #pragma warning(disable:810) /* conversion may lose significant bits */ - return htons(usnum); - #pragma warning(pop) -#endif -} - -unsigned short curlx_ntohs(unsigned short usnum) -{ -#if (__INTEL_COMPILER == 910) && defined(__i386__) - return (unsigned short)(((usnum << 8) & 0xFF00) | ((usnum >> 8) & 0x00FF)); -#else - #pragma warning(push) - #pragma warning(disable:810) /* conversion may lose significant bits */ - return ntohs(usnum); - #pragma warning(pop) -#endif -} - -#endif /* __INTEL_COMPILER && __unix__ */ diff --git a/Externals/curl/lib/warnless.h b/Externals/curl/lib/warnless.h deleted file mode 100644 index ab6d29998d..0000000000 --- a/Externals/curl/lib/warnless.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef HEADER_CURL_WARNLESS_H -#define HEADER_CURL_WARNLESS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#ifdef USE_WINSOCK -#include /* for curl_socket_t */ -#endif - -unsigned short curlx_ultous(unsigned long ulnum); - -unsigned char curlx_ultouc(unsigned long ulnum); - -int curlx_ultosi(unsigned long ulnum); - -int curlx_uztosi(size_t uznum); - -curl_off_t curlx_uztoso(size_t uznum); - -unsigned long curlx_uztoul(size_t uznum); - -unsigned int curlx_uztoui(size_t uznum); - -int curlx_sltosi(long slnum); - -unsigned int curlx_sltoui(long slnum); - -unsigned short curlx_sltous(long slnum); - -ssize_t curlx_uztosz(size_t uznum); - -size_t curlx_sotouz(curl_off_t sonum); - -int curlx_sztosi(ssize_t sznum); - -unsigned short curlx_uitous(unsigned int uinum); - -unsigned char curlx_uitouc(unsigned int uinum); - -int curlx_uitosi(unsigned int uinum); - -size_t curlx_sitouz(int sinum); - -#ifdef USE_WINSOCK - -int curlx_sktosi(curl_socket_t s); - -curl_socket_t curlx_sitosk(int i); - -#endif /* USE_WINSOCK */ - -#if defined(WIN32) || defined(_WIN32) - -ssize_t curlx_read(int fd, void *buf, size_t count); - -ssize_t curlx_write(int fd, const void *buf, size_t count); - -#ifndef BUILDING_WARNLESS_C -# undef read -# define read(fd, buf, count) curlx_read(fd, buf, count) -# undef write -# define write(fd, buf, count) curlx_write(fd, buf, count) -#endif - -#endif /* WIN32 || _WIN32 */ - -#if defined(__INTEL_COMPILER) && defined(__unix__) - -int curlx_FD_ISSET(int fd, fd_set *fdset); - -void curlx_FD_SET(int fd, fd_set *fdset); - -void curlx_FD_ZERO(fd_set *fdset); - -unsigned short curlx_htons(unsigned short usnum); - -unsigned short curlx_ntohs(unsigned short usnum); - -#ifndef BUILDING_WARNLESS_C -# undef FD_ISSET -# define FD_ISSET(a,b) curlx_FD_ISSET((a),(b)) -# undef FD_SET -# define FD_SET(a,b) curlx_FD_SET((a),(b)) -# undef FD_ZERO -# define FD_ZERO(a) curlx_FD_ZERO((a)) -# undef htons -# define htons(a) curlx_htons((a)) -# undef ntohs -# define ntohs(a) curlx_ntohs((a)) -#endif - -#endif /* __INTEL_COMPILER && __unix__ */ - -#endif /* HEADER_CURL_WARNLESS_H */ diff --git a/Externals/curl/lib/wildcard.c b/Externals/curl/lib/wildcard.c deleted file mode 100644 index dbbe45f6fb..0000000000 --- a/Externals/curl/lib/wildcard.c +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#include "wildcard.h" -#include "llist.h" -#include "fileinfo.h" -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - -CURLcode Curl_wildcard_init(struct WildcardData *wc) -{ - DEBUGASSERT(wc->filelist == NULL); - /* now allocate only wc->filelist, everything else - will be allocated if it is needed. */ - wc->filelist = Curl_llist_alloc(Curl_fileinfo_dtor); - if(!wc->filelist) {; - return CURLE_OUT_OF_MEMORY; - } - return CURLE_OK; -} - -void Curl_wildcard_dtor(struct WildcardData *wc) -{ - if(!wc) - return; - - if(wc->tmp_dtor) { - wc->tmp_dtor(wc->tmp); - wc->tmp_dtor = ZERO_NULL; - wc->tmp = NULL; - } - DEBUGASSERT(wc->tmp == NULL); - - if(wc->filelist) { - Curl_llist_destroy(wc->filelist, NULL); - wc->filelist = NULL; - } - - free(wc->path); - wc->path = NULL; - free(wc->pattern); - wc->pattern = NULL; - - wc->customptr = NULL; - wc->state = CURLWC_INIT; -} diff --git a/Externals/curl/lib/wildcard.h b/Externals/curl/lib/wildcard.h deleted file mode 100644 index 7d66992b16..0000000000 --- a/Externals/curl/lib/wildcard.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef HEADER_CURL_WILDCARD_H -#define HEADER_CURL_WILDCARD_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 2010 - 2013, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -/* list of wildcard process states */ -typedef enum { - CURLWC_INIT = 0, - CURLWC_MATCHING, /* library is trying to get list of addresses for - downloading */ - CURLWC_DOWNLOADING, - CURLWC_CLEAN, /* deallocate resources and reset settings */ - CURLWC_SKIP, /* skip over concrete file */ - CURLWC_ERROR, /* error cases */ - CURLWC_DONE /* if is wildcard->state == CURLWC_DONE wildcard loop - will end */ -} curl_wildcard_states; - -typedef void (*curl_wildcard_tmp_dtor)(void *ptr); - -/* struct keeping information about wildcard download process */ -struct WildcardData { - curl_wildcard_states state; - char *path; /* path to the directory, where we trying wildcard-match */ - char *pattern; /* wildcard pattern */ - struct curl_llist *filelist; /* llist with struct Curl_fileinfo */ - void *tmp; /* pointer to protocol specific temporary data */ - curl_wildcard_tmp_dtor tmp_dtor; - void *customptr; /* for CURLOPT_CHUNK_DATA pointer */ -}; - -CURLcode Curl_wildcard_init(struct WildcardData *wc); -void Curl_wildcard_dtor(struct WildcardData *wc); - -struct SessionHandle; - -#endif /* HEADER_CURL_WILDCARD_H */ diff --git a/Externals/curl/lib/x509asn1.c b/Externals/curl/lib/x509asn1.c deleted file mode 100644 index c221ba075a..0000000000 --- a/Externals/curl/lib/x509asn1.c +++ /dev/null @@ -1,1185 +0,0 @@ -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ - defined(USE_CYASSL) - -#include -#include "urldata.h" -#include "strequal.h" -#include "hostcheck.h" -#include "vtls/vtls.h" -#include "sendf.h" -#include "inet_pton.h" -#include "curl_base64.h" -#include "x509asn1.h" - -/* The last 3 #include files should be in this order */ -#include "curl_printf.h" -#include "curl_memory.h" -#include "memdebug.h" - - -/* ASN.1 OIDs. */ -static const char cnOID[] = "2.5.4.3"; /* Common name. */ -static const char sanOID[] = "2.5.29.17"; /* Subject alternative name. */ - -static const curl_OID OIDtable[] = { - { "1.2.840.10040.4.1", "dsa" }, - { "1.2.840.10040.4.3", "dsa-with-sha1" }, - { "1.2.840.10045.2.1", "ecPublicKey" }, - { "1.2.840.10045.3.0.1", "c2pnb163v1" }, - { "1.2.840.10045.4.1", "ecdsa-with-SHA1" }, - { "1.2.840.10046.2.1", "dhpublicnumber" }, - { "1.2.840.113549.1.1.1", "rsaEncryption" }, - { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" }, - { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" }, - { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" }, - { "1.2.840.113549.1.1.10", "RSASSA-PSS" }, - { "1.2.840.113549.1.1.14", "sha224WithRSAEncryption" }, - { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" }, - { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" }, - { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" }, - { "1.2.840.113549.2.2", "md2" }, - { "1.2.840.113549.2.5", "md5" }, - { "1.3.14.3.2.26", "sha1" }, - { cnOID, "CN" }, - { "2.5.4.4", "SN" }, - { "2.5.4.5", "serialNumber" }, - { "2.5.4.6", "C" }, - { "2.5.4.7", "L" }, - { "2.5.4.8", "ST" }, - { "2.5.4.9", "streetAddress" }, - { "2.5.4.10", "O" }, - { "2.5.4.11", "OU" }, - { "2.5.4.12", "title" }, - { "2.5.4.13", "description" }, - { "2.5.4.17", "postalCode" }, - { "2.5.4.41", "name" }, - { "2.5.4.42", "givenName" }, - { "2.5.4.43", "initials" }, - { "2.5.4.44", "generationQualifier" }, - { "2.5.4.45", "X500UniqueIdentifier" }, - { "2.5.4.46", "dnQualifier" }, - { "2.5.4.65", "pseudonym" }, - { "1.2.840.113549.1.9.1", "emailAddress" }, - { "2.5.4.72", "role" }, - { sanOID, "subjectAltName" }, - { "2.5.29.18", "issuerAltName" }, - { "2.5.29.19", "basicConstraints" }, - { "2.16.840.1.101.3.4.2.4", "sha224" }, - { "2.16.840.1.101.3.4.2.1", "sha256" }, - { "2.16.840.1.101.3.4.2.2", "sha384" }, - { "2.16.840.1.101.3.4.2.3", "sha512" }, - { (const char *) NULL, (const char *) NULL } -}; - -/* - * Lightweight ASN.1 parser. - * In particular, it does not check for syntactic/lexical errors. - * It is intended to support certificate information gathering for SSL backends - * that offer a mean to get certificates as a whole, but do not supply - * entry points to get particular certificate sub-fields. - * Please note there is no pretention here to rewrite a full SSL library. - */ - - -const char * Curl_getASN1Element(curl_asn1Element * elem, - const char * beg, const char * end) -{ - unsigned char b; - unsigned long len; - curl_asn1Element lelem; - - /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg' - ending at `end'. - Returns a pointer in source string after the parsed element, or NULL - if an error occurs. */ - - if(beg >= end || !*beg) - return (const char *) NULL; - - /* Process header byte. */ - elem->header = beg; - b = (unsigned char) *beg++; - elem->constructed = (b & 0x20) != 0; - elem->class = (b >> 6) & 3; - b &= 0x1F; - if(b == 0x1F) - return (const char *) NULL; /* Long tag values not supported here. */ - elem->tag = b; - - /* Process length. */ - if(beg >= end) - return (const char *) NULL; - b = (unsigned char) *beg++; - if(!(b & 0x80)) - len = b; - else if(!(b &= 0x7F)) { - /* Unspecified length. Since we have all the data, we can determine the - effective length by skipping element until an end element is found. */ - if(!elem->constructed) - return (const char *) NULL; - elem->beg = beg; - while(beg < end && *beg) { - beg = Curl_getASN1Element(&lelem, beg, end); - if(!beg) - return (const char *) NULL; - } - if(beg >= end) - return (const char *) NULL; - elem->end = beg; - return beg + 1; - } - else if(beg + b > end) - return (const char *) NULL; /* Does not fit in source. */ - else { - /* Get long length. */ - len = 0; - do { - if(len & 0xFF000000L) - return (const char *) NULL; /* Lengths > 32 bits are not supported. */ - len = (len << 8) | (unsigned char) *beg++; - } while(--b); - } - if((unsigned long) (end - beg) < len) - return (const char *) NULL; /* Element data does not fit in source. */ - elem->beg = beg; - elem->end = beg + len; - return elem->end; -} - -static const curl_OID * searchOID(const char * oid) -{ - const curl_OID * op; - - /* Search the null terminated OID or OID identifier in local table. - Return the table entry pointer or NULL if not found. */ - - for(op = OIDtable; op->numoid; op++) - if(!strcmp(op->numoid, oid) || curl_strequal(op->textoid, oid)) - return op; - - return (const curl_OID *) NULL; -} - -static const char * bool2str(const char * beg, const char * end) -{ - /* Convert an ASN.1 Boolean value into its string representation. - Return the dynamically allocated string, or NULL if source is not an - ASN.1 Boolean value. */ - - if(end - beg != 1) - return (const char *) NULL; - return strdup(*beg? "TRUE": "FALSE"); -} - -static const char * octet2str(const char * beg, const char * end) -{ - size_t n = end - beg; - char * buf; - - /* Convert an ASN.1 octet string to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - - buf = malloc(3 * n + 1); - if(buf) - for(n = 0; beg < end; n += 3) - snprintf(buf + n, 4, "%02x:", *(const unsigned char *) beg++); - return buf; -} - -static const char * bit2str(const char * beg, const char * end) -{ - /* Convert an ASN.1 bit string to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - - if(++beg > end) - return (const char *) NULL; - return octet2str(beg, end); -} - -static const char * int2str(const char * beg, const char * end) -{ - long val = 0; - size_t n = end - beg; - - /* Convert an ASN.1 integer value into its string representation. - Return the dynamically allocated string, or NULL if source is not an - ASN.1 integer value. */ - - if(!n) - return (const char *) NULL; - - if(n > 4) - return octet2str(beg, end); - - /* Represent integers <= 32-bit as a single value. */ - if(*beg & 0x80) - val = ~val; - - do - val = (val << 8) | *(const unsigned char *) beg++; - while(beg < end); - return curl_maprintf("%s%lx", (val < 0 || val >= 10)? "0x": "", val); -} - -static ssize_t -utf8asn1str(char * * to, int type, const char * from, const char * end) -{ - size_t inlength = end - from; - int size = 1; - size_t outlength; - int charsize; - unsigned int wc; - char * buf; - - /* Perform a lazy conversion from an ASN.1 typed string to UTF8. Allocate the - destination buffer dynamically. The allocation size will normally be too - large: this is to avoid buffer overflows. - Terminate the string with a nul byte and return the converted - string length. */ - - *to = (char *) NULL; - switch (type) { - case CURL_ASN1_BMP_STRING: - size = 2; - break; - case CURL_ASN1_UNIVERSAL_STRING: - size = 4; - break; - case CURL_ASN1_NUMERIC_STRING: - case CURL_ASN1_PRINTABLE_STRING: - case CURL_ASN1_TELETEX_STRING: - case CURL_ASN1_IA5_STRING: - case CURL_ASN1_VISIBLE_STRING: - case CURL_ASN1_UTF8_STRING: - break; - default: - return -1; /* Conversion not supported. */ - } - - if(inlength % size) - return -1; /* Length inconsistent with character size. */ - buf = malloc(4 * (inlength / size) + 1); - if(!buf) - return -1; /* Not enough memory. */ - - if(type == CURL_ASN1_UTF8_STRING) { - /* Just copy. */ - outlength = inlength; - if(outlength) - memcpy(buf, from, outlength); - } - else { - for(outlength = 0; from < end;) { - wc = 0; - switch (size) { - case 4: - wc = (wc << 8) | *(const unsigned char *) from++; - wc = (wc << 8) | *(const unsigned char *) from++; - /* fallthrough */ - case 2: - wc = (wc << 8) | *(const unsigned char *) from++; - /* fallthrough */ - default: /* case 1: */ - wc = (wc << 8) | *(const unsigned char *) from++; - } - charsize = 1; - if(wc >= 0x00000080) { - if(wc >= 0x00000800) { - if(wc >= 0x00010000) { - if(wc >= 0x00200000) { - free(buf); - return -1; /* Invalid char. size for target encoding. */ - } - buf[outlength + 3] = (char) (0x80 | (wc & 0x3F)); - wc = (wc >> 6) | 0x00010000; - charsize++; - } - buf[outlength + 2] = (char) (0x80 | (wc & 0x3F)); - wc = (wc >> 6) | 0x00000800; - charsize++; - } - buf[outlength + 1] = (char) (0x80 | (wc & 0x3F)); - wc = (wc >> 6) | 0x000000C0; - charsize++; - } - buf[outlength] = (char) wc; - outlength += charsize; - } - } - buf[outlength] = '\0'; - *to = buf; - return outlength; -} - -static const char * string2str(int type, const char * beg, const char * end) -{ - char * buf; - - /* Convert an ASN.1 String into its UTF-8 string representation. - Return the dynamically allocated string, or NULL if an error occurs. */ - - if(utf8asn1str(&buf, type, beg, end) < 0) - return (const char *) NULL; - return buf; -} - -static int encodeUint(char * buf, int n, unsigned int x) -{ - int i = 0; - unsigned int y = x / 10; - - /* Decimal ASCII encode unsigned integer `x' in the `n'-byte buffer at `buf'. - Return the total number of encoded digits, even if larger than `n'. */ - - if(y) { - i += encodeUint(buf, n, y); - x -= y * 10; - } - if(i < n) - buf[i] = (char) ('0' + x); - i++; - if(i < n) - buf[i] = '\0'; /* Store a terminator if possible. */ - return i; -} - -static int encodeOID(char * buf, int n, const char * beg, const char * end) -{ - int i = 0; - unsigned int x; - unsigned int y; - - /* Convert an ASN.1 OID into its dotted string representation. - Store the result in th `n'-byte buffer at `buf'. - Return the converted string length, or -1 if an error occurs. */ - - /* Process the first two numbers. */ - y = *(const unsigned char *) beg++; - x = y / 40; - y -= x * 40; - i += encodeUint(buf + i, n - i, x); - if(i < n) - buf[i] = '.'; - i++; - i += encodeUint(buf + i, n - i, y); - - /* Process the trailing numbers. */ - while(beg < end) { - if(i < n) - buf[i] = '.'; - i++; - x = 0; - do { - if(x & 0xFF000000) - return -1; - y = *(const unsigned char *) beg++; - x = (x << 7) | (y & 0x7F); - } while(y & 0x80); - i += encodeUint(buf + i, n - i, x); - } - if(i < n) - buf[i] = '\0'; - return i; -} - -static const char * OID2str(const char * beg, const char * end, bool symbolic) -{ - char * buf = (char *) NULL; - const curl_OID * op; - int n; - - /* Convert an ASN.1 OID into its dotted or symbolic string representation. - Return the dynamically allocated string, or NULL if an error occurs. */ - - if(beg < end) { - n = encodeOID((char *) NULL, -1, beg, end); - if(n >= 0) { - buf = malloc(n + 1); - if(buf) { - encodeOID(buf, n, beg, end); - buf[n] = '\0'; - - if(symbolic) { - op = searchOID(buf); - if(op) { - free(buf); - buf = strdup(op->textoid); - } - } - } - } - } - return buf; -} - -static const char * GTime2str(const char * beg, const char * end) -{ - const char * tzp; - const char * fracp; - char sec1, sec2; - size_t fracl; - size_t tzl; - const char * sep = ""; - - /* Convert an ASN.1 Generalized time to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - - for(fracp = beg; fracp < end && *fracp >= '0' && *fracp <= '9'; fracp++) - ; - - /* Get seconds digits. */ - sec1 = '0'; - switch (fracp - beg - 12) { - case 0: - sec2 = '0'; - break; - case 2: - sec1 = fracp[-2]; - case 1: - sec2 = fracp[-1]; - break; - default: - return (const char *) NULL; - } - - /* Scan for timezone, measure fractional seconds. */ - tzp = fracp; - fracl = 0; - if(fracp < end && (*fracp == '.' || *fracp == ',')) { - fracp++; - do - tzp++; - while(tzp < end && *tzp >= '0' && *tzp <= '9'); - /* Strip leading zeroes in fractional seconds. */ - for(fracl = tzp - fracp - 1; fracl && fracp[fracl - 1] == '0'; fracl--) - ; - } - - /* Process timezone. */ - if(tzp >= end) - ; /* Nothing to do. */ - else if(*tzp == 'Z') { - tzp = " GMT"; - end = tzp + 4; - } - else { - sep = " "; - tzp++; - } - - tzl = end - tzp; - return curl_maprintf("%.4s-%.2s-%.2s %.2s:%.2s:%c%c%s%.*s%s%.*s", - beg, beg + 4, beg + 6, - beg + 8, beg + 10, sec1, sec2, - fracl? ".": "", fracl, fracp, - sep, tzl, tzp); -} - -static const char * UTime2str(const char * beg, const char * end) -{ - const char * tzp; - size_t tzl; - const char * sec; - - /* Convert an ASN.1 UTC time to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - - for(tzp = beg; tzp < end && *tzp >= '0' && *tzp <= '9'; tzp++) - ; - /* Get the seconds. */ - sec = beg + 10; - switch (tzp - sec) { - case 0: - sec = "00"; - case 2: - break; - default: - return (const char *) NULL; - } - - /* Process timezone. */ - if(tzp >= end) - return (const char *) NULL; - if(*tzp == 'Z') { - tzp = "GMT"; - end = tzp + 3; - } - else - tzp++; - - tzl = end - tzp; - return curl_maprintf("%u%.2s-%.2s-%.2s %.2s:%.2s:%.2s %.*s", - 20 - (*beg >= '5'), beg, beg + 2, beg + 4, - beg + 6, beg + 8, sec, - tzl, tzp); -} - -const char * Curl_ASN1tostr(curl_asn1Element * elem, int type) -{ - /* Convert an ASN.1 element to a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - - if(elem->constructed) - return (const char *) NULL; /* No conversion of structured elements. */ - - if(!type) - type = elem->tag; /* Type not forced: use element tag as type. */ - - switch (type) { - case CURL_ASN1_BOOLEAN: - return bool2str(elem->beg, elem->end); - case CURL_ASN1_INTEGER: - case CURL_ASN1_ENUMERATED: - return int2str(elem->beg, elem->end); - case CURL_ASN1_BIT_STRING: - return bit2str(elem->beg, elem->end); - case CURL_ASN1_OCTET_STRING: - return octet2str(elem->beg, elem->end); - case CURL_ASN1_NULL: - return strdup(""); - case CURL_ASN1_OBJECT_IDENTIFIER: - return OID2str(elem->beg, elem->end, TRUE); - case CURL_ASN1_UTC_TIME: - return UTime2str(elem->beg, elem->end); - case CURL_ASN1_GENERALIZED_TIME: - return GTime2str(elem->beg, elem->end); - case CURL_ASN1_UTF8_STRING: - case CURL_ASN1_NUMERIC_STRING: - case CURL_ASN1_PRINTABLE_STRING: - case CURL_ASN1_TELETEX_STRING: - case CURL_ASN1_IA5_STRING: - case CURL_ASN1_VISIBLE_STRING: - case CURL_ASN1_UNIVERSAL_STRING: - case CURL_ASN1_BMP_STRING: - return string2str(type, elem->beg, elem->end); - } - - return (const char *) NULL; /* Unsupported. */ -} - -static ssize_t encodeDN(char * buf, size_t n, curl_asn1Element * dn) -{ - curl_asn1Element rdn; - curl_asn1Element atv; - curl_asn1Element oid; - curl_asn1Element value; - size_t l = 0; - const char * p1; - const char * p2; - const char * p3; - const char * str; - - /* ASCII encode distinguished name at `dn' into the `n'-byte buffer at `buf'. - Return the total string length, even if larger than `n'. */ - - for(p1 = dn->beg; p1 < dn->end;) { - p1 = Curl_getASN1Element(&rdn, p1, dn->end); - for(p2 = rdn.beg; p2 < rdn.end;) { - p2 = Curl_getASN1Element(&atv, p2, rdn.end); - p3 = Curl_getASN1Element(&oid, atv.beg, atv.end); - Curl_getASN1Element(&value, p3, atv.end); - str = Curl_ASN1tostr(&oid, 0); - if(!str) - return -1; - - /* Encode delimiter. - If attribute has a short uppercase name, delimiter is ", ". */ - if(l) { - for(p3 = str; isupper(*p3); p3++) - ; - for(p3 = (*p3 || p3 - str > 2)? "/": ", "; *p3; p3++) { - if(l < n) - buf[l] = *p3; - l++; - } - } - - /* Encode attribute name. */ - for(p3 = str; *p3; p3++) { - if(l < n) - buf[l] = *p3; - l++; - } - free((char *) str); - - /* Generate equal sign. */ - if(l < n) - buf[l] = '='; - l++; - - /* Generate value. */ - str = Curl_ASN1tostr(&value, 0); - if(!str) - return -1; - for(p3 = str; *p3; p3++) { - if(l < n) - buf[l] = *p3; - l++; - } - free((char *) str); - } - } - - return l; -} - -const char * Curl_DNtostr(curl_asn1Element * dn) -{ - char * buf = (char *) NULL; - ssize_t n = encodeDN(buf, 0, dn); - - /* Convert an ASN.1 distinguished name into a printable string. - Return the dynamically allocated string, or NULL if an error occurs. */ - - if(n >= 0) { - buf = malloc(n + 1); - if(buf) { - encodeDN(buf, n + 1, dn); - buf[n] = '\0'; - } - } - return (const char *) buf; -} - -/* - * X509 parser. - */ - -void Curl_parseX509(curl_X509certificate * cert, - const char * beg, const char * end) -{ - curl_asn1Element elem; - curl_asn1Element tbsCertificate; - const char * ccp; - static const char defaultVersion = 0; /* v1. */ - - /* ASN.1 parse an X509 certificate into structure subfields. - Syntax is assumed to have already been checked by the SSL backend. - See RFC 5280. */ - - cert->certificate.header = NULL; - cert->certificate.beg = beg; - cert->certificate.end = end; - - /* Get the sequence content. */ - Curl_getASN1Element(&elem, beg, end); - beg = elem.beg; - end = elem.end; - - /* Get tbsCertificate. */ - beg = Curl_getASN1Element(&tbsCertificate, beg, end); - /* Skip the signatureAlgorithm. */ - beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end); - /* Get the signatureValue. */ - Curl_getASN1Element(&cert->signature, beg, end); - - /* Parse TBSCertificate. */ - beg = tbsCertificate.beg; - end = tbsCertificate.end; - /* Get optional version, get serialNumber. */ - cert->version.header = NULL; - cert->version.beg = &defaultVersion; - cert->version.end = &defaultVersion + sizeof defaultVersion;; - beg = Curl_getASN1Element(&elem, beg, end); - if(elem.tag == 0) { - Curl_getASN1Element(&cert->version, elem.beg, elem.end); - beg = Curl_getASN1Element(&elem, beg, end); - } - cert->serialNumber = elem; - /* Get signature algorithm. */ - beg = Curl_getASN1Element(&cert->signatureAlgorithm, beg, end); - /* Get issuer. */ - beg = Curl_getASN1Element(&cert->issuer, beg, end); - /* Get notBefore and notAfter. */ - beg = Curl_getASN1Element(&elem, beg, end); - ccp = Curl_getASN1Element(&cert->notBefore, elem.beg, elem.end); - Curl_getASN1Element(&cert->notAfter, ccp, elem.end); - /* Get subject. */ - beg = Curl_getASN1Element(&cert->subject, beg, end); - /* Get subjectPublicKeyAlgorithm and subjectPublicKey. */ - beg = Curl_getASN1Element(&cert->subjectPublicKeyInfo, beg, end); - ccp = Curl_getASN1Element(&cert->subjectPublicKeyAlgorithm, - cert->subjectPublicKeyInfo.beg, - cert->subjectPublicKeyInfo.end); - Curl_getASN1Element(&cert->subjectPublicKey, ccp, - cert->subjectPublicKeyInfo.end); - /* Get optional issuerUiqueID, subjectUniqueID and extensions. */ - cert->issuerUniqueID.tag = cert->subjectUniqueID.tag = 0; - cert->extensions.tag = elem.tag = 0; - cert->issuerUniqueID.header = cert->subjectUniqueID.header = NULL; - cert->issuerUniqueID.beg = cert->issuerUniqueID.end = ""; - cert->subjectUniqueID.beg = cert->subjectUniqueID.end = ""; - cert->extensions.header = NULL; - cert->extensions.beg = cert->extensions.end = ""; - if(beg < end) - beg = Curl_getASN1Element(&elem, beg, end); - if(elem.tag == 1) { - cert->issuerUniqueID = elem; - if(beg < end) - beg = Curl_getASN1Element(&elem, beg, end); - } - if(elem.tag == 2) { - cert->subjectUniqueID = elem; - if(beg < end) - beg = Curl_getASN1Element(&elem, beg, end); - } - if(elem.tag == 3) - Curl_getASN1Element(&cert->extensions, elem.beg, elem.end); -} - -static size_t copySubstring(char * to, const char * from) -{ - size_t i; - - /* Copy at most 64-characters, terminate with a newline and returns the - effective number of stored characters. */ - - for(i = 0; i < 64; i++) { - to[i] = *from; - if(!*from++) - break; - } - - to[i++] = '\n'; - return i; -} - -static const char * dumpAlgo(curl_asn1Element * param, - const char * beg, const char * end) -{ - curl_asn1Element oid; - - /* Get algorithm parameters and return algorithm name. */ - - beg = Curl_getASN1Element(&oid, beg, end); - param->header = NULL; - param->tag = 0; - param->beg = param->end = end; - if(beg < end) - Curl_getASN1Element(param, beg, end); - return OID2str(oid.beg, oid.end, TRUE); -} - -static void do_pubkey_field(struct SessionHandle * data, int certnum, - const char * label, curl_asn1Element * elem) -{ - const char * output; - - /* Generate a certificate information record for the public key. */ - - output = Curl_ASN1tostr(elem, 0); - if(output) { - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, label, output); - if(!certnum) - infof(data, " %s: %s\n", label, output); - free((char *) output); - } -} - -static void do_pubkey(struct SessionHandle * data, int certnum, - const char * algo, curl_asn1Element * param, - curl_asn1Element * pubkey) -{ - curl_asn1Element elem; - curl_asn1Element pk; - const char * p; - const char * q; - unsigned long len; - unsigned int i; - - /* Generate all information records for the public key. */ - - /* Get the public key (single element). */ - Curl_getASN1Element(&pk, pubkey->beg + 1, pubkey->end); - - if(curl_strequal(algo, "rsaEncryption")) { - p = Curl_getASN1Element(&elem, pk.beg, pk.end); - /* Compute key length. */ - for(q = elem.beg; !*q && q < elem.end; q++) - ; - len = (unsigned long)((elem.end - q) * 8); - if(len) - for(i = *(unsigned char *) q; !(i & 0x80); i <<= 1) - len--; - if(len > 32) - elem.beg = q; /* Strip leading zero bytes. */ - if(!certnum) - infof(data, " RSA Public Key (%lu bits)\n", len); - if(data->set.ssl.certinfo) { - q = curl_maprintf("%lu", len); - if(q) { - Curl_ssl_push_certinfo(data, certnum, "RSA Public Key", q); - free((char *) q); - } - } - /* Generate coefficients. */ - do_pubkey_field(data, certnum, "rsa(n)", &elem); - Curl_getASN1Element(&elem, p, pk.end); - do_pubkey_field(data, certnum, "rsa(e)", &elem); - } - else if(curl_strequal(algo, "dsa")) { - p = Curl_getASN1Element(&elem, param->beg, param->end); - do_pubkey_field(data, certnum, "dsa(p)", &elem); - p = Curl_getASN1Element(&elem, p, param->end); - do_pubkey_field(data, certnum, "dsa(q)", &elem); - Curl_getASN1Element(&elem, p, param->end); - do_pubkey_field(data, certnum, "dsa(g)", &elem); - do_pubkey_field(data, certnum, "dsa(pub_key)", &pk); - } - else if(curl_strequal(algo, "dhpublicnumber")) { - p = Curl_getASN1Element(&elem, param->beg, param->end); - do_pubkey_field(data, certnum, "dh(p)", &elem); - Curl_getASN1Element(&elem, param->beg, param->end); - do_pubkey_field(data, certnum, "dh(g)", &elem); - do_pubkey_field(data, certnum, "dh(pub_key)", &pk); - } -#if 0 /* Patent-encumbered. */ - else if(curl_strequal(algo, "ecPublicKey")) { - /* Left TODO. */ - } -#endif -} - -CURLcode Curl_extract_certinfo(struct connectdata * conn, - int certnum, - const char * beg, - const char * end) -{ - curl_X509certificate cert; - struct SessionHandle * data = conn->data; - curl_asn1Element param; - const char * ccp; - char * cp1; - size_t cl1; - char * cp2; - CURLcode result; - unsigned long version; - size_t i; - size_t j; - - if(!data->set.ssl.certinfo) - if(certnum) - return CURLE_OK; - - /* Prepare the certificate information for curl_easy_getinfo(). */ - - /* Extract the certificate ASN.1 elements. */ - Curl_parseX509(&cert, beg, end); - - /* Subject. */ - ccp = Curl_DNtostr(&cert.subject); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Subject", ccp); - if(!certnum) - infof(data, "%2d Subject: %s\n", certnum, ccp); - free((char *) ccp); - - /* Issuer. */ - ccp = Curl_DNtostr(&cert.issuer); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Issuer", ccp); - if(!certnum) - infof(data, " Issuer: %s\n", ccp); - free((char *) ccp); - - /* Version (always fits in less than 32 bits). */ - version = 0; - for(ccp = cert.version.beg; ccp < cert.version.end; ccp++) - version = (version << 8) | *(const unsigned char *) ccp; - if(data->set.ssl.certinfo) { - ccp = curl_maprintf("%lx", version); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - Curl_ssl_push_certinfo(data, certnum, "Version", ccp); - free((char *) ccp); - } - if(!certnum) - infof(data, " Version: %lu (0x%lx)\n", version + 1, version); - - /* Serial number. */ - ccp = Curl_ASN1tostr(&cert.serialNumber, 0); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Serial Number", ccp); - if(!certnum) - infof(data, " Serial Number: %s\n", ccp); - free((char *) ccp); - - /* Signature algorithm .*/ - ccp = dumpAlgo(¶m, cert.signatureAlgorithm.beg, - cert.signatureAlgorithm.end); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Signature Algorithm", ccp); - if(!certnum) - infof(data, " Signature Algorithm: %s\n", ccp); - free((char *) ccp); - - /* Start Date. */ - ccp = Curl_ASN1tostr(&cert.notBefore, 0); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Start Date", ccp); - if(!certnum) - infof(data, " Start Date: %s\n", ccp); - free((char *) ccp); - - /* Expire Date. */ - ccp = Curl_ASN1tostr(&cert.notAfter, 0); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Expire Date", ccp); - if(!certnum) - infof(data, " Expire Date: %s\n", ccp); - free((char *) ccp); - - /* Public Key Algorithm. */ - ccp = dumpAlgo(¶m, cert.subjectPublicKeyAlgorithm.beg, - cert.subjectPublicKeyAlgorithm.end); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Public Key Algorithm", ccp); - if(!certnum) - infof(data, " Public Key Algorithm: %s\n", ccp); - do_pubkey(data, certnum, ccp, ¶m, &cert.subjectPublicKey); - free((char *) ccp); - -/* TODO: extensions. */ - - /* Signature. */ - ccp = Curl_ASN1tostr(&cert.signature, 0); - if(!ccp) - return CURLE_OUT_OF_MEMORY; - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Signature", ccp); - if(!certnum) - infof(data, " Signature: %s\n", ccp); - free((char *) ccp); - - /* Generate PEM certificate. */ - result = Curl_base64_encode(data, cert.certificate.beg, - cert.certificate.end - cert.certificate.beg, - &cp1, &cl1); - if(result) - return result; - /* Compute the number of characters in final certificate string. Format is: - -----BEGIN CERTIFICATE-----\n - \n - . - . - . - -----END CERTIFICATE-----\n - */ - i = 28 + cl1 + (cl1 + 64 - 1) / 64 + 26; - cp2 = malloc(i + 1); - if(!cp2) { - free(cp1); - return CURLE_OUT_OF_MEMORY; - } - /* Build the certificate string. */ - i = copySubstring(cp2, "-----BEGIN CERTIFICATE-----"); - for(j = 0; j < cl1; j += 64) - i += copySubstring(cp2 + i, cp1 + j); - i += copySubstring(cp2 + i, "-----END CERTIFICATE-----"); - cp2[i] = '\0'; - free(cp1); - if(data->set.ssl.certinfo) - Curl_ssl_push_certinfo(data, certnum, "Cert", cp2); - if(!certnum) - infof(data, "%s\n", cp2); - free(cp2); - return CURLE_OK; -} - -#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */ - -#if defined(USE_GSKIT) - -static const char * checkOID(const char * beg, const char * end, - const char * oid) -{ - curl_asn1Element e; - const char * ccp; - const char * p; - bool matched; - - /* Check if first ASN.1 element at `beg' is the given OID. - Return a pointer in the source after the OID if found, else NULL. */ - - ccp = Curl_getASN1Element(&e, beg, end); - if(!ccp || e.tag != CURL_ASN1_OBJECT_IDENTIFIER) - return (const char *) NULL; - - p = OID2str(e.beg, e.end, FALSE); - if(!p) - return (const char *) NULL; - - matched = !strcmp(p, oid); - free((char *) p); - return matched? ccp: (const char *) NULL; -} - -CURLcode Curl_verifyhost(struct connectdata * conn, - const char * beg, const char * end) -{ - struct SessionHandle * data = conn->data; - curl_X509certificate cert; - curl_asn1Element dn; - curl_asn1Element elem; - curl_asn1Element ext; - curl_asn1Element name; - const char * p; - const char * q; - char * dnsname; - int matched = -1; - size_t addrlen = (size_t) -1; - ssize_t len; -#ifdef ENABLE_IPV6 - struct in6_addr addr; -#else - struct in_addr addr; -#endif - - /* Verify that connection server matches info in X509 certificate at - `beg'..`end'. */ - - if(!data->set.ssl.verifyhost) - return CURLE_OK; - - if(!beg) - return CURLE_PEER_FAILED_VERIFICATION; - Curl_parseX509(&cert, beg, end); - - /* Get the server IP address. */ -#ifdef ENABLE_IPV6 - if(conn->bits.ipv6_ip && Curl_inet_pton(AF_INET6, conn->host.name, &addr)) - addrlen = sizeof(struct in6_addr); - else -#endif - if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) - addrlen = sizeof(struct in_addr); - - /* Process extensions. */ - for(p = cert.extensions.beg; p < cert.extensions.end && matched != 1;) { - p = Curl_getASN1Element(&ext, p, cert.extensions.end); - /* Check if extension is a subjectAlternativeName. */ - ext.beg = checkOID(ext.beg, ext.end, sanOID); - if(ext.beg) { - ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end); - /* Skip critical if present. */ - if(elem.tag == CURL_ASN1_BOOLEAN) - ext.beg = Curl_getASN1Element(&elem, ext.beg, ext.end); - /* Parse the octet string contents: is a single sequence. */ - Curl_getASN1Element(&elem, elem.beg, elem.end); - /* Check all GeneralNames. */ - for(q = elem.beg; matched != 1 && q < elem.end;) { - q = Curl_getASN1Element(&name, q, elem.end); - switch (name.tag) { - case 2: /* DNS name. */ - len = utf8asn1str(&dnsname, CURL_ASN1_IA5_STRING, - name.beg, name.end); - if(len > 0 && (size_t)len == strlen(dnsname)) - matched = Curl_cert_hostcheck(dnsname, conn->host.name); - else - matched = 0; - free(dnsname); - break; - - case 7: /* IP address. */ - matched = (size_t) (name.end - q) == addrlen && - !memcmp(&addr, q, addrlen); - break; - } - } - } - } - - switch (matched) { - case 1: - /* an alternative name matched the server hostname */ - infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname); - return CURLE_OK; - case 0: - /* an alternative name field existed, but didn't match and then - we MUST fail */ - infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname); - return CURLE_PEER_FAILED_VERIFICATION; - } - - /* Process subject. */ - name.header = NULL; - name.beg = name.end = ""; - q = cert.subject.beg; - /* we have to look to the last occurrence of a commonName in the - distinguished one to get the most significant one. */ - while(q < cert.subject.end) { - q = Curl_getASN1Element(&dn, q, cert.subject.end); - for(p = dn.beg; p < dn.end;) { - p = Curl_getASN1Element(&elem, p, dn.end); - /* We have a DN's AttributeTypeAndValue: check it in case it's a CN. */ - elem.beg = checkOID(elem.beg, elem.end, cnOID); - if(elem.beg) - name = elem; /* Latch CN. */ - } - } - - /* Check the CN if found. */ - if(!Curl_getASN1Element(&elem, name.beg, name.end)) - failf(data, "SSL: unable to obtain common name from peer certificate"); - else { - len = utf8asn1str(&dnsname, elem.tag, elem.beg, elem.end); - if(len < 0) { - free(dnsname); - return CURLE_OUT_OF_MEMORY; - } - if(strlen(dnsname) != (size_t) len) /* Nul byte in string ? */ - failf(data, "SSL: illegal cert name field"); - else if(Curl_cert_hostcheck((const char *) dnsname, conn->host.name)) { - infof(data, "\t common name: %s (matched)\n", dnsname); - free(dnsname); - return CURLE_OK; - } - else - failf(data, "SSL: certificate subject name '%s' does not match " - "target host name '%s'", dnsname, conn->host.dispname); - free(dnsname); - } - - return CURLE_PEER_FAILED_VERIFICATION; -} - -#endif /* USE_GSKIT */ diff --git a/Externals/curl/lib/x509asn1.h b/Externals/curl/lib/x509asn1.h deleted file mode 100644 index e6a1e24440..0000000000 --- a/Externals/curl/lib/x509asn1.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef HEADER_CURL_X509ASN1_H -#define HEADER_CURL_X509ASN1_H - -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at https://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include "curl_setup.h" - -#if defined(USE_GSKIT) || defined(USE_NSS) || defined(USE_GNUTLS) || \ - defined(USE_CYASSL) - -#include "urldata.h" - -/* - * Constants. - */ - -/* ASN.1 classes. */ -#define CURL_ASN1_UNIVERSAL 0 -#define CURL_ASN1_APPLICATION 1 -#define CURL_ASN1_CONTEXT_SPECIFIC 2 -#define CURL_ASN1_PRIVATE 3 - -/* ASN.1 types. */ -#define CURL_ASN1_BOOLEAN 1 -#define CURL_ASN1_INTEGER 2 -#define CURL_ASN1_BIT_STRING 3 -#define CURL_ASN1_OCTET_STRING 4 -#define CURL_ASN1_NULL 5 -#define CURL_ASN1_OBJECT_IDENTIFIER 6 -#define CURL_ASN1_OBJECT_DESCRIPTOR 7 -#define CURL_ASN1_INSTANCE_OF 8 -#define CURL_ASN1_REAL 9 -#define CURL_ASN1_ENUMERATED 10 -#define CURL_ASN1_EMBEDDED 11 -#define CURL_ASN1_UTF8_STRING 12 -#define CURL_ASN1_RELATIVE_OID 13 -#define CURL_ASN1_SEQUENCE 16 -#define CURL_ASN1_SET 17 -#define CURL_ASN1_NUMERIC_STRING 18 -#define CURL_ASN1_PRINTABLE_STRING 19 -#define CURL_ASN1_TELETEX_STRING 20 -#define CURL_ASN1_VIDEOTEX_STRING 21 -#define CURL_ASN1_IA5_STRING 22 -#define CURL_ASN1_UTC_TIME 23 -#define CURL_ASN1_GENERALIZED_TIME 24 -#define CURL_ASN1_GRAPHIC_STRING 25 -#define CURL_ASN1_VISIBLE_STRING 26 -#define CURL_ASN1_GENERAL_STRING 27 -#define CURL_ASN1_UNIVERSAL_STRING 28 -#define CURL_ASN1_CHARACTER_STRING 29 -#define CURL_ASN1_BMP_STRING 30 - - -/* - * Types. - */ - -/* ASN.1 parsed element. */ -typedef struct { - const char * header; /* Pointer to header byte. */ - const char * beg; /* Pointer to element data. */ - const char * end; /* Pointer to 1st byte after element. */ - unsigned char class; /* ASN.1 element class. */ - unsigned char tag; /* ASN.1 element tag. */ - bool constructed; /* Element is constructed. */ -} curl_asn1Element; - - -/* ASN.1 OID table entry. */ -typedef struct { - const char * numoid; /* Dotted-numeric OID. */ - const char * textoid; /* OID name. */ -} curl_OID; - - -/* X509 certificate: RFC 5280. */ -typedef struct { - curl_asn1Element certificate; - curl_asn1Element version; - curl_asn1Element serialNumber; - curl_asn1Element signatureAlgorithm; - curl_asn1Element signature; - curl_asn1Element issuer; - curl_asn1Element notBefore; - curl_asn1Element notAfter; - curl_asn1Element subject; - curl_asn1Element subjectPublicKeyInfo; - curl_asn1Element subjectPublicKeyAlgorithm; - curl_asn1Element subjectPublicKey; - curl_asn1Element issuerUniqueID; - curl_asn1Element subjectUniqueID; - curl_asn1Element extensions; -} curl_X509certificate; - - -/* - * Prototypes. - */ - -const char * Curl_getASN1Element(curl_asn1Element * elem, - const char * beg, const char * end); -const char * Curl_ASN1tostr(curl_asn1Element * elem, int type); -const char * Curl_DNtostr(curl_asn1Element * dn); -void Curl_parseX509(curl_X509certificate * cert, - const char * beg, const char * end); -CURLcode Curl_extract_certinfo(struct connectdata * conn, int certnum, - const char * beg, const char * end); -CURLcode Curl_verifyhost(struct connectdata * conn, - const char * beg, const char * end); - -#endif /* USE_GSKIT or USE_NSS or USE_GNUTLS or USE_CYASSL */ -#endif /* HEADER_CURL_X509ASN1_H */ diff --git a/Source/VSProps/Base.Dolphin.props b/Source/VSProps/Base.Dolphin.props index 6a9d0192d2..a575d9290b 100644 --- a/Source/VSProps/Base.Dolphin.props +++ b/Source/VSProps/Base.Dolphin.props @@ -77,6 +77,8 @@ $(ExternalsDir)FFmpeg-bin\$(Platform)\lib;%(AdditionalLibraryDirectories) avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;bcrypt.lib;%(AdditionalDependencies) + + Crypt32.lib;%(AdditionalDependencies) enableCompatPatches From b5be399fd4175eb6c4ba83201bd4866b357b3200 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Sat, 22 Jul 2023 23:12:34 +0200 Subject: [PATCH 48/99] cubeb: Change name to "Dolphin Emulator" To avoid conflicts with KDE's file manager. --- Source/Core/AudioCommon/CubebUtils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/AudioCommon/CubebUtils.cpp b/Source/Core/AudioCommon/CubebUtils.cpp index f7682f6ade..766a5c3b83 100644 --- a/Source/Core/AudioCommon/CubebUtils.cpp +++ b/Source/Core/AudioCommon/CubebUtils.cpp @@ -72,7 +72,7 @@ std::shared_ptr CubebUtils::GetContext() } cubeb* ctx; - if (cubeb_init(&ctx, "Dolphin", nullptr) != CUBEB_OK) + if (cubeb_init(&ctx, "Dolphin Emulator", nullptr) != CUBEB_OK) { ERROR_LOG_FMT(AUDIO, "Error initializing cubeb library"); return nullptr; From 8c2a1c191e138d24ec5d525e6cb2532fae376b58 Mon Sep 17 00:00:00 2001 From: Sketch <75850871+SketchMaster2001@users.noreply.github.com> Date: Sat, 22 Jul 2023 22:24:09 -0400 Subject: [PATCH 49/99] Remove force disable WC24 Standby --- Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp index 5356449cdb..1e6d2efca3 100644 --- a/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/BaseConfigLoader.cpp @@ -69,17 +69,6 @@ void SaveToSYSCONF(Config::LayerType layer, std::function("IPL.CB", SysConf::Entry::Type::Long, 0); - - // Disable WiiConnect24's standby mode. If it is enabled, it prevents us from receiving - // shutdown commands in the State Transition Manager (STM). - // TODO: remove this if and once Dolphin supports WC24 standby mode. - SysConf::Entry* idle_entry = sysconf.GetOrAddEntry("IPL.IDL", SysConf::Entry::Type::SmallArray); - if (idle_entry->bytes.empty()) - idle_entry->bytes = std::vector(2); - else - idle_entry->bytes[0] = 0; - NOTICE_LOG_FMT(CORE, "Disabling WC24 'standby' (shutdown to idle) to avoid hanging on shutdown"); - IOS::HLE::RestoreBTInfoSection(&sysconf); sysconf.Save(); } From a486168448dd0676c7370ba48c14cc3381cca1a2 Mon Sep 17 00:00:00 2001 From: Bram Speeckaert Date: Fri, 21 Jul 2023 14:50:13 +0200 Subject: [PATCH 50/99] JitArm64: Use LogicalImm in boolX ARM64 has a special logical immediate encoding scheme, that can be used with AND, ORR, and EOR. By taking advantage of this, we no longer need to materialize the immediate value in a register, saving instructions and/or reducing register pressure. - orx Before: mov w23, #0x1 orr w23, w25, w23 After: orr w23, w25, #0x1 - andx Before: mov w26, #-0x80000000 and w27, w27, w26 sxtw x24, w27 After: and w27, w27, #0x80000000 sxtw x26, w27 - eqvx Before: mov w23, #0x4 eon w26, w23, w22 After: eor w26, w22, #0xfffffffb - xorx Before: mov w23, #0x1e eor w23, w27, w23 After: eor w23, w27, #0x1e - norx Before: mov w25, #-0x2001 orr w23, w23, w25 mvn w23, w23 After: orr w23, w23, #0xffffdfff mvn w23, w23 --- .../PowerPC/JitArm64/JitArm64_Integer.cpp | 107 +++++++++++++----- 1 file changed, 80 insertions(+), 27 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 46b246c910..0e8dd60658 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -323,8 +323,10 @@ void JitArm64::boolX(UGeckoInstruction inst) PanicAlertFmt("WTF!"); } } - else if ((gpr.IsImm(s) && (gpr.GetImm(s) == 0 || gpr.GetImm(s) == 0xFFFFFFFF)) || - (gpr.IsImm(b) && (gpr.GetImm(b) == 0 || gpr.GetImm(b) == 0xFFFFFFFF))) + else if ((gpr.IsImm(s) && + (gpr.GetImm(s) == 0 || gpr.GetImm(s) == 0xFFFFFFFF || LogicalImm(gpr.GetImm(s), 32))) || + (gpr.IsImm(b) && + (gpr.GetImm(b) == 0 || gpr.GetImm(b) == 0xFFFFFFFF || LogicalImm(gpr.GetImm(b), 32)))) { int i, j; if (gpr.IsImm(s)) @@ -337,7 +339,6 @@ void JitArm64::boolX(UGeckoInstruction inst) i = b; j = s; } - bool is_zero = gpr.GetImm(i) == 0; bool complement_b = (inst.SUBOP10 == 60 /* andcx */) || (inst.SUBOP10 == 412 /* orcx */); const bool final_not = (inst.SUBOP10 == 476 /* nandx */) || (inst.SUBOP10 == 124 /* norx */); @@ -347,23 +348,39 @@ void JitArm64::boolX(UGeckoInstruction inst) (inst.SUBOP10 == 124 /* norx */); const bool is_xor = (inst.SUBOP10 == 316 /* xorx */) || (inst.SUBOP10 == 284 /* eqvx */); + u32 imm = gpr.GetImm(i); if ((complement_b && i == b) || (inst.SUBOP10 == 284 /* eqvx */)) { - is_zero = !is_zero; + imm = ~imm; complement_b = false; } + const bool is_zero = imm == 0; + const bool is_ones = imm == 0xFFFFFFFF; + // If imm can be represented as LogicalImm, so can ~imm. + const auto log_imm = LogicalImm(imm, 32); + if (is_xor) { - if (!is_zero) + if (is_zero) + { + if (a != j) + { + gpr.BindToRegister(a, false); + MOV(gpr.R(a), gpr.R(j)); + } + } + else { gpr.BindToRegister(a, a == j); - MVN(gpr.R(a), gpr.R(j)); - } - else if (a != j) - { - gpr.BindToRegister(a, false); - MOV(gpr.R(a), gpr.R(j)); + if (is_ones) + { + MVN(gpr.R(a), gpr.R(j)); + } + else + { + EOR(gpr.R(a), gpr.R(j), log_imm); + } } if (inst.Rc) ComputeRC0(gpr.R(a)); @@ -376,16 +393,14 @@ void JitArm64::boolX(UGeckoInstruction inst) if (inst.Rc) ComputeRC0(gpr.GetImm(a)); } - else if (final_not || complement_b) + else if (is_ones) { - gpr.BindToRegister(a, a == j); - MVN(gpr.R(a), gpr.R(j)); - if (inst.Rc) - ComputeRC0(gpr.R(a)); - } - else - { - if (a != j) + if (final_not || complement_b) + { + gpr.BindToRegister(a, a == j); + MVN(gpr.R(a), gpr.R(j)); + } + else if (a != j) { gpr.BindToRegister(a, false); MOV(gpr.R(a), gpr.R(j)); @@ -393,28 +408,66 @@ void JitArm64::boolX(UGeckoInstruction inst) if (inst.Rc) ComputeRC0(gpr.R(a)); } + else + { + if (!complement_b) + { + gpr.BindToRegister(a, a == j); + AND(gpr.R(a), gpr.R(j), log_imm); + if (final_not) + MVN(gpr.R(a), gpr.R(a)); + } + else + { + // No shorter instruction sequence is possible. Just materialize the + // immediate in a register as usual, so subsequent uses can leech off + // of it. + gpr.BindToRegister(a, (a == i) || (a == j)); + BIC(gpr.R(a), gpr.R(i), gpr.R(j)); + } + if (inst.Rc) + ComputeRC0(gpr.R(a)); + } } else if (is_or) { - if (!is_zero) + if (is_ones) { gpr.SetImmediate(a, final_not ? 0 : 0xFFFFFFFF); if (inst.Rc) ComputeRC0(gpr.GetImm(a)); } - else if (final_not || complement_b) + else if (is_zero) { - gpr.BindToRegister(a, a == j); - MVN(gpr.R(a), gpr.R(j)); + if (final_not || complement_b) + { + gpr.BindToRegister(a, a == j); + MVN(gpr.R(a), gpr.R(j)); + } + else if (a != j) + { + gpr.BindToRegister(a, false); + MOV(gpr.R(a), gpr.R(j)); + } if (inst.Rc) ComputeRC0(gpr.R(a)); } else { - if (a != j) + if (!complement_b) { - gpr.BindToRegister(a, false); - MOV(gpr.R(a), gpr.R(j)); + gpr.BindToRegister(a, a == j); + ORR(gpr.R(a), gpr.R(j), log_imm); + if (final_not) + MVN(gpr.R(a), gpr.R(a)); + } + else + { + // No shorter instruction sequence is possible. Just materialize the + // immediate in a register as usual, so subsequent uses can leech off + // of it. + gpr.BindToRegister(a, (a == i) || (a == j)); + ORN(gpr.R(a), gpr.R(i), gpr.R(j)); } if (inst.Rc) ComputeRC0(gpr.R(a)); From e54b7ac3564ee59181411c3398b419dbbf42a599 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Thu, 20 Jul 2023 19:23:34 -0500 Subject: [PATCH 51/99] Core: save core timing parameters into variables updated during refresh --- Source/Core/Core/CoreTiming.cpp | 25 +++++++++++++------------ Source/Core/Core/CoreTiming.h | 4 ++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp index da7f89b1be..8e5d489a58 100644 --- a/Source/Core/Core/CoreTiming.cpp +++ b/Source/Core/Core/CoreTiming.cpp @@ -127,6 +127,14 @@ void CoreTimingManager::RefreshConfig() Config::Get(Config::MAIN_OVERCLOCK_ENABLE) ? Config::Get(Config::MAIN_OVERCLOCK) : 1.0f; m_config_oc_inv_factor = 1.0f / m_config_oc_factor; m_config_sync_on_skip_idle = Config::Get(Config::MAIN_SYNC_ON_SKIP_IDLE); + + // A maximum fallback is used to prevent the system from sleeping for + // too long or going full speed in an attempt to catch up to timings. + m_max_fallback = std::chrono::duration_cast
(DT_ms(Config::Get(Config::MAIN_MAX_FALLBACK))); + + m_max_variance = std::chrono::duration_cast
(DT_ms(Config::Get(Config::MAIN_TIMING_VARIANCE))); + + m_emulation_speed = Config::Get(Config::MAIN_EMULATION_SPEED); } void CoreTimingManager::DoState(PointerWrap& p) @@ -355,21 +363,15 @@ void CoreTimingManager::Throttle(const s64 target_cycle) m_throttle_last_cycle = target_cycle; - const double speed = - Core::GetIsThrottlerTempDisabled() ? 0.0 : Config::Get(Config::MAIN_EMULATION_SPEED); + const double speed = Core::GetIsThrottlerTempDisabled() ? 0.0 : m_emulation_speed; if (0.0 < speed) m_throttle_deadline += std::chrono::duration_cast
(DT_s(cycles) / (speed * m_throttle_clock_per_sec)); - // A maximum fallback is used to prevent the system from sleeping for - // too long or going full speed in an attempt to catch up to timings. - const DT max_fallback = - std::chrono::duration_cast
(DT_ms(Config::Get(Config::MAIN_MAX_FALLBACK))); - const TimePoint time = Clock::now(); - const TimePoint min_deadline = time - max_fallback; - const TimePoint max_deadline = time + max_fallback; + const TimePoint min_deadline = time - m_max_fallback; + const TimePoint max_deadline = time + m_max_fallback; if (m_throttle_deadline > max_deadline) { @@ -382,11 +384,10 @@ void CoreTimingManager::Throttle(const s64 target_cycle) m_throttle_deadline = min_deadline; } + const TimePoint vi_deadline = time - std::min(m_max_fallback, m_max_variance) / 2; + // Skip the VI interrupt if the CPU is lagging by a certain amount. // It doesn't matter what amount of lag we skip VI at, as long as it's constant. - const DT max_variance = - std::chrono::duration_cast
(DT_ms(Config::Get(Config::MAIN_TIMING_VARIANCE))); - const TimePoint vi_deadline = time - std::min(max_fallback, max_variance) / 2; m_throttle_disable_vi_int = 0.0 < speed && m_throttle_deadline < vi_deadline; // Only sleep if we are behind the deadline diff --git a/Source/Core/Core/CoreTiming.h b/Source/Core/Core/CoreTiming.h index 525b7e8913..1790dd70ee 100644 --- a/Source/Core/Core/CoreTiming.h +++ b/Source/Core/Core/CoreTiming.h @@ -193,6 +193,10 @@ private: s64 m_throttle_min_clock_per_sleep = 0; bool m_throttle_disable_vi_int = false; + DT m_max_fallback = {}; + DT m_max_variance = {}; + double m_emulation_speed = 1.0; + void ResetThrottle(s64 cycle); int DowncountToCycles(int downcount) const; From 7e38ff496c0b098312f21ca7acadccc35a15bb05 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 23 Jul 2023 15:17:04 -0700 Subject: [PATCH 52/99] Rename "Show Debugging UI" to "Enable Debugging UI" This will hopefully reduce confusion on e.g. https://bugs.dolphin-emu.org/issues/13306. --- Source/Core/DolphinQt/Settings/InterfacePane.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/DolphinQt/Settings/InterfacePane.cpp b/Source/Core/DolphinQt/Settings/InterfacePane.cpp index 8cbcc62ee3..ef0985bfd4 100644 --- a/Source/Core/DolphinQt/Settings/InterfacePane.cpp +++ b/Source/Core/DolphinQt/Settings/InterfacePane.cpp @@ -146,7 +146,7 @@ void InterfacePane::CreateUI() m_checkbox_use_userstyle = new QCheckBox(tr("Use Custom User Style")); m_checkbox_use_covers = new QCheckBox(tr("Download Game Covers from GameTDB.com for Use in Grid Mode")); - m_checkbox_show_debugging_ui = new QCheckBox(tr("Show Debugging UI")); + m_checkbox_show_debugging_ui = new QCheckBox(tr("Enable Debugging UI")); m_checkbox_focused_hotkeys = new QCheckBox(tr("Hotkeys Require Window Focus")); m_checkbox_disable_screensaver = new QCheckBox(tr("Inhibit Screensaver During Emulation")); From 0892998af170ecbbe45dff87d8352bdfb97bca82 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Mon, 24 Jul 2023 20:12:32 +0200 Subject: [PATCH 53/99] Qt/GameConfigWidget: Add `reverse` argument for `{Save,Load}CheckBox` In order to not hard code `if (key == "FastDiscSpeed")` --- .../DolphinQt/Config/GameConfigWidget.cpp | 35 +++++-------------- .../Core/DolphinQt/Config/GameConfigWidget.h | 6 ++-- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp index a702c90f84..3ab83c11ff 100644 --- a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp +++ b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp @@ -219,30 +219,19 @@ void GameConfigWidget::ConnectWidgets() } void GameConfigWidget::LoadCheckBox(QCheckBox* checkbox, const std::string& section, - const std::string& key) + const std::string& key, bool reverse) { bool checked; - if (key == "FastDiscSpeed") - { - if (m_gameini_local.GetOrCreateSection(section)->Get("FastDiscSpeed", &checked)) - return checkbox->setCheckState(!checked ? Qt::Checked : Qt::Unchecked); + if (m_gameini_local.GetOrCreateSection(section)->Get(key, &checked)) + return checkbox->setCheckState(checked ^ reverse ? Qt::Checked : Qt::Unchecked); - if (m_gameini_default.GetOrCreateSection(section)->Get("FastDiscSpeed", &checked)) - return checkbox->setCheckState(!checked ? Qt::Checked : Qt::Unchecked); - } - else - { - if (m_gameini_local.GetOrCreateSection(section)->Get(key, &checked)) - return checkbox->setCheckState(checked ? Qt::Checked : Qt::Unchecked); - - if (m_gameini_default.GetOrCreateSection(section)->Get(key, &checked)) - return checkbox->setCheckState(checked ? Qt::Checked : Qt::Unchecked); - } + if (m_gameini_default.GetOrCreateSection(section)->Get(key, &checked)) + return checkbox->setCheckState(checked ^ reverse ? Qt::Checked : Qt::Unchecked); checkbox->setCheckState(Qt::PartiallyChecked); } void GameConfigWidget::SaveCheckBox(QCheckBox* checkbox, const std::string& section, - const std::string& key) + const std::string& key, bool reverse) { // Delete any existing entries from the local gameini if checkbox is undetermined. // Otherwise, write the current value to the local gameini if the value differs from the default @@ -256,13 +245,7 @@ void GameConfigWidget::SaveCheckBox(QCheckBox* checkbox, const std::string& sect return; } - bool checked = checkbox->checkState() == Qt::Checked; - - if (key == "FastDiscSpeed") - { - m_gameini_local.GetOrCreateSection(section)->Set(key, !checked); - return; - } + bool checked = (checkbox->checkState() == Qt::Checked) ^ reverse; if (m_gameini_default.Exists(section, key)) { @@ -293,7 +276,7 @@ void GameConfigWidget::LoadSettings() LoadCheckBox(m_enable_mmu, "Core", "MMU"); LoadCheckBox(m_enable_fprf, "Core", "FPRF"); LoadCheckBox(m_sync_gpu, "Core", "SyncGPU"); - LoadCheckBox(m_enable_fast_disc, "Core", "FastDiscSpeed"); + LoadCheckBox(m_enable_fast_disc, "Core", "FastDiscSpeed", true); LoadCheckBox(m_use_dsp_hle, "Core", "DSPHLE"); std::string determinism_mode; @@ -343,7 +326,7 @@ void GameConfigWidget::SaveSettings() SaveCheckBox(m_enable_mmu, "Core", "MMU"); SaveCheckBox(m_enable_fprf, "Core", "FPRF"); SaveCheckBox(m_sync_gpu, "Core", "SyncGPU"); - SaveCheckBox(m_enable_fast_disc, "Core", "FastDiscSpeed"); + SaveCheckBox(m_enable_fast_disc, "Core", "FastDiscSpeed", true); SaveCheckBox(m_use_dsp_hle, "Core", "DSPHLE"); int determinism_num = m_deterministic_dual_core->currentIndex(); diff --git a/Source/Core/DolphinQt/Config/GameConfigWidget.h b/Source/Core/DolphinQt/Config/GameConfigWidget.h index 44ae2375f5..7eda19cdc5 100644 --- a/Source/Core/DolphinQt/Config/GameConfigWidget.h +++ b/Source/Core/DolphinQt/Config/GameConfigWidget.h @@ -35,8 +35,10 @@ private: void LoadSettings(); void SaveSettings(); - void SaveCheckBox(QCheckBox* checkbox, const std::string& section, const std::string& key); - void LoadCheckBox(QCheckBox* checkbox, const std::string& section, const std::string& key); + void SaveCheckBox(QCheckBox* checkbox, const std::string& section, const std::string& key, + bool reverse = false); + void LoadCheckBox(QCheckBox* checkbox, const std::string& section, const std::string& key, + bool reverse = false); QString m_gameini_sys_path; QString m_gameini_local_path; From 41f81aca6933d9ec93fa0f4e23429df3bd935137 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Mon, 24 Jul 2023 20:51:02 +0200 Subject: [PATCH 54/99] Qt/GameConfigWidget: Rename `m_enable_fast_disc` to `m_emulate_disc_speed` --- .../DolphinQt/Config/GameConfigWidget.cpp | 19 ++++++++++--------- .../Core/DolphinQt/Config/GameConfigWidget.h | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp index 3ab83c11ff..8bbf7376aa 100644 --- a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp +++ b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp @@ -88,7 +88,7 @@ void GameConfigWidget::CreateWidgets() m_enable_mmu = new QCheckBox(tr("Enable MMU")); m_enable_fprf = new QCheckBox(tr("Enable FPRF")); m_sync_gpu = new QCheckBox(tr("Synchronize GPU thread")); - m_enable_fast_disc = new QCheckBox(tr("Emulate Disc Speed")); + m_emulate_disc_speed = new QCheckBox(tr("Emulate Disc Speed")); m_use_dsp_hle = new QCheckBox(tr("DSP HLE (fast)")); m_deterministic_dual_core = new QComboBox; @@ -102,15 +102,16 @@ void GameConfigWidget::CreateWidgets() "games. (ON = Compatible, OFF = Fast)")); m_sync_gpu->setToolTip(tr("Synchronizes the GPU and CPU threads to help prevent random freezes " "in Dual core mode. (ON = Compatible, OFF = Fast)")); - m_enable_fast_disc->setToolTip(tr("Enable emulated disc speed. Disabling this can cause crashes " - "and other problems in some games. " - "(ON = Compatible, OFF = Unlocked)")); + m_emulate_disc_speed->setToolTip( + tr("Enable emulated disc speed. Disabling this can cause crashes " + "and other problems in some games. " + "(ON = Compatible, OFF = Unlocked)")); core_layout->addWidget(m_enable_dual_core, 0, 0); core_layout->addWidget(m_enable_mmu, 1, 0); core_layout->addWidget(m_enable_fprf, 2, 0); core_layout->addWidget(m_sync_gpu, 3, 0); - core_layout->addWidget(m_enable_fast_disc, 4, 0); + core_layout->addWidget(m_emulate_disc_speed, 4, 0); core_layout->addWidget(m_use_dsp_hle, 5, 0); core_layout->addWidget(new QLabel(tr("Deterministic dual core:")), 6, 0); core_layout->addWidget(m_deterministic_dual_core, 6, 1); @@ -160,7 +161,7 @@ void GameConfigWidget::CreateWidgets() general_layout->addWidget(m_refresh_config, 1, 0, 1, -1); for (QCheckBox* item : {m_enable_dual_core, m_enable_mmu, m_enable_fprf, m_sync_gpu, - m_enable_fast_disc, m_use_dsp_hle, m_use_monoscopic_shadows}) + m_emulate_disc_speed, m_use_dsp_hle, m_use_monoscopic_shadows}) item->setTristate(true); auto* general_widget = new QWidget; @@ -207,7 +208,7 @@ void GameConfigWidget::ConnectWidgets() connect(m_refresh_config, &QPushButton::clicked, this, &GameConfigWidget::LoadSettings); for (QCheckBox* box : {m_enable_dual_core, m_enable_mmu, m_enable_fprf, m_sync_gpu, - m_enable_fast_disc, m_use_dsp_hle, m_use_monoscopic_shadows}) + m_emulate_disc_speed, m_use_dsp_hle, m_use_monoscopic_shadows}) connect(box, &QCheckBox::stateChanged, this, &GameConfigWidget::SaveSettings); connect(m_deterministic_dual_core, qOverload(&QComboBox::currentIndexChanged), this, @@ -276,7 +277,7 @@ void GameConfigWidget::LoadSettings() LoadCheckBox(m_enable_mmu, "Core", "MMU"); LoadCheckBox(m_enable_fprf, "Core", "FPRF"); LoadCheckBox(m_sync_gpu, "Core", "SyncGPU"); - LoadCheckBox(m_enable_fast_disc, "Core", "FastDiscSpeed", true); + LoadCheckBox(m_emulate_disc_speed, "Core", "FastDiscSpeed", true); LoadCheckBox(m_use_dsp_hle, "Core", "DSPHLE"); std::string determinism_mode; @@ -326,7 +327,7 @@ void GameConfigWidget::SaveSettings() SaveCheckBox(m_enable_mmu, "Core", "MMU"); SaveCheckBox(m_enable_fprf, "Core", "FPRF"); SaveCheckBox(m_sync_gpu, "Core", "SyncGPU"); - SaveCheckBox(m_enable_fast_disc, "Core", "FastDiscSpeed", true); + SaveCheckBox(m_emulate_disc_speed, "Core", "FastDiscSpeed", true); SaveCheckBox(m_use_dsp_hle, "Core", "DSPHLE"); int determinism_num = m_deterministic_dual_core->currentIndex(); diff --git a/Source/Core/DolphinQt/Config/GameConfigWidget.h b/Source/Core/DolphinQt/Config/GameConfigWidget.h index 7eda19cdc5..2184549dc6 100644 --- a/Source/Core/DolphinQt/Config/GameConfigWidget.h +++ b/Source/Core/DolphinQt/Config/GameConfigWidget.h @@ -50,7 +50,7 @@ private: QCheckBox* m_enable_mmu; QCheckBox* m_enable_fprf; QCheckBox* m_sync_gpu; - QCheckBox* m_enable_fast_disc; + QCheckBox* m_emulate_disc_speed; QCheckBox* m_use_dsp_hle; QCheckBox* m_use_monoscopic_shadows; From 1e5e319783cb69a106556a9e3b0ab77b7aff1021 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Mon, 24 Jul 2023 20:12:44 +0200 Subject: [PATCH 55/99] Qt/GameConfigWidget: Add Manual Texture Sampling --- .../Core/DolphinQt/Config/GameConfigWidget.cpp | 18 ++++++++++++------ .../Core/DolphinQt/Config/GameConfigWidget.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp index 8bbf7376aa..d918f5cd62 100644 --- a/Source/Core/DolphinQt/Config/GameConfigWidget.cpp +++ b/Source/Core/DolphinQt/Config/GameConfigWidget.cpp @@ -90,6 +90,7 @@ void GameConfigWidget::CreateWidgets() m_sync_gpu = new QCheckBox(tr("Synchronize GPU thread")); m_emulate_disc_speed = new QCheckBox(tr("Emulate Disc Speed")); m_use_dsp_hle = new QCheckBox(tr("DSP HLE (fast)")); + m_manual_texture_sampling = new QCheckBox(tr("Manual Texture Sampling")); m_deterministic_dual_core = new QComboBox; for (const auto& item : {tr("Not Set"), tr("auto"), tr("none"), tr("fake-completion")}) @@ -113,8 +114,9 @@ void GameConfigWidget::CreateWidgets() core_layout->addWidget(m_sync_gpu, 3, 0); core_layout->addWidget(m_emulate_disc_speed, 4, 0); core_layout->addWidget(m_use_dsp_hle, 5, 0); - core_layout->addWidget(new QLabel(tr("Deterministic dual core:")), 6, 0); - core_layout->addWidget(m_deterministic_dual_core, 6, 1); + core_layout->addWidget(m_manual_texture_sampling, 6, 0); + core_layout->addWidget(new QLabel(tr("Deterministic dual core:")), 7, 0); + core_layout->addWidget(m_deterministic_dual_core, 7, 1); // Stereoscopy auto* stereoscopy_box = new QGroupBox(tr("Stereoscopy")); @@ -160,8 +162,9 @@ void GameConfigWidget::CreateWidgets() general_layout->addWidget(m_refresh_config, 1, 0, 1, -1); - for (QCheckBox* item : {m_enable_dual_core, m_enable_mmu, m_enable_fprf, m_sync_gpu, - m_emulate_disc_speed, m_use_dsp_hle, m_use_monoscopic_shadows}) + for (QCheckBox* item : + {m_enable_dual_core, m_enable_mmu, m_enable_fprf, m_sync_gpu, m_emulate_disc_speed, + m_use_dsp_hle, m_manual_texture_sampling, m_use_monoscopic_shadows}) item->setTristate(true); auto* general_widget = new QWidget; @@ -207,8 +210,9 @@ void GameConfigWidget::ConnectWidgets() // Buttons connect(m_refresh_config, &QPushButton::clicked, this, &GameConfigWidget::LoadSettings); - for (QCheckBox* box : {m_enable_dual_core, m_enable_mmu, m_enable_fprf, m_sync_gpu, - m_emulate_disc_speed, m_use_dsp_hle, m_use_monoscopic_shadows}) + for (QCheckBox* box : + {m_enable_dual_core, m_enable_mmu, m_enable_fprf, m_sync_gpu, m_emulate_disc_speed, + m_use_dsp_hle, m_manual_texture_sampling, m_use_monoscopic_shadows}) connect(box, &QCheckBox::stateChanged, this, &GameConfigWidget::SaveSettings); connect(m_deterministic_dual_core, qOverload(&QComboBox::currentIndexChanged), this, @@ -279,6 +283,7 @@ void GameConfigWidget::LoadSettings() LoadCheckBox(m_sync_gpu, "Core", "SyncGPU"); LoadCheckBox(m_emulate_disc_speed, "Core", "FastDiscSpeed", true); LoadCheckBox(m_use_dsp_hle, "Core", "DSPHLE"); + LoadCheckBox(m_manual_texture_sampling, "Video_Hacks", "FastTextureSampling", true); std::string determinism_mode; @@ -329,6 +334,7 @@ void GameConfigWidget::SaveSettings() SaveCheckBox(m_sync_gpu, "Core", "SyncGPU"); SaveCheckBox(m_emulate_disc_speed, "Core", "FastDiscSpeed", true); SaveCheckBox(m_use_dsp_hle, "Core", "DSPHLE"); + SaveCheckBox(m_manual_texture_sampling, "Video_Hacks", "FastTextureSampling", true); int determinism_num = m_deterministic_dual_core->currentIndex(); diff --git a/Source/Core/DolphinQt/Config/GameConfigWidget.h b/Source/Core/DolphinQt/Config/GameConfigWidget.h index 2184549dc6..7ad4e64925 100644 --- a/Source/Core/DolphinQt/Config/GameConfigWidget.h +++ b/Source/Core/DolphinQt/Config/GameConfigWidget.h @@ -53,6 +53,7 @@ private: QCheckBox* m_emulate_disc_speed; QCheckBox* m_use_dsp_hle; QCheckBox* m_use_monoscopic_shadows; + QCheckBox* m_manual_texture_sampling; QPushButton* m_refresh_config; From 44d25602a0e4400fdfbb79344c9c8a47e313eb78 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Wed, 26 Jul 2023 15:31:51 +0200 Subject: [PATCH 56/99] Translation resources sync with Transifex --- Languages/po/ar.po | 253 ++++++++++------- Languages/po/ca.po | 151 ++++++---- Languages/po/cs.po | 151 ++++++---- Languages/po/da.po | 151 ++++++---- Languages/po/de.po | 157 +++++++---- Languages/po/dolphin-emu.pot | 151 ++++++---- Languages/po/el.po | 151 ++++++---- Languages/po/en.po | 151 ++++++---- Languages/po/es.po | 409 ++++++++++++++++++--------- Languages/po/fa.po | 151 ++++++---- Languages/po/fi.po | 157 +++++++---- Languages/po/fr.po | 409 ++++++++++++++++++--------- Languages/po/hr.po | 151 ++++++---- Languages/po/hu.po | 151 ++++++---- Languages/po/it.po | 401 ++++++++++++++++++--------- Languages/po/ja.po | 157 +++++++---- Languages/po/ko.po | 157 +++++++---- Languages/po/ms.po | 151 ++++++---- Languages/po/nb.po | 151 ++++++---- Languages/po/nl.po | 404 +++++++++++++++++---------- Languages/po/pl.po | 151 ++++++---- Languages/po/pt.po | 151 ++++++---- Languages/po/pt_BR.po | 407 ++++++++++++++++++--------- Languages/po/ro.po | 151 ++++++---- Languages/po/ru.po | 158 +++++++---- Languages/po/sr.po | 151 ++++++---- Languages/po/sv.po | 199 ++++++++----- Languages/po/tr.po | 151 ++++++---- Languages/po/zh_CN.po | 521 ++++++++++++++++++++++------------- Languages/po/zh_TW.po | 151 ++++++---- 30 files changed, 4224 insertions(+), 2132 deletions(-) diff --git a/Languages/po/ar.po b/Languages/po/ar.po index 927a31c1a0..7ff3cab9c6 100644 --- a/Languages/po/ar.po +++ b/Languages/po/ar.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: mansoor , 2013,2015-2023\n" "Language-Team: Arabic (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -186,6 +186,16 @@ msgstr "%1 قد انضم" msgid "%1 has left" msgstr "%1 لقد غادر" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 القرص غير صالح" @@ -203,6 +213,11 @@ msgstr "نطاقات الذاكرة %1" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 وجدت جلسة" @@ -261,7 +276,7 @@ msgstr "%1[%2]: %3/%4 ميغابايت" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "%1x MSAA" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -270,7 +285,7 @@ msgstr "%1x Native (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "%1x SSAA" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -754,7 +769,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 GiB" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -762,7 +777,7 @@ msgstr "128 Mbit (2043 blocks)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 MiB" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -770,7 +785,7 @@ msgstr "16 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -804,11 +819,11 @@ msgstr "1x" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 GiB" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 MiB" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -824,7 +839,7 @@ msgstr "2x Native (1280x1056) for 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -876,7 +891,7 @@ msgstr "4 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -900,7 +915,7 @@ msgstr "4x Native (2560x2112) for 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -912,7 +927,7 @@ msgstr "64 Mbit (1019 blocks)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 MiB" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -943,7 +958,7 @@ msgstr "8 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -1132,10 +1147,10 @@ msgstr "تأثير مقياس التسارع" msgid "Accuracy:" msgstr "ضبط" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" -msgstr "" +msgstr "الإنجازات" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1414,7 +1429,7 @@ msgstr "محاذاة لطول نوع البيانات" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "الكل" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -2302,7 +2317,7 @@ msgstr "الصين" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "اختر" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2322,7 +2337,7 @@ msgstr "اختر ملف الإدخال الثانوي" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:514 msgid "Choose the GCI base folder" -msgstr "" +msgstr "GCI اختر المجلد الأساسي" #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:216 msgid "Choose the folder to extract to" @@ -2407,17 +2422,17 @@ msgstr "رمز" msgid "Codes received!" msgstr "الرموز الواردة!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "إعدادات تصحيح الألوان" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "تصحيح الألوان" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "مساحة اللون" #: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Combine &Two Signature Files..." @@ -2703,6 +2718,14 @@ msgstr "إعدادات وحدة التحكم" msgid "Controllers" msgstr "وحدات التحكم" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2823,19 +2846,19 @@ msgstr "" "تحويل...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2895,11 +2918,11 @@ msgstr "B نسخ إلى" msgid "Core" msgstr "النواة" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "مساحة اللون الصحيحة" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3132,9 +3155,13 @@ msgstr "مساحة العنوان المخصصة" msgid "Custom RTC Options" msgstr "خيارات تخصيص وقت النظام " +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "تخصيص" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3451,22 +3478,6 @@ msgstr "اتصال مباشر" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "غير متصل" @@ -3952,7 +3963,7 @@ msgstr "إخراج القرص" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "عنصر" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4030,7 +4041,7 @@ msgstr "تمكين طبقات التحقق من واجهة برمجة التطب #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "تمكين الإنجازات" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4044,6 +4055,10 @@ msgstr "تمكين الأسرار" msgid "Enable Custom RTC" msgstr "تمكين وقت مخصص" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "تمكين ثنائي النواة" @@ -4062,7 +4077,7 @@ msgstr "تمكين تجاوز المحاكي حجم الذاكرة" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "تمكين ظهور الإنجازات " #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4074,7 +4089,7 @@ msgstr "تمكين تعديلات الرسومات" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:62 msgid "Enable Leaderboards" -msgstr "" +msgstr "تمكين المتصدرين" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:88 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:66 @@ -4087,7 +4102,7 @@ msgstr "تمكين المسح التدريجي" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "RetroAchievements.org تمكين التكامل" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" @@ -4108,7 +4123,7 @@ msgstr "تمكين بيانات مكبر صوت" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "تمكين الإنجازات غير الرسمية" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4164,7 +4179,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" -msgstr "" +msgstr "
تمكين فتح الإنجازات" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:74 msgid "" @@ -4764,7 +4779,7 @@ msgstr "Redump.org فشل الاتصال بـ" msgid "Failed to connect to server: %1" msgstr "%1 فشل الاتصال بالخادم" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "D3D فشل إنشاء سلسله مبادله" @@ -5634,7 +5649,7 @@ msgstr "GCI مجلد" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:120 msgid "GCI Folder Path:" -msgstr "" +msgstr "GCI مسار مجلد " #: Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp:428 msgid "GCMemcardDirectory: ClearBlock called with invalid block address" @@ -5739,8 +5754,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "%1 جيم بوي أدفانس في منفذ" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5755,10 +5770,14 @@ msgstr "تفاصيل اللعبة" msgid "Game Folders" msgstr "مجلدات الألعاب" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5865,9 +5884,9 @@ msgstr "فتحة ميكروفون جيم كيوب %1" msgid "GameCube TAS Input %1" msgstr "GameCube TAS Input %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "جاما" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -5999,12 +6018,16 @@ msgstr "جيروسكوب" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" +msgstr "HDR" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 +msgid "HDR Paper White Nits" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 -msgid "HDR Paper White Nits" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" msgstr "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 @@ -6787,7 +6810,7 @@ msgstr "JIT Register Cache Off" msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7038,7 +7061,7 @@ msgstr "تحميل النسيج المخصص" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "تحميل الملف" #: Source/Core/DolphinQt/MenuBar.cpp:249 msgid "Load GameCube Main Menu" @@ -7063,7 +7086,7 @@ msgstr "تحميل القرص" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "فتحة التحميل" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7216,6 +7239,7 @@ msgstr "محلي" msgid "Lock Mouse Cursor" msgstr "قفل مؤشر الماوس" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7247,15 +7271,15 @@ msgstr "مسجل المخرجات" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "تسجيل الدخول" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "فشل تسجيل الدخول" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "تسجيل الخروج" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7559,24 +7583,25 @@ msgstr "NKit تحذير" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7977,7 +8002,7 @@ msgstr "وثائق على الانترنت" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "عرض المجموعة فقط" #: Source/Core/DolphinQt/MenuBar.cpp:1615 msgid "" @@ -8119,9 +8144,9 @@ msgstr "تشغيل تسجيل الإدخال" msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8397,7 +8422,7 @@ msgstr "منفذ" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "فتحات البوابة" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -8532,6 +8557,7 @@ msgstr "الملف الشخصي" msgid "Program Counter" msgstr "عداد البرنامج" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9061,12 +9087,8 @@ msgstr "SD Root:" msgid "SD Sync Folder:" msgstr "مجلد مزامنة SD:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9353,7 +9375,7 @@ msgstr "تعليمات البحث" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "بحث:" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9722,7 +9744,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9783,10 +9805,6 @@ msgstr "أستراليا" msgid "Show Current Game on Discord" msgstr "عرض اللعبة الحالية على الخلاف" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "عرض تصحيح واجهة المستخدم" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -9803,7 +9821,7 @@ msgstr "إظهار الرموز الممكّنة أولاً" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:53 msgid "Show FPS" -msgstr "عرض عدد الإطارات" +msgstr "FPS عرض" #: Source/Core/DolphinQt/MenuBar.cpp:785 msgid "Show Frame Counter" @@ -10290,7 +10308,7 @@ msgstr "سرعة" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "Spyro's Adventure" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -10779,6 +10797,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11660,15 +11687,15 @@ msgstr "امريكا" #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "محاكاة جهاز يو اس بي" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "محاكاة يو اس بي" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "محاكاة اجهزة يو اس بي" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -11898,6 +11925,22 @@ msgstr "إلغاء تحميل القرص" msgid "Unlock Cursor" msgstr "فتح المؤشر" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "تفريغ" @@ -12099,7 +12142,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "اسم المستخدم" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -12933,6 +12976,10 @@ msgstr "او حدد الجهاز" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "هذه القيمة " diff --git a/Languages/po/ca.po b/Languages/po/ca.po index 57e9c27c49..001d23e9bf 100644 --- a/Languages/po/ca.po +++ b/Languages/po/ca.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Puniasterus , 2013-2016,2021-2023\n" "Language-Team: Catalan (http://app.transifex.com/delroth/dolphin-emu/" @@ -192,6 +192,16 @@ msgstr "%1 s'ha unit" msgid "%1 has left" msgstr "%1 s'ha marxat" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 no és una ROM vàlida" @@ -209,6 +219,11 @@ msgstr "%1 rangs de memòria" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "S'ha trobat %1 sessió" @@ -1116,7 +1131,7 @@ msgstr "" msgid "Accuracy:" msgstr "Precisió:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2365,7 +2380,7 @@ msgstr "Codi:" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2373,7 +2388,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2658,6 +2673,14 @@ msgstr "" msgid "Controllers" msgstr "Comandaments" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2761,19 +2784,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2833,11 +2856,11 @@ msgstr "" msgid "Core" msgstr "Nucli" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3052,6 +3075,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3365,16 +3392,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3941,6 +3958,10 @@ msgstr "Activar Trucs" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Habilitar Doble nucli" @@ -4652,7 +4673,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5601,8 +5622,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5617,10 +5638,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5723,7 +5748,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5857,14 +5882,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6615,7 +6644,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7038,6 +7067,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7375,7 +7405,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7383,16 +7413,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7928,7 +7959,7 @@ msgstr "&Reprodueix l'enregistrament d'entrades" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8333,6 +8364,7 @@ msgstr "Perfil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8857,12 +8889,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9508,7 +9536,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9569,10 +9597,6 @@ msgstr "Mostrar Austràlia" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10557,6 +10581,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11604,6 +11637,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12612,6 +12661,10 @@ msgstr "" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/cs.po b/Languages/po/cs.po index a7813a6913..0f5ba90c86 100644 --- a/Languages/po/cs.po +++ b/Languages/po/cs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Zbyněk Schwarz , 2011-2016\n" "Language-Team: Czech (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -168,6 +168,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -185,6 +195,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1090,7 +1105,7 @@ msgstr "" msgid "Accuracy:" msgstr "Přesnost:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2339,7 +2354,7 @@ msgstr "Kód:" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2347,7 +2362,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2632,6 +2647,14 @@ msgstr "" msgid "Controllers" msgstr "Ovladače" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2735,19 +2758,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2807,11 +2830,11 @@ msgstr "" msgid "Core" msgstr "Jádro" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3026,6 +3049,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3339,16 +3366,6 @@ msgstr "Přímé spojení" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3915,6 +3932,10 @@ msgstr "Povolit Cheaty" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Povolit dvojité jádro" @@ -4627,7 +4648,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5576,8 +5597,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5592,10 +5613,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5698,7 +5723,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5832,14 +5857,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6589,7 +6618,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7012,6 +7041,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7349,7 +7379,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7357,16 +7387,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7903,7 +7934,7 @@ msgstr "&Spustit vstupní nahrávku..." msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8308,6 +8339,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8832,12 +8864,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9485,7 +9513,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9546,10 +9574,6 @@ msgstr "Zobrazit Autrálii" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10534,6 +10558,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11582,6 +11615,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Rozbalování" @@ -12590,6 +12639,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/da.po b/Languages/po/da.po index 0d310faaf8..a74d1666b3 100644 --- a/Languages/po/da.po +++ b/Languages/po/da.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Lars Lyngby , 2020-2022\n" "Language-Team: Danish (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -187,6 +187,16 @@ msgstr "%1 ha tilsluttet sig" msgid "%1 has left" msgstr "%1 har forladt gruppen" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 er ikke en gyldig ROM" @@ -204,6 +214,11 @@ msgstr "%1 hukommelsesområder" msgid "%1 ms" msgstr "%1 ms." +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 session fundet" @@ -1123,7 +1138,7 @@ msgstr "" msgid "Accuracy:" msgstr "Nøjagtighed:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2374,7 +2389,7 @@ msgstr "Kode:" msgid "Codes received!" msgstr "Koder modtaget!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2382,7 +2397,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2667,6 +2682,14 @@ msgstr "Kontrollerindstillinger" msgid "Controllers" msgstr "Kontrollere" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2772,19 +2795,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2844,11 +2867,11 @@ msgstr "Kopiér til B" msgid "Core" msgstr "Kerne" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3068,6 +3091,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Tilpassede RTC indstillinger" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3381,16 +3408,6 @@ msgstr "Direkte forbindelse" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3957,6 +3974,10 @@ msgstr "Aktivér snydekoder" msgid "Enable Custom RTC" msgstr "Aktivér tilpasset RTC" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Aktivér dualcore" @@ -4673,7 +4694,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5622,8 +5643,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5638,10 +5659,14 @@ msgstr "" msgid "Game Folders" msgstr "Spilmapper" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5744,7 +5769,7 @@ msgstr "GameCube mikrofonstik %1" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5878,14 +5903,18 @@ msgstr "" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6643,7 +6672,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7066,6 +7095,7 @@ msgstr "Lokal" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7405,7 +7435,7 @@ msgstr "" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7413,16 +7443,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7960,7 +7991,7 @@ msgstr "Spi&l inputoptagelse..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8365,6 +8396,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8889,12 +8921,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9543,7 +9571,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9604,10 +9632,6 @@ msgstr "Vis Australien" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Vis debuggingskærmflade" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10592,6 +10616,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11652,6 +11685,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Udpakker" @@ -12665,6 +12714,10 @@ msgstr "eller vælg en enhed" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/de.po b/Languages/po/de.po index 3f92621285..16debcdf9e 100644 --- a/Languages/po/de.po +++ b/Languages/po/de.po @@ -33,7 +33,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Marc Godhusen , 2016-2022\n" "Language-Team: German (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -209,6 +209,16 @@ msgstr "%1 ist beigetreten" msgid "%1 has left" msgstr "%1 ist gegangen" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -226,6 +236,11 @@ msgstr "" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 Sitzung gefunden" @@ -1162,7 +1177,7 @@ msgstr "" msgid "Accuracy:" msgstr "Genauigkeit:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2494,7 +2509,7 @@ msgstr "Code:" msgid "Codes received!" msgstr "Codes empfangen!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2502,7 +2517,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2788,6 +2803,14 @@ msgstr "Controller-Einstellungen" msgid "Controllers" msgstr "Controller" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2912,19 +2935,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2984,11 +3007,11 @@ msgstr "Nach B kopieren" msgid "Core" msgstr "Kern" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3237,6 +3260,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Benutzerdefinierte Echtzeituhr" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3560,22 +3587,6 @@ msgstr "Direktverbindung" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Der Direct3D 11-Renderer erfordert Unterstützung für Funktionen, die von " -"deiner Systemkonfiguration nicht unterstützt werden. Dies liegt " -"wahrscheinlich daran, dass du Windows 7 verwendest. Du kannst dieses Backend " -"weiterhin verwenden, es können jedoch Grafikfehler auftreten.\n" -"\n" -"Möchtest du wirklich zu Direct3D 11 wechseln? Im Zweifel 'Nein' auswählen." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -4179,6 +4190,10 @@ msgstr "Cheats aktivieren" msgid "Enable Custom RTC" msgstr "Benutzerdefinierte Echtzeituhr aktivieren" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Dual Core aktivieren" @@ -4924,7 +4939,7 @@ msgstr "Konnte nicht mit Redump.org verbinden" msgid "Failed to connect to server: %1" msgstr "Konnte nicht mit Server %1 verbinden" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Fehler beim Erstellen der D3D-Swap-Kette" @@ -5948,8 +5963,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5964,10 +5979,14 @@ msgstr "Spieldetails" msgid "Game Folders" msgstr "Spiele-Ordner" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -6072,7 +6091,7 @@ msgstr "GameCube Mikrofonslot %1" msgid "GameCube TAS Input %1" msgstr "GameCube TAS-Eingabe %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -6211,14 +6230,18 @@ msgstr "Gyroskop" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -7032,7 +7055,7 @@ msgstr "JIT-Register-Cache Aus" msgid "JIT SystemRegisters Off" msgstr "JIT-SystemRegister Aus" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7467,6 +7490,7 @@ msgstr "Lokal" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7819,7 +7843,7 @@ msgstr "NKit-Warnung" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7827,16 +7851,17 @@ msgstr "" msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8382,7 +8407,7 @@ msgstr "Eingabeau&fzeichnung wiedergeben..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8802,6 +8827,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "Programmzähler" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9337,12 +9363,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -10016,7 +10038,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10077,10 +10099,6 @@ msgstr "Australien anzeigen" msgid "Show Current Game on Discord" msgstr "Zeige momentanes Spiel auf Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Zeige Debugging UI" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -11103,6 +11121,15 @@ msgstr "" "Die mindeste Loader-Version des DFF ({0}) überschreitet die Version dieses " "FIFO-Players ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "Die H3-Hash-Tabelle für die {0} Partition ist nicht korrekt." @@ -12283,6 +12310,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Auspacken" @@ -13399,6 +13442,10 @@ msgstr "oder wähle ein Gerät" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/dolphin-emu.pot b/Languages/po/dolphin-emu.pot index fada52445b..a793459e56 100644 --- a/Languages/po/dolphin-emu.pot +++ b/Languages/po/dolphin-emu.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -165,6 +165,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -182,6 +192,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1087,7 +1102,7 @@ msgstr "" msgid "Accuracy:" msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2336,7 +2351,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2344,7 +2359,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2629,6 +2644,14 @@ msgstr "" msgid "Controllers" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2732,19 +2755,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2804,11 +2827,11 @@ msgstr "" msgid "Core" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3023,6 +3046,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3336,16 +3363,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3912,6 +3929,10 @@ msgstr "" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "" @@ -4619,7 +4640,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5568,8 +5589,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5584,10 +5605,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5690,7 +5715,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5824,14 +5849,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6581,7 +6610,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7001,6 +7030,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7338,7 +7368,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7346,16 +7376,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7891,7 +7922,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8296,6 +8327,7 @@ msgstr "" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8820,12 +8852,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9471,7 +9499,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9532,10 +9560,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10520,6 +10544,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11563,6 +11596,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12571,6 +12620,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/el.po b/Languages/po/el.po index 7b86d6ca70..d8985651d2 100644 --- a/Languages/po/el.po +++ b/Languages/po/el.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: MRCYO Dev, 2023\n" "Language-Team: Greek (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -176,6 +176,16 @@ msgstr "" msgid "%1 has left" msgstr "%1 έχει φύγει" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -193,6 +203,11 @@ msgstr "" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1101,7 +1116,7 @@ msgstr "" msgid "Accuracy:" msgstr "Ακρίβεια:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2350,7 +2365,7 @@ msgstr "Κωδικός:" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2358,7 +2373,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2643,6 +2658,14 @@ msgstr "Ρυθμίσεις Χειριστηρίων" msgid "Controllers" msgstr "Χειριστήρια" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2748,19 +2771,19 @@ msgstr "" "Μετατροπή\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2820,11 +2843,11 @@ msgstr "" msgid "Core" msgstr "Πυρήνας" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3039,6 +3062,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3353,16 +3380,6 @@ msgstr "" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3934,6 +3951,10 @@ msgstr "Ενεργοποίηση Cheat" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Ενεργοποίηση Διπλού Πυρήνα" @@ -4647,7 +4668,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5596,8 +5617,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5612,10 +5633,14 @@ msgstr "" msgid "Game Folders" msgstr "Φάκελοι Παιχνιδιών" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5718,7 +5743,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5852,14 +5877,18 @@ msgstr "" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6609,7 +6638,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7032,6 +7061,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7371,7 +7401,7 @@ msgstr "" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7379,16 +7409,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7924,7 +7955,7 @@ msgstr "Α&ναπαραγωγή Εγγραφής Χειρισμών..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8329,6 +8360,7 @@ msgstr "Προφίλ" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8853,12 +8885,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9507,7 +9535,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9568,10 +9596,6 @@ msgstr "Εμφάνιση Αυστραλίας" msgid "Show Current Game on Discord" msgstr "Εμφάνιση Τρέχοντος Παιχνιδιού σε Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Εμφάνιση Διεπαφής Αποσφαλμάτωσης" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10556,6 +10580,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11607,6 +11640,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Αποσυμπίεση" @@ -12618,6 +12667,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/en.po b/Languages/po/en.po index c0d2cb2a87..dd6ba69020 100644 --- a/Languages/po/en.po +++ b/Languages/po/en.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emu\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2011-01-06 14:53+0100\n" "Last-Translator: BhaaL \n" "Language-Team: \n" @@ -164,6 +164,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -181,6 +191,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1086,7 +1101,7 @@ msgstr "" msgid "Accuracy:" msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2335,7 +2350,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2343,7 +2358,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2628,6 +2643,14 @@ msgstr "" msgid "Controllers" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2731,19 +2754,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2803,11 +2826,11 @@ msgstr "" msgid "Core" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3022,6 +3045,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3335,16 +3362,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3911,6 +3928,10 @@ msgstr "" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "" @@ -4618,7 +4639,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5567,8 +5588,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5583,10 +5604,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5689,7 +5714,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5823,14 +5848,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6580,7 +6609,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7000,6 +7029,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7337,7 +7367,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7345,16 +7375,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7890,7 +7921,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8295,6 +8326,7 @@ msgstr "" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8819,12 +8851,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9470,7 +9498,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9531,10 +9559,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10519,6 +10543,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11562,6 +11595,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12570,6 +12619,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/es.po b/Languages/po/es.po index 727723db56..23957380d1 100644 --- a/Languages/po/es.po +++ b/Languages/po/es.po @@ -31,7 +31,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Víctor González, 2021-2023\n" "Language-Team: Spanish (http://app.transifex.com/delroth/dolphin-emu/" @@ -208,6 +208,16 @@ msgstr "%1 se ha unido" msgid "%1 has left" msgstr "%1 se ha salido" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 no es una ROM válida" @@ -225,6 +235,11 @@ msgstr "%1 rango(s) de memoria" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 sesión encontrada" @@ -283,7 +298,7 @@ msgstr "%1[%2]: %3/%4 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "MSAA %1x" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -292,7 +307,7 @@ msgstr "Nativa %1x (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "SSAA %1x" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -776,7 +791,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 GiB" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -784,7 +799,7 @@ msgstr "128 Mbit (2043 bloques)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 MiB" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -792,7 +807,7 @@ msgstr "16 bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -826,11 +841,11 @@ msgstr "x1" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 GiB" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 MiB" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -846,7 +861,7 @@ msgstr "Nativa x2 (1280x1056) a 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -898,7 +913,7 @@ msgstr "4 bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -922,7 +937,7 @@ msgstr "Nativa x4 (2560x2112) a 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -934,7 +949,7 @@ msgstr "64 Mbit (1019 bloques)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 MiB" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -965,7 +980,7 @@ msgstr "8 bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -1065,6 +1080,9 @@ msgid "" "A group of features to make the colors more accurate, matching the color " "space Wii and GC games were meant for." msgstr "" +"Un conjunto de características con las que mostrar unos colores más " +"fidedignos, igualando el espacio de color para el que fueron diseñados los " +"juegos de Wii y GC." #: Source/Core/DolphinQt/Main.cpp:226 msgid "A save state cannot be loaded without specifying a game to launch." @@ -1166,10 +1184,10 @@ msgstr "Influencia del acelerómetro" msgid "Accuracy:" msgstr "Exactitud:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" -msgstr "" +msgstr "Logros" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1474,7 +1492,7 @@ msgstr "África" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:342 msgid "Air" -msgstr "" +msgstr "Aire" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:116 msgid "Aligned to data type length" @@ -1482,7 +1500,7 @@ msgstr "Alineación a la longitud del tipo de datos" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "Todas" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -2412,7 +2430,7 @@ msgstr "China" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "Seleccionar" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2467,7 +2485,7 @@ msgstr "Borrar caché" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:119 msgid "Clear Slot" -msgstr "" +msgstr "Vaciar posición" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:83 msgid "Clock Override" @@ -2517,17 +2535,17 @@ msgstr "Código:" msgid "Codes received!" msgstr "¡Códigos recibidos!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "Configuración de corrección de colores" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "Corrección de color:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "Espacio de color" #: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Combine &Two Signature Files..." @@ -2661,6 +2679,57 @@ msgid "" "possible for them to go out of range or to become NaN. A warning will be " "given if NaN is returned, and the var that became NaN will be logged." msgstr "" +"Condiciones:\n" +"Establece una expresión que será evaluada al llegar a un punto de " +"interrupción. Si la expresión está configurada como «false» o 0, se ignorará " +"el punto de interrupción hasta que se vuelva a llegar a este. Cada " +"instrucción debe estar separada por comas. La última instrucción será la " +"única que se utilice para determinar la acción a tomar.\n" +"\n" +"Registros que se pueden referenciar:\n" +"GPRs : r0..r31\n" +"FPRs : f0..f31\n" +" LR, CTR, PC\n" +"\n" +"Funciones:\n" +"Establecer una instrucción: r1 = 8\n" +"Conversiones: s8(0xff). Disponibles: s8, u8, s16, u16, s32, u32\n" +"Pila de llamadas: callstack(0x80123456), callstack(\"anim\")\n" +"Comparación de cadenas: streq(r3, \"abc\"). Ambos parámetros pueden ser " +"direcciones o constantes de cadenas.\n" +"Leer memoria: read_u32(0x80000000). Disponibles: u8, s8, u16, s16, u32, s32, " +"f32, f64\n" +"Escribir memoria: write_u32(r3, 0x80000000). Disponibles: u8, u16, u32, f32, " +"f64\n" +"*actualmente, las escrituras siempre harán de desencadenantes\n" +"\n" +"Operaciones:\n" +"Unarias: -u, !u, ~u\n" +"Matemáticas: * / + -, potencias: **, restantes: %, «shifts»: <<, >>\n" +"Comparaciones: <, <=, >, >=, ==, !=, &&, ||\n" +"Operaciones bit a bit: &, |, ^\n" +"\n" +"Ejemplos:\n" +"r4 == 1\n" +"f0 == 1.0 && f2 < 10.0\n" +"r26 <= r0 && ((r5 + 3) & -4) * ((r6 + 3) & -4)* 4 > r0\n" +"p = r3 + 0x8, p == 0x8003510 && read_u32(p) != 0\n" +"Escribir e interrumpir: r4 = 8, 1\n" +"Escribir y continuar: f3 = f1 + f2, 0\n" +"La condición debe ir siempre en último lugar.\n" +"\n" +"Solo se deberían utilizar cadenas en callstack() o streq() y siempre deben " +"ir \"entrecomilladas\". No asignes cadenas a una variable.\n" +"Todas las variables se mostrarán en el registro de la interfaz de la memoria " +"en caso de que haya una coincidencia o un resultado NaN (no numérico). Para " +"buscar problemas, asigna una variable a tu ecuación para que se muestre en " +"el registro.\n" +"\n" +"Nota: todos los valores se convertirán de forma interna al formato de doble " +"palabra para hacer los cálculos. Es posible que estos valores se salgan de " +"su rango o se conviertan en NaN (no numéricos). Se mostrará una advertencia " +"en caso de generar un NaN y la variable que se haya convertido en NaN " +"quedará registrada." #: Source/Core/DolphinQt/ToolBar.cpp:129 msgid "Config" @@ -2818,6 +2887,14 @@ msgstr "Ajustes del mando" msgid "Controllers" msgstr "Mandos" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2945,24 +3022,28 @@ msgstr "" "Convirtiendo...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." "

If unsure, leave this unchecked." msgstr "" +"Convierte el gamma previsto por el juego al gamma objetivo de tu pantalla " +"SDR actual.
Los monitores suelen estar diseñados para sRGB. Los " +"televisores suelen estar diseñados para 2,2.

Si " +"tienes dudas, deja esta opción desactivada." #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:290 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:704 @@ -3017,13 +3098,13 @@ msgstr "Copiar a B" msgid "Core" msgstr "Núcleo" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "Corregir espacio de color" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" -msgstr "" +msgstr "Corregir gamma para SDR" #. i18n: Performance cost, not monetary cost #: Source/Core/DolphinQt/Debugger/JITWidget.cpp:91 @@ -3184,7 +3265,7 @@ msgstr "Crear archivo de Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:80 msgid "Create Skylander Folder" -msgstr "" +msgstr "Crear carpeta de Skylanders" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:109 msgid "Create mappings for other devices" @@ -3279,9 +3360,13 @@ msgstr "Espacio de dirección personalizado" msgid "Custom RTC Options" msgstr "Opciones de fecha en tiempo real personalizada (RTC)" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "Personalizar" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3604,22 +3689,6 @@ msgstr "Conexión directa" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"El renderizador de Direct3D 11 requiere soporte para características no " -"soportadas por la configuración de tu sistema. Esto se debe probablemente a " -"que estás usando Windows 7. Puedes seguir usando este motor, pero puedes " -"encontrar artefactos gráficos.\n" -"\n" -"¿Realmente quieres cambiar a Direct3D 11? Si tienes dudas, selecciona «No»." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "Des&conectado" @@ -4103,7 +4172,7 @@ msgstr "Refresco temprano de memoria" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:336 msgid "Earth" -msgstr "" +msgstr "Tierra" #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "East Asia" @@ -4150,7 +4219,7 @@ msgstr "Expulsar disco" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "Clase elemental" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4231,7 +4300,7 @@ msgstr "Activar capas de validación de la API" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "Activar logros" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4245,6 +4314,10 @@ msgstr "Activar trucos" msgid "Enable Custom RTC" msgstr "RTC personalizado" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Activar doble núcleo" @@ -4263,7 +4336,7 @@ msgstr "Forzar tamaño de la memoria emulada" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "Activar repetición de logros («Encore»)" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4275,7 +4348,7 @@ msgstr "Activar modificaciones de gráficos" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:62 msgid "Enable Leaderboards" -msgstr "" +msgstr "Activar tablas de clasificación" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:88 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:66 @@ -4288,11 +4361,11 @@ msgstr "Activar escaneo progresivo" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "Activar integración con RetroAchievements.org" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" -msgstr "" +msgstr "Activar presencia en aplicación" #: Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.cpp:39 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:353 @@ -4309,7 +4382,7 @@ msgstr "Activar envío de datos al altavoz" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "Activar logros no oficiales" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4317,7 +4390,7 @@ msgstr "Informar de estadísticas de uso" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:161 msgid "Enable WiiConnect24 via WiiLink" -msgstr "" +msgstr "Activar WiiConnect24 a través de WiiLink" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:81 msgid "Enable Wireframe" @@ -4332,6 +4405,8 @@ msgid "" "Enable competing in RetroAchievements leaderboards.

Hardcore Mode " "must be enabled to use." msgstr "" +"Permite competir en las tablas de clasificación de RetroAchievements." +"

Es necesario activar el modo «hardcore»." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:68 msgid "" @@ -4340,6 +4415,11 @@ msgid "" "website. If this is disabled, the website will only report what game is " "being played.

This has no bearing on Discord rich presence." msgstr "" +"Activa la presencia enriquecida en la página web de RetroAchievements." +"

Mostrará una descripción detallada de lo que esté haciendo el " +"jugador en la página web. Al desactivar esta opción, la página mostrará " +"únicamente el juego al que se esté jugando.

No tiene relación alguna " +"con la Rich Presence de Discord." #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 msgid "" @@ -4357,6 +4437,10 @@ msgid "" "account to use. Dolphin does not save your password locally and uses an API " "token to maintain login." msgstr "" +"Activa la integración con RetroAchievements para poder ganar logros y " +"competir en sus tablas de clasificación.

Es necesario iniciar sesión " +"con una cuenta de RetroAchievements. Dolphin no guardará tu contraseña de " +"forma local y utilizará un token de su API para almacenar tu sesión." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:80 msgid "" @@ -4365,10 +4449,15 @@ msgid "" "will be notified if they meet the unlock conditions again, useful for custom " "speedrun criteria or simply for fun." msgstr "" +"Permite desbloquear logros en el modo de repetición («Encore»).

El " +"modo de repetición vuelve a activar los logros si el jugador ya los ha " +"desbloqueado en la página web, así aparecerán notificaciones si se vuelven a " +"cumplir las condiciones para el desbloqueo. Ideal para hacer «speedruns» " +"personalizadas o por puro placer." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" -msgstr "" +msgstr "Activa el desbloqueo de logros.
" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:74 msgid "" @@ -4377,6 +4466,10 @@ msgid "" "that have not been deemed official by RetroAchievements and may be useful " "for testing or simply for fun." msgstr "" +"Permite desbloquear tanto logros no oficiales como oficiales.

Los " +"logros no oficiales pueden ser logros opcionales o inacabados que " +"RetroAchievements no considere oficiales, útiles para hacer pruebas o por " +"puro placer." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:97 msgid "" @@ -4459,6 +4552,14 @@ msgid "" "

Note that games still render in SDR internally." "

If unsure, leave this unchecked." msgstr "" +"Activa la salida de vídeo HDR scRGB (si es compatible con tu motor gráfico y " +"tu monitor). Es posible que tengas que activar el modo a pantalla completa." +"

Ofrece una mayor precisión a los sombreadores de posprocesado, " +"permite el funcionamiento de los sombreadores AutoHDR y también mostrar la " +"totalidad de los espacios de color PAL y NTSC-J.

Ten en cuenta que " +"los juegos seguirán renderizándose internamente en SDR." +"

Si tienes dudas, deja esta opción desactivada." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:151 msgid "Enables stretching of the audio to match emulation speed." @@ -4495,6 +4596,10 @@ msgid "" "such as the Forecast and Nintendo Channels\n" "Read the Terms of Service at: https://www.wiilink24.com/tos" msgstr "" +"Activa el servicio WiiLink para los canales de WiiConnect24.\n" +"WiiLink es un proveedor alternativo para los canales de WiiConnect24 " +"descontinuados, tales como los Canales Tiempo y Nintendo.\n" +"Puedes leer las condiciones del servicio aquí: https://www.wiilink24.com/tos" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:298 msgid "" @@ -5025,7 +5130,7 @@ msgstr "¡No se ha podido borrar el Skylander!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:575 msgid "Failed to clear the Skylander from slot(%1)!" -msgstr "" +msgstr "¡No se ha podido quitar al Skylander del espacio (%1)!" #: Source/Core/DiscIO/VolumeVerifier.cpp:108 msgid "Failed to connect to Redump.org" @@ -5035,7 +5140,7 @@ msgstr "No se ha podido conectar con redump.org" msgid "Failed to connect to server: %1" msgstr "No se ha podido conectar al servidor: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "No se ha podido crear la cadena de intercambio D3D" @@ -5066,6 +5171,9 @@ msgid "" "%1\n" "(Skylander may already be on the portal)" msgstr "" +"No se ha podido crear el archivo de Skylander:\n" +"%1\n" +"(El Skylander podría estar ya en el portal)" #: Source/Core/Core/NetPlayClient.cpp:1292 msgid "" @@ -5622,7 +5730,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:333 msgid "Fire" -msgstr "" +msgstr "Fuego" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:40 msgid "First Person" @@ -5987,6 +6095,13 @@ msgid "" "Further errors will be sent to the Video Backend log and Dolphin will now " "likely crash or hang." msgstr "" +"GFX FIFO: código de operación desconocido ({0:#04x} en {1}, " +"preproceso={2}).\n" +"\n" +"{3}\n" +"\n" +"Se enviará más información de los errores al registro del motor de vídeo y " +"es probable que Dolphin se cuelgue en breve." #: Source/Core/VideoBackends/OGL/OGLMain.cpp:181 msgid "GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024." @@ -6093,8 +6208,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "Game Boy Advance en el puerto %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -6109,8 +6224,12 @@ msgstr "Detalles del juego" msgid "Game Folders" msgstr "Carpetas de juego" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" +msgstr "Gamma del juego" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 @@ -6220,9 +6339,9 @@ msgstr "Ranura de micrófono de GameCube %1" msgid "GameCube TAS Input %1" msgstr "Entrada TAS de GameCube %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "Gamma" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -6286,7 +6405,7 @@ msgstr "GiB" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:267 msgid "Giants" -msgstr "" +msgstr "Giants" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:195 msgid "Golf Mode" @@ -6359,17 +6478,21 @@ msgstr "Giroscopio" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" -msgstr "" +msgstr "HDR" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" +msgstr "Cd/m² de blanco «papel» de HDR" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" msgstr "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" -msgstr "" +msgstr "Posprocesado HDR" #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:62 msgid "Hacks" @@ -7208,7 +7331,7 @@ msgstr "Sin registro de caché de JIT" msgid "JIT SystemRegisters Off" msgstr "Sin SystemRegisters JIT" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7411,7 +7534,7 @@ msgstr "Licencia" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:339 msgid "Life" -msgstr "" +msgstr "Vida" #: Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp:35 #: Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp:53 @@ -7462,7 +7585,7 @@ msgstr "Cargar texturas personalizadas" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "Cargar archivo" #: Source/Core/DolphinQt/MenuBar.cpp:249 msgid "Load GameCube Main Menu" @@ -7487,7 +7610,7 @@ msgstr "Cargar ROM" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "Cargar en espacio" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7647,6 +7770,7 @@ msgstr "Local" msgid "Lock Mouse Cursor" msgstr "Bloquear cursor del ratón" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "Bloqueada" @@ -7678,15 +7802,15 @@ msgstr "Salida de registro" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "Iniciar sesión" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "Fallo al iniciar sesión" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "Cerrar sesión" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7736,7 +7860,7 @@ msgstr "Archivos Gameshark de MadCatz" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:324 msgid "Magic" -msgstr "" +msgstr "Magia" #: Source/Core/DolphinQt/TAS/GCTASInputWindow.cpp:29 msgid "Main Stick" @@ -8014,24 +8138,25 @@ msgstr "Advertencia NKit" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8452,7 +8577,7 @@ msgstr "&Documentación en línea" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "Mostrar solo tu colección" #: Source/Core/DolphinQt/MenuBar.cpp:1615 msgid "" @@ -8594,9 +8719,9 @@ msgstr "Reproducir pu&lsaciones grabadas..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8847,6 +8972,8 @@ msgid "" "Please change the \"SyncOnSkipIdle\" setting to \"True\"! It's currently " "disabled, which makes this problem very likely to happen." msgstr "" +"¡Por favor, cambia el valor de «SyncOnSkipIdle» a «True»! El valor está " +"desactivado, lo que hace que este problema pase fácilmente." #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:164 msgid "" @@ -8877,7 +9004,7 @@ msgstr "Puerto:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "Espacios del portal" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -9018,6 +9145,7 @@ msgstr "Perfil" msgid "Program Counter" msgstr "Contador del programa (PC)" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9545,7 +9673,7 @@ msgstr "Tarjeta SD" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:266 msgid "SD Card File Size:" -msgstr "" +msgstr "Tamaño del archivo de tarjeta SD:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:506 msgid "SD Card Image (*.raw);;All Files (*)" @@ -9567,12 +9695,8 @@ msgstr "Raíz de la SD:" msgid "SD Sync Folder:" msgstr "Carpeta de sincronización de la SD:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9861,7 +9985,7 @@ msgstr "Búsqueda de instrucciones" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "Buscar:" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9932,7 +10056,7 @@ msgstr "Seleccionar archivo XML de Riivolution" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:410 msgid "Select Skylander Collection" -msgstr "" +msgstr "Seleccionar colección de Skylanders" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:481 msgid "Select Skylander File" @@ -10268,7 +10392,7 @@ msgstr "" "dirección virtual de la MEM1 y (en el caso de la Wii) la MEM2. Compatible " "con la gran mayoría de los juegos." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10329,10 +10453,6 @@ msgstr "Australia" msgid "Show Current Game on Discord" msgstr "Mostrar el juego actual en Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Ver opciones de depuración" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10377,7 +10497,7 @@ msgstr "Mostrar superposición de modo de golf" #: Source/Core/Core/HotkeyManager.cpp:199 msgid "Show Infinity Base" -msgstr "" +msgstr "Mostrar base de Infinity" #: Source/Core/DolphinQt/MenuBar.cpp:791 msgid "Show Input Display" @@ -10454,7 +10574,7 @@ msgstr "Rusia" #: Source/Core/Core/HotkeyManager.cpp:198 msgid "Show Skylanders Portal" -msgstr "" +msgstr "Mostrar portal de Skylanders" #: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Spain" @@ -10745,15 +10865,16 @@ msgstr "Skylander %1" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:482 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:551 msgid "Skylander (*.sky);;All Files (*)" -msgstr "" +msgstr "Skylander (*.sky);;Todos los archivos (*)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:217 msgid "Skylander Collection Path:" -msgstr "" +msgstr "Ruta de la colección de Skylanders:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:448 msgid "Skylander not found in this collection. Create new file?" msgstr "" +"No se han encontrado Skylanders en esta colección. ¿Crear un archivo nuevo?" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:42 msgid "Skylanders Manager" @@ -10762,6 +10883,8 @@ msgstr "Administrador de Skylanders" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:81 msgid "Skylanders folder not found for this user. Create new folder?" msgstr "" +"No se ha encontrado la carpeta de Skylanders para este usuario. ¿Crear una " +"carpeta nueva?" #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:97 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:140 @@ -10889,7 +11012,7 @@ msgstr "Velocidad" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "Spyro's Adventure" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -11172,7 +11295,7 @@ msgstr "El título ha sido desinstalado correctamente de la NAND. " #. all countries they were released in. They were not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:277 msgid "SuperChargers" -msgstr "" +msgstr "SuperChargers" #: Source/Core/DolphinQt/AboutDialog.cpp:69 msgid "Support" @@ -11203,7 +11326,7 @@ msgstr "Invertir ojos" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:270 msgid "Swap Force" -msgstr "" +msgstr "Swap Force" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:500 msgid "" @@ -11365,7 +11488,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:330 msgid "Tech" -msgstr "" +msgstr "Tecnología" #: Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp:244 msgid "Test" @@ -11404,6 +11527,15 @@ msgstr "" "La versión mínima del cargador DFF ({0}) excede la versión de este " "reproductor FIFO ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "La tabla hash H3 para la partición {0} no es correcta." @@ -11959,12 +12091,19 @@ msgid "" "CPU, but your current settings make this unlikely to happen. If this error " "is stopping the game from working, please report it to the developers." msgstr "" +"Este error suele ocurrir cuando la GPU emulada se desincroniza con la CPU " +"emulada, pero tu configuración actual debería evitar que eso ocurra. Si este " +"error impide que se ejecute el juego, informa a los desarrolladores de lo " +"ocurrido." #: Source/Core/VideoCommon/CommandProcessor.cpp:724 msgid "" "This error is usually caused by the emulated GPU desyncing with the emulated " "CPU. Turn off the \"Dual Core\" setting to avoid this." msgstr "" +"Este error suele ocurrir cuando la GPU emulada se desincroniza con la CPU " +"emulada. Desactiva la opción «Activar doble núcleo» para evitar que esto " +"pase." #: Source/Core/DiscIO/NANDImporter.cpp:116 msgid "This file does not contain a valid Wii filesystem." @@ -12304,7 +12443,7 @@ msgstr "Chino tradicional" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:273 msgid "Trap Team" -msgstr "" +msgstr "Trap Team" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:991 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:995 @@ -12367,15 +12506,15 @@ msgstr "EE. UU." #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "Emulación de dispositivos USB" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "Emulación de USB" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "Dispositivos de emulación USB" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -12492,7 +12631,7 @@ msgstr "Archivos ISO de GC/Wii sin comprimir (*.iso *.gcm)" #. https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:346 msgid "Undead" -msgstr "" +msgstr "Muertos" #: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Undo Load State" @@ -12623,6 +12762,22 @@ msgstr "Extraer ROM" msgid "Unlock Cursor" msgstr "Desbloquear cursor" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Descomprimiendo" @@ -12865,7 +13020,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "Usuario" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -13298,7 +13453,7 @@ msgstr "Vigilar" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:327 msgid "Water" -msgstr "" +msgstr "Agua" #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Website" @@ -13825,6 +13980,10 @@ msgstr "o elige un dispositivo" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "este valor:" diff --git a/Languages/po/fa.po b/Languages/po/fa.po index c990050db1..da56f21368 100644 --- a/Languages/po/fa.po +++ b/Languages/po/fa.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: H.Khakbiz , 2011\n" "Language-Team: Persian (http://app.transifex.com/delroth/dolphin-emu/" @@ -168,6 +168,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -185,6 +195,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1090,7 +1105,7 @@ msgstr "" msgid "Accuracy:" msgstr "دقت:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2339,7 +2354,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2347,7 +2362,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2632,6 +2647,14 @@ msgstr "" msgid "Controllers" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2735,19 +2758,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2807,11 +2830,11 @@ msgstr "" msgid "Core" msgstr "هسته" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3026,6 +3049,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3339,16 +3366,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3915,6 +3932,10 @@ msgstr "فعال کردن کدهای تقلب" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "فعال کردن پردازنده با دو هسته یا بیشتر" @@ -4625,7 +4646,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5574,8 +5595,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5590,10 +5611,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5696,7 +5721,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5830,14 +5855,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6587,7 +6616,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7010,6 +7039,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7347,7 +7377,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7355,16 +7385,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7900,7 +7931,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8305,6 +8336,7 @@ msgstr "پروفایل" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8829,12 +8861,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9480,7 +9508,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9541,10 +9569,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10529,6 +10553,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11576,6 +11609,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12584,6 +12633,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/fi.po b/Languages/po/fi.po index c6677fc9b0..47868202e9 100644 --- a/Languages/po/fi.po +++ b/Languages/po/fi.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Aleksi, 2023\n" "Language-Team: Finnish (http://app.transifex.com/delroth/dolphin-emu/" @@ -188,6 +188,16 @@ msgstr "%1 liittyi" msgid "%1 has left" msgstr "%1 lähti" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 ei ole kelvollinen ROM" @@ -205,6 +215,11 @@ msgstr "%1 muistialuetta" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 istunto löytyi" @@ -1139,7 +1154,7 @@ msgstr "Kiihtyvyysanturin vaikutus" msgid "Accuracy:" msgstr "Tarkkuus:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2488,7 +2503,7 @@ msgstr "Koodi:" msgid "Codes received!" msgstr "Koodit saatu!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2496,7 +2511,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2787,6 +2802,14 @@ msgstr "Ohjainasetukset" msgid "Controllers" msgstr "Ohjaimet" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2914,19 +2937,19 @@ msgstr "" "Muunnetaan...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2986,11 +3009,11 @@ msgstr "Kopioi B:hen" msgid "Core" msgstr "Ydin" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3245,6 +3268,10 @@ msgstr "Nykyinen osoiteavaruus" msgid "Custom RTC Options" msgstr "Mukautetun reaaliaikaisen kellon asetukset" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3572,22 +3599,6 @@ msgstr "Suora yhteys" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Direct3D 11 -hahmonnin vaatii sellaisten ominaisuuksia tukea, joita " -"järjestelmäsi ei tue. Tämä johtuu mitä luultavimmin siitä, että käytössä on " -"Windows 7. Tätä hahmonninta voi silti käyttää, mutta vastaan voi tulla " -"graafisia virheitä\n" -".\n" -"Haluatko todella ottaa käyttöön Direct3D 11:n? Ellet ole varma, valitse 'Ei¨." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "Ei &yhteyttä" @@ -4209,6 +4220,10 @@ msgstr "Ota huijauskoodit käyttöön" msgid "Enable Custom RTC" msgstr "Ota mukautettu reaaliaikainen kello käyttöön" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Ota kaksiydinsuoritin käyttöön" @@ -4988,7 +5003,7 @@ msgstr "Redump.orgiin yhdistäminen epäonnistui" msgid "Failed to connect to server: %1" msgstr "Palvelinyhteys epäonnistui: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "D3D-vaihtoketjun luonti epäonnistui" @@ -6031,8 +6046,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "Game Boy Advance portissa %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -6047,10 +6062,14 @@ msgstr "Pelin lisätiedot" msgid "Game Folders" msgstr "Pelikansiot" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -6157,7 +6176,7 @@ msgstr "GameCube -mikrofonin paikka %1" msgid "GameCube TAS Input %1" msgstr "GameCube-TAS-syöte %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -6297,14 +6316,18 @@ msgstr "Gyroskooppi" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -7140,7 +7163,7 @@ msgstr "JIT-rekisterivälimuisti pois" msgid "JIT SystemRegisters Off" msgstr "JIT-järjestelmärekisterit pois" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7579,6 +7602,7 @@ msgstr "Paikallinen" msgid "Lock Mouse Cursor" msgstr "Lukitse hiiren osoitin paikoilleen" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "Lukittu" @@ -7950,7 +7974,7 @@ msgstr "NKit-varoitus" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7958,16 +7982,17 @@ msgstr "" msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8529,7 +8554,7 @@ msgstr "&Toista nauhoitus..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8951,6 +8976,7 @@ msgstr "Profiili" msgid "Program Counter" msgstr "Ohjelmalaskuri" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9494,12 +9520,8 @@ msgstr "SD-juuri:" msgid "SD Sync Folder:" msgstr "SD-synkronointikansio:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -10191,7 +10213,7 @@ msgstr "" "Järjestää haun käyttäen tavallisia MEM1- ja (Wii-konsolilla) MEM2-alueita " "näennäisosoiteavaruudessa. Tämä toimii suurimmalle osalle peleistä." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10252,10 +10274,6 @@ msgstr "Näytä Australia" msgid "Show Current Game on Discord" msgstr "Näytä peli Discordissa" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Näytä virheenjäljityskäyttöliittymä" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -11318,6 +11336,15 @@ msgstr "" "DFF:n pienin käynnistysversio ({0}) on suurempi kuin tämän FIFO-toistimen " "version ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "Osion {0} H3-tiivistetaulukko on virheellinen." @@ -12512,6 +12539,22 @@ msgstr "Poista ROMin lataus" msgid "Unlock Cursor" msgstr "Poista hiiren osoittimen lukitus" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Purku käynnissä" @@ -13691,6 +13734,10 @@ msgstr "tai valitse laite" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "tämä arvo:" diff --git a/Languages/po/fr.po b/Languages/po/fr.po index 9b356893fa..75d7211690 100644 --- a/Languages/po/fr.po +++ b/Languages/po/fr.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Pascal , 2013-2023\n" "Language-Team: French (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -194,6 +194,16 @@ msgstr "%1 s'est connecté" msgid "%1 has left" msgstr "%1 s'est déconnecté" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 n'est pas une ROM valide" @@ -211,6 +221,11 @@ msgstr "%1 zones de mémoire" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 session trouvée" @@ -269,7 +284,7 @@ msgstr "%1[%2] : %3/%4 Mio" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "%1x MSAA" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -278,7 +293,7 @@ msgstr "%1x la réso. native (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "%1x SSAA" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -762,7 +777,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 Gio" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -770,7 +785,7 @@ msgstr "128 Mbit (2043 blocs)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 Mio" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -778,7 +793,7 @@ msgstr "16 octets" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 Gio (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -812,11 +827,11 @@ msgstr "1x" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 Gio" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 Mio" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -832,7 +847,7 @@ msgstr "2x la réso. native (1280x1056) pour 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 Gio (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -884,7 +899,7 @@ msgstr "4 octets" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 Gio (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -908,7 +923,7 @@ msgstr "4x la réso. native (2560x2112) pour 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 Mio" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -920,7 +935,7 @@ msgstr "64 Mbit (1019 blocs)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 Mio" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -951,7 +966,7 @@ msgstr "8 octets" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 Gio (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -1050,6 +1065,9 @@ msgid "" "A group of features to make the colors more accurate, matching the color " "space Wii and GC games were meant for." msgstr "" +"Un ensemble de fonctionnalités pour rendre les couleurs plus justes, pour " +"que les jeux GC et Wii s'affichent dans l'espace de couleur pour lequel ils " +"sont prévus." #: Source/Core/DolphinQt/Main.cpp:226 msgid "A save state cannot be loaded without specifying a game to launch." @@ -1152,10 +1170,10 @@ msgstr "Influence sur l'accéléromètre" msgid "Accuracy:" msgstr "Précision :" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" -msgstr "" +msgstr "Succès" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1456,7 +1474,7 @@ msgstr "Afrique" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:342 msgid "Air" -msgstr "" +msgstr "Air" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:116 msgid "Aligned to data type length" @@ -1464,7 +1482,7 @@ msgstr "Aligné sur le type de longueur de données" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "Tout" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -2400,7 +2418,7 @@ msgstr "Chine" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "Choisissez" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2455,7 +2473,7 @@ msgstr "Effacer le cache" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:119 msgid "Clear Slot" -msgstr "" +msgstr "Effacer le slot" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:83 msgid "Clock Override" @@ -2505,17 +2523,17 @@ msgstr "Code :" msgid "Codes received!" msgstr "Codes reçus !" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "Configuration de la correction des couleurs" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "Correction de couleur :" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "Espace de couleur" #: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Combine &Two Signature Files..." @@ -2648,6 +2666,56 @@ msgid "" "possible for them to go out of range or to become NaN. A warning will be " "given if NaN is returned, and the var that became NaN will be logged." msgstr "" +"Conditions :\n" +"Définit une expression qui est évaluée lorsqu'un point d'arrêt est atteint. " +"Si l'expression fausse ou 0, le point d'arrêt est ignoré jusqu'à ce qu'il " +"soit à nouveau atteint. Les déclarations doivent être séparées d'une " +"virgule. Seule la dernière déclaration sera utilisée pour déterminer ce " +"qu'il faut faire.\n" +"\n" +"Registres qui peuvent être référencés :\n" +"GPRs : r0..r31\n" +"FPRs : f0..f31\n" +" LR, CTR, PC\n" +"\n" +"Fonctions :\n" +"Définir un registre : r1 = 8\n" +"Casts: s8(0xff). Disponible : s8, u8, s16, u16, s32, u32\n" +"Callstack: callstack(0x80123456), callstack(\"anim\")\n" +"Comparer le texte: streq(r3, \"abc\"). Chaque paramètre peut être une " +"adresse ou des constantes de texte.\n" +"Lire en mémoire : read_u32(0x80000000). Disponible : u8, s8, u16, s16, u32, " +"s32, f32, f64\n" +"Écrire en mémoire : write_u32(r3, 0x80000000). Disponible : u8, u16, u32, " +"f32, f64\n" +"*l'écriture est actuellement toujours déclenchée\n" +"\n" +"Opérations :\n" +"Unary: -u, !u, ~u\n" +"Math: * / + -, power: **, remainder: %, shift: <<, >>\n" +"Comparer : <, <=, >, >=, ==, !=, &&, ||\n" +"Bitwise: &, |, ^\n" +"\n" +"Exemples :\n" +"r4 == 1\n" +"f0 == 1.0 && f2 < 10.0\n" +"r26 <= r0 && ((r5 + 3) & -4) * ((r6 + 3) & -4)* 4 > r0\n" +"p = r3 + 0x8, p == 0x8003510 && read_u32(p) != 0\n" +"Écrire et pause: r4 = 8, 1\n" +"Écrire et continuer : f3 = f1 + f2, 0\n" +"La condition doit toujours être à la fin\n" +"\n" +"Les valeurs doivent toujours être utilisées dans callstack() ou streq() et " +"\"quoted\". Ne pas assigner une valeur à une variable.\n" +"Toutes les variables seront affichées dans le journal de la mémoire " +"d'interface, si elle est atteinte ou un résultat NaN. Pour vérifier s'il y a " +"un problème, assignez une variable à votre équation pour qu'elle puisse être " +"affichée.\n" +"\n" +"Note: Toutes les valeurs sont converties en interne en Doubles par les " +"calculs. Il leur est possible de sortir des limites ou devenir un NaN. Un " +"avertissement sera affiché si un NaN est retourné, et la variable qui est " +"devenue un NaN sera journalisée." #: Source/Core/DolphinQt/ToolBar.cpp:129 msgid "Config" @@ -2804,6 +2872,14 @@ msgstr "Paramètres des manettes" msgid "Controllers" msgstr "Manettes" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2932,24 +3008,28 @@ msgstr "" "Conversion...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." "

If unsure, leave this unchecked." msgstr "" +"Convertit le gamma que le jeu ciblait vers ce que votre écran SDR cible." +"
La plupart des écrans ciblent du sRGB. Les TV ciblent la plupart du " +"temps 2,2.

Dans le doute, décochez cette case." #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:290 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:704 @@ -3004,13 +3084,13 @@ msgstr "Copier vers B" msgid "Core" msgstr "Core" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "Corriger l'espace de couleurs" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" -msgstr "" +msgstr "Corriger le gamma SDR" #. i18n: Performance cost, not monetary cost #: Source/Core/DolphinQt/Debugger/JITWidget.cpp:91 @@ -3170,7 +3250,7 @@ msgstr "Créer un fichier Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:80 msgid "Create Skylander Folder" -msgstr "" +msgstr "Créer le dossier pour Skylander" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:109 msgid "Create mappings for other devices" @@ -3265,9 +3345,13 @@ msgstr "Espace d'adresse personnalisé" msgid "Custom RTC Options" msgstr "Options pour l'horloge personnalisée" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "Personnaliser" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3591,23 +3675,6 @@ msgstr "Connexion directe" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Le moteur de rendu Direct3D 11 requiert la prise en charge de " -"fonctionnalités que votre configuration ne satisfait pas. La cause la plus " -"probable est que vous utilisez Windows 7. Vous pouvez toujours utiliser ce " -"moteur, mais il se peut que vous rencontriez des artefacts graphiques.\n" -"\n" -"Souhaitez-vous vraiment utiliser Direct3D 11 ? Dans le doute, choisissez " -"'Non'." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "Dé&connecté" @@ -4090,7 +4157,7 @@ msgstr "Premières mises à jour de mémoire" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:336 msgid "Earth" -msgstr "" +msgstr "Terre" #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "East Asia" @@ -4137,7 +4204,7 @@ msgstr "Éjecter le disque" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "Élément" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4217,7 +4284,7 @@ msgstr "Activer les couches de validation d'API" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "Activer les succès" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4231,6 +4298,10 @@ msgstr "Activer les Cheats" msgid "Enable Custom RTC" msgstr "Activer l'horloge personnalisée" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Activer le double cœur" @@ -4249,7 +4320,7 @@ msgstr "Modifier la taille de la mémoire émulée" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "Activer les succès Encore" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4261,7 +4332,7 @@ msgstr "Activer les mods graphiques" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:62 msgid "Enable Leaderboards" -msgstr "" +msgstr "Activer les tableaux de classements" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:88 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:66 @@ -4274,11 +4345,11 @@ msgstr "Activer le balayage progressif" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "Activer l'intégration de RetroAchievements.org" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" -msgstr "" +msgstr "Activer la Rich Presence" #: Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.cpp:39 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:353 @@ -4295,7 +4366,7 @@ msgstr "Activer les données du haut-parleur" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "Activer les succès non officiels" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4303,7 +4374,7 @@ msgstr "Activer l'envoi des statistiques d'utilisation" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:161 msgid "Enable WiiConnect24 via WiiLink" -msgstr "" +msgstr "Activer WiiConnect24 via WiiLink" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:81 msgid "Enable Wireframe" @@ -4318,6 +4389,8 @@ msgid "" "Enable competing in RetroAchievements leaderboards.

Hardcore Mode " "must be enabled to use." msgstr "" +"Activer la compétition dans les tableaux de classements de RetroAchievements." +"

Le mode Hardcore doit être activé pour l'utiliser." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:68 msgid "" @@ -4326,6 +4399,11 @@ msgid "" "website. If this is disabled, the website will only report what game is " "being played.

This has no bearing on Discord rich presence." msgstr "" +"Activer la rich presence détaillée sur le site RetroAchievements." +"

Cela fournit une description détaillée de ce que le joueur fait dans " +"le jeu sur le site web. Si désactivé, le site va seulement afficher le jeu " +"qui est joué.

Cela n'a aucune incidence sur la rich presence de " +"Discord." #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 msgid "" @@ -4343,6 +4421,11 @@ msgid "" "account to use. Dolphin does not save your password locally and uses an API " "token to maintain login." msgstr "" +"Active l'intégration avec RetroAchievements pour gagner des succès et " +"participer aux compétitions dans les tableaux de classements.

Vous " +"devez vous connecter avec un compte RetroAchievements pour l'utiliser. " +"Dolphin ne sauvegarde pas votre mot de passe sur votre appareil et utilise " +"un jeton d'API pour maintenir votre connection. " #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:80 msgid "" @@ -4351,10 +4434,14 @@ msgid "" "will be notified if they meet the unlock conditions again, useful for custom " "speedrun criteria or simply for fun." msgstr "" +"Active le déblocage des succès dans le mode Encore.

Ce mode ré-active " +"les succès que le joueur a déjà débloqués sur le site pour que le joueur " +"soit informé si il remplit à nouveau les conditions de déblocage, utile pour " +"les critères personnalisés de speedrun ou juste pour le fun." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" -msgstr "" +msgstr "Activer le déblocage des succès.
" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:74 msgid "" @@ -4363,6 +4450,10 @@ msgid "" "that have not been deemed official by RetroAchievements and may be useful " "for testing or simply for fun." msgstr "" +"Active le déblocage des succès non officiels ainsi que les officiels." +"

Les succès non officiels peuvent être optionnels ou des succès non " +"terminés qui n'ont pas été reconnus comme officiels par RetroAchievements et " +"peuvent être utiles pour tester ou pour le fun." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:97 msgid "" @@ -4445,6 +4536,14 @@ msgid "" "

Note that games still render in SDR internally." "

If unsure, leave this unchecked." msgstr "" +"Active la sortie HDR scRGB (si prise en charge par votre moteur graphique et " +"votre écran). Le plein écran peut être requis.

Ceci donne au shaders " +"de post-processing davantage de latitude pour la précision, permet aux " +"shaders de post-process \"AutoHDR\" de fonctionner, et permet d'afficher " +"entièrement les espaces de couleurs PAL et NTSC-J.

Veuillez noter que " +"les jeux sont tout de même rendus en SDR en interne." +"

Dans le doute, décochez cette case." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:151 msgid "Enables stretching of the audio to match emulation speed." @@ -4479,6 +4578,10 @@ msgid "" "such as the Forecast and Nintendo Channels\n" "Read the Terms of Service at: https://www.wiilink24.com/tos" msgstr "" +"Active le service WiiLink pour les chaînes WiiConnect24.\n" +"WiiLink est un fournisseur alternatif qui remplace les chaînes WiiConnect24 " +"désormais disparues telles que la Météo ou les Chaînes Nintendo.\n" +"Lisez les Termes de service sur : https://www.wiilink24.com/fr/tos" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:298 msgid "" @@ -5010,7 +5113,7 @@ msgstr "Impossible d'effacer Skylander !" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:575 msgid "Failed to clear the Skylander from slot(%1)!" -msgstr "" +msgstr "Impossible d'effacer Skylander depuis le slot(%1) !" #: Source/Core/DiscIO/VolumeVerifier.cpp:108 msgid "Failed to connect to Redump.org" @@ -5020,7 +5123,7 @@ msgstr "Impossible de se connecter à Redump.org" msgid "Failed to connect to server: %1" msgstr "Impossible de se connecter au serveur : %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Impossible de créer D3D swap chain" @@ -5051,6 +5154,9 @@ msgid "" "%1\n" "(Skylander may already be on the portal)" msgstr "" +"Impossible de créer le fichier Skylander :\n" +"%1\n" +"(Skylander est peut-être déjà sur le portail)" #: Source/Core/Core/NetPlayClient.cpp:1292 msgid "" @@ -5603,7 +5709,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:333 msgid "Fire" -msgstr "" +msgstr "Feu" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:40 msgid "First Person" @@ -5965,6 +6071,12 @@ msgid "" "Further errors will be sent to the Video Backend log and Dolphin will now " "likely crash or hang." msgstr "" +"GFX FIFO : Opcode inconnu ({0:#04x} @ {1}, preprocess={2}).\n" +"\n" +"{3}\n" +"\n" +"D'autres erreurs vont être envoyées au journal du moteur graphique et " +"Dolphin va probablement planter ou bloquer." #: Source/Core/VideoBackends/OGL/OGLMain.cpp:181 msgid "GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024." @@ -6073,8 +6185,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "Game Boy Advance sur le Port %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -6089,8 +6201,12 @@ msgstr "Détails du jeu" msgid "Game Folders" msgstr "Dossier de jeux" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" +msgstr "Gamma du jeu" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 @@ -6200,9 +6316,9 @@ msgstr "Micro pour GameCube, Slot %1" msgid "GameCube TAS Input %1" msgstr "Entrée TAS %1 pour GameCube" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "Gamma" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -6266,7 +6382,7 @@ msgstr "Gio" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:267 msgid "Giants" -msgstr "" +msgstr "Giants" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:195 msgid "Golf Mode" @@ -6339,17 +6455,21 @@ msgstr "Gyroscope" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" -msgstr "" +msgstr "HDR" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" +msgstr "HDR Paper White Nits" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" msgstr "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" -msgstr "" +msgstr "Post-Processing HDR" #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:62 msgid "Hacks" @@ -7188,7 +7308,7 @@ msgstr "Cache de registre JIT désactivé" msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7391,7 +7511,7 @@ msgstr "Licence" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:339 msgid "Life" -msgstr "" +msgstr "Vie" #: Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp:35 #: Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp:53 @@ -7442,7 +7562,7 @@ msgstr "Charger textures personnalisées" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "Charger le fichier" #: Source/Core/DolphinQt/MenuBar.cpp:249 msgid "Load GameCube Main Menu" @@ -7467,7 +7587,7 @@ msgstr "Charger une ROM" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "Charger le slot" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7627,6 +7747,7 @@ msgstr "Local" msgid "Lock Mouse Cursor" msgstr "Verrouiller le curseur de la souris" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "Verrouillé" @@ -7658,15 +7779,15 @@ msgstr "Sorties des journalisations" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "Connection" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "Échec de la connection" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "Déconnection" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7716,7 +7837,7 @@ msgstr "Fichiers MadCatz Gameshark" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:324 msgid "Magic" -msgstr "" +msgstr "Magie" #: Source/Core/DolphinQt/TAS/GCTASInputWindow.cpp:29 msgid "Main Stick" @@ -7999,24 +8120,25 @@ msgstr "Avertissement pour NKit" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8438,7 +8560,7 @@ msgstr "&Documentation en ligne" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "Afficher uniquement la Collection" #: Source/Core/DolphinQt/MenuBar.cpp:1615 msgid "" @@ -8580,9 +8702,9 @@ msgstr "&Jouer l'enregistrement..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8834,6 +8956,8 @@ msgid "" "Please change the \"SyncOnSkipIdle\" setting to \"True\"! It's currently " "disabled, which makes this problem very likely to happen." msgstr "" +"Veuillez changer le paramètre de \"SyncOnSkipIdle\" pour \"True\" ! Il est " +"actuellement désactivé, ce qui fait que ce problème va probablement arriver." #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:164 msgid "" @@ -8864,7 +8988,7 @@ msgstr "Port :" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "Slots de portail" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -9006,6 +9130,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "Program Counter" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9529,7 +9654,7 @@ msgstr "Carte SD" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:266 msgid "SD Card File Size:" -msgstr "" +msgstr "Taille du fichier de la carte SD :" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:506 msgid "SD Card Image (*.raw);;All Files (*)" @@ -9551,12 +9676,8 @@ msgstr "Racine de la carte SD :" msgid "SD Sync Folder:" msgstr "Dossier de synchronisation SD :" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9847,7 +9968,7 @@ msgstr "Rechercher une instruction" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "Rechercher :" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9917,7 +10038,7 @@ msgstr "Sélectionner le fichier XML Riivolution" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:410 msgid "Select Skylander Collection" -msgstr "" +msgstr "Sélectionner la collection Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:481 msgid "Select Skylander File" @@ -10249,7 +10370,7 @@ msgstr "" "Wii) MEM2 dans l'adressage de la mémoire virtuelle. Ceci fonctionnera pour " "la grande majorité des jeux." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10310,10 +10431,6 @@ msgstr "Afficher Australie" msgid "Show Current Game on Discord" msgstr "Afficher le jeu en cours sur Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Afficher l'interface de débogage" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10358,7 +10475,7 @@ msgstr "Afficher le Mode golf en surimpression" #: Source/Core/Core/HotkeyManager.cpp:199 msgid "Show Infinity Base" -msgstr "" +msgstr "Afficher la Base Infinity" #: Source/Core/DolphinQt/MenuBar.cpp:791 msgid "Show Input Display" @@ -10435,7 +10552,7 @@ msgstr "Afficher Russie" #: Source/Core/Core/HotkeyManager.cpp:198 msgid "Show Skylanders Portal" -msgstr "" +msgstr "Afficher le Portail Skylanders" #: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Spain" @@ -10726,15 +10843,17 @@ msgstr "Skylander %1" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:482 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:551 msgid "Skylander (*.sky);;All Files (*)" -msgstr "" +msgstr "Skylander (*.sky);;Tous les fichiers (*)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:217 msgid "Skylander Collection Path:" -msgstr "" +msgstr "Dossier de la collection Skylander :" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:448 msgid "Skylander not found in this collection. Create new file?" msgstr "" +"Skylander n'a pas été trouvé dans cette collection. Créer un nouveau " +"fichier ?" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:42 msgid "Skylanders Manager" @@ -10743,6 +10862,8 @@ msgstr "Gestionnaire de Skylanders" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:81 msgid "Skylanders folder not found for this user. Create new folder?" msgstr "" +"Le dossier Skylander n'a pas été trouvé pour cet utilisateur. Créer un " +"nouveau dossier ?" #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:97 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:140 @@ -10871,7 +10992,7 @@ msgstr "Vitesse" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "Spyro's Adventure" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -11153,7 +11274,7 @@ msgstr "Ce titre a été supprimé avec succès de la NAND." #. all countries they were released in. They were not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:277 msgid "SuperChargers" -msgstr "" +msgstr "SuperChargers" #: Source/Core/DolphinQt/AboutDialog.cpp:69 msgid "Support" @@ -11185,7 +11306,7 @@ msgstr "Inverser les yeux" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:270 msgid "Swap Force" -msgstr "" +msgstr "Swap Forces" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:500 msgid "" @@ -11346,7 +11467,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:330 msgid "Tech" -msgstr "" +msgstr "Tech" #: Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp:244 msgid "Test" @@ -11385,6 +11506,15 @@ msgstr "" "La version minimum du loader DFF ({0}) est supérieure à la version de ce " "lecteur FIFO ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "Le table de hash H3 pour la partition {0} n'est pas correcte." @@ -11933,12 +12063,19 @@ msgid "" "CPU, but your current settings make this unlikely to happen. If this error " "is stopping the game from working, please report it to the developers." msgstr "" +"Cette erreur est habituellement causée par le fait que le GPU émulé se soit " +"désynchronisé de CPU émulé, mais vos réglages actuels ne sont probablement " +"pas en cause. Si cette erreur arrête le jeu ou le fait planter, informez les " +"développeurs." #: Source/Core/VideoCommon/CommandProcessor.cpp:724 msgid "" "This error is usually caused by the emulated GPU desyncing with the emulated " "CPU. Turn off the \"Dual Core\" setting to avoid this." msgstr "" +"Cette erreur est habituellement causée par le fait que le GPU émulé se soit " +"désynchronisé de CPU émulé. Désactivez le réglage \"double cœur\" pour " +"éviter cela." #: Source/Core/DiscIO/NANDImporter.cpp:116 msgid "This file does not contain a valid Wii filesystem." @@ -12280,7 +12417,7 @@ msgstr "Chinois traditionnel" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:273 msgid "Trap Team" -msgstr "" +msgstr "Trap Team" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:991 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:995 @@ -12341,15 +12478,15 @@ msgstr "USA" #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "Émulation d'un appareil USB" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "Émulation de l'USB" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "Émulation d'appareils USB" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -12468,7 +12605,7 @@ msgstr "Images GC/Wii non compressées (*.iso *.gcm)" #. https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:346 msgid "Undead" -msgstr "" +msgstr "Mort-vivant" #: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Undo Load State" @@ -12599,6 +12736,22 @@ msgstr "Décharger la ROM" msgid "Unlock Cursor" msgstr "Débloquer le curseur" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Décompression" @@ -12842,7 +12995,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "Nom d'utilisateur" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -13271,7 +13424,7 @@ msgstr "Surveiller" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:327 msgid "Water" -msgstr "" +msgstr "Eau" #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Website" @@ -13799,6 +13952,10 @@ msgstr "ou sélectionnez un de ces périphériques" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "cette valeur :" diff --git a/Languages/po/hr.po b/Languages/po/hr.po index 3e48036585..71d62b5705 100644 --- a/Languages/po/hr.po +++ b/Languages/po/hr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Alberto Poljak , 2013-2014\n" "Language-Team: Croatian (http://app.transifex.com/delroth/dolphin-emu/" @@ -168,6 +168,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -185,6 +195,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1090,7 +1105,7 @@ msgstr "" msgid "Accuracy:" msgstr "Kvaliteta:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2339,7 +2354,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2347,7 +2362,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2632,6 +2647,14 @@ msgstr "" msgid "Controllers" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2735,19 +2758,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2807,11 +2830,11 @@ msgstr "" msgid "Core" msgstr "Jezgra" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3026,6 +3049,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3339,16 +3366,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3915,6 +3932,10 @@ msgstr "Omogućite kodove za varanje" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Omogućite korištenje dvije jezgre" @@ -4625,7 +4646,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5574,8 +5595,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5590,10 +5611,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5696,7 +5721,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5830,14 +5855,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6587,7 +6616,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7010,6 +7039,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7347,7 +7377,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7355,16 +7385,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7900,7 +7931,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8305,6 +8336,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8829,12 +8861,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9480,7 +9508,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9541,10 +9569,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10529,6 +10553,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11572,6 +11605,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12580,6 +12629,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/hu.po b/Languages/po/hu.po index 615fe20b94..d620f85583 100644 --- a/Languages/po/hu.po +++ b/Languages/po/hu.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Evin, 2016,2023\n" "Language-Team: Hungarian (http://app.transifex.com/delroth/dolphin-emu/" @@ -173,6 +173,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -190,6 +200,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1095,7 +1110,7 @@ msgstr "" msgid "Accuracy:" msgstr "Pontosság:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2345,7 +2360,7 @@ msgstr "Kód:" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2353,7 +2368,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2638,6 +2653,14 @@ msgstr "" msgid "Controllers" msgstr "Vezérlők" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2741,19 +2764,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2813,11 +2836,11 @@ msgstr "" msgid "Core" msgstr "Mag" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3032,6 +3055,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Egyéni RTC beállítások" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3345,16 +3372,6 @@ msgstr "Közvetlen kapcsolat" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3921,6 +3938,10 @@ msgstr "Csalások használata" msgid "Enable Custom RTC" msgstr "Egyéni RTC használata" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Kétmagos mód használata" @@ -4634,7 +4655,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5583,8 +5604,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5599,10 +5620,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5705,7 +5730,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5839,14 +5864,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6597,7 +6626,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7020,6 +7049,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7357,7 +7387,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7365,16 +7395,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7912,7 +7943,7 @@ msgstr "Bemeneti fe&lvétel lejátszása..." msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8317,6 +8348,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8841,12 +8873,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9495,7 +9523,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9556,10 +9584,6 @@ msgstr "Ausztrália megjelenítése" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10544,6 +10568,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11595,6 +11628,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Kicsomagolása" @@ -12605,6 +12654,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/it.po b/Languages/po/it.po index e728e22e2c..f9ec6c80d6 100644 --- a/Languages/po/it.po +++ b/Languages/po/it.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Mewster , 2023\n" "Language-Team: Italian (http://app.transifex.com/delroth/dolphin-emu/" @@ -187,6 +187,16 @@ msgstr "%1 è entrato" msgid "%1 has left" msgstr "%1 è uscito" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 non è una ROM valida" @@ -204,6 +214,11 @@ msgstr "%1 range di memoria" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "Trovata %1 sessione" @@ -262,7 +277,7 @@ msgstr "%1[%2]: %3/%4 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "%1x MSAA" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -271,7 +286,7 @@ msgstr "%1x Nativo (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "%1x SSAA" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -755,7 +770,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 GiB" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -763,7 +778,7 @@ msgstr "128 Mbit (2043 blocchi)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 MiB" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -771,7 +786,7 @@ msgstr "16 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -805,11 +820,11 @@ msgstr "1x" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 GiB" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 MiB" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -825,7 +840,7 @@ msgstr "2x Nativo (1280x1056) per 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -877,7 +892,7 @@ msgstr "4 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -901,7 +916,7 @@ msgstr "4x Nativo (2560x2112) per 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -913,7 +928,7 @@ msgstr "64 Mbit (1019 blocchi)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 MiB" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -944,7 +959,7 @@ msgstr "8 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -1042,6 +1057,8 @@ msgid "" "A group of features to make the colors more accurate, matching the color " "space Wii and GC games were meant for." msgstr "" +"Una serie di funzionalità per rendere i colori più accurati e abbinati allo " +"spazio di colori per cui i giochi Wii e GC sono stati pensati." #: Source/Core/DolphinQt/Main.cpp:226 msgid "A save state cannot be loaded without specifying a game to launch." @@ -1142,10 +1159,10 @@ msgstr "Influenza Accelerometro" msgid "Accuracy:" msgstr "Precisione:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" -msgstr "" +msgstr "Achievement" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1449,7 +1466,7 @@ msgstr "Africa" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:342 msgid "Air" -msgstr "" +msgstr "Aria" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:116 msgid "Aligned to data type length" @@ -1457,7 +1474,7 @@ msgstr "Allineato alla dimensione del tipo di dato" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "Tutti" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -2383,7 +2400,7 @@ msgstr "Cina" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "Scegli" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2438,7 +2455,7 @@ msgstr "Pulisci Cache" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:119 msgid "Clear Slot" -msgstr "" +msgstr "Pulisci Slot" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:83 msgid "Clock Override" @@ -2488,17 +2505,17 @@ msgstr "Codice:" msgid "Codes received!" msgstr "Codici ricevuti!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "Configurazione Correzione Colore" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "Correzione Colore:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "Spazio dei Colori" #: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Combine &Two Signature Files..." @@ -2632,6 +2649,54 @@ msgid "" "possible for them to go out of range or to become NaN. A warning will be " "given if NaN is returned, and the var that became NaN will be logged." msgstr "" +"Condizioni:\n" +"Imposta un'espressione valutata quando viene raggiunto un punto di " +"interruzione. Se l'espressione è falsa o 0, il punto di interruzione viene " +"ignorato fino alla volta successiva. Le espressioni devono essere separate " +"da una virgola. Solo l'ultima espressione verrà usata per determinare cosa " +"fare.\n" +"\n" +"Registri che possono essere referenziati:\n" +"GPRs : r0..r31\n" +"FPRs : f0..f31\n" +"LR, CTR, PC\n" +"\n" +"Funzioni:\n" +"Imposta un registro: r1 = 8\n" +"Cast: s8(0xff). Disponibili: s8, u8, s16, u16, s32, u32\n" +"Stack di chiamate: callstack(0x80123456), callstack(\"anim\")\n" +"Confronta stringhe: streq(r3, \"abc\"). Entrambi i parametri possono essere " +"indirizzi o stringhe costanti.\n" +"Leggi Memoria: read_u32(0x80000000). Disponibili: u8, s8, u16, s16, u32, " +"s32, f32, f64\n" +"Scrivi Memoria: write_u32(r3, 0x80000000). Disponibili: u8, u16, u32, f32, " +"f64\n" +"*attualmente la scrittura verrà sempre attivata\n" +"\n" +"Operazioni:\n" +"Unarie: -u, !u, ~u\n" +"Operazioni: * / + -, potenza: **, resto: %, shift: <<, >>\n" +"Compara: <, <=, >, >=, ==, !=, &&, ||\n" +"Bitwise: &, |, ^\n" +"\n" +"Esempi:\n" +"r4 == 1\n" +"f0 == 1.0 && f2 < 10.0\n" +"r26 <= r0 && ((r5 + 3) & -4) * ((r6 + 3) & -4)* 4 > r0\n" +"p = r3 + 0x8, p == 0x8003510 && read_u32(p) != 0\n" +"Scrivi e interrompi: r4 = 8, 1\n" +"Scrivi e continua: f3 = f1 + f2, 0\n" +"La condizione va sempre per ultima\n" +"\n" +"Le stringhe vanno usate solo con callstack() o streq() e \"virgolettate\". " +"Non assegnare stringhe a variabili.\n" +"Tutte le variabili verranno stampate nel log Memory Interface, se c'è " +"un'interruzione o un risultato NaN. In caso di problemi, assegna una " +"variabile alla tua equazione perché possa venir stampata.\n" +"\n" +"Nota: Tutti i valori sono internamente convertiti a Double per i calcoli. È " +"possibile che vadano fuori dal range o che diventino NaN. Se viene ritornato " +"NaN verrà fornito un avviso e verrà loggata la variabile che è diventata NaN." #: Source/Core/DolphinQt/ToolBar.cpp:129 msgid "Config" @@ -2788,6 +2853,14 @@ msgstr "Impostazioni Controller" msgid "Controllers" msgstr "Controller" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2914,24 +2987,28 @@ msgstr "" "Conversione in corso...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." "

If unsure, leave this unchecked." msgstr "" +"Converte la gamma da quella concepita dal gioco a quella del tuo attuale " +"display SDR.
I monitor spesso hanno sRGB come obiettivo, le TV invece 2.2." +"

Nel dubbio, lascia deselezionato." #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:290 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:704 @@ -2986,13 +3063,13 @@ msgstr "Copia su B" msgid "Core" msgstr "Core" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "Correzione Spazio Colore" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" -msgstr "" +msgstr "Correzione Gamma SDR" #. i18n: Performance cost, not monetary cost #: Source/Core/DolphinQt/Debugger/JITWidget.cpp:91 @@ -3153,7 +3230,7 @@ msgstr "Crea File Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:80 msgid "Create Skylander Folder" -msgstr "" +msgstr "Crea Cartella Skylander" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:109 msgid "Create mappings for other devices" @@ -3247,9 +3324,13 @@ msgstr "Spazio degli Indirizzi Personalizzato" msgid "Custom RTC Options" msgstr "Opzioni RTC Custom" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "Personalizza" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3574,22 +3655,6 @@ msgstr "Connessione Diretta" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Il renderer Direct3D 11 richiede il supporto a funzionalità non disponibili " -"sulla tua configurazione di sistema. Probabilmente è perché stai usando " -"Windows 7. Puoi comunque usare questo backend, ma potresti riscontrare " -"artefatti grafici.\n" -"\n" -"Vuoi davvero passare a Direct3D 11? Nel dubbio, seleziona 'No'." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "Dis&connesso" @@ -4068,7 +4133,7 @@ msgstr "Aggiornamenti Anticipati della Memoria" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:336 msgid "Earth" -msgstr "" +msgstr "Terra" #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "East Asia" @@ -4115,7 +4180,7 @@ msgstr "Espelli Disco" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "Elemento" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4195,7 +4260,7 @@ msgstr "Abilita Layer di Validazione API" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "Abilita Achievement" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4209,6 +4274,10 @@ msgstr "Abilita Trucchi" msgid "Enable Custom RTC" msgstr "Abilita RTC Custom" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Abilita Dual Core" @@ -4227,7 +4296,7 @@ msgstr "Abilità Override Dimensione Memoria Emulata" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "Abilita Achievement Encore" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4239,7 +4308,7 @@ msgstr "Abilita Mod Grafiche" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:62 msgid "Enable Leaderboards" -msgstr "" +msgstr "Abilita Leaderboard" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:88 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:66 @@ -4252,11 +4321,11 @@ msgstr "Abilita Scansione Progressiva" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "Abilita Integrazione RetroAchievements.org" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" -msgstr "" +msgstr "Abilita Rich Presence" #: Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.cpp:39 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:353 @@ -4273,7 +4342,7 @@ msgstr "Abilita Dati Altoparlante" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "Abilita Achievement non Ufficiali" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4281,7 +4350,7 @@ msgstr "Abilita Report Statistiche d'Uso" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:161 msgid "Enable WiiConnect24 via WiiLink" -msgstr "" +msgstr "Abilita WiiConnect24 tramite WiiLink" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:81 msgid "Enable Wireframe" @@ -4296,6 +4365,8 @@ msgid "" "Enable competing in RetroAchievements leaderboards.

Hardcore Mode " "must be enabled to use." msgstr "" +"Abilita la competizione nella leaderboard di RetroAchievements.

La " +"Modalità Hardcore deve essere abilitata per il suo utilizzo." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:68 msgid "" @@ -4304,6 +4375,10 @@ msgid "" "website. If this is disabled, the website will only report what game is " "being played.

This has no bearing on Discord rich presence." msgstr "" +"Abliita la rich presence dettagliata nel sito di RetroAchievements." +"

Verrà fornita al sito una descrizione dettagliata di cosa sta " +"facendo il giocatore nel gioco. Se è disabilitata, il sito mostrerà soltanto " +"il nome del gioco in uso.

Non influenza la rich presence di Discord." #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 msgid "" @@ -4321,6 +4396,10 @@ msgid "" "account to use. Dolphin does not save your password locally and uses an API " "token to maintain login." msgstr "" +"Abilita l'integrazione con RetroAchievements per gli achievement e per la " +"competizione nelle leaderboard.

Occorre autenticarsi con un account " +"RetroAchievements. Dolphin non salva la password localmente e usa un token " +"API per mantenere l'autenticazione." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:80 msgid "" @@ -4329,10 +4408,14 @@ msgid "" "will be notified if they meet the unlock conditions again, useful for custom " "speedrun criteria or simply for fun." msgstr "" +"Abilita lo sblocco degli achievement in Modalità Encore.

La Modalità " +"Encore ri-attiva gli achievement che il giocatore ha già sbloccato sul sito " +"per poter ricevere le notifiche quando il giocatore soddisfa nuovamente le " +"condizioni, utile per speedrun custom o anche solo per divertimento." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" -msgstr "" +msgstr "Abilita lo sblocco di achievement.
" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:74 msgid "" @@ -4341,6 +4424,10 @@ msgid "" "that have not been deemed official by RetroAchievements and may be useful " "for testing or simply for fun." msgstr "" +"Abilita lo sblocco di achivement ufficiali e non ufficiali.

Gli " +"achievement non ufficiali potrebbero essere achievement opzionali o non " +"completi che non sono stati ritenuti ufficiali da RetroAchievements, e " +"potrebbero essere utili per testing o anche solo per divertimento." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:97 msgid "" @@ -4418,6 +4505,13 @@ msgid "" "

Note that games still render in SDR internally." "

If unsure, leave this unchecked." msgstr "" +"Abilita l'output HDR scRGB (se supportato dal tuo backend grafico e dal " +"monitor). Potrebbe essere richiesto lo schermo intero.

Fa sì che gli " +"shader di post processing siano più accurati, permette agli shader di post " +"processing \"AutoHDR\" di funzionare, e permette la visualizzazione intera " +"degli spazi colore PAL e NTSC-J.

Tieni presente che internamente i " +"giochi continueranno a renderizzare in SDR.

Nel " +"dubbio, lascia deselezionato." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:151 msgid "Enables stretching of the audio to match emulation speed." @@ -4453,6 +4547,10 @@ msgid "" "such as the Forecast and Nintendo Channels\n" "Read the Terms of Service at: https://www.wiilink24.com/tos" msgstr "" +"Abilita il servizio WiiLink per i canali WiiConnect24.\n" +"WiiLink è un provider alternativo per i canali WiiConnect24 cessati, come il " +"Meteo e i Canali Nintendo\n" +"Leggi i Termini del Servizio su: https://www.wiilink24.com/tos" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:298 msgid "" @@ -4980,7 +5078,7 @@ msgstr "Fallita rimozione dello Skylander!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:575 msgid "Failed to clear the Skylander from slot(%1)!" -msgstr "" +msgstr "Fallita rimozione dello Skylander dallo slot(%1)!" #: Source/Core/DiscIO/VolumeVerifier.cpp:108 msgid "Failed to connect to Redump.org" @@ -4990,7 +5088,7 @@ msgstr "Impossibile connettersi a Redump.org" msgid "Failed to connect to server: %1" msgstr "Impossibile connettersi al server: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Impossibile creare la swap chain D3D" @@ -5021,6 +5119,9 @@ msgid "" "%1\n" "(Skylander may already be on the portal)" msgstr "" +"Fallita creazione del file Skylander:\n" +"%1\n" +"(Lo Skylander potrebbe già essere nel portale)" #: Source/Core/Core/NetPlayClient.cpp:1292 msgid "" @@ -5573,7 +5674,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:333 msgid "Fire" -msgstr "" +msgstr "Fuoco" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:40 msgid "First Person" @@ -5932,6 +6033,12 @@ msgid "" "Further errors will be sent to the Video Backend log and Dolphin will now " "likely crash or hang." msgstr "" +"GFX FIFO: Opcode Sconosciuto ({0:#04x} @ {1}, preprocess={2}).\n" +"\n" +"{3}\n" +"\n" +"Ulteriori errori verranno inviati al log Video Backend e Dolphin ora " +"probabilmente crasherà o si bloccherà." #: Source/Core/VideoBackends/OGL/OGLMain.cpp:181 msgid "GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024." @@ -6037,8 +6144,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "Game Boy Advance sulla Porta %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -6053,8 +6160,12 @@ msgstr "Dettagli del Gioco" msgid "Game Folders" msgstr "Cartelle di Gioco" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" +msgstr "Gamma di Gioco" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 @@ -6164,9 +6275,9 @@ msgstr "Microfono GameCube Slot %1" msgid "GameCube TAS Input %1" msgstr "GameCube TAS Input %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "Gamma" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -6230,7 +6341,7 @@ msgstr "GiB" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:267 msgid "Giants" -msgstr "" +msgstr "Giganti" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:195 msgid "Golf Mode" @@ -6303,17 +6414,21 @@ msgstr "Giroscopio" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" -msgstr "" +msgstr "HDR" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" +msgstr "HDR Paper White Nits" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" msgstr "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" -msgstr "" +msgstr "HDR Post-Processing" #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:62 msgid "Hacks" @@ -7146,7 +7261,7 @@ msgstr "Registro Cache JIT Off" msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7349,7 +7464,7 @@ msgstr "Licenza" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:339 msgid "Life" -msgstr "" +msgstr "Vita" #: Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp:35 #: Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp:53 @@ -7400,7 +7515,7 @@ msgstr "Carica Texture Personalizzate" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "Carica File" #: Source/Core/DolphinQt/MenuBar.cpp:249 msgid "Load GameCube Main Menu" @@ -7425,7 +7540,7 @@ msgstr "Carica ROM" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "Carica Slot" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7583,6 +7698,7 @@ msgstr "Locale" msgid "Lock Mouse Cursor" msgstr "Blocca il Cursore del Mouse" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "Bloccato" @@ -7614,15 +7730,15 @@ msgstr "Destinazione Logger" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "Login" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "Login non Riuscita" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "Logout" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7672,7 +7788,7 @@ msgstr "File Gameshark MadCatz" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:324 msgid "Magic" -msgstr "" +msgstr "Magia" #: Source/Core/DolphinQt/TAS/GCTASInputWindow.cpp:29 msgid "Main Stick" @@ -7954,24 +8070,25 @@ msgstr "Attenzione NKit" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8393,7 +8510,7 @@ msgstr "&Documentazione Online" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "Mostra Solo Collezione" #: Source/Core/DolphinQt/MenuBar.cpp:1615 msgid "" @@ -8535,9 +8652,9 @@ msgstr "&Riproduci Registrazione Input..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8788,6 +8905,9 @@ msgid "" "Please change the \"SyncOnSkipIdle\" setting to \"True\"! It's currently " "disabled, which makes this problem very likely to happen." msgstr "" +"Cambia l'impostazione \"SyncOnSkipIdle\" a \"True\"! Attualmente è " +"disabilitata, per cui molto probabilmente il problema si verificherà di " +"nuovo." #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:164 msgid "" @@ -8817,7 +8937,7 @@ msgstr "Porta:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "Slot Portale" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -8957,6 +9077,7 @@ msgstr "Profilo" msgid "Program Counter" msgstr "Program Counter" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9475,7 +9596,7 @@ msgstr "Scheda SD" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:266 msgid "SD Card File Size:" -msgstr "" +msgstr "Dimensione File Scheda SD:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:506 msgid "SD Card Image (*.raw);;All Files (*)" @@ -9497,12 +9618,8 @@ msgstr "SD Root:" msgid "SD Sync Folder:" msgstr "Cartella Sync SD:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9791,7 +9908,7 @@ msgstr "Ricerca istruzione" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "Cerca:" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9861,7 +9978,7 @@ msgstr "Seleziona file Riivolution XML" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:410 msgid "Select Skylander Collection" -msgstr "" +msgstr "Seleziona Collezione Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:481 msgid "Select Skylander File" @@ -10193,7 +10310,7 @@ msgstr "" "Imposta la ricerca utilizzando i mapping MEM1 e (su Wii) MEM2 nello spazio " "di indirizzi virtuale. Funzionerà per la maggior parte dei giochi." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10254,10 +10371,6 @@ msgstr "Mostra Australia" msgid "Show Current Game on Discord" msgstr "Mostra Gioco Corrente su Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Mostra UI Debugging" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10302,7 +10415,7 @@ msgstr "Mostra Overlay Modalità Golf" #: Source/Core/Core/HotkeyManager.cpp:199 msgid "Show Infinity Base" -msgstr "" +msgstr "Mostra Base Infinity" #: Source/Core/DolphinQt/MenuBar.cpp:791 msgid "Show Input Display" @@ -10379,7 +10492,7 @@ msgstr "Mostra Russia" #: Source/Core/Core/HotkeyManager.cpp:198 msgid "Show Skylanders Portal" -msgstr "" +msgstr "Mostra Portale Skylanders" #: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Spain" @@ -10665,15 +10778,16 @@ msgstr "Skylander %1" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:482 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:551 msgid "Skylander (*.sky);;All Files (*)" -msgstr "" +msgstr "Skylander (*.sky);;Tutti i File (*)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:217 msgid "Skylander Collection Path:" -msgstr "" +msgstr "Percorso Collezione Skylander:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:448 msgid "Skylander not found in this collection. Create new file?" msgstr "" +"Non sono stati trovati Skylander in questa collezione. Creare un nuovo file?" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:42 msgid "Skylanders Manager" @@ -10682,6 +10796,8 @@ msgstr "Manager Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:81 msgid "Skylanders folder not found for this user. Create new folder?" msgstr "" +"Non è stata trovata una cartella Skylander per questo utente. Creare una " +"nuova cartella?" #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:97 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:140 @@ -10807,7 +10923,7 @@ msgstr "Velocità" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "Spyro's Adventure" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -11089,7 +11205,7 @@ msgstr "Il titolo è stato rimosso con successo dalla NAND." #. all countries they were released in. They were not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:277 msgid "SuperChargers" -msgstr "" +msgstr "SuperChargers" #: Source/Core/DolphinQt/AboutDialog.cpp:69 msgid "Support" @@ -11120,7 +11236,7 @@ msgstr "Inverti Occhi" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:270 msgid "Swap Force" -msgstr "" +msgstr "Swap Force" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:500 msgid "" @@ -11281,7 +11397,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:330 msgid "Tech" -msgstr "" +msgstr "Tecnica" #: Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp:244 msgid "Test" @@ -11320,6 +11436,15 @@ msgstr "" "La versinoe minima del loader DFF ({0}) supera la versione di questo Player " "FIFO ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "L'hash table H3 della partizione {0} non è corretta." @@ -11863,12 +11988,18 @@ msgid "" "CPU, but your current settings make this unlikely to happen. If this error " "is stopping the game from working, please report it to the developers." msgstr "" +"Questo errore è di solito causato dalla desincronizzazione della GPU emulata " +"con la CPU emulata, ma dovrebbe essere mitigato dalle tue impostazioni " +"correnti. Se questo errore impedisce il corretto funzionamento del gioco, " +"informa gli sviluppatori." #: Source/Core/VideoCommon/CommandProcessor.cpp:724 msgid "" "This error is usually caused by the emulated GPU desyncing with the emulated " "CPU. Turn off the \"Dual Core\" setting to avoid this." msgstr "" +"Questo errore è di solito causato dalla desincronizzazione della GPU emulata " +"con la CPU emulata. Disabilita l'impostazione \"Dual Core\" per evitarlo." #: Source/Core/DiscIO/NANDImporter.cpp:116 msgid "This file does not contain a valid Wii filesystem." @@ -12208,7 +12339,7 @@ msgstr "Cinese Tradizionale" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:273 msgid "Trap Team" -msgstr "" +msgstr "Trap Team" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:991 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:995 @@ -12270,15 +12401,15 @@ msgstr "USA" #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "Dispositivo di Emulazione USB" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "Emulazione USB" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "Dispositivi di Emulazione USB" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -12395,7 +12526,7 @@ msgstr "Immagini GC/Wii non compresse (*.iso *.gcm)" #. https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:346 msgid "Undead" -msgstr "" +msgstr "Non-morti" #: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Undo Load State" @@ -12528,6 +12659,22 @@ msgstr "Rimuovi ROM" msgid "Unlock Cursor" msgstr "Sblocca il Cursore" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Apertura" @@ -12767,7 +12914,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "Username" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -13190,7 +13337,7 @@ msgstr "Espressione di controllo" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:327 msgid "Water" -msgstr "" +msgstr "Acqua" #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Website" @@ -13714,6 +13861,10 @@ msgstr "o seleziona un dispositivo" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "questo valore:" diff --git a/Languages/po/ja.po b/Languages/po/ja.po index db37bda2dd..542c58d113 100644 --- a/Languages/po/ja.po +++ b/Languages/po/ja.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: DanbSky , 2015-2022\n" "Language-Team: Japanese (http://app.transifex.com/delroth/dolphin-emu/" @@ -194,6 +194,16 @@ msgstr "%1 が入室しました" msgid "%1 has left" msgstr "%1 が退室しました" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -211,6 +221,11 @@ msgstr "%1 memory ranges" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 個のセッションを発見" @@ -1140,7 +1155,7 @@ msgstr "" msgid "Accuracy:" msgstr "精度:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2467,7 +2482,7 @@ msgstr "コード:" msgid "Codes received!" msgstr "コードを受け取りました!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2475,7 +2490,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2760,6 +2775,14 @@ msgstr "Dolphin コントローラ設定" msgid "Controllers" msgstr "コントローラ" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2879,19 +2902,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2951,11 +2974,11 @@ msgstr "Bへコピー" msgid "Core" msgstr "コア" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3181,6 +3204,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "リアルタイムクロック設定" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3498,22 +3525,6 @@ msgstr "直接接続 (Direct)" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Direct3D 11 レンダラは、使用中のシステムではサポートされていない機能を必要と" -"しています。これは主に Windows 7 を使用していることが原因である可能性が高いで" -"す。このまま使用することはできますが、描画に問題が発生する場合があります。\n" -"\n" -"本当に Direct3D 11 を使いますか?\n" -"よく分からない場合、「いいえ」を選択してください。" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -4111,6 +4122,10 @@ msgstr "チートコードを有効化" msgid "Enable Custom RTC" msgstr "Custom RTC を使用する" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "デュアルコア動作を行う" @@ -4866,7 +4881,7 @@ msgstr "Redump.org に接続できませんでした" msgid "Failed to connect to server: %1" msgstr "サーバー %1 に接続できませんでした" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Failed to create D3D swap chain" @@ -5860,8 +5875,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "ポート %1 のゲームボーイアドバンス" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5876,10 +5891,14 @@ msgstr "ゲーム情報" msgid "Game Folders" msgstr "ゲームファイルのあるフォルダ" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5982,7 +6001,7 @@ msgstr "ゲームキューブ マイク スロット %1" msgid "GameCube TAS Input %1" msgstr "TAS用入力 ゲームキューブ %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -6120,14 +6139,18 @@ msgstr "ジャイロスコープ" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6935,7 +6958,7 @@ msgstr "JIT Register Cache Off" msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7371,6 +7394,7 @@ msgstr "IPアドレスと使用ポート番号" msgid "Lock Mouse Cursor" msgstr "マウスカーソルをロック" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7728,7 +7752,7 @@ msgstr "NKit Warning" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7736,16 +7760,17 @@ msgstr "" msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8294,7 +8319,7 @@ msgstr "録画ファイルを再生(&L)" msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8713,6 +8738,7 @@ msgstr "プロファイル" msgid "Program Counter" msgstr "Program Counter" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9251,12 +9277,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "同期させるフォルダ" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9934,7 +9956,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9995,10 +10017,6 @@ msgstr "オーストラリア" msgid "Show Current Game on Discord" msgstr "Discordにプレイ中のゲームを表示" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "デバッグモード" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -11037,6 +11055,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "The H3 hash table for the {0} partition is not correct." @@ -12141,6 +12168,22 @@ msgstr "ROMを取り外してリセット" msgid "Unlock Cursor" msgstr "マウスカーソルをロック 解除" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "復元処理を行っています..." @@ -13204,6 +13247,10 @@ msgstr "もしくは下の一覧から選択" msgid "s" msgstr "秒" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "this value:" diff --git a/Languages/po/ko.po b/Languages/po/ko.po index 594e5ebdd7..ee4119a500 100644 --- a/Languages/po/ko.po +++ b/Languages/po/ko.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Siegfried, 2013-2023\n" "Language-Team: Korean (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -186,6 +186,16 @@ msgstr "%1 가 참가했습니다" msgid "%1 has left" msgstr "%1 가 떠났습니다" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 는 적합한 롬이 아닙니다" @@ -203,6 +213,11 @@ msgstr "%1 메모리 영역" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 세션이 발견되었습니다" @@ -1134,7 +1149,7 @@ msgstr "가속도계 영향" msgid "Accuracy:" msgstr "정확성:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2460,7 +2475,7 @@ msgstr "코드:" msgid "Codes received!" msgstr "코드들을 받았습니다!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2468,7 +2483,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2759,6 +2774,14 @@ msgstr "컨트롤러 설정" msgid "Controllers" msgstr "컨트롤러" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2881,19 +2904,19 @@ msgstr "" "변환중...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2953,11 +2976,11 @@ msgstr "B로 복사" msgid "Core" msgstr "코어" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3208,6 +3231,10 @@ msgstr "커스텀 주소 공간" msgid "Custom RTC Options" msgstr "사용자 지정 RTC 옵션" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3530,22 +3557,6 @@ msgstr "직접 연결" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Direct3D 11 렌더러는 당신의 시스템 환경에서 지원하지 않는 특성들 지원을 요구" -"합니다. 이것은 대체로 아마 당신이 윈도우7을 사용하고 있기 때문입니다. 당신은 " -"이 백엔드를 여전히 사용할지도 모릅니다, 하지만 그래픽적 인공물을 접할지도 모" -"릅니다.\n" -"\n" -"정말 Direct3D 11로 전환하고 싶습니까? 잘 모르겠으면, '아니오'를 선택하세요." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "연결 끊어진(&c)" @@ -4156,6 +4167,10 @@ msgstr "치트 활성화" msgid "Enable Custom RTC" msgstr "사용자 지정 RTC 켜기" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "듀얼 코어 활성화" @@ -4922,7 +4937,7 @@ msgstr "Redump.org 연결에 실패했습니다" msgid "Failed to connect to server: %1" msgstr "서버 연결에 실패했습니다: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "D3D 스왑 체인 생성에 실패했습니다" @@ -5945,8 +5960,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "포트 %1 에 게임 보이 어드밴스" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5961,10 +5976,14 @@ msgstr "게임 세부사항" msgid "Game Folders" msgstr "게임 폴더들" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -6070,7 +6089,7 @@ msgstr "게임큐브 마이크 슬롯 %1" msgid "GameCube TAS Input %1" msgstr "게임큐브 TAS 입력 %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -6208,14 +6227,18 @@ msgstr "자이로스" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -7039,7 +7062,7 @@ msgstr "JIT 레지스터 캐시 끄기" msgid "JIT SystemRegisters Off" msgstr "JIT 시스템레지스터 끄기" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7476,6 +7499,7 @@ msgstr "지역" msgid "Lock Mouse Cursor" msgstr "마우스 커서 가두기" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "잠긴" @@ -7835,7 +7859,7 @@ msgstr "NKit 경고" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7843,16 +7867,17 @@ msgstr "" msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8412,7 +8437,7 @@ msgstr "입력 기록 플레이...(&l)" msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8832,6 +8857,7 @@ msgstr "프로파일" msgid "Program Counter" msgstr "프로그램 카운터" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9371,12 +9397,8 @@ msgstr "SD 루트:" msgid "SD Sync Folder:" msgstr "SD 동기화 폴더:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -10059,7 +10081,7 @@ msgstr "" "가상 주소 공간에서 표준 MEM1 과 (Wii 상의) MEM2 매핑을 사용하여 검색을 설정합" "니다. 방대한 다수의 게임들에서 작동할 것입니다." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10120,10 +10142,6 @@ msgstr "오스트레일리아" msgid "Show Current Game on Discord" msgstr "디스코드에 현재 게임을 보여주기" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "UI 디버깅 표시" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -11172,6 +11190,15 @@ msgid "" msgstr "" "DFF 의 최소 로더 버전 ({0}) 이 이 FIFO 플레이어의 버전 ({1}) 을 초과합니다" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "{0} 파티션에 대한 H3 해쉬 테이블이 올바르지 않습니다." @@ -12354,6 +12381,22 @@ msgstr "롬 언로드" msgid "Unlock Cursor" msgstr "마우스 커서 풀기" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "풀기" @@ -13513,6 +13556,10 @@ msgstr "또는 장치를 선택하세요" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "이 값:" diff --git a/Languages/po/ms.po b/Languages/po/ms.po index 6b8a851108..56098dc651 100644 --- a/Languages/po/ms.po +++ b/Languages/po/ms.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: abuyop , 2018\n" "Language-Team: Malay (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -175,6 +175,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -192,6 +202,11 @@ msgstr "" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1099,7 +1114,7 @@ msgstr "" msgid "Accuracy:" msgstr "Ketepatan:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2363,7 +2378,7 @@ msgstr "Kod:" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2371,7 +2386,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2656,6 +2671,14 @@ msgstr "Tetapan Pengawal" msgid "Controllers" msgstr "Kawalan" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2759,19 +2782,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2831,11 +2854,11 @@ msgstr "" msgid "Core" msgstr "Teras" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3058,6 +3081,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Pilihan RTC Suai" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3371,16 +3398,6 @@ msgstr "Sambungan Terus" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3950,6 +3967,10 @@ msgstr "Benarkan Menipu" msgid "Enable Custom RTC" msgstr "Benarkan RTC Suai" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Benarkan Dwi-Teras" @@ -4667,7 +4688,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5620,8 +5641,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5636,10 +5657,14 @@ msgstr "" msgid "Game Folders" msgstr "Folder Permainan" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5742,7 +5767,7 @@ msgstr "Slot Mikrofon GameCube %1" msgid "GameCube TAS Input %1" msgstr "Input TAS GameCube %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5876,14 +5901,18 @@ msgstr "" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6645,7 +6674,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7068,6 +7097,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7409,7 +7439,7 @@ msgstr "" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7417,16 +7447,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7966,7 +7997,7 @@ msgstr "Ma&in Rakaman Input..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8375,6 +8406,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "Kiraan Program" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8899,12 +8931,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9555,7 +9583,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9616,10 +9644,6 @@ msgstr "Tunjuk Australia" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Tunjuk UI Penyahpepijatan" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10606,6 +10630,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11679,6 +11712,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Nyahpek" @@ -12695,6 +12744,10 @@ msgstr "atau pilih satu peranti" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/nb.po b/Languages/po/nb.po index 958ec7968e..e911b67b45 100644 --- a/Languages/po/nb.po +++ b/Languages/po/nb.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: d1fcc80a35d5442129c384ac221ef98f_d2a8fa7 " ", 2015\n" @@ -190,6 +190,16 @@ msgstr "%1 ble med" msgid "%1 has left" msgstr "%1 har forlatt" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -207,6 +217,11 @@ msgstr "" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 økt funnet" @@ -1128,7 +1143,7 @@ msgstr "" msgid "Accuracy:" msgstr "Nøyaktighet:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2396,7 +2411,7 @@ msgstr "Kode:" msgid "Codes received!" msgstr "Koder mottatt!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2404,7 +2419,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2689,6 +2704,14 @@ msgstr "Kontroller-innstillinger" msgid "Controllers" msgstr "Kontrollere" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2798,19 +2821,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2870,11 +2893,11 @@ msgstr "Kopier til B" msgid "Core" msgstr "Kjerne" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3097,6 +3120,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Egendefinerte RTC-valg" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3410,16 +3437,6 @@ msgstr "Direkte tilkobling" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3990,6 +4007,10 @@ msgstr "Aktiver juksekoder" msgid "Enable Custom RTC" msgstr "Aktiver egendefinert RTC (klokke)" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Aktiver bruk av dobbelkjerne" @@ -4710,7 +4731,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "Kunne ikke koble til server: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Kunne ikke lage D3D swap chain" @@ -5671,8 +5692,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5687,10 +5708,14 @@ msgstr "Spilldetaljer" msgid "Game Folders" msgstr "Spillmapper" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5793,7 +5818,7 @@ msgstr "GameCube-mikrofoninngang i inngang %1" msgid "GameCube TAS Input %1" msgstr "GameCube TAS-inndata %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5927,14 +5952,18 @@ msgstr "Gyroskop" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6695,7 +6724,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "JIT Systemregistre Av" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7122,6 +7151,7 @@ msgstr "Lokal" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7463,7 +7493,7 @@ msgstr "NKit-advarsel" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7471,16 +7501,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8025,7 +8056,7 @@ msgstr "Spi&ll av inndataopptak…" msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8440,6 +8471,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "Programteller" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8964,12 +8996,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9623,7 +9651,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9684,10 +9712,6 @@ msgstr "Vis Australia" msgid "Show Current Game on Discord" msgstr "Vis nåværende spill på Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Vis utviklingsgrensesnitt" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10678,6 +10702,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11792,6 +11825,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Utpakning" @@ -12810,6 +12859,10 @@ msgstr "eller velg en enhet" msgid "s" msgstr "sek" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/nl.po b/Languages/po/nl.po index a87e587d88..ced5d7a3fa 100644 --- a/Languages/po/nl.po +++ b/Languages/po/nl.po @@ -17,7 +17,7 @@ # Mike van der Kuijl , 2019-2020 # Mike van der Kuijl , 2020-2023 # Mike van der Kuijl , 2021-2022 -# Mourits Pvllen , 2014 +# Appel “Appel Taart” Taart , 2014 # Philip Goto , 2023 # Pierre Bourdon , 2014 # Simon Mariën, 2022 @@ -28,7 +28,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Mike van der Kuijl , 2020-2023\n" "Language-Team: Dutch (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -204,6 +204,16 @@ msgstr "%1 doet nu mee" msgid "%1 has left" msgstr "%1 is vertrokken" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 is geen geldige ROM" @@ -221,6 +231,11 @@ msgstr "%1 geheugen reeksen" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 sessie gevonden" @@ -279,7 +294,7 @@ msgstr "%1[%2]: %3/%4 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "%1x MSAA" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -288,7 +303,7 @@ msgstr "%1x Native (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "%1x SSAA" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -653,7 +668,7 @@ msgstr "&Scan e-Reader Kaart(en)..." #: Source/Core/DolphinQt/MenuBar.cpp:229 msgid "&Skylanders Portal" -msgstr "&Skylanders Portaal" +msgstr "&Skylanders Portal" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:175 msgid "&Speed Limit:" @@ -773,7 +788,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 GiB" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -781,7 +796,7 @@ msgstr "128 Mbit (2043 blokken)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 MiB" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -789,7 +804,7 @@ msgstr "16 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -823,11 +838,11 @@ msgstr "1x" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 GiB" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 MiB" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -843,7 +858,7 @@ msgstr "2x Native (1280x1056) voor 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -895,7 +910,7 @@ msgstr "4 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -919,7 +934,7 @@ msgstr "4x Native (2560x2112) voor 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -931,7 +946,7 @@ msgstr "64 Mbit (1019 blokken)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 MiB" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -962,7 +977,7 @@ msgstr "8 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -1059,6 +1074,8 @@ msgid "" "A group of features to make the colors more accurate, matching the color " "space Wii and GC games were meant for." msgstr "" +"Een groep functies om de kleuren nauwkeuriger te maken, zodat ze " +"overeenkomen met de kleurruimte waar Wii en GC-spellen voor bedoeld zijn." #: Source/Core/DolphinQt/Main.cpp:226 msgid "A save state cannot be loaded without specifying a game to launch." @@ -1158,10 +1175,10 @@ msgstr "Versnellingsmeter Invloed" msgid "Accuracy:" msgstr "Nauwkeurigheid:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" -msgstr "" +msgstr "Prestaties" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1461,7 +1478,7 @@ msgstr "Afrika" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:342 msgid "Air" -msgstr "" +msgstr "Lucht" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:116 msgid "Aligned to data type length" @@ -1469,7 +1486,7 @@ msgstr "Uitgelijnd naar data type lengte" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "Alle" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -2393,7 +2410,7 @@ msgstr "China" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "Kies" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2448,7 +2465,7 @@ msgstr "Cache legen" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:119 msgid "Clear Slot" -msgstr "" +msgstr "Slot Legen" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:83 msgid "Clock Override" @@ -2498,17 +2515,17 @@ msgstr "Code:" msgid "Codes received!" msgstr "Codes ontvangen!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "Kleur Correctie Configuratie" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "Kleur Correctie:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "Kleurruimte" #: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Combine &Two Signature Files..." @@ -2642,6 +2659,55 @@ msgid "" "possible for them to go out of range or to become NaN. A warning will be " "given if NaN is returned, and the var that became NaN will be logged." msgstr "" +"Conditie:\n" +"Stelt een uitdrukking in die wordt geëvalueerd wanneer een onderbrekingspunt " +"wordt geraakt. Als de uitdrukking onwaar of 0 is, wordt het " +"onderbrekingspunt genegeerd tot het opnieuw wordt geraakt. Verklaringen " +"moeten worden gescheiden door een komma. Alleen het laatste statement zal " +"worden gebruikt om te bepalen wat er moet gebeuren.\n" +"\n" +"Registers waarnaar verwezen kan worden:\n" +"GPR's : r0..r31\n" +"FPR's : f0..f31\n" +"LR, CTR, PC\n" +"\n" +"Functies:\n" +"Een register instellen: r1 = 8\n" +"Cast: s8(0xff). Beschikbaar: s8, u8, s16, u16, s32, u32\n" +"Callstack: callstack(0x80123456), callstack(\"anim\")\n" +"Strings vergelijken: streq(r3, \"abc\"). Beide parameters kunnen adressen of " +"stringconstanten zijn.\n" +"Geheugen lezen: read_u32(0x80000000). Beschikbaar: u8, s8, u16, s16, u32, " +"s32, f32, f64\n" +"Geheugen schrijven: write_u32(r3, 0x80000000). Beschikbaar: u8, u16, u32, " +"f32, f64\n" +"*Momenteel schrijven wordt altijd getriggerd\n" +"\n" +"Bewerkingen:\n" +"Unair: -u, !u, ~u\n" +"Wiskunde: * / + -, macht: **, rest: %, shift: <<, >>\n" +"Vergelijken: <, <=, >, >=, ==, !=, &&, ||\n" +"Bitwise: &, |, ^\n" +"\n" +"Voorbeelden:\n" +"r4 == 1\n" +"f0 == 1,0 && f2 < 10,0\n" +"r26 <= r0 && ((r5 + 3) & -4) * ((r6 + 3) & -4)* 4 > r0\n" +"p = r3 + 0x8, p == 0x8003510 && read_u32(p) != 0\n" +"Schrijven en onderbreken: r4 = 8, 1\n" +"Schrijven en doorgaan: f3 = f1 + f2, 0\n" +"De voorwaarde moet altijd als laatste\n" +"\n" +"Strings mogen alleen gebruikt worden in callstack() of streq() en \"geciteerd" +"\" worden. Wijs geen strings toe aan een variabele.\n" +"Alle variabelen worden afgedrukt in het logboek van de geheugeninterface als " +"er een hit of een NaN-resultaat is. Om te controleren op problemen, wijs je " +"een variabele toe aan je vergelijking, zodat deze kan worden afgedrukt.\n" +"\n" +"Opmerking: Alle waarden worden intern geconverteerd naar dubbele precisie " +"voor berekeningen. Het is mogelijk dat ze buiten het bereik vallen of NaN " +"worden. Er wordt een waarschuwing gegeven als NaN wordt geretourneerd en de " +"var die NaN werd, wordt gelogd." #: Source/Core/DolphinQt/ToolBar.cpp:129 msgid "Config" @@ -2798,6 +2864,14 @@ msgstr "Controllerinstellingen" msgid "Controllers" msgstr "Controllers" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2923,19 +2997,19 @@ msgstr "" "Converteren...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2995,13 +3069,13 @@ msgstr "Kopiëren naar B" msgid "Core" msgstr "Core" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "Correcte Kleurruimte" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" -msgstr "" +msgstr "Correcte SDR Gamma" #. i18n: Performance cost, not monetary cost #: Source/Core/DolphinQt/Debugger/JITWidget.cpp:91 @@ -3160,7 +3234,7 @@ msgstr "Maak Skylander Bestand aan" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:80 msgid "Create Skylander Folder" -msgstr "" +msgstr "Maak Skylander Map aan" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:109 msgid "Create mappings for other devices" @@ -3253,9 +3327,13 @@ msgstr "Aangepaste Adresruimte" msgid "Custom RTC Options" msgstr "Aangepaste RTC Opties" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "Aanpassen" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3579,22 +3657,6 @@ msgstr "Rechtstreekse Verbinding" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Direct3D 11 renderer vereist ondersteuning voor features die uw systeem niet " -"ondersteund. Dit komt waarschijnlijk omdat u Windows 7 gebruikt. U kan nog " -"steeds deze backend gebruiken, maar u kunt misschien op grafische problemen " -"stuiten.\n" -"\n" -"Wilt u echt Direct3D 11 gebruiken? In geval van twijfel 'Nee' selecteren." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "&Verbinding Verbroken" @@ -3849,7 +3911,7 @@ msgstr "Niet Updaten" #: Source/Core/DolphinQt/NKitWarningDialog.cpp:53 msgid "Don't show this again" -msgstr "Laat dit niet meer zien" +msgstr "Laat dit niet meer tonen" #: Source/Core/DiscIO/CompressedBlob.cpp:369 msgid "Done compressing disc image." @@ -4073,7 +4135,7 @@ msgstr "Vroege Geheugen Updates" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:336 msgid "Earth" -msgstr "" +msgstr "Aarde" #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "East Asia" @@ -4120,7 +4182,7 @@ msgstr "Schijf uitwerpen" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "Element" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4144,7 +4206,7 @@ msgstr "Emuleer Infinity Base" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:146 msgid "Emulate Skylander Portal" -msgstr "Emuleer Skylander Portaal" +msgstr "Emuleer Skylander Portal" #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:110 msgid "Emulate the Wii's Bluetooth adapter" @@ -4200,7 +4262,7 @@ msgstr "Activeer API Validatielagen" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "Activeer Prestaties" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4214,6 +4276,10 @@ msgstr "Activeer Cheats" msgid "Enable Custom RTC" msgstr "Activeer Aangepaste RTC" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Activeer Dual-Core" @@ -4232,7 +4298,7 @@ msgstr "Schakel Gemuleerde Geheugen Grootte Overschrijven in" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "Activeer Encore Prestaties" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4244,7 +4310,7 @@ msgstr "Schakel Grafische Mods in" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:62 msgid "Enable Leaderboards" -msgstr "" +msgstr "Activeer Leaderboard" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:88 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:66 @@ -4257,11 +4323,11 @@ msgstr "Activeer Progressieve Scan" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "Activeer RetroAchievements.org Integratie" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" -msgstr "" +msgstr "Activeer Rich Presence" #: Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.cpp:39 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:353 @@ -4278,7 +4344,7 @@ msgstr "Activeer Speaker Data" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "Activeer Onofficiële Prestaties" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4286,7 +4352,7 @@ msgstr "Rapportage van gebruiksstatistieken inschakelen" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:161 msgid "Enable WiiConnect24 via WiiLink" -msgstr "" +msgstr "Activeer WiiConnect24 via WiiLink" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:81 msgid "Enable Wireframe" @@ -4301,6 +4367,8 @@ msgid "" "Enable competing in RetroAchievements leaderboards.

Hardcore Mode " "must be enabled to use." msgstr "" +"Activeer deelname aan RetroAchievements.\n" +"Hardcore modus moet ingeschakeld zijn om te gebruiken." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:68 msgid "" @@ -4337,7 +4405,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" -msgstr "" +msgstr "Activeer het vrijspelen van prestaties.
" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:74 msgid "" @@ -4460,6 +4528,10 @@ msgid "" "such as the Forecast and Nintendo Channels\n" "Read the Terms of Service at: https://www.wiilink24.com/tos" msgstr "" +"Activeer de WiiLink-dienst voor WiiConnect24-kanalen.\n" +"WiiLink is een alternatieve provider voor de beëindigde WiiConnect24-kanalen " +"zoals de Voorspellings- en Nintendo-kanalen.\n" +"Lees de servicevoorwaarden op: https://www.wiilink24.com/tos" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:298 msgid "" @@ -4984,7 +5056,7 @@ msgstr "Legen van Skylander mislukt!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:575 msgid "Failed to clear the Skylander from slot(%1)!" -msgstr "" +msgstr "Legen van Skylander uit slot(%1) mislukt!" #: Source/Core/DiscIO/VolumeVerifier.cpp:108 msgid "Failed to connect to Redump.org" @@ -4994,7 +5066,7 @@ msgstr "Verbinden met Redump.org mislukt" msgid "Failed to connect to server: %1" msgstr "Kon geen verbinding maken met server: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Kon D3D swap chain niet maken" @@ -5025,6 +5097,9 @@ msgid "" "%1\n" "(Skylander may already be on the portal)" msgstr "" +"Maken van Skylander bestand mislukt:\n" +"%1\n" +"(Skylander is mogelijk al op het portal)" #: Source/Core/Core/NetPlayClient.cpp:1292 msgid "" @@ -5566,7 +5641,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:333 msgid "Fire" -msgstr "" +msgstr "Vuur" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:40 msgid "First Person" @@ -5926,6 +6001,12 @@ msgid "" "Further errors will be sent to the Video Backend log and Dolphin will now " "likely crash or hang." msgstr "" +"GFX FIFO: Onbekende Opcode ({0:#04x} @ {1}, preprocess={2}).\n" +"\n" +"{3}\n" +"\n" +"Verdere fouten worden naar het Video Backend log gestuurd en Dolphin zal nu " +"waarschijnlijk crashen of hangen." #: Source/Core/VideoBackends/OGL/OGLMain.cpp:181 msgid "GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024." @@ -6031,8 +6112,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "Game Boy Advance aan Poort %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -6047,8 +6128,12 @@ msgstr "Spel Details" msgid "Game Folders" msgstr "Spelmappen" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" +msgstr "Spel Gamma" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 @@ -6156,9 +6241,9 @@ msgstr "GameCube Microfoon Slot %1" msgid "GameCube TAS Input %1" msgstr "GameCube-TAS-invoer %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "Gamma" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -6222,7 +6307,7 @@ msgstr "GiB" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:267 msgid "Giants" -msgstr "" +msgstr "Giants" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:195 msgid "Golf Mode" @@ -6296,17 +6381,21 @@ msgstr "Gyroscoop" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" -msgstr "" +msgstr "HDR" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" +msgstr "HDR Papier Wit Nits" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" msgstr "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" -msgstr "" +msgstr "HDR Post-Processing" #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:62 msgid "Hacks" @@ -6852,7 +6941,7 @@ msgstr "&Nop invoegen" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:219 msgid "Insert SD Card" -msgstr "SD-kaart invoegen" +msgstr "SD-Kaart Invoegen" #: Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp:82 #: Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp:144 @@ -7135,7 +7224,7 @@ msgstr "JIT-registercache uitgeschakld" msgid "JIT SystemRegisters Off" msgstr "JIT SysteemRegisters Uit" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7338,7 +7427,7 @@ msgstr "Licentie" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:339 msgid "Life" -msgstr "" +msgstr "Leven" #: Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp:35 #: Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp:53 @@ -7389,7 +7478,7 @@ msgstr "Laad Aangepaste Textures" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "Laad Bestand" #: Source/Core/DolphinQt/MenuBar.cpp:249 msgid "Load GameCube Main Menu" @@ -7414,7 +7503,7 @@ msgstr "Laad ROM" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "Laad Slot" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7572,6 +7661,7 @@ msgstr "Lokaal" msgid "Lock Mouse Cursor" msgstr "Vergrendel Muisaanwijzer" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "Vergrendeld" @@ -7579,11 +7669,11 @@ msgstr "Vergrendeld" #: Source/Core/DolphinQt/Config/LogWidget.cpp:34 #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:236 msgid "Log" -msgstr "Logboek" +msgstr "Log" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:22 msgid "Log Configuration" -msgstr "Logboekconfiguratie" +msgstr "Logconfiguratie" #: Source/Core/DolphinQt/MenuBar.cpp:864 msgid "Log JIT Instruction Coverage" @@ -7603,15 +7693,15 @@ msgstr "Logger-uitvoer" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "Inloggen" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "Inloggen Mislukt" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "Uitloggen" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7660,7 +7750,7 @@ msgstr "MadCatz Gameshark bestanden" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:324 msgid "Magic" -msgstr "" +msgstr "Magie" #: Source/Core/DolphinQt/TAS/GCTASInputWindow.cpp:29 msgid "Main Stick" @@ -7936,24 +8026,25 @@ msgstr "NKit-waarschuwing" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8373,7 +8464,7 @@ msgstr "Online &Documentatie" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "Alleen Collectie Tonen" #: Source/Core/DolphinQt/MenuBar.cpp:1615 msgid "" @@ -8515,9 +8606,9 @@ msgstr "O&pname Invoer Afspelen..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8769,6 +8860,8 @@ msgid "" "Please change the \"SyncOnSkipIdle\" setting to \"True\"! It's currently " "disabled, which makes this problem very likely to happen." msgstr "" +"Verander de instelling \"SyncOnSkipIdle\" naar \"True\"! Op dit moment is " +"het uitgeschakeld, waardoor dit probleem zeer waarschijnlijk zal optreden." #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:164 msgid "" @@ -8799,7 +8892,7 @@ msgstr "Poort:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "Portal Slots" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -8940,6 +9033,7 @@ msgstr "Profiel" msgid "Program Counter" msgstr "Programmateller" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9457,23 +9551,23 @@ msgstr "Rusland" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:221 msgid "SD Card" -msgstr "SD-kaart" +msgstr "SD-Kaart" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:266 msgid "SD Card File Size:" -msgstr "" +msgstr "SD-Kaart Bestandsgrootte:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:506 msgid "SD Card Image (*.raw);;All Files (*)" -msgstr "SD-kaartafbeedling (*.raw);;Alle Bestanden(*)" +msgstr "SD-Kaartafbeedling (*.raw);;Alle Bestanden(*)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:233 msgid "SD Card Path:" -msgstr "Pad naar SD-kaart:" +msgstr "SD-Kaart Pad:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:213 msgid "SD Card Settings" -msgstr "SD-kaart-instellingen" +msgstr "SD-Kaart-instellingen" #: Source/Core/DolphinQt/RiivolutionBootWidget.cpp:168 msgid "SD Root:" @@ -9483,12 +9577,8 @@ msgstr "SD Root:" msgid "SD Sync Folder:" msgstr "SD Sync Map:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9777,7 +9867,7 @@ msgstr "Zoek instructie" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "Zoeken:" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9846,7 +9936,7 @@ msgstr "Selecteer Riivolution XML bestand" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:410 msgid "Select Skylander Collection" -msgstr "" +msgstr "Selecteer Skylander Collectie" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:481 msgid "Select Skylander File" @@ -9936,7 +10026,7 @@ msgstr "Selecteer een Spel" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:504 msgid "Select a SD Card Image" -msgstr "Selecteer een SD-kaartafbeelding" +msgstr "Selecteer een SD-Kaartafbeelding" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:694 msgid "Select a file" @@ -10179,7 +10269,7 @@ msgstr "" "virtuele adresruimte. Dit zal werken voor de overgrote meerderheid van " "spellen." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10218,7 +10308,7 @@ msgstr "Snelheidspercentage tonen" #: Source/Core/DolphinQt/MenuBar.cpp:404 msgid "Show &Log" -msgstr "&Logboek tonen" +msgstr "&Log tonen" #: Source/Core/DolphinQt/MenuBar.cpp:417 msgid "Show &Toolbar" @@ -10240,10 +10330,6 @@ msgstr "Australië tonen" msgid "Show Current Game on Discord" msgstr "Huidig spel op Discord tonen" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Foutopsporingsinterface tonen" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10288,7 +10374,7 @@ msgstr "Golfmodus-overlay tonen" #: Source/Core/Core/HotkeyManager.cpp:199 msgid "Show Infinity Base" -msgstr "" +msgstr "Toon Infinity Base" #: Source/Core/DolphinQt/MenuBar.cpp:791 msgid "Show Input Display" @@ -10316,7 +10402,7 @@ msgstr "Taal tonen:" #: Source/Core/DolphinQt/MenuBar.cpp:410 msgid "Show Log &Configuration" -msgstr "Logboek&configuratie tonen" +msgstr "Log&configuratie tonen" #: Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp:90 msgid "Show NetPlay Messages" @@ -10365,7 +10451,7 @@ msgstr "Rusland tonen" #: Source/Core/Core/HotkeyManager.cpp:198 msgid "Show Skylanders Portal" -msgstr "" +msgstr "Toon Skylanders Portal" #: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Spain" @@ -10649,15 +10735,15 @@ msgstr "Skylander %1" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:482 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:551 msgid "Skylander (*.sky);;All Files (*)" -msgstr "" +msgstr "Skylander (*.sky);;Alle Bestanden (*)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:217 msgid "Skylander Collection Path:" -msgstr "" +msgstr "Skylander Collectie Pad:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:448 msgid "Skylander not found in this collection. Create new file?" -msgstr "" +msgstr "Skylander niet gevonden in deze collectie. Nieuw bestand maken?" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:42 msgid "Skylanders Manager" @@ -10665,7 +10751,7 @@ msgstr "Skylanders Beheer" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:81 msgid "Skylanders folder not found for this user. Create new folder?" -msgstr "" +msgstr "Skylanders map niet gevonden voor deze gebruiker. Nieuwe map maken?" #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:97 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:140 @@ -10792,7 +10878,7 @@ msgstr "Snelheid" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "Spyro's Adventure" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -11074,7 +11160,7 @@ msgstr "Titel succesvol verwijderd van de NAND." #. all countries they were released in. They were not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:277 msgid "SuperChargers" -msgstr "" +msgstr "SuperChargers" #: Source/Core/DolphinQt/AboutDialog.cpp:69 msgid "Support" @@ -11105,7 +11191,7 @@ msgstr "Wissel Ogen" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:270 msgid "Swap Force" -msgstr "" +msgstr "Swap Force" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:500 msgid "" @@ -11266,7 +11352,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:330 msgid "Tech" -msgstr "" +msgstr "Tech" #: Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp:244 msgid "Test" @@ -11305,6 +11391,15 @@ msgstr "" "De DFF's minimale loader versie ({0}) overschrijd de versie van deze FIFO " "Player ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "De H3 hashtabel voor de {0} partitie is onjuist." @@ -11856,12 +11951,19 @@ msgid "" "CPU, but your current settings make this unlikely to happen. If this error " "is stopping the game from working, please report it to the developers." msgstr "" +"Deze fout wordt meestal veroorzaakt doordat de geëmuleerde GPU " +"desynchroniseert met de geëmuleerde CPU, maar je huidige instellingen maken " +"het onwaarschijnlijk dat dit gebeurt. Als deze fout ervoor zorgt dat het " +"spel niet werkt, meld dit dan bij de ontwikkelaars." #: Source/Core/VideoCommon/CommandProcessor.cpp:724 msgid "" "This error is usually caused by the emulated GPU desyncing with the emulated " "CPU. Turn off the \"Dual Core\" setting to avoid this." msgstr "" +"Deze fout wordt meestal veroorzaakt doordat de geëmuleerde GPU " +"desynchroniseert met de geëmuleerde CPU. Schakel de instelling \"Dual Core\" " +"uit om dit te voorkomen." #: Source/Core/DiscIO/NANDImporter.cpp:116 msgid "This file does not contain a valid Wii filesystem." @@ -12201,7 +12303,7 @@ msgstr "Chinees (Traditioneel)" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:273 msgid "Trap Team" -msgstr "" +msgstr "Trap Team" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:991 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:995 @@ -12262,15 +12364,15 @@ msgstr "USA" #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "USB Apparaat Emulatie" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "USB Emulatie" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "USB Emulatie Apparaat" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -12387,7 +12489,7 @@ msgstr "Ongecomprimeerde GC/Wii-afbeeldingen (*.iso *.gcm)" #. https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:346 msgid "Undead" -msgstr "" +msgstr "Ondood" #: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Undo Load State" @@ -12520,6 +12622,22 @@ msgstr "Leeg ROM" msgid "Unlock Cursor" msgstr "Ontgrendel Cursor" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Uitpakken" @@ -12755,7 +12873,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "Gebruikersnaam" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -13174,7 +13292,7 @@ msgstr "Watch" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:327 msgid "Water" -msgstr "" +msgstr "Water" #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Website" @@ -13699,6 +13817,10 @@ msgstr "of selecteer een apparaat" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "deze waarde:" diff --git a/Languages/po/pl.po b/Languages/po/pl.po index bf01861e71..9ca7b87409 100644 --- a/Languages/po/pl.po +++ b/Languages/po/pl.po @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: FlexBy, 2021,2023\n" "Language-Team: Polish (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -197,6 +197,16 @@ msgstr "%1 dołączył(a)" msgid "%1 has left" msgstr "%1 wyszedł" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -214,6 +224,11 @@ msgstr "" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "Znaleziono %1 sesję" @@ -1127,7 +1142,7 @@ msgstr "" msgid "Accuracy:" msgstr "Dokładność:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2390,7 +2405,7 @@ msgstr "Kod:" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2398,7 +2413,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2683,6 +2698,14 @@ msgstr "Ustawienia kontrolera" msgid "Controllers" msgstr "Kontrolery" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2786,19 +2809,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2858,11 +2881,11 @@ msgstr "" msgid "Core" msgstr "Rdzeń" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3081,6 +3104,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Opcje dostosowanego RTC" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3394,16 +3421,6 @@ msgstr "Bezpośrednie połączenie" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3973,6 +3990,10 @@ msgstr "Włącz cheaty" msgid "Enable Custom RTC" msgstr "Włącz dostosowany RTC" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Włącz dwa rdzenie" @@ -4691,7 +4712,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5642,8 +5663,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5658,10 +5679,14 @@ msgstr "" msgid "Game Folders" msgstr "Foldery gry" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5764,7 +5789,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5898,14 +5923,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6666,7 +6695,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7089,6 +7118,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7426,7 +7456,7 @@ msgstr "" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7434,16 +7464,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7981,7 +8012,7 @@ msgstr "&Odtwórz nagranie wejścia..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8388,6 +8419,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "Licznik programu" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8912,12 +8944,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9566,7 +9594,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9627,10 +9655,6 @@ msgstr "Pokaż Australię" msgid "Show Current Game on Discord" msgstr "Pokazuj aktualną grę w programie Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10617,6 +10641,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11673,6 +11706,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Rozpakowywanie" @@ -12681,6 +12730,10 @@ msgstr "lub wybierz urządzenie" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "ta wartość:" diff --git a/Languages/po/pt.po b/Languages/po/pt.po index cef47c49fc..e8d1a79000 100644 --- a/Languages/po/pt.po +++ b/Languages/po/pt.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Zilaan , 2011\n" "Language-Team: Portuguese (http://app.transifex.com/delroth/dolphin-emu/" @@ -169,6 +169,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -186,6 +196,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1091,7 +1106,7 @@ msgstr "" msgid "Accuracy:" msgstr "Precisão:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2340,7 +2355,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2348,7 +2363,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2633,6 +2648,14 @@ msgstr "" msgid "Controllers" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2736,19 +2759,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2808,11 +2831,11 @@ msgstr "" msgid "Core" msgstr "Core" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3027,6 +3050,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3340,16 +3367,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3916,6 +3933,10 @@ msgstr "Activar Cheats" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Activar Dual Core" @@ -4627,7 +4648,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5576,8 +5597,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5592,10 +5613,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5698,7 +5723,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5832,14 +5857,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6589,7 +6618,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7012,6 +7041,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7349,7 +7379,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7357,16 +7387,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7902,7 +7933,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8307,6 +8338,7 @@ msgstr "Perfil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8831,12 +8863,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9482,7 +9510,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9543,10 +9571,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10531,6 +10555,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11578,6 +11611,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12586,6 +12635,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/pt_BR.po b/Languages/po/pt_BR.po index 1bca1204e7..0becf1cd41 100644 --- a/Languages/po/pt_BR.po +++ b/Languages/po/pt_BR.po @@ -46,7 +46,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Runo , 2013\n" "Language-Team: Portuguese (Brazil) (http://app.transifex.com/delroth/dolphin-" @@ -223,6 +223,16 @@ msgstr "%1 entrou" msgid "%1 has left" msgstr "%1 saiu" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 não é uma ROM válida" @@ -240,6 +250,11 @@ msgstr "%1 alcances da memória" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 sessão encontrada" @@ -298,7 +313,7 @@ msgstr "%1[%2]: %3/%4 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "%1x MSAA" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -307,7 +322,7 @@ msgstr "%1x Nativa (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "%1x SSAA" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -791,7 +806,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 GiB" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -799,7 +814,7 @@ msgstr "128 Mbits (2043 blocos)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 MiB" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -807,7 +822,7 @@ msgstr "16 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -841,11 +856,11 @@ msgstr "1x" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 GiB" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 MiB" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -861,7 +876,7 @@ msgstr "2x Nativa (1280x1056) para 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -913,7 +928,7 @@ msgstr "4 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -937,7 +952,7 @@ msgstr "4x Nativa (2560x2112) para 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -949,7 +964,7 @@ msgstr "64 Mbits (1019 blocos)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 MiB" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -980,7 +995,7 @@ msgstr "8 Bytes" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -1079,6 +1094,9 @@ msgid "" "A group of features to make the colors more accurate, matching the color " "space Wii and GC games were meant for." msgstr "" +"Um grupo de ajustes para tornar as cores mais precisas, correspondendo ao " +"espaço de cores para qual os jogos de GameCube e Wii foram desenvolvidos " +"originalmente." #: Source/Core/DolphinQt/Main.cpp:226 msgid "A save state cannot be loaded without specifying a game to launch." @@ -1177,10 +1195,10 @@ msgstr "Influência do acelerômetro" msgid "Accuracy:" msgstr "Precisão:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" -msgstr "" +msgstr "Conquistas" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1485,7 +1503,7 @@ msgstr "África" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:342 msgid "Air" -msgstr "" +msgstr "Ar" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:116 msgid "Aligned to data type length" @@ -1493,7 +1511,7 @@ msgstr "Alinhado ao comprimento do tipo de dados" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "Todos" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -2423,7 +2441,7 @@ msgstr "China" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "..." #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2478,7 +2496,7 @@ msgstr "Limpar Cache" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:119 msgid "Clear Slot" -msgstr "" +msgstr "Limpar Slot" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:83 msgid "Clock Override" @@ -2528,17 +2546,17 @@ msgstr "Código:" msgid "Codes received!" msgstr "Códigos recebidos!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "Configurações da Correção de Cores" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "Correção de Cores:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "Espaço de Cores" #: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Combine &Two Signature Files..." @@ -2672,6 +2690,54 @@ msgid "" "possible for them to go out of range or to become NaN. A warning will be " "given if NaN is returned, and the var that became NaN will be logged." msgstr "" +"Condições:\n" +"Define uma expressão que é evaliada quando um ponto de interrupção é " +"atingido. Se a expressão é falsa ou 0 o ponto de interrupção é ignorado até " +"ser atingido de novo. As declarações devem ser separadas por uma vírgula. Só " +"a última declaração será usada pra determinar o que fazer.\n" +"\n" +"Registros que podem ser referenciados:\n" +"GPRs : r0..r31\n" +"FPRs : f0..f31\n" +" LR, CTR, PC\n" +"\n" +"Funções:\n" +"Define um registro: r1 = 8\n" +"Lança: s8(0xff). Disponíveis: s8, u8, s16, u16, s32, u32\n" +"Callstack: callstack(0x80123456), callstack(\"anim\")\n" +"Comparar Strings: streq(r3, \"abc\"). Ambos os parâmetros podem ser " +"endereços ou constants das strings.\n" +"Ler Memória: read_u32(0x80000000). Disponíveis: u8, s8, u16, s16, u32, s32, " +"f32, f64\n" +"Gravar Memória: write_u32(r3, 0x80000000). Disponíveis: u8, u16, u32, f32, " +"f64\n" +"*a gravação atual sempre estará engatilhada\n" +"\n" +"Operações:\n" +"Unário: -u, !u, ~u\n" +"Math: * / + -, power: **, remainder: %, shift: <<, >>\n" +"Comparação: <, <=, >, >=, ==, !=, &&, ||\n" +"Bitwise: &, |, ^\n" +"\n" +"Exemplos:\n" +"r4 == 1\n" +"f0 == 1.0 && f2 < 10.0\n" +"r26 <= r0 && ((r5 + 3) & -4) * ((r6 + 3) & -4)* 4 > r0\n" +"p = r3 + 0x8, p == 0x8003510 && read_u32(p) != 0\n" +"Gravação e interrupção: r4 = 8, 1\n" +"Gravar e continuar: f3 = f1 + f2, 0\n" +"A condição deve ser sempre a última\n" +"\n" +"As strings só devem ser usadas no callstack() or streq() and \"quoted\". Não " +"atribua as strings a uma variável.\n" +"Todas as variáveis serão impressas no registro de Interface da Memória, se " +"há um acerto ou um resultado da NaN. Pra procurar problemas atribua uma " +"variável a sua equação pra que possa ser impressa.\n" +"\n" +"Nota: Todos os valores são convertidos internamente em Duplos pra cálculos. " +"É possível pra eles sairem fora do alcance ou se tornarem NaNs. Um aviso " +"será dado se for retornado um NaN e a variável que se tornou NaN será " +"registrada." #: Source/Core/DolphinQt/ToolBar.cpp:129 msgid "Config" @@ -2828,6 +2894,14 @@ msgstr "Configuração dos Controles" msgid "Controllers" msgstr "Controles" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2954,24 +3028,28 @@ msgstr "" "Convertendo...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." "

If unsure, leave this unchecked." msgstr "" +"Converte o alvo de gama utilizado pelo jogo para corresponder ao alvo de " +"gama da tela SDR.
Monitores normalmente usam o alvo sRGB. TVs " +"normalmente usam o alvo 2.2.

Na dúvida, mantenha " +"essa opção desativada." #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:290 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:704 @@ -3026,13 +3104,13 @@ msgstr "Copiar para B" msgid "Core" msgstr "Core" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "Corrigir Espaço de Cores" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" -msgstr "" +msgstr "Corrigir Gama SDR" #. i18n: Performance cost, not monetary cost #: Source/Core/DolphinQt/Debugger/JITWidget.cpp:91 @@ -3196,7 +3274,7 @@ msgstr "Criar Arquivo do Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:80 msgid "Create Skylander Folder" -msgstr "" +msgstr "Criar Pasta do Skylander" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:109 msgid "Create mappings for other devices" @@ -3291,9 +3369,13 @@ msgstr "Espaço do Endereço Personalizado" msgid "Custom RTC Options" msgstr "Opções do RTC Personalizado" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "Personalizar" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3616,23 +3698,6 @@ msgstr "Conexão Direta" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"O renderizador do Direct3D 11 exige o suporte de alguns recursos não " -"compatíveis com a configuração do seu sistema. A causa mais provável é a de " -"você estar usando o Windows 7. Você ainda pode utilizar este backend mas " -"provavelmente encontrará defeitos gráficos.\n" -"\n" -"Tem certeza de que deseja trocar para o Direct3D 11? Na dúvida, selecione " -"'Não'." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "Des&conectado" @@ -4115,7 +4180,7 @@ msgstr "Atualizações Prévias de Memória" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:336 msgid "Earth" -msgstr "" +msgstr "Terra" #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "East Asia" @@ -4162,7 +4227,7 @@ msgstr "Ejetar Disco" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "Elemento" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4242,7 +4307,7 @@ msgstr "Ativar Camadas de Validação da API" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "Ativar Conquistas" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4256,6 +4321,10 @@ msgstr "Ativar Cheats" msgid "Enable Custom RTC" msgstr "Ativar RTC Personalizado" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Ativar Dual Core" @@ -4274,7 +4343,7 @@ msgstr "Ativar Ajuste de Memória do Console Emulado" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "Ativar Conquistas Encore" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4286,7 +4355,7 @@ msgstr "Ativar Mods Gráficos" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:62 msgid "Enable Leaderboards" -msgstr "" +msgstr "Ativar Placar de Líderes" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:88 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:66 @@ -4299,11 +4368,11 @@ msgstr "Ativar Varredura Progressiva" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "Ativar Integração RetroAchievements.org" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" -msgstr "" +msgstr "Ativar Status de Atividade" #: Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.cpp:39 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:353 @@ -4320,7 +4389,7 @@ msgstr "Ativar Dados do Auto-Falante" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "Ativar Conquistas Não Oficiais" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4328,7 +4397,7 @@ msgstr "Ativar Envio de Estatísticas de Uso" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:161 msgid "Enable WiiConnect24 via WiiLink" -msgstr "" +msgstr "Ativar WiiConnect24 via WiiLink" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:81 msgid "Enable Wireframe" @@ -4343,6 +4412,8 @@ msgid "" "Enable competing in RetroAchievements leaderboards.

Hardcore Mode " "must be enabled to use." msgstr "" +"Ativa submissão nos placares de líderes do RetroAchievements.

Exige " +"que o Modo Hardcore esteja ativado." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:68 msgid "" @@ -4351,6 +4422,11 @@ msgid "" "website. If this is disabled, the website will only report what game is " "being played.

This has no bearing on Discord rich presence." msgstr "" +"Ativa status de atividade detalhados no website do RetroAchievements." +"

Isso mostra descrições detalhadas sobre o que o jogador está fazendo " +"dentro do jogo no website. Se desativado, o website mostrará apenas qual " +"jogo está em execução.

Essa opção não tem relação com o status de " +"atividade do Discord." #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 msgid "" @@ -4367,6 +4443,10 @@ msgid "" "account to use. Dolphin does not save your password locally and uses an API " "token to maintain login." msgstr "" +"Ativa integração com o RetroAchievements para desbloquear conquistas e " +"participar de placares de líderes.

Requer uma conta RetroAchievements " +"para ser utilizada. Dolphin não salva sua senha localmente, utilizando um " +"token de API para manter o acesso." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:80 msgid "" @@ -4375,10 +4455,15 @@ msgid "" "will be notified if they meet the unlock conditions again, useful for custom " "speedrun criteria or simply for fun." msgstr "" +"Ativa o desbloqueio de conquistas no modo Encore.

O modo Encore " +"reativa conquistas que já foram desbloqueadas no website, de modo que os " +"jogadores sejam notificados sempre que atenderem os requisitos de " +"desbloqueio, útil para critérios de speedrun personalizados, ou por pura " +"diversão." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" -msgstr "" +msgstr "Ativa o desbloqueio de conquistas.
" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:74 msgid "" @@ -4387,6 +4472,10 @@ msgid "" "that have not been deemed official by RetroAchievements and may be useful " "for testing or simply for fun." msgstr "" +"Ativa o desbloqueio de conquistas não oficiais, assim como conquistas " +"oficiais.

Conquistas não oficiais utilizam critérios opcionais ou não " +"finalizados, que não tenham sido validados como oficiais pela equipe do " +"RetroAchievements, útil para teste, ou por pura diversão." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:97 msgid "" @@ -4466,6 +4555,13 @@ msgid "" "

Note that games still render in SDR internally." "

If unsure, leave this unchecked." msgstr "" +"Ativa saída HDR scRGB (se suportado pelo backend gráfico e pelo monitor). " +"Modo tela cheia pode ser necessário.

Isso permite que os efeitos de " +"pós-processamento entreguem resultados mais precisos, o funcionamento de " +"shaders \"AutoHDR\", e a exibição de todo o espaço de cores PAL e NTSC-J." +"

Note que os jogos ainda serão renderizados em SDR internamente." +"

Na dúvida, mantenha essa opção desativada." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:151 msgid "Enables stretching of the audio to match emulation speed." @@ -4501,6 +4597,10 @@ msgid "" "such as the Forecast and Nintendo Channels\n" "Read the Terms of Service at: https://www.wiilink24.com/tos" msgstr "" +"Ativa o serviço WiiLink para canais WiiConnect24.\n" +"WiiLink é um provedor alternativo para canais WiiConnect24 descontinuados, " +"como o Forecast Channel e o Nintendo Channel.\n" +"Leia os Termos de Serviço em: https://www.wiilink24.com/tos" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:298 msgid "" @@ -5024,7 +5124,7 @@ msgstr "Falha ao remover Skylander!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:575 msgid "Failed to clear the Skylander from slot(%1)!" -msgstr "" +msgstr "Falha ao remover o Skylander do slot(%1)!" #: Source/Core/DiscIO/VolumeVerifier.cpp:108 msgid "Failed to connect to Redump.org" @@ -5034,7 +5134,7 @@ msgstr "Falha na conexão com Redump.org" msgid "Failed to connect to server: %1" msgstr "Falha na conexão com o servidor: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Falha ao criar a cadeia de swap do Direct3D" @@ -5065,6 +5165,9 @@ msgid "" "%1\n" "(Skylander may already be on the portal)" msgstr "" +"Falha ao criar arquivo do Skylander:\n" +"%1\n" +"(Skylander pode já estar inserido no portal)" #: Source/Core/Core/NetPlayClient.cpp:1292 msgid "" @@ -5620,7 +5723,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:333 msgid "Fire" -msgstr "" +msgstr "Fogo" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:40 msgid "First Person" @@ -5986,6 +6089,12 @@ msgid "" "Further errors will be sent to the Video Backend log and Dolphin will now " "likely crash or hang." msgstr "" +"GFX FIFO: Opcode Desconhecido ({0:#04x} @ {1}, preprocess={2}).\n" +"\n" +"{3}\n" +"\n" +"Erros subsequentes serão encaminhados ao log 'Video Backend' e o Dolphin " +"provavelmente irá travar ou congelar." #: Source/Core/VideoBackends/OGL/OGLMain.cpp:181 msgid "GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024." @@ -6092,8 +6201,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "Game Boy Advance na Porta %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -6108,8 +6217,12 @@ msgstr "Detalhes do Jogo" msgid "Game Folders" msgstr "Pastas de Jogos" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" +msgstr "Gama do Jogo" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 @@ -6219,9 +6332,9 @@ msgstr "Microfone de GameCube no Slot %1" msgid "GameCube TAS Input %1" msgstr "Entrada de Dados TAS - Controle de GameCube %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "Gama" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -6285,7 +6398,7 @@ msgstr "GiB" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:267 msgid "Giants" -msgstr "" +msgstr "Giants" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:195 msgid "Golf Mode" @@ -6358,17 +6471,21 @@ msgstr "Giroscópio" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" -msgstr "" +msgstr "HDR" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" +msgstr "Branco de Papel HDR (nits)" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" msgstr "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" -msgstr "" +msgstr "Pós-Processamento HDR" #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:62 msgid "Hacks" @@ -7205,7 +7322,7 @@ msgstr "Registro do Cache do JIT Desligado" msgid "JIT SystemRegisters Off" msgstr "Registros do Sistema do JIT Desligado" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7408,7 +7525,7 @@ msgstr "Licença" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:339 msgid "Life" -msgstr "" +msgstr "Vida" #: Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp:35 #: Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp:53 @@ -7459,7 +7576,7 @@ msgstr "Carregar Texturas Personalizadas" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "Carregar Arquivo" #: Source/Core/DolphinQt/MenuBar.cpp:249 msgid "Load GameCube Main Menu" @@ -7484,7 +7601,7 @@ msgstr "Abrir ROM" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "Carregar Slot" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7644,6 +7761,7 @@ msgstr "IP Local" msgid "Lock Mouse Cursor" msgstr "Travar Cursor do Mouse" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "Trancado" @@ -7675,15 +7793,15 @@ msgstr "Saída de Dados" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "Login" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "Falha no Login" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "Logout" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7733,7 +7851,7 @@ msgstr "Arquivos de GameShark da Mad Catz" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:324 msgid "Magic" -msgstr "" +msgstr "Magia" #: Source/Core/DolphinQt/TAS/GCTASInputWindow.cpp:29 msgid "Main Stick" @@ -8013,24 +8131,25 @@ msgstr "Aviso sobre o NKit" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8449,7 +8568,7 @@ msgstr "&Documentação Online" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "Mostrar Apenas Coleção" #: Source/Core/DolphinQt/MenuBar.cpp:1615 msgid "" @@ -8591,9 +8710,9 @@ msgstr "&Reproduzir Gravação de Replay..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8845,6 +8964,8 @@ msgid "" "Please change the \"SyncOnSkipIdle\" setting to \"True\"! It's currently " "disabled, which makes this problem very likely to happen." msgstr "" +"Por favor altere a configuração \"SyncOnSkipIdle\" para \"True\"! Ela está " +"desativada no momento, o que torna esse problema muito provável de acontecer." #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:164 msgid "" @@ -8875,7 +8996,7 @@ msgstr "Porta:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "Slots do Portal" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -9016,6 +9137,7 @@ msgstr "Perfil" msgid "Program Counter" msgstr "Contador do Programa" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9538,7 +9660,7 @@ msgstr "Cartão SD" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:266 msgid "SD Card File Size:" -msgstr "" +msgstr "Tamanho do Cartão SD:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:506 msgid "SD Card Image (*.raw);;All Files (*)" @@ -9546,7 +9668,7 @@ msgstr "Imagem do Cartão SD (*.raw);;Todos os arquivos (*)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:233 msgid "SD Card Path:" -msgstr "Cartão SD:" +msgstr "Local do Cartão SD:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:213 msgid "SD Card Settings" @@ -9560,12 +9682,8 @@ msgstr "Raiz do SD:" msgid "SD Sync Folder:" msgstr "Pasta de Sincronização do SD:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9854,7 +9972,7 @@ msgstr "Procurar instrução" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "Pesquisar:" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9925,7 +10043,7 @@ msgstr "Selecione o arquivo XML do Riivolution" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:410 msgid "Select Skylander Collection" -msgstr "" +msgstr "Selecione a Correção do Skylander" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:481 msgid "Select Skylander File" @@ -10258,7 +10376,7 @@ msgstr "" "Configura a busca usando mapeamentos MEM1 e MEM2 padrão (no Wii) no espaço " "do endereço virtual. Isto funcionará para a vasta maioria dos jogos." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10319,10 +10437,6 @@ msgstr "Austrália" msgid "Show Current Game on Discord" msgstr "Mostrar Jogo em Execução no Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Mostrar Interface de Depuração" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10367,7 +10481,7 @@ msgstr "Mostrar Sobreposição do Modo Golfe" #: Source/Core/Core/HotkeyManager.cpp:199 msgid "Show Infinity Base" -msgstr "" +msgstr "Mostrar Base Infinity" #: Source/Core/DolphinQt/MenuBar.cpp:791 msgid "Show Input Display" @@ -10444,7 +10558,7 @@ msgstr "Rússia" #: Source/Core/Core/HotkeyManager.cpp:198 msgid "Show Skylanders Portal" -msgstr "" +msgstr "Mostrar Portal Skylanders" #: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Spain" @@ -10729,15 +10843,15 @@ msgstr "Skylander %1" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:482 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:551 msgid "Skylander (*.sky);;All Files (*)" -msgstr "" +msgstr "Skylander (*.sky);;Todos os arquivos (*)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:217 msgid "Skylander Collection Path:" -msgstr "" +msgstr "Local da Coleção Skylander:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:448 msgid "Skylander not found in this collection. Create new file?" -msgstr "" +msgstr "Skylander não encontrado na coleção. Criar novo arquivo?" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:42 msgid "Skylanders Manager" @@ -10745,7 +10859,7 @@ msgstr "Gerenciador de Skylanders" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:81 msgid "Skylanders folder not found for this user. Create new folder?" -msgstr "" +msgstr "Pasta de coleção Skylander não encontrada. Criar nova pasta?" #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:97 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:140 @@ -10872,7 +10986,7 @@ msgstr "Velocidade" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "Spyro's Adventure" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -11154,7 +11268,7 @@ msgstr "Software removido da NAND com sucesso." #. all countries they were released in. They were not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:277 msgid "SuperChargers" -msgstr "" +msgstr "SuperChargers" #: Source/Core/DolphinQt/AboutDialog.cpp:69 msgid "Support" @@ -11185,7 +11299,7 @@ msgstr "Inverter Olhos" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:270 msgid "Swap Force" -msgstr "" +msgstr "Swap Force" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:500 msgid "" @@ -11346,7 +11460,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:330 msgid "Tech" -msgstr "" +msgstr "Tecno" #: Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp:244 msgid "Test" @@ -11385,6 +11499,15 @@ msgstr "" "A versão mínima do carregador do DFF ({0}) excede a versão deste FIFO Player " "({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "A tabela de hash H3 para a partição {0} não está correta." @@ -11935,12 +12058,18 @@ msgid "" "CPU, but your current settings make this unlikely to happen. If this error " "is stopping the game from working, please report it to the developers." msgstr "" +"Esse erro normalmente é causado quando a GPU emulada perde sincronia com a " +"CPU emulada, mas suas configurações atuais evitam que esse problema " +"aconteça. Se esse erro estiver impedindo que o jogo funcione, por favor " +"relate esse problema para os desenvolvedores do Dolphin." #: Source/Core/VideoCommon/CommandProcessor.cpp:724 msgid "" "This error is usually caused by the emulated GPU desyncing with the emulated " "CPU. Turn off the \"Dual Core\" setting to avoid this." msgstr "" +"Esse erro normalmente é causado quando a GPU emulada perde sincronia com a " +"CPU emulada. Desative a configuração \"Dual Core\" para evitar esse problema." #: Source/Core/DiscIO/NANDImporter.cpp:116 msgid "This file does not contain a valid Wii filesystem." @@ -12281,7 +12410,7 @@ msgstr "Chinês Tradicional" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:273 msgid "Trap Team" -msgstr "" +msgstr "Trap Team" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:991 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:995 @@ -12342,15 +12471,15 @@ msgstr "USA" #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "Emulação de Dispositivo USB" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "Emulação USB" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "Emulação de Dispositivos USB" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -12468,7 +12597,7 @@ msgstr "Imagens do GC/Wii sem compressão (*.iso *.gcm)" #. https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:346 msgid "Undead" -msgstr "" +msgstr "Morto-Vivo" #: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Undo Load State" @@ -12599,6 +12728,22 @@ msgstr "Fechar ROM" msgid "Unlock Cursor" msgstr "Destravar Cursor" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Descomprimindo" @@ -12836,7 +12981,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "Nome do Usuário" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -13262,7 +13407,7 @@ msgstr "Observar" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:327 msgid "Water" -msgstr "" +msgstr "Água" #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Website" @@ -13795,6 +13940,10 @@ msgstr "ou selecione um dispositivo da lista" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "este valor:" diff --git a/Languages/po/ro.po b/Languages/po/ro.po index e84991ae63..508cba5f50 100644 --- a/Languages/po/ro.po +++ b/Languages/po/ro.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Arian - Cazare Muncitori , 2014\n" "Language-Team: Romanian (http://app.transifex.com/delroth/dolphin-emu/" @@ -168,6 +168,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -185,6 +195,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1090,7 +1105,7 @@ msgstr "" msgid "Accuracy:" msgstr "Precizie:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2339,7 +2354,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2347,7 +2362,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2632,6 +2647,14 @@ msgstr "" msgid "Controllers" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2735,19 +2758,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2807,11 +2830,11 @@ msgstr "" msgid "Core" msgstr "Nucleu" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3026,6 +3049,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3339,16 +3366,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3915,6 +3932,10 @@ msgstr "Activare Trucuri" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Activare Nucleu Dublu" @@ -4626,7 +4647,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5575,8 +5596,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5591,10 +5612,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5697,7 +5722,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5831,14 +5856,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6590,7 +6619,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7013,6 +7042,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7350,7 +7380,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7358,16 +7388,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7903,7 +7934,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8308,6 +8339,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8832,12 +8864,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9483,7 +9511,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9544,10 +9572,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10532,6 +10556,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11579,6 +11612,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12587,6 +12636,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/ru.po b/Languages/po/ru.po index 990c6dc136..e4d8a0e1dc 100644 --- a/Languages/po/ru.po +++ b/Languages/po/ru.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Sukharev Andrey , 2015-2022\n" "Language-Team: Russian (http://app.transifex.com/delroth/dolphin-emu/" @@ -193,6 +193,16 @@ msgstr "%1 присоединился" msgid "%1 has left" msgstr "%1 вышел" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 — не корректный образ игры" @@ -210,6 +220,11 @@ msgstr "%1 байт памяти" msgid "%1 ms" msgstr "%1 мс" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "Найдено сессий: %1" @@ -1138,7 +1153,7 @@ msgstr "" msgid "Accuracy:" msgstr "Точность:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2464,7 +2479,7 @@ msgstr "Код:" msgid "Codes received!" msgstr "Коды получены!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2472,7 +2487,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2757,6 +2772,14 @@ msgstr "Настройки управления" msgid "Controllers" msgstr "Управление" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2882,19 +2905,19 @@ msgstr "" "Идёт конвертация...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2954,11 +2977,11 @@ msgstr "Скопировать на B" msgid "Core" msgstr "Ядро" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3209,6 +3232,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Свои настройки времени" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3534,23 +3561,6 @@ msgstr "Прямое подключение" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Для отрисовки при помощи Direct3D 11 требуются функции, не поддерживаемые " -"конфигурацией вашей системы. Скорее всего, это связано с тем, что вы " -"используете Windows 7. Вы всё ещё можете использовать этот бэкенд, но можете " -"столкнуться с графическими артефактами.\n" -"\n" -"Вы действительно хотите переключиться на Direct3D 11? Если не уверены – " -"выберите \"Нет\"." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -4161,6 +4171,10 @@ msgstr "Включить чит-коды" msgid "Enable Custom RTC" msgstr "Включить переопределение времени" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Включить двухядерный режим" @@ -4918,7 +4932,7 @@ msgstr "Не удалось подключиться к Redump.org" msgid "Failed to connect to server: %1" msgstr "Не удалось подключиться к серверу: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Не удалось создать D3D swap chain" @@ -5946,8 +5960,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5962,10 +5976,14 @@ msgstr "Информация об игре" msgid "Game Folders" msgstr "Папки с играми" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -6070,7 +6088,7 @@ msgstr "Микрофон GameCube − Слот %1" msgid "GameCube TAS Input %1" msgstr "Ввод GameCube TAS %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -6210,14 +6228,18 @@ msgstr "Гироскоп" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -7032,7 +7054,7 @@ msgstr "Отключить кэш регистров JIT" msgid "JIT SystemRegisters Off" msgstr "Отключить JIT SystemRegisters" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7467,6 +7489,7 @@ msgstr "Локальный адрес" msgid "Lock Mouse Cursor" msgstr "Захватывать курсор мыши" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7829,7 +7852,7 @@ msgstr "Предупреждение NKit" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7837,16 +7860,17 @@ msgstr "" msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8398,7 +8422,7 @@ msgstr "&Проиграть записанный ввод..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8818,6 +8842,7 @@ msgstr "Профиль" msgid "Program Counter" msgstr "Счётчик команд" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9357,12 +9382,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -10050,7 +10071,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10111,10 +10132,6 @@ msgstr "Австралия" msgid "Show Current Game on Discord" msgstr "Показывать текущую игру в Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Показывать интерфейс отладки" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -11140,6 +11157,15 @@ msgstr "" "Минимальная версия загрузчика DFF ({0}) выше, чем версия текущего плеера " "FIFO ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "Хэш-таблица H3 для раздела {0} некорректна." @@ -12307,6 +12333,22 @@ msgstr "Выгрузить образ игры" msgid "Unlock Cursor" msgstr "Разблок. курсор" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Распаковка" @@ -13419,6 +13461,10 @@ msgstr "или выберите устройство" msgid "s" msgstr "с" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "это значение:" diff --git a/Languages/po/sr.po b/Languages/po/sr.po index 1f277be255..3fb4debbf8 100644 --- a/Languages/po/sr.po +++ b/Languages/po/sr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: nikolassj, 2011\n" "Language-Team: Serbian (http://app.transifex.com/delroth/dolphin-emu/" @@ -168,6 +168,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -185,6 +195,11 @@ msgstr "" msgid "%1 ms" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1090,7 +1105,7 @@ msgstr "" msgid "Accuracy:" msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2339,7 +2354,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2347,7 +2362,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2632,6 +2647,14 @@ msgstr "" msgid "Controllers" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2735,19 +2758,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2807,11 +2830,11 @@ msgstr "" msgid "Core" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3026,6 +3049,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3339,16 +3366,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3915,6 +3932,10 @@ msgstr "" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "" @@ -4622,7 +4643,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5571,8 +5592,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5587,10 +5608,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5693,7 +5718,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5827,14 +5852,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6584,7 +6613,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7004,6 +7033,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7341,7 +7371,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7349,16 +7379,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7894,7 +7925,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8299,6 +8330,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8823,12 +8855,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9474,7 +9502,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9535,10 +9563,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10523,6 +10547,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11566,6 +11599,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12574,6 +12623,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/sv.po b/Languages/po/sv.po index c1250879e3..3fecd9bf70 100644 --- a/Languages/po/sv.po +++ b/Languages/po/sv.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: JosJuice, 2015-2023\n" "Language-Team: Swedish (http://app.transifex.com/delroth/dolphin-emu/" @@ -190,6 +190,16 @@ msgstr "%1 har gått med" msgid "%1 has left" msgstr "%1 har gått ut" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 är inte en giltig ROM" @@ -207,6 +217,11 @@ msgstr "%1 minnesintervall" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 session hittades" @@ -265,7 +280,7 @@ msgstr "%1[%2]: %3/%4 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "%1x MSAA" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -274,7 +289,7 @@ msgstr "%1x ursprunglig (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "%1x SSAA" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -738,7 +753,7 @@ msgstr "--> %1" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:215 msgid "--Unknown--" -msgstr "" +msgstr "--Okänd--" #: Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp:298 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:714 @@ -1142,7 +1157,7 @@ msgstr "Accelerometerpåverkan" msgid "Accuracy:" msgstr "Precision:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -1438,7 +1453,7 @@ msgstr "Afrika" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:342 msgid "Air" -msgstr "" +msgstr "Luft" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:116 msgid "Aligned to data type length" @@ -1446,7 +1461,7 @@ msgstr "Justerat till datatypens längd" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "Alla" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -2366,7 +2381,7 @@ msgstr "Kina" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "Välj" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2471,7 +2486,7 @@ msgstr "Kod:" msgid "Codes received!" msgstr "Koder mottagna!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2479,7 +2494,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2764,6 +2779,14 @@ msgstr "Kontrollinställningar" msgid "Controllers" msgstr "Kontroller" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2890,19 +2913,19 @@ msgstr "" "Konverterar...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2962,11 +2985,11 @@ msgstr "Kopiera till B" msgid "Core" msgstr "Kärna" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3220,6 +3243,10 @@ msgstr "Anpassat adressutrymme" msgid "Custom RTC Options" msgstr "Alternativ för egen realtidsklocka" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3543,22 +3570,6 @@ msgstr "Direkt anslutning" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Direct3D 11-renderaren kräver stöd för funktioner som inte stöds av din " -"systemkonfiguration. Detta är antagligen på grund av att du använder Windows " -"7. Du kan använda Direct3D 11-renderaren ändå, men det kan uppstå grafiska " -"problem.\n" -"\n" -"Vill du verkligen byta till Direct3D 11? Om du är osäker, välj 'Nej'." - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "&Frånkopplad" @@ -4037,7 +4048,7 @@ msgstr "Tidiga minnesuppdateringar" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:336 msgid "Earth" -msgstr "" +msgstr "Jord" #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "East Asia" @@ -4084,7 +4095,7 @@ msgstr "Mata ut skiva" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "Element" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4100,7 +4111,7 @@ msgstr "Emuleringstråd körs redan" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:91 msgid "Emulate Disc Speed" -msgstr "" +msgstr "Emulera skivhastighet" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:60 msgid "Emulate Infinity Base" @@ -4176,6 +4187,10 @@ msgstr "Aktivera fusk" msgid "Enable Custom RTC" msgstr "Aktivera egen realtidsklocka" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Aktivera dubbla kärnor" @@ -4930,7 +4945,7 @@ msgstr "Misslyckades att ansluta till Redump.org" msgid "Failed to connect to server: %1" msgstr "Misslyckades att ansluta till server: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "Misslyckades att skapa D3D-swapchain" @@ -5497,7 +5512,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:333 msgid "Fire" -msgstr "" +msgstr "Eld" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:40 msgid "First Person" @@ -5958,8 +5973,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "Game Boy Advance i uttag %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5974,10 +5989,14 @@ msgstr "Speldetaljer" msgid "Game Folders" msgstr "Spelmappar" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -6084,7 +6103,7 @@ msgstr "GameCube-mikrofon i plats %1" msgid "GameCube TAS Input %1" msgstr "GameCube-TAS-inmatning %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -6150,7 +6169,7 @@ msgstr "GiB" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:267 msgid "Giants" -msgstr "" +msgstr "Giants" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:195 msgid "Golf Mode" @@ -6223,14 +6242,18 @@ msgstr "Gyroskop" msgid "HDMI 3D" msgstr "HDMI-3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -7058,7 +7081,7 @@ msgstr "JIT Register Cache av" msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters av" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7261,7 +7284,7 @@ msgstr "Licens" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:339 msgid "Life" -msgstr "" +msgstr "Liv" #: Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp:35 #: Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp:53 @@ -7496,6 +7519,7 @@ msgstr "Lokalt" msgid "Lock Mouse Cursor" msgstr "Lås muspekare" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "Låst" @@ -7585,7 +7609,7 @@ msgstr "MadCatz Gameshark-filer" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:324 msgid "Magic" -msgstr "" +msgstr "Magi" #: Source/Core/DolphinQt/TAS/GCTASInputWindow.cpp:29 msgid "Main Stick" @@ -7860,7 +7884,7 @@ msgstr "NKit-varning" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7868,16 +7892,17 @@ msgstr "" msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8427,9 +8452,9 @@ msgstr "Spe&la upp inspelning..." msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8852,6 +8877,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "Program Counter" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9393,12 +9419,8 @@ msgstr "SD-rot:" msgid "SD Sync Folder:" msgstr "SD-synkmapp:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -10087,7 +10109,7 @@ msgstr "" "mappningarna i virtuellt adressutrymme. Detta fungerar för de allra flesta " "spel." -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -10148,10 +10170,6 @@ msgstr "Visa Australien" msgid "Show Current Game on Discord" msgstr "Visa nuvarande spel på Discord" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "Visa felsökningsgränssnitt" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10680,7 +10698,7 @@ msgstr "Hastighet" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "Spyro's Adventure" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -10962,7 +10980,7 @@ msgstr "Titeln har tagits bort från NAND-minnet." #. all countries they were released in. They were not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:277 msgid "SuperChargers" -msgstr "" +msgstr "SuperChargers" #: Source/Core/DolphinQt/AboutDialog.cpp:69 msgid "Support" @@ -10993,7 +11011,7 @@ msgstr "Byt plats på ögon" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:270 msgid "Swap Force" -msgstr "" +msgstr "Swap Force" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:500 msgid "" @@ -11148,7 +11166,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:330 msgid "Tech" -msgstr "" +msgstr "Teknologi" #: Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp:244 msgid "Test" @@ -11187,6 +11205,15 @@ msgstr "" "DFF-filens minsta tillåtna läsarversion ({0}) är större än den här FIFO-" "spelarens version ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "H3-hashtabellen för {0}-partitionen är inte korrekt." @@ -12062,7 +12089,7 @@ msgstr "Traditionell kinesiska" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:273 msgid "Trap Team" -msgstr "" +msgstr "Trap Team" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:991 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:995 @@ -12247,7 +12274,7 @@ msgstr "Okomprimerade GC/Wii-skivavbildningar (*.iso *.gcm)" #. https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:346 msgid "Undead" -msgstr "" +msgstr "Odöd" #: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Undo Load State" @@ -12380,6 +12407,22 @@ msgstr "Ladda ur ROM" msgid "Unlock Cursor" msgstr "Lås upp muspekare" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Packar upp" @@ -13009,7 +13052,7 @@ msgstr "Bevakning" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:327 msgid "Water" -msgstr "" +msgstr "Vatten" #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Website" @@ -13531,6 +13574,10 @@ msgstr "eller välj en enhet" msgid "s" msgstr "s" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "följande värde:" diff --git a/Languages/po/tr.po b/Languages/po/tr.po index e9380534ad..f232946a63 100644 --- a/Languages/po/tr.po +++ b/Languages/po/tr.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: i286, 2022\n" "Language-Team: Turkish (http://app.transifex.com/delroth/dolphin-emu/" @@ -182,6 +182,16 @@ msgstr "%1 katıldı" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 geçerli bir ROM değil" @@ -199,6 +209,11 @@ msgstr "" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "%1 oturum bulundu" @@ -1116,7 +1131,7 @@ msgstr "" msgid "Accuracy:" msgstr "Doğruluk:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2368,7 +2383,7 @@ msgstr "Code:" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2376,7 +2391,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2663,6 +2678,14 @@ msgstr "" msgid "Controllers" msgstr "Denetleyiciler" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2766,19 +2789,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2838,11 +2861,11 @@ msgstr "" msgid "Core" msgstr "Çekirdek" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3065,6 +3088,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "Özel RTC Seçenekleri" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3378,16 +3405,6 @@ msgstr "Doğrudan Bağlantı" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3956,6 +3973,10 @@ msgstr "Hilelere İzin Ver" msgid "Enable Custom RTC" msgstr "Özel RTC'yi Etkinleştir" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "Çift Çekirdeğe İzin Ver" @@ -4669,7 +4690,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5618,8 +5639,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5634,10 +5655,14 @@ msgstr "Oyun Ayrıntıları" msgid "Game Folders" msgstr "Oyun Klasörleri" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5740,7 +5765,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5874,14 +5899,18 @@ msgstr "" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6631,7 +6660,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7054,6 +7083,7 @@ msgstr "Yerel" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7391,7 +7421,7 @@ msgstr "" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7399,16 +7429,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7944,7 +7975,7 @@ msgstr "" msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8351,6 +8382,7 @@ msgstr "Profil" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8875,12 +8907,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9531,7 +9559,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9592,10 +9620,6 @@ msgstr "Avusturalya'yı Göster" msgid "Show Current Game on Discord" msgstr "Discord'da Mevcut Oyunu Göster" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10582,6 +10606,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11640,6 +11673,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "Açma" @@ -12655,6 +12704,10 @@ msgstr "ya da bir aygıt seçin" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" diff --git a/Languages/po/zh_CN.po b/Languages/po/zh_CN.po index 887ed2eec6..f5e6a27aaf 100644 --- a/Languages/po/zh_CN.po +++ b/Languages/po/zh_CN.po @@ -21,9 +21,9 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" -"Last-Translator: 陈 依云 , 2023\n" +"Last-Translator: 天绝星 , 2015-2023\n" "Language-Team: Chinese (China) (http://app.transifex.com/delroth/dolphin-emu/" "language/zh_CN/)\n" "Language: zh_CN\n" @@ -196,6 +196,16 @@ msgstr "%1 已加入" msgid "%1 has left" msgstr "%1 已离开" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "%1 不是有效的 ROM" @@ -213,6 +223,11 @@ msgstr "%1 内存范围" msgid "%1 ms" msgstr "%1 毫秒" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "已找到 %1 个会话" @@ -271,7 +286,7 @@ msgstr "%1[%2]: %3/%4 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:286 #, c-format msgid "%1x MSAA" -msgstr "" +msgstr "%1x MSAA" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:78 msgid "%1x Native (%2x%3)" @@ -280,7 +295,7 @@ msgstr "%1x 原生 (%2x%3)" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:298 #, c-format msgid "%1x SSAA" -msgstr "" +msgstr "%1x SSAA" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:315 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:333 @@ -644,7 +659,7 @@ msgstr "扫描 e-Reader 卡...(&S)" #: Source/Core/DolphinQt/MenuBar.cpp:229 msgid "&Skylanders Portal" -msgstr "Skylanders 插槽(&S)" +msgstr "Skylanders 传送门(&S)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:175 msgid "&Speed Limit:" @@ -764,7 +779,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 GiB" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -772,7 +787,7 @@ msgstr "128 Mbit (2043 区块)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 MiB" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -780,7 +795,7 @@ msgstr "16 字节" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -814,11 +829,11 @@ msgstr "1x" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 GiB" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 MiB" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -834,7 +849,7 @@ msgstr "2x 原生 (1280x1056) 适合 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -886,7 +901,7 @@ msgstr "4 字节" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -910,7 +925,7 @@ msgstr "4x 原生 (2560x2112) 适合 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -922,7 +937,7 @@ msgstr "64 Mbit (1019 区块)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 MiB" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -953,7 +968,7 @@ msgstr "8 字节" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -995,7 +1010,7 @@ msgstr "<系统语言>" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:406 msgid "If unsure, leave this unchecked." -msgstr "如果不确定,请不要勾选此项。" +msgstr "如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:700 #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:293 @@ -1046,7 +1061,7 @@ msgstr "光盘已可插入。" msgid "" "A group of features to make the colors more accurate, matching the color " "space Wii and GC games were meant for." -msgstr "" +msgstr "一些使颜色更准确的功能,使其与 Wii 和 GC 游戏的色彩空间相匹配。" #: Source/Core/DolphinQt/Main.cpp:226 msgid "A save state cannot be loaded without specifying a game to launch." @@ -1140,10 +1155,10 @@ msgstr "加速度器影响" msgid "Accuracy:" msgstr "精确度:" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" -msgstr "" +msgstr "成就" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1431,7 +1446,7 @@ msgstr "非洲" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:342 msgid "Air" -msgstr "" +msgstr "风" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:116 msgid "Aligned to data type length" @@ -1439,7 +1454,7 @@ msgstr "与数据类型长度对齐" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:320 msgid "All" -msgstr "" +msgstr "全部" #. i18n: A double precision floating point number #: Source/Core/DolphinQt/Debugger/RegisterWidget.cpp:168 @@ -1517,7 +1532,7 @@ msgid "" "Allows manipulation of the in-game camera.

If " "unsure, leave this unchecked." msgstr "" -"允许操纵游戏中的镜头。

如果不确定,请不要勾选此项。" +"允许操纵游戏中的镜头。

如果不确定,请不要选中此项。" "" #: Source/Core/DolphinQt/Config/CommonControllersWidget.cpp:36 @@ -1728,7 +1743,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "自动将窗口大小调整为内部分辨率。

如果不确定,请不要" -"勾选此项。" +"选中此项。
" #. i18n: One of the options shown below "Address Space". "Auxiliary" is the address space of ARAM #. (Auxiliary RAM). @@ -2104,7 +2119,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "在启动时将自定义纹理缓存到系统内存。

这将导致内存需求指数级增加但会修" -"正可能的卡顿。

如果不确定,请不要勾选此项。
如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:107 @@ -2120,7 +2135,7 @@ msgid "" msgstr "" "逐个像素而非逐个顶点地计算 3D 物体的光照,这将使被照明多边形外观更平滑,单个" "三角面更不明显。

很少造成速度降低或图像问题。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Mapping/MappingIndicator.cpp:897 msgid "Calibrate" @@ -2267,8 +2282,8 @@ msgid "" "Changes the color of the FPS counter depending on emulation speed." "

If unsure, leave this checked." msgstr "" -"根据模拟速度改变 FPS 计数器的颜色。

如果不确定,请勾" -"选此项。" +"根据模拟速度改变 FPS 计数器的颜色。

如果不确定,请选" +"中此项。" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:44 msgid "" @@ -2343,7 +2358,7 @@ msgstr "中国" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:220 msgid "Choose" -msgstr "" +msgstr "选择" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:620 msgid "Choose a file to open" @@ -2398,7 +2413,7 @@ msgstr "清除缓存" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:119 msgid "Clear Slot" -msgstr "" +msgstr "清除插槽" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:83 msgid "Clock Override" @@ -2448,17 +2463,17 @@ msgstr "代码:" msgid "Codes received!" msgstr "代码已接收!" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "色彩校正配置" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "色彩校正:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "色彩空间" #: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Combine &Two Signature Files..." @@ -2589,6 +2604,46 @@ msgid "" "possible for them to go out of range or to become NaN. A warning will be " "given if NaN is returned, and the var that became NaN will be logged." msgstr "" +"状况:\n" +"设置命中断点时计算的表达式。如果表达式为 false 或 0,则忽略断点,直到再次命中" +"断点。语句应该用逗号间隔。只有最后一个语句将用于确定要做什么。\n" +"\n" +"可以参考的寄存器:\n" +"GPRs : r0..r31\n" +"FPRs : f0..f31\n" +"LR, CTR, PC\n" +"\n" +"函数:\n" +"设置寄存器:r1 = 8\n" +"转换:s8(0xff). 可用:s8, u8, s16, u16, s32, u32\n" +"调用堆栈:callstack(0x80123456), callstack(\"anim\")\n" +"比较字符串:streq(r3, \"abc\"). 两个参数都可以是地址或字符串常量。\n" +"读取内存:read_u32(0x80000000). 可用:u8, s8, u16, s16, u32, s32, f32, f64\n" +"写入内存:write_u32(r3, 0x80000000). 可用:u8, u16, u32, f32, f64\n" +"*当前写入会一直触发\n" +"\n" +"操作:\n" +"一元:-u, !u, ~u\n" +"数学:* / + -, power: **, remainder: %, shift: <<, >>\n" +"比较:<, <=, >, >=, ==, !=, &&, ||\n" +"按位:&, |, ^\n" +"\n" +"示例:\n" +"r4 == 1\n" +"f0 == 1.0 && f2 < 10.0\n" +"r26 <= r0 && ((r5 + 3) & -4) * ((r6 + 3) & -4)* 4 > r0\n" +"p = r3 + 0x8, p == 0x8003510 && read_u32(p) != 0\n" +"写入并中断:r4 = 8, 1\n" +"写入并继续:f3 = f1 + f2, 0\n" +"条件必须始终是最后一个\n" +"\n" +"字符串只能在 callstack() 或 streq() 中使用并且“引用”。不要将字符串分配给变" +"量。\n" +"如果有命中或 NaN 结果,所有变量都将打印在内存接口日志中。要检查问题,请为方程" +"分配一个变量,以便可以打印显示。\n" +"\n" +"注意:所有值都会在内部转换为双精度数以进行计算。它们有可能超出范围或变为 " +"NaN。如果返回 NaN 将给出警告,并且将变为 NaN 的值记录下来。" #: Source/Core/DolphinQt/ToolBar.cpp:129 msgid "Config" @@ -2745,6 +2800,14 @@ msgstr "控制器设置" msgid "Controllers" msgstr "控制器" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2860,24 +2923,27 @@ msgstr "" "正在转换...\n" "%1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." "

If unsure, leave this unchecked." msgstr "" +"将伽玛值从游戏标准转换为当前 SDR 显示标准。
显示器通常以 sRGB 为标准。电视" +"通常以 2.2 为标准。

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:290 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:704 @@ -2932,13 +2998,13 @@ msgstr "复制到 B" msgid "Core" msgstr "核心" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "校正色彩空间" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" -msgstr "" +msgstr "校正 SDR 伽玛" #. i18n: Performance cost, not monetary cost #: Source/Core/DolphinQt/Debugger/JITWidget.cpp:91 @@ -3089,7 +3155,7 @@ msgstr "创建 Skylander 文件" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:80 msgid "Create Skylander Folder" -msgstr "" +msgstr "创建 Skylander 文件夹" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:109 msgid "Create mappings for other devices" @@ -3109,7 +3175,7 @@ msgid "" msgstr "" "以渲染器的内部分辨率创建帧转储和屏幕截图,而不是其在窗口中显示的大小。" "

如果长宽比是宽屏,输出图像将会水平缩放以保持垂直分辨率。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/CheatCodeEditor.cpp:82 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:109 @@ -3130,7 +3196,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "将图像由原生长宽比裁切为 4:3 或 16:9 。

如果不确定," -"请不要勾选此项。" +"请不要选中此项。
" #: Source/Core/Core/HW/WiimoteEmu/Extension/Turntable.cpp:82 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:175 @@ -3148,7 +3214,7 @@ msgid "" "leave this unchecked.
" msgstr "" "清除 CPU 上的顶点以减少所需的绘制调用数。可能影响性能和绘制统计数据。" -"

如不确定,请不要勾选此项。" +"

如不确定,请不要选中此项。" #: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Current Region" @@ -3178,9 +3244,13 @@ msgstr "自定义地址空间" msgid "Custom RTC Options" msgstr "自定义 RTC 选项" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "自定义" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3383,7 +3453,7 @@ msgid "" msgstr "" "将 EFB 访问缓存失效推迟至 GPU 同步指令执行时。如果禁用,每次绘制调用都将令缓" "存失效。

可能提高一些依靠 CPU EFB 访问游戏的性能,但会牺牲稳定性。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:132 #: Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp:111 @@ -3497,20 +3567,6 @@ msgstr "直接连接" msgid "Direct3D 11" msgstr "Direct3D 11" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" -"Direct3D 11 渲染器需要某些您的系统配置所不支持的特性。这很可能是因为您使用的" -"是 Windows 7 系统。您仍然可以使用此后端,但您可能会遇到图像错误。\n" -"\n" -"你真的想切换到 Direct3D 11 吗?如果不确定,请选择“否”。" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "断开连接(&C)" @@ -3559,7 +3615,7 @@ msgid "" "unsure, leave this checked.
" msgstr "" "禁用边界框模拟。

这可能显著提高 GPU 性能,但是一些游戏可能会停止运行。" -"

如果不确定,请勾选此项。" +"

如果不确定,请选中此项。" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:331 msgid "" @@ -3568,7 +3624,7 @@ msgid "" "dolphin_emphasis>" msgstr "" "禁用 VRAM 中的 EFB 副本,而强制从 RAM 中读取。所有放大将不可用。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:508 msgid "" @@ -3580,7 +3636,7 @@ msgid "" msgstr "" "禁用复制 EFB 时相邻行间的混合。一些游戏称之为“抗闪烁”或“平滑”。

禁用此" "过滤器对性能没有影响,但会使图像更锐利,且很少导致图像问题。" -"

如果不确定,请勾选此项。" +"

如果不确定,请选中此项。" #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:96 msgid "Disc" @@ -3608,7 +3664,7 @@ msgid "" msgstr "" "在 XFB 副本创建后立即将其显示,而不是等待扫描输出。

在一些不将所有 " "XFB 副本用于显示的游戏中会导致图像瑕疵。然而开启此项可以降低延迟。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/Force.cpp:28 msgid "Distance" @@ -3902,7 +3958,7 @@ msgid "" "dolphin_emphasis>" msgstr "" "根据其他标记将解码的游戏纹理转储到 User/Dump/Textures/<game_id>/ 目录" -"中。

如果不确定,请不要勾选此项。" +"中。

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:325 msgid "" @@ -3910,7 +3966,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "将 EFB 副本的内容转储到 User/Dump/Textures/ 目录中。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:328 msgid "" @@ -3918,7 +3974,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "将 XFB 副本的内容转储到 User/Dump/Textures/ 目录中。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:58 msgid "Duration of Turbo Button Press (frames):" @@ -3970,7 +4026,7 @@ msgstr "内存提前更新" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:336 msgid "Earth" -msgstr "" +msgstr "土" #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "East Asia" @@ -4017,7 +4073,7 @@ msgstr "弹出光盘" #. check the Skylanders SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:289 msgid "Element" -msgstr "" +msgstr "元素" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:41 msgid "Embedded Frame Buffer (EFB)" @@ -4041,7 +4097,7 @@ msgstr "模拟 Infinity 底座" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:146 msgid "Emulate Skylander Portal" -msgstr "模拟 Skylander 插槽" +msgstr "模拟 Skylander 传送门" #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:110 msgid "Emulate the Wii's Bluetooth adapter" @@ -4095,7 +4151,7 @@ msgstr "启用 API 验证层" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "启用成就" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4109,6 +4165,10 @@ msgstr "启用金手指" msgid "Enable Custom RTC" msgstr "启用自定义 RTC" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "启用双核心" @@ -4127,7 +4187,7 @@ msgstr "启用模拟内存大小覆盖" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "启用硬核成就" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4139,7 +4199,7 @@ msgstr "启用图形模组" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:62 msgid "Enable Leaderboards" -msgstr "" +msgstr "启用排行榜" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:88 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:66 @@ -4152,11 +4212,11 @@ msgstr "启用逐行扫描" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "启用 RetroAchievements.org 集成" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" -msgstr "" +msgstr "启用详细状态信息" #: Source/Core/DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.cpp:39 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:353 @@ -4173,7 +4233,7 @@ msgstr "启用扬声器" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "启用非官方成就" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4181,7 +4241,7 @@ msgstr "启用使用情况统计报告" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:161 msgid "Enable WiiConnect24 via WiiLink" -msgstr "" +msgstr "通过 WiiLink 启用 WiiConnect24" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:81 msgid "Enable Wireframe" @@ -4196,6 +4256,7 @@ msgid "" "Enable competing in RetroAchievements leaderboards.

Hardcore Mode " "must be enabled to use." msgstr "" +"允许在 RetroAchievements 排行榜中竞争。

必须启用硬核模式才能使用。" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:68 msgid "" @@ -4204,6 +4265,9 @@ msgid "" "website. If this is disabled, the website will only report what game is " "being played.

This has no bearing on Discord rich presence." msgstr "" +"在 RetroAchievements 网站上启用详细的状态展示。

这向网站提供了玩家在游" +"戏中所做操作的详细描述。如果禁用此功能,网站将仅报告正在玩的游戏。

这" +"对 Discord 的详细状态没有影响。" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 msgid "" @@ -4220,6 +4284,9 @@ msgid "" "account to use. Dolphin does not save your password locally and uses an API " "token to maintain login." msgstr "" +"启用集成 RetroAchievements,以获取成就并参与排行榜竞争。

必须使用 " +"RetroAchievements 帐户登录才能使用。Dolphin 不会在本地保存您的密码,而是使用 " +"API 令牌来维持登录。" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:80 msgid "" @@ -4228,10 +4295,13 @@ msgid "" "will be notified if they meet the unlock conditions again, useful for custom " "speedrun criteria or simply for fun." msgstr "" +"在硬核模式中启用解锁成就。

硬核模式会重新启用玩家已在网站上解锁的成" +"就,以便玩家再次满足解锁条件时会收到通知,这对于自定义速通标准很有用或者只是" +"为了好玩。" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" -msgstr "" +msgstr "启用解锁成就。
" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:74 msgid "" @@ -4240,6 +4310,8 @@ msgid "" "that have not been deemed official by RetroAchievements and may be useful " "for testing or simply for fun." msgstr "" +"允许像官方成就一样解锁非官方成就。

非官方成就可能是可选的或未完成的成" +"就,尚未被 RetroAchievements 视为官方成就,可能对测试有用或只是为了好玩。" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:97 msgid "" @@ -4266,7 +4338,7 @@ msgstr "" "启用对非常规多级纹理的检测。一些游戏使用这一技术实现基于距离的特殊效果。" "

可能存在误判而导致高内部分辨率下的纹理模糊,例如在使用很低分辨率的多" "级纹理的游戏中。禁用此功能还可以在频繁加载新纹理的游戏中减少卡顿。此功能与 " -"GPU 纹理解码不兼容。

如果不确定,请勾选此项。
如果不确定,请选中此项。" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:79 @@ -4288,7 +4360,7 @@ msgid "" msgstr "" "在支持的后端中启用多线程指令提交。启用此选项可能会在两个以上 CPU 核心的系统中" "有性能提升。目前仅限于 Vulkan 后端。

如果不确定,请" -"勾选此项。" +"选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:361 msgid "" @@ -4297,7 +4369,7 @@ msgid "" "this unchecked.
" msgstr "" "启用逐行扫描模拟支持该特性的软件。对多数游戏无任何影响。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:522 msgid "" @@ -4308,6 +4380,10 @@ msgid "" "

Note that games still render in SDR internally." "

If unsure, leave this unchecked." msgstr "" +"启用 scRGB HDR 输出(如果您的图形后端和显示器支持)。可能需要全屏。

这" +"为后处理着色器提供了更多的准确性空间,允许“AutoHDR”后处理着色器工作,并允许完" +"全显示 PAL 和 NTSC-J 色彩空间。

请注意,游戏仍然在内部以 SDR 渲染。" +"

如果 不确定,请不要选中此项。" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:151 msgid "Enables stretching of the audio to match emulation speed." @@ -4321,7 +4397,7 @@ msgid "" "
" msgstr "" "启用 GPU 而非 CPU 进行纹理解码。

这将在某些场景下,或 CPU 成为瓶颈的系" -"统中带来性能提升。

如果不确定,请不要勾选此项。
如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 @@ -4338,6 +4414,10 @@ msgid "" "such as the Forecast and Nintendo Channels\n" "Read the Terms of Service at: https://www.wiilink24.com/tos" msgstr "" +"启用 WiiConnect24 频道的 WiiLink 服务。\n" +"WiiLink 是已停服的 WiiConnect24 频道(例如 Forecast 和 Nintendo 频道)的替代" +"提供商\n" +"请阅读服务条款:https://www.wiilink24.com/tos" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:298 msgid "" @@ -4348,7 +4428,7 @@ msgid "" msgstr "" "启用由视频后端调用的 API 验证,这可以帮助调试图形问题。在 Vulkan 和 D3D 后" "端,这也为已编译的着色器启用调试符号。

如果不确定," -"请不要勾选此项。" +"请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:344 msgid "" @@ -4356,7 +4436,7 @@ msgid "" "unsure, leave this unchecked.
" msgstr "" "使用 FFV1 编解码器编码转储的帧。

如果不确定,请不要" -"勾选此项。" +"选中此项。
" #. i18n: Character encoding #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:43 @@ -4849,11 +4929,11 @@ msgstr "申请蓝牙直通接口失败: {0}" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:574 msgid "Failed to clear Skylander!" -msgstr "移除 Skylander 失败!" +msgstr "清除 Skylander 失败!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:575 msgid "Failed to clear the Skylander from slot(%1)!" -msgstr "" +msgstr "清除插槽 (%1) 的 Skylander 失败!" #: Source/Core/DiscIO/VolumeVerifier.cpp:108 msgid "Failed to connect to Redump.org" @@ -4863,7 +4943,7 @@ msgstr "连接 Redump.org 失败" msgid "Failed to connect to server: %1" msgstr "连接服务器失败: %1" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "创建 D3D 交换链失败" @@ -4894,6 +4974,9 @@ msgid "" "%1\n" "(Skylander may already be on the portal)" msgstr "" +"创建 Skylander 文件失败:\n" +"%1\n" +"(此 Skylander 可能已在传送门上)" #: Source/Core/Core/NetPlayClient.cpp:1292 msgid "" @@ -5099,7 +5182,7 @@ msgid "" "File may already be in use on the base." msgstr "" "打开 Infinity 文件 (%1) 失败!\n" -"此文件可能已在使用中。" +"此 Skylander 可能已在传送门上。" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:696 msgid "Failed to open the Skylander file!" @@ -5111,7 +5194,7 @@ msgid "" "File may already be in use on the portal." msgstr "" "打开 Skylander 文件 (%1) 失败!\n" -"此文件可能已在使用中。" +"此 Skylander 可能已在传送门上。" #: Source/Core/DolphinQt/ConvertDialog.cpp:472 msgid "Failed to open the input file \"%1\"." @@ -5418,7 +5501,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:333 msgid "Fire" -msgstr "" +msgstr "火" #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:40 msgid "First Person" @@ -5535,8 +5618,8 @@ msgid "" msgstr "" "强制游戏输出任何比例的图像。配合“强制 16:9”的“长宽比”设置可使仅用于 4:3 比例" "的游戏在 16:9 下运行。

很少能够得到理想的结果并经常会部分破坏图像和游" -"戏界面。如果使用任何 AR/Gecko 宽屏补丁代码则不应勾选此项。" -"

如果不确定,请不要勾选此项。" +"戏界面。如果使用任何 AR/Gecko 宽屏补丁代码则不应选中此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:503 msgid "" @@ -5547,7 +5630,7 @@ msgid "" msgstr "" "强制游戏渲染 24 位的 RGB 颜色通道,从而通过减少渐变色带来提高质量。

对" "性能没有影响,并且几乎没有图形问题。

如果不确定,请" -"勾选此项。" +"选中此项。
" #: Source/Core/DolphinQt/ConvertDialog.cpp:59 msgid "Format:" @@ -5770,6 +5853,11 @@ msgid "" "Further errors will be sent to the Video Backend log and Dolphin will now " "likely crash or hang." msgstr "" +"GFX FIFO: 未知 Opcode ({0:#04x} @ {1}, preprocess={2}).\n" +"\n" +"{3}\n" +"\n" +"更多错误将被发送到视频后端日志,Dolphin 现在可能会崩溃或挂起。" #: Source/Core/VideoBackends/OGL/OGLMain.cpp:181 msgid "GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024." @@ -5875,8 +5963,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "GameBoy Advance 连至端口 %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5891,8 +5979,12 @@ msgstr "游戏详细信息" msgid "Game Folders" msgstr "游戏文件夹" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" +msgstr "游戏伽玛" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 @@ -5999,9 +6091,9 @@ msgstr "GameCube 麦克风插槽 %1" msgid "GameCube TAS Input %1" msgstr "GameCube TAS 输入 %1" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "伽玛" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -6065,7 +6157,7 @@ msgstr "GiB" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:267 msgid "Giants" -msgstr "" +msgstr "巨人" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:195 msgid "Golf Mode" @@ -6104,7 +6196,7 @@ msgid "" msgstr "" "显著提高渲染到纹理效果所生成纹理的质量。

轻微提升 GPU 占用率,较少产生" "图像问题。提高内部分辨率将增强此选项的效果。

如果不" -"确定,请勾选此项。" +"确定,请选中此项。
" #: Source/Core/Core/HW/WiimoteEmu/Extension/Drums.cpp:38 #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:49 @@ -6136,17 +6228,21 @@ msgstr "陀螺仪" msgid "HDMI 3D" msgstr "HDMI 3D" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" -msgstr "" +msgstr "HDR" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" +msgstr "HDR 白色亮度尼特数" + +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" msgstr "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" -msgstr "" +msgstr "HDR 后处理" #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:62 msgid "Hacks" @@ -6448,7 +6544,7 @@ msgid "" msgstr "" "如果启用,则所有内存刷新都会在第一帧之前立即发生。

会导致问题并出现大" "量 fifo 日志,但对测试很有帮助。

如果不确定,请不要" -"勾选此项。" +"选中此项。
" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:208 msgid "" @@ -6457,7 +6553,7 @@ msgid "" "

If unsure, leave this checked." msgstr "" "如果未选中,则 fifo 日志 的回放将在最后一帧后停止。

这通常仅在启用帧转" -"储选项时有用。

如果不确定,请勾选此项。
如果不确定,请选中此项。" #: Source/Core/DolphinQt/DiscordJoinRequestDialog.cpp:55 @@ -6481,7 +6577,7 @@ msgid "" "checked." msgstr "" "忽略 EFB 格式的任何变化。

在许多游戏中会提高性能且无负面作用。但在其余" -"一小部分游戏中也会导致图像瑕疵。

如果不确定,请勾选" +"一小部分游戏中也会导致图像瑕疵。

如果不确定,请选中" "此项。" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:219 @@ -6493,7 +6589,7 @@ msgid "" msgstr "" "忽略 CPU 对 EFB 的任何读写请求。

在一些游戏中可提高性能,但会禁用所有" "基于 EFB 的图形效果或与游戏相关的特性。

如果不确定," -"请不要勾选此项。" +"请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:89 msgid "Immediately Present XFB" @@ -6509,7 +6605,7 @@ msgid "" msgstr "" "使用一个覆盖整个屏幕的无边框窗口来实现全屏模式,而非使用独占模式。开启后在全" "屏模式与窗口模式之间切换会更快,但是输入延迟将略有增加,影响操作流畅性并且性" -"能也会略微降低。

如果不确定,请不要勾选此项。
如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/MenuBar.cpp:266 @@ -6566,7 +6662,7 @@ msgid "" msgstr "" "在即时存档中包含内置帧缓冲 (EFB) 和放大的 EFB 副本内容。可解决读取即时存档时" "纹理与物体缺失或模糊的问题,但会加长存/读档时间。

如" -"果不确定,请勾选此项。" +"果不确定,请选中此项。
" #: Source/Core/Core/FreeLookManager.cpp:98 msgid "Increase" @@ -6954,7 +7050,7 @@ msgstr "关闭 JIT 寄存器缓存" msgid "JIT SystemRegisters Off" msgstr "关闭 JIT 系统寄存器" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7156,7 +7252,7 @@ msgstr "许可" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:339 msgid "Life" -msgstr "" +msgstr "生命" #: Source/Core/Core/HW/WiimoteEmu/Extension/DrawsomeTablet.cpp:35 #: Source/Core/Core/HW/WiimoteEmu/Extension/UDrawTablet.cpp:53 @@ -7207,7 +7303,7 @@ msgstr "加载自定义纹理" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "载入文件" #: Source/Core/DolphinQt/MenuBar.cpp:249 msgid "Load GameCube Main Menu" @@ -7232,7 +7328,7 @@ msgstr "载入 ROM" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "载入插槽" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7372,7 +7468,7 @@ msgid "" msgstr "" "加载 User/Load/Textures/<game_id>/ 和 User/Load/DynamicInputTextures/" "<game_id>/ 目录中的自定义纹理。

如果不确定,请" -"不要勾选此项。" +"不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:335 msgid "" @@ -7380,7 +7476,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "从 User/Load/GraphicsMods/ 加载图形模组。

如果不确" -"定,请不要勾选此项。" +"定,请不要选中此项。
" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:525 msgid "Local" @@ -7390,6 +7486,7 @@ msgstr "本地" msgid "Lock Mouse Cursor" msgstr "锁定鼠标光标" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "已锁定" @@ -7421,15 +7518,15 @@ msgstr "日志输出" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "登录" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "登录失败" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "注销" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7438,7 +7535,7 @@ msgid "" "unsure, leave this unchecked.
" msgstr "" "将每帧的渲染时间记录于 User/Logs/render_time.txt 文件。

启用此功能可衡" -"量 Dolphin 的性能。

如果不确定,请不要勾选此项。
如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:123 @@ -7478,7 +7575,7 @@ msgstr "MadCatz Gameshark 文件" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:324 msgid "Magic" -msgstr "" +msgstr "魔法" #: Source/Core/DolphinQt/TAS/GCTASInputWindow.cpp:29 msgid "Main Stick" @@ -7503,8 +7600,8 @@ msgid "" "unchecked." msgstr "" "通过移除雾提升远处对象的可见性,进而增加整体细节。

有些游戏依赖正确的" -"雾模拟,禁用雾将破坏其游戏性。

如果不确定,请不要勾" -"选此项。" +"雾模拟,禁用雾将破坏其游戏性。

如果不确定,请不要选" +"中此项。" #: Source/Core/DolphinQt/MenuBar.cpp:265 msgid "Manage NAND" @@ -7654,7 +7751,7 @@ msgid "" "unchecked.
" msgstr "" "修改纹理以显示以其编码格式。

可能需要重置模拟才能生效。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/MenuBar.cpp:1290 #: Source/Core/DolphinQt/MenuBar.cpp:1439 @@ -7744,24 +7841,25 @@ msgstr "NKit 警告" msgid "NTSC-J" msgstr "NTSC-J" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" msgstr "NTSC-K" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -8169,7 +8267,7 @@ msgstr "在线文档(&D)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "只显示合集" #: Source/Core/DolphinQt/MenuBar.cpp:1615 msgid "" @@ -8311,9 +8409,9 @@ msgstr "播放录制...(&L)" msgid "PAL" msgstr "PAL" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" -msgstr "" +msgstr "PAL (EBU)" #. i18n: PCAP is a file format #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:425 @@ -8564,6 +8662,7 @@ msgid "" "Please change the \"SyncOnSkipIdle\" setting to \"True\"! It's currently " "disabled, which makes this problem very likely to happen." msgstr "" +"请将“SyncOnSkipIdle”设置更改为“True”!当前已被禁用,使得很可能发生这个问题。" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:164 msgid "" @@ -8592,7 +8691,7 @@ msgstr "端口 :" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "传送门插槽" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -8724,6 +8823,7 @@ msgstr "预设" msgid "Program Counter" msgstr "程序计数器" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -9030,7 +9130,7 @@ msgid "" "Renders the scene as a wireframe.

If unsure, leave " "this unchecked." msgstr "" -"将场景以线框样式渲染。

如果不确定,请不要勾选此项。" +"将场景以线框样式渲染。

如果不确定,请不要选中此项。" "" #: Source/Core/Core/HW/GCMemcard/GCMemcardDirectory.cpp:408 @@ -9198,7 +9298,7 @@ msgid "" msgstr "" "将 2D 顶点舍入为整数像素并将视口大小舍入为整数。

修正部分游戏在较高内" "部分辨率下的图像问题。该选项在使用原生内部分辨率时没有效果。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/Core/HW/GCPadEmu.h:59 #: Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp:283 @@ -9237,7 +9337,7 @@ msgstr "SD 卡" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:266 msgid "SD Card File Size:" -msgstr "" +msgstr "SD 卡文件大小:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:506 msgid "SD Card Image (*.raw);;All Files (*)" @@ -9259,12 +9359,8 @@ msgstr "SD 根目录:" msgid "SD Sync Folder:" msgstr "SD 同步文件夹:" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9548,7 +9644,7 @@ msgstr "搜索指令" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "搜索:" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9617,7 +9713,7 @@ msgstr "选择 Riivolutione XML 文件" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:410 msgid "Select Skylander Collection" -msgstr "" +msgstr "选择 Skylander 合集" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:481 msgid "Select Skylander File" @@ -9936,7 +10032,7 @@ msgstr "" "设置搜索在虚拟地址空间中使用标准内存 1 和(在 Wii 上)内存 2 映射。这将适用于" "绝大多数游戏。" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9997,10 +10093,6 @@ msgstr "显示澳大利亚" msgid "Show Current Game on Discord" msgstr "在 Discord 软件中显示当前游戏" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "显示调试界面" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10045,7 +10137,7 @@ msgstr "叠加显示高尔夫模式" #: Source/Core/Core/HotkeyManager.cpp:199 msgid "Show Infinity Base" -msgstr "" +msgstr "显示 Infinity 底座" #: Source/Core/DolphinQt/MenuBar.cpp:791 msgid "Show Input Display" @@ -10122,7 +10214,7 @@ msgstr "显示俄罗斯" #: Source/Core/Core/HotkeyManager.cpp:198 msgid "Show Skylanders Portal" -msgstr "" +msgstr "显示 Skylanders 传送门" #: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Spain" @@ -10207,7 +10299,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "在联机游戏时显示聊天消息、缓冲变化和未同步警告。

如" -"果不确定,请不要勾选此项。" +"果不确定,请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:266 msgid "" @@ -10216,7 +10308,7 @@ msgid "" "dolphin_emphasis>" msgstr "" "显示帧时间图以及统计数据来展现模拟性能。

如果不确" -"定,请不要勾选此项。" +"定,请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:270 #, c-format @@ -10225,7 +10317,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "显示与全速相对的百分比模拟速度。

如果不确定,请不要" -"勾选此项。" +"选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:254 msgid "" @@ -10234,7 +10326,7 @@ msgid "" "unchecked.
" msgstr "" "以毫秒显示每个不同渲染帧与标准差之间的平均时间。

如" -"果不确定,请不要勾选此项。" +"果不确定,请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:262 msgid "" @@ -10243,7 +10335,7 @@ msgid "" "
" msgstr "" "以毫秒显示每个渲染帧与标准差之间的平均时间。

如果不" -"确定,请不要勾选此项。" +"确定,请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:250 msgid "" @@ -10252,7 +10344,7 @@ msgid "" "
" msgstr "" "显示每秒呈现的不同帧数以衡量视觉平滑度。

如果不确" -"定,请不要勾选此项。" +"定,请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:258 msgid "" @@ -10261,7 +10353,7 @@ msgid "" "dolphin_emphasis>" msgstr "" "显示每秒渲染的帧数以衡量模拟速度。

如果不确定,请不" -"要勾选此项。" +"要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp:220 msgid "" @@ -10269,14 +10361,14 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "在联机游戏时显示玩家的最大延迟。

如果不确定,请不要" -"勾选此项。" +"选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:291 msgid "" "Shows various rendering statistics.

If unsure, " "leave this unchecked." msgstr "" -"显示各种渲染统计数据。

如果不确定,请不要勾选此项。" +"显示各种渲染统计数据。

如果不确定,请不要选中此项。" "" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:167 @@ -10372,7 +10464,7 @@ msgid "" msgstr "" "检测到延迟时跳过垂直消隐中断,从而在模拟速度不是 100% 时平滑地播放音频。" "

警告:可能导致卡死和兼容性问题。

如果不确定,请不要勾选此项。

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:258 @@ -10385,7 +10477,7 @@ msgid "" msgstr "" "在 25fps/30fps 游戏中跳过重复帧(XFB 副本)的显示。这可以提高低端设备的性能," "同时会降低帧定步的一致性。

可禁用此选项并启用 “垂直同步” 来获得最佳" -"的帧定步。

如果不确定,请勾选此项。
如果不确定,请选中此项。" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:177 @@ -10395,15 +10487,15 @@ msgstr "Skylander %1" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:482 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:551 msgid "Skylander (*.sky);;All Files (*)" -msgstr "" +msgstr "Skylander (*.sky);;所有文件 (*)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:217 msgid "Skylander Collection Path:" -msgstr "" +msgstr "Skylander 合集路径:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:448 msgid "Skylander not found in this collection. Create new file?" -msgstr "" +msgstr "在此合集中未找到 Skylander。是否创建新文件?" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:42 msgid "Skylanders Manager" @@ -10411,7 +10503,7 @@ msgstr "Skylander 管理器" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:81 msgid "Skylanders folder not found for this user. Create new folder?" -msgstr "" +msgstr "未找到该用户的 Skylanders 文件夹。是否创建新文件夹?" #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:97 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:140 @@ -10532,7 +10624,7 @@ msgstr "速度" #. countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:264 msgid "Spyro's Adventure" -msgstr "" +msgstr "小龙斯派罗的大冒险" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:186 msgid "Stack end" @@ -10707,7 +10799,7 @@ msgid "" msgstr "" "绕过系统内存而仅在 GPU 中存储 EFB 副本。会在少数游戏中导致图形缺陷。

" "开启 = EFB 副本为纹理
关闭 = EFB 副本为内存(和纹理)" -"

如果不确定,请勾选此项。" +"

如果不确定,请选中此项。" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:248 msgid "" @@ -10719,7 +10811,7 @@ msgid "" msgstr "" "绕过系统内存而仅在 GPU 中存储 XFB 副本。会在少数游戏中导致图形缺陷。

" "开启 = XFB 副本为纹理
关闭 = XFB 副本为内存(和纹理)" -"

如果不确定,请勾选此项。" +"

如果不确定,请选中此项。" #: Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp:57 msgid "Stretch to Window" @@ -10810,7 +10902,7 @@ msgstr "成功将此软件从 NAND 中移除。" #. all countries they were released in. They were not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:277 msgid "SuperChargers" -msgstr "" +msgstr "超级充能者" #: Source/Core/DolphinQt/AboutDialog.cpp:69 msgid "Support" @@ -10841,7 +10933,7 @@ msgstr "交换双眼" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:270 msgid "Swap Force" -msgstr "" +msgstr "交换力量" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:500 msgid "" @@ -10849,7 +10941,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" "交换左右眼图像。通常用于左右并排立体模式。

如果不确" -"定,请不要勾选此项。" +"定,请不要选中此项。
" #: Source/Core/Core/HW/WiimoteEmu/Extension/Nunchuk.cpp:58 #: Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp:230 @@ -10998,7 +11090,7 @@ msgstr "" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:330 msgid "Tech" -msgstr "" +msgstr "科技" #: Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp:244 msgid "Test" @@ -11035,6 +11127,15 @@ msgid "" "Player ({1})" msgstr "DFF 的最低加载程序版本 ({0}) 超过此 FIFO 播放器的版本 ({1})" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "分区 {0} 的 H3 哈希表不正确。" @@ -11538,12 +11639,16 @@ msgid "" "CPU, but your current settings make this unlikely to happen. If this error " "is stopping the game from working, please report it to the developers." msgstr "" +"此错误通常是由模拟 GPU 与模拟 CPU 不同步引起的,但您当前的设置使这种情况不太" +"可能发生。如果此错误导致游戏无法运行,请向开发人员报告。" #: Source/Core/VideoCommon/CommandProcessor.cpp:724 msgid "" "This error is usually caused by the emulated GPU desyncing with the emulated " "CPU. Turn off the \"Dual Core\" setting to avoid this." msgstr "" +"此错误通常是由于模拟 GPU 与模拟 CPU 不同步引起的。关闭“双核”设置以避免这种情" +"况。" #: Source/Core/DiscIO/NANDImporter.cpp:116 msgid "This file does not contain a valid Wii filesystem." @@ -11606,7 +11711,7 @@ msgid "" msgstr "" "该设定可以让你设置一个与当前系统时间隔离的自定义实时时钟(RTC)。\n" "\n" -"如果不确定,请不要勾选此项。" +"如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/AboutDialog.cpp:66 msgid "This software should not be used to play games you do not legally own." @@ -11864,7 +11969,7 @@ msgstr "繁体中文" #. it was released in. It was not released in Japan. #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:273 msgid "Trap Team" -msgstr "" +msgstr "诱捕小队" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:991 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:995 @@ -11923,15 +12028,15 @@ msgstr "美国" #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "USB 设备模拟" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "USB 模拟" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "USB 模拟设备" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -12042,7 +12147,7 @@ msgstr "未压缩的 GC/Wii 镜像 (*.iso *.gcm)" #. https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:346 msgid "Undead" -msgstr "" +msgstr "亡灵" #: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Undo Load State" @@ -12168,6 +12273,22 @@ msgstr "卸载 ROM" msgid "Unlock Cursor" msgstr "解锁光标" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "正在解包" @@ -12309,7 +12430,7 @@ msgstr "" "样将允许在特殊情况下正确模拟纹理打包(在 1x 内部分辨率或禁用缩放 EFB 时,并禁" "用自定义纹理)并更好地模拟细节级别计算。

代价是性能消耗可能会更大,尤" "其是在更高的内部分辨率下;此外,各向异性过滤目前与手动纹理采样不兼容。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 msgid "Use a single depth buffer for both eyes. Needed for a few games." @@ -12390,7 +12511,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "用户名" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -12400,7 +12521,7 @@ msgid "" "checked.
" msgstr "" "使用精确度较低的算法计算深度值。

在一些游戏中将导致问题但可能带来可观" -"的提速,取决于游戏和/或 GPU。

如果不确定,请勾选此" +"的提速,取决于游戏和/或 GPU。

如果不确定,请选中此" "项。" #: Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp:199 @@ -12410,7 +12531,7 @@ msgid "" "unchecked.
" msgstr "" "使用整个屏幕进行渲染。

如果禁用,则会创建一个渲染窗口。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp:206 msgid "" @@ -12419,7 +12540,7 @@ msgid "" "dolphin_emphasis>" msgstr "" "使用 Dolphin 主窗口而非单独的渲染窗口进行渲染。

如果" -"不确定,请不要勾选此项。" +"不确定,请不要选中此项。
" #: Source/Core/DolphinQt/AboutDialog.cpp:57 msgid "Using Qt %1" @@ -12653,7 +12774,7 @@ msgstr "" "等到所有着色器编译完成再开始游戏。启用此选项将会减少游戏开始后短时间的卡顿," "但游戏开始前会有更长的延迟。对于有两个或以下核心的系统,较大的着色器队列将降" "低帧率,因而建议启用此选项。

其他情况下,如果不确" -"定,请不要勾选此项。" +"定,请不要选中此项。
" #: Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp:215 msgid "" @@ -12662,7 +12783,7 @@ msgid "" "unsure, leave this unchecked.
" msgstr "" "等待场消隐期以防止撕裂。

模拟速度低于 100% 时会降低性能。" -"

如果不确定,请不要勾选此项。" +"

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:235 msgid "" @@ -12674,7 +12795,7 @@ msgid "" msgstr "" "在将 EFB 副本的内容写入内存之前等待,直到游戏与模拟 GPU 同步。

可减少 " "EFB 内存副本占用,在许多游戏中有性能提升,但有可能导致某些无法与模拟 GPU 安全" -"同步的风险。

如果不确定,请勾选此项。
如果不确定,请选中此项。" #: Source/Core/Common/MsgHandler.cpp:61 @@ -12781,7 +12902,7 @@ msgstr "监视" #. in other languages, check the SuperChargers manual at https://support.activision.com/manuals #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:327 msgid "Water" -msgstr "" +msgstr "水" #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Website" @@ -12805,7 +12926,7 @@ msgid "" msgstr "" "是否将基本游戏纹理转储到 User/Dump/Textures/<game_id>/。如果在增强选项" "卡中启用了“特殊多级纹理检测”,则特殊基本纹理也会被转储。" -"

如果不确定,请勾选此项。" +"

如果不确定,请选中此项。" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:307 msgid "" @@ -12816,7 +12937,7 @@ msgid "" msgstr "" "是否将多级纹理的游戏材质转储到 User/Dump/Textures/<game_id>/。如果在增" "强选项卡中启用了“特殊多级纹理检测”,则特殊多级纹理也会被转储。" -"

如果不确定,请勾选此项。" +"

如果不确定,请选中此项。" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:341 msgid "Whitelisted USB Passthrough Devices" @@ -13290,6 +13411,10 @@ msgstr "或选择一个设备" msgid "s" msgstr "秒" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "这个值:" diff --git a/Languages/po/zh_TW.po b/Languages/po/zh_TW.po index cc3055b3f6..159effb0e3 100644 --- a/Languages/po/zh_TW.po +++ b/Languages/po/zh_TW.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-06-27 22:41+0200\n" +"POT-Creation-Date: 2023-07-26 15:31+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Narusawa Yui , 2016,2018\n" "Language-Team: Chinese (Taiwan) (http://app.transifex.com/delroth/dolphin-" @@ -173,6 +173,16 @@ msgstr "" msgid "%1 has left" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:120 +msgid "" +"%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " +"hardcore)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 +msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" msgstr "" @@ -190,6 +200,11 @@ msgstr "" msgid "%1 ms" msgstr "%1 ms" +#: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 +msgid "%1 points" +msgstr "" + #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" msgstr "" @@ -1095,7 +1110,7 @@ msgstr "" msgid "Accuracy:" msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:16 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 #: Source/Core/DolphinQt/MenuBar.cpp:243 msgid "Achievements" msgstr "" @@ -2344,7 +2359,7 @@ msgstr "" msgid "Codes received!" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:22 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" msgstr "" @@ -2352,7 +2367,7 @@ msgstr "" msgid "Color Correction:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:52 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" msgstr "" @@ -2637,6 +2652,14 @@ msgstr "控制器設定" msgid "Controllers" msgstr "控制器" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:51 +msgid "" +"Controls the base luminance of a paper white surface in nits. Useful for " +"adjusting to different environmental lighting conditions when using a HDR " +"display.

HDR output is required for this setting to take effect." +"

If unsure, leave this at 200." +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" "Controls the distance of the convergence plane. This is the distance at " @@ -2740,19 +2763,19 @@ msgid "" "%1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:32 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:34 msgid "" -"Converts the colors to the color spaces that GC/Wii were meant to work with " -"to sRGB/Rec.709.

There's no way of knowing what exact color space " -"games were meant for,
given there were multiple standards and most games " -"didn't acknowledge them,
so it's not correct to assume a format from the " -"game disc region.
Just pick the one that looks more natural to you, or " +"Converts the colors from the color spaces that GC/Wii were meant to work " +"with to sRGB/Rec.709.

There's no way of knowing what exact color " +"space games were meant for, given there were multiple standards and most " +"games didn't acknowledge them, so it's not correct to assume a format from " +"the game disc region. Just pick the one that looks more natural to you, or " "match it with the region the game was developed in.

HDR output is " "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:46 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" "Converts the gamma from what the game targeted to what your current SDR " "display targets.
Monitors often target sRGB. TVs often target 2.2." @@ -2812,11 +2835,11 @@ msgstr "" msgid "Core" msgstr "核心" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:59 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:89 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" msgstr "" @@ -3031,6 +3054,10 @@ msgstr "" msgid "Custom RTC Options" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 +msgid "Custom:" +msgstr "" + #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" msgstr "" @@ -3344,16 +3371,6 @@ msgstr "" msgid "Direct3D 11" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 -msgid "" -"Direct3D 11 renderer requires support for features not supported by your " -"system configuration. This is most likely because you are using Windows 7. " -"You may still use this backend, but you might encounter graphical " -"artifacts.\n" -"\n" -"Do you really want to switch to Direct3D 11? If unsure, select 'No'." -msgstr "" - #: Source/Core/DolphinQt/GBAWidget.cpp:386 msgid "Dis&connected" msgstr "" @@ -3920,6 +3937,10 @@ msgstr "開啟作弊" msgid "Enable Custom RTC" msgstr "" +#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 +msgid "Enable Debugging UI" +msgstr "" + #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" msgstr "開啟雙核心" @@ -4627,7 +4648,7 @@ msgstr "" msgid "Failed to connect to server: %1" msgstr "" -#: Source/Core/VideoBackends/D3D/D3DMain.cpp:153 +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:154 #: Source/Core/VideoBackends/D3D12/VideoBackend.cpp:129 msgid "Failed to create D3D swap chain" msgstr "" @@ -5576,8 +5597,8 @@ msgstr "" msgid "Game Boy Advance at Port %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:68 -msgid "Game Color Space" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 +msgid "Game Color Space:" msgstr "" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 @@ -5592,10 +5613,14 @@ msgstr "" msgid "Game Folders" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:83 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 +msgid "Game Gamma:" +msgstr "" + #: Source/Core/DolphinQt/GameList/GameList.cpp:988 #: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "Game ID" @@ -5698,7 +5723,7 @@ msgstr "" msgid "GameCube TAS Input %1" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:75 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" msgstr "" @@ -5832,14 +5857,18 @@ msgstr "" msgid "HDMI 3D" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:114 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:123 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 +msgid "HDR Paper White Nits:" +msgstr "" + #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" msgstr "" @@ -6589,7 +6618,7 @@ msgstr "" msgid "JIT SystemRegisters Off" msgstr "" -#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:792 +#: Source/Core/Core/PowerPC/Jit64/Jit.cpp:793 #: Source/Core/Core/PowerPC/JitArm64/Jit.cpp:795 msgid "" "JIT failed to find code space after a cache clear. This should never happen. " @@ -7012,6 +7041,7 @@ msgstr "" msgid "Lock Mouse Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:115 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:97 msgid "Locked" msgstr "" @@ -7349,7 +7379,7 @@ msgstr "" msgid "NTSC-J" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" msgstr "" @@ -7357,16 +7387,17 @@ msgstr "" msgid "NTSC-K" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:41 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" "NTSC-M and NTSC-J target gamma ~2.2. PAL targets gamma ~2.8.
None of the " -"two were necessarily followed by games or TVs. 2.35 is a good generic value " -"for all regions.
If a game allows you to chose a gamma value, match it " -"here." +"two were necessarily followed by games or TVs.
2.35 is a good generic " +"value for all regions.

If a game allows you to chose a gamma value, " +"match it here.

If unsure, leave this at 2.35." msgstr "" #: Source/Core/DolphinQt/MenuBar.cpp:253 @@ -7902,7 +7933,7 @@ msgstr "" msgid "PAL" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:65 +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:70 msgid "PAL (EBU)" msgstr "" @@ -8307,6 +8338,7 @@ msgstr "設定檔" msgid "Program Counter" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:46 #: Source/Core/DolphinQt/Config/FilesystemWidget.cpp:344 #: Source/Core/DolphinQt/ConvertDialog.cpp:434 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:284 @@ -8831,12 +8863,8 @@ msgstr "" msgid "SD Sync Folder:" msgstr "" -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:100 -msgid "SDR Display Custom Gamma" -msgstr "" - -#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:94 -msgid "SDR Display Gamma sRGB" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 +msgid "SDR Display Gamma Target" msgstr "" #: Source/Core/Core/HW/GBAPadEmu.h:43 @@ -9482,7 +9510,7 @@ msgid "" "address space. This will work for the vast majority of games." msgstr "" -#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:36 +#: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:45 #: Source/Core/DolphinQt/Config/SettingsWindow.cpp:27 #: Source/Core/DolphinQt/TAS/TASInputWindow.cpp:70 msgid "Settings" @@ -9543,10 +9571,6 @@ msgstr "" msgid "Show Current Game on Discord" msgstr "" -#: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 -msgid "Show Debugging UI" -msgstr "" - #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" @@ -10531,6 +10555,15 @@ msgid "" "Player ({1})" msgstr "" +#: Source/Core/VideoBackends/D3D/D3DMain.cpp:57 +msgid "" +"The Direct3D 11 renderer requires support for features not supported by your " +"system configuration. You may still use this backend, but you will encounter " +"graphical artifacts in certain games.\n" +"\n" +"Do you really want to switch to Direct3D 11? If unsure, select 'No'." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." msgstr "" @@ -11576,6 +11609,22 @@ msgstr "" msgid "Unlock Cursor" msgstr "" +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 +msgid "Unlocked" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 +msgid "Unlocked %1 times this session" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 +msgid "Unlocked (Casual)" +msgstr "" + +#: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 +msgid "Unlocked this session" +msgstr "" + #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" msgstr "" @@ -12584,6 +12633,10 @@ msgstr "" msgid "s" msgstr "" +#: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 +msgid "sRGB" +msgstr "" + #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" msgstr "" From ec5d2a4f414cb78a6216145b6d8c151ebc6d1209 Mon Sep 17 00:00:00 2001 From: riidefi <34194588+riidefi@users.noreply.github.com> Date: Wed, 26 Jul 2023 13:01:10 -0600 Subject: [PATCH 57/99] [Core] Prevent SD data loss from silent resync failure --- Source/Core/Core/Core.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index e8e738854e..2865c81a9d 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -535,7 +535,16 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi Common::ScopeGuard sd_folder_sync_guard{[sync_sd_folder] { if (sync_sd_folder && Config::Get(Config::MAIN_ALLOW_SD_WRITES)) - Common::SyncSDImageToSDFolder([]() { return false; }); + { + const bool sync_ok = Common::SyncSDImageToSDFolder([]() { return false; }); + if (!sync_ok) + { + PanicAlertFmtT( + "Failed to sync SD card with folder. All changes made this session will be " + "discarded on next boot if you do not manually re-issue a resync in Config > " + "Wii > SD Card Settings > Convert File to Folder Now!"); + } + } }}; // Load Wiimotes - only if we are booting in Wii mode From 350e51951b94204681a3610efdb291d03bf07859 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 23 Jul 2023 13:43:50 -0500 Subject: [PATCH 58/99] VideoCommon: update imgui to 1.89.7 (and implot to 0.15); fix issues with upgrade; keep the demo code in case someone wants to reference it but don't compile it by enabling 'IMGUI_DISABLE_DEMO_WINDOWS' in config --- Externals/imgui/CMakeLists.txt | 1 + Externals/imgui/imconfig.h | 32 +- Externals/imgui/imgui.cpp | 6899 ++++++++++++++------ Externals/imgui/imgui.h | 1123 ++-- Externals/imgui/imgui.vcxproj | 1 + Externals/imgui/imgui_demo.cpp | 8130 ++++++++++++++++++++++++ Externals/imgui/imgui_draw.cpp | 419 +- Externals/imgui/imgui_internal.h | 1295 ++-- Externals/imgui/imgui_tables.cpp | 427 +- Externals/imgui/imgui_widgets.cpp | 2132 ++++--- Externals/imgui/imstb_rectpack.h | 42 +- Externals/imgui/imstb_textedit.h | 50 +- Externals/imgui/imstb_truetype.h | 782 ++- Externals/implot/implot | 2 +- Source/Core/VideoCommon/OnScreenUI.cpp | 16 +- Source/Core/VideoCommon/OnScreenUI.h | 2 + 16 files changed, 16819 insertions(+), 4534 deletions(-) create mode 100644 Externals/imgui/imgui_demo.cpp diff --git a/Externals/imgui/CMakeLists.txt b/Externals/imgui/CMakeLists.txt index becebfbe65..5a1a836563 100644 --- a/Externals/imgui/CMakeLists.txt +++ b/Externals/imgui/CMakeLists.txt @@ -6,6 +6,7 @@ endif() set(SRCS imgui.cpp + imgui_demo.cpp imgui_draw.cpp imgui_tables.cpp imgui_widgets.cpp diff --git a/Externals/imgui/imconfig.h b/Externals/imgui/imconfig.h index 5cdc92ecaa..0a6acea0ab 100644 --- a/Externals/imgui/imconfig.h +++ b/Externals/imgui/imconfig.h @@ -19,6 +19,7 @@ //---- Define assertion handler. Defaults to calling assert(). // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. #define IM_ASSERT(_EXPR) ASSERT(_EXPR) +//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. @@ -29,12 +30,13 @@ //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names. #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS +//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions. -//---- Disable all of Dear ImGui or don't implement standard windows. -// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp. +//---- Disable all of Dear ImGui or don't implement standard windows/tools. +// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. -//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended. -//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty. +#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. +//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowStackToolWindow() will be empty (this was called IMGUI_DISABLE_METRICS_WINDOW before 1.88). //---- Don't implement some functions to reduce linkage requirements. //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) @@ -62,12 +64,13 @@ // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" +//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION -//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) -// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf. -// #define IMGUI_USE_STB_SPRINTF +//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) +// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h. +//#define IMGUI_USE_STB_SPRINTF //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). @@ -81,14 +84,16 @@ //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. // This will be inlined as part of ImVec2 and ImVec4 class declarations. /* -#define IM_VEC2_CLASS_EXTRA \ - ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ +#define IM_VEC2_CLASS_EXTRA \ + constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ operator MyVec2() const { return MyVec2(x,y); } -#define IM_VEC4_CLASS_EXTRA \ - ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ +#define IM_VEC4_CLASS_EXTRA \ + constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ operator MyVec4() const { return MyVec4(x,y,z,w); } */ +//---- ...Or use Dear ImGui's own very basic math operators. +//#define IMGUI_DEFINE_MATH_OPERATORS //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). @@ -107,11 +112,6 @@ //#define IM_DEBUG_BREAK IM_ASSERT(0) //#define IM_DEBUG_BREAK __debugbreak() -//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(), -// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.) -// This adds a small runtime cost which is why it is not enabled by default. -//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX - //---- Debug Tools: Enable slower asserts //#define IMGUI_DEBUG_PARANOID diff --git a/Externals/imgui/imgui.cpp b/Externals/imgui/imgui.cpp index e6f206e7c9..39fcd70723 100644 --- a/Externals/imgui/imgui.cpp +++ b/Externals/imgui/imgui.cpp @@ -1,23 +1,25 @@ -// dear imgui, v1.85 +// dear imgui, v1.89.7 // (main code and documentation) // Help: -// - Read FAQ at http://dearimgui.org/faq +// - Read FAQ at http://dearimgui.com/faq // - Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase. // - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that. // Read imgui.cpp for details, links and comments. // Resources: -// - FAQ http://dearimgui.org/faq -// - Homepage & latest https://github.com/ocornut/imgui +// - FAQ http://dearimgui.com/faq +// - Homepage https://github.com/ocornut/imgui // - Releases & changelog https://github.com/ocornut/imgui/releases -// - Gallery https://github.com/ocornut/imgui/issues/4451 (please post your screenshots/video there!) +// - Gallery https://github.com/ocornut/imgui/issues/6478 (please post your screenshots/video there!) // - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there) +// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started // - Glossary https://github.com/ocornut/imgui/wiki/Glossary // - Issues & support https://github.com/ocornut/imgui/issues // Getting Started? -// - For first-time users having issues compiling/linking/running or issues loading fonts: +// - Read https://github.com/ocornut/imgui/wiki/Getting-Started +// - For first-time users having issues compiling/linking/running/loading fonts: // please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. // Developed by Omar Cornut and every direct or indirect contributors to the GitHub. @@ -39,17 +41,16 @@ Index of this file: DOCUMENTATION - MISSION STATEMENT -- END-USER GUIDE +- CONTROLS GUIDE - PROGRAMMER GUIDE - READ FIRST - HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI - GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE - HOW A SIMPLE APPLICATION MAY LOOK LIKE - HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE - - USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS - API BREAKING CHANGES (read me when you update!) - FREQUENTLY ASKED QUESTIONS (FAQ) - - Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer) + - Read all answers online: https://www.dearimgui.com/faq, or in docs/FAQ.md (with a Markdown viewer) CODE (search for "[SECTION]" in the code to find them) @@ -65,11 +66,13 @@ CODE // [SECTION] MISC HELPERS/UTILITIES (Color functions) // [SECTION] ImGuiStorage // [SECTION] ImGuiTextFilter -// [SECTION] ImGuiTextBuffer +// [SECTION] ImGuiTextBuffer, ImGuiTextIndex // [SECTION] ImGuiListClipper // [SECTION] STYLING // [SECTION] RENDER HELPERS +// [SECTION] INITIALIZATION, SHUTDOWN // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!) +// [SECTION] INPUTS // [SECTION] ERROR CHECKING // [SECTION] LAYOUT // [SECTION] SCROLLING @@ -79,9 +82,11 @@ CODE // [SECTION] DRAG AND DROP // [SECTION] LOGGING/CAPTURING // [SECTION] SETTINGS -// [SECTION] VIEWPORTS +// [SECTION] LOCALIZATION +// [SECTION] VIEWPORTS, PLATFORM WINDOWS // [SECTION] PLATFORM DEPENDENT HELPERS // [SECTION] METRICS/DEBUGGER WINDOW +// [SECTION] DEBUG LOG WINDOW // [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, STACK TOOL) */ @@ -100,6 +105,7 @@ CODE - Easy to hack and improve. - Minimize setup and maintenance. - Minimize state storage on user side. + - Minimize state synchronization. - Portable, minimize dependencies, run on target (consoles, phones, etc.). - Efficient runtime and memory consumption. @@ -109,28 +115,73 @@ CODE - Limited layout features, intricate layouts are typically crafted in code. - END-USER GUIDE + CONTROLS GUIDE ============== - - Double-click on title bar to collapse window. - - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin(). - - Click and drag on lower right corner to resize window (double-click to auto fit window to its contents). - - Click and drag on any empty space to move window. - - TAB/SHIFT+TAB to cycle through keyboard editable fields. - - CTRL+Click on a slider or drag box to input value as text. - - Use mouse wheel to scroll. - - Text editor: - - Hold SHIFT or use mouse to select text. - - CTRL+Left/Right to word jump. - - CTRL+Shift+Left/Right to select words. - - CTRL+A our Double-Click to select all. - - CTRL+X,CTRL+C,CTRL+V to use OS clipboard/ - - CTRL+Z,CTRL+Y to undo/redo. - - ESCAPE to revert text to its original value. - - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) - - Controls are automatically adjusted for OSX to match standard OSX text editing operations. - - General Keyboard controls: enable with ImGuiConfigFlags_NavEnableKeyboard. - - General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. See suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at http://dearimgui.org/controls_sheets + - MOUSE CONTROLS + - Mouse wheel: Scroll vertically. + - SHIFT+Mouse wheel: Scroll horizontally. + - Click [X]: Close a window, available when 'bool* p_open' is passed to ImGui::Begin(). + - Click ^, Double-Click title: Collapse window. + - Drag on corner/border: Resize window (double-click to auto fit window to its contents). + - Drag on any empty space: Move window (unless io.ConfigWindowsMoveFromTitleBarOnly = true). + - Left-click outside popup: Close popup stack (right-click over underlying popup: Partially close popup stack). + + - TEXT EDITOR + - Hold SHIFT or Drag Mouse: Select text. + - CTRL+Left/Right: Word jump. + - CTRL+Shift+Left/Right: Select words. + - CTRL+A or Double-Click: Select All. + - CTRL+X, CTRL+C, CTRL+V: Use OS clipboard. + - CTRL+Z, CTRL+Y: Undo, Redo. + - ESCAPE: Revert text to its original value. + - On OSX, controls are automatically adjusted to match standard OSX text editing shortcuts and behaviors. + + - KEYBOARD CONTROLS + - Basic: + - Tab, SHIFT+Tab Cycle through text editable fields. + - CTRL+Tab, CTRL+Shift+Tab Cycle through windows. + - CTRL+Click Input text into a Slider or Drag widget. + - Extended features with `io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard`: + - Tab, SHIFT+Tab: Cycle through every items. + - Arrow keys Move through items using directional navigation. Tweak value. + - Arrow keys + Alt, Shift Tweak slower, tweak faster (when using arrow keys). + - Enter Activate item (prefer text input when possible). + - Space Activate item (prefer tweaking with arrows when possible). + - Escape Deactivate item, leave child window, close popup. + - Page Up, Page Down Previous page, next page. + - Home, End Scroll to top, scroll to bottom. + - Alt Toggle between scrolling layer and menu layer. + - CTRL+Tab then Ctrl+Arrows Move window. Hold SHIFT to resize instead of moving. + - Output when ImGuiConfigFlags_NavEnableKeyboard set, + - io.WantCaptureKeyboard flag is set when keyboard is claimed. + - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. + - io.NavVisible: true when the navigation cursor is visible (usually goes to back false when mouse is used). + + - GAMEPAD CONTROLS + - Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. + - Particularly useful to use Dear ImGui on a console system (e.g. PlayStation, Switch, Xbox) without a mouse! + - Download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets + - Backend support: backend needs to: + - Set 'io.BackendFlags |= ImGuiBackendFlags_HasGamepad' + call io.AddKeyEvent/AddKeyAnalogEvent() with ImGuiKey_Gamepad_XXX keys. + - For analog values (0.0f to 1.0f), backend is responsible to handling a dead-zone and rescaling inputs accordingly. + Backend code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.). + - BEFORE 1.87, BACKENDS USED TO WRITE TO io.NavInputs[]. This is now obsolete. Please call io functions instead! + - If you need to share inputs between your game and the Dear ImGui interface, the easiest approach is to go all-or-nothing, + with a buttons combo to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. + + - REMOTE INPUTS SHARING & MOUSE EMULATION + - PS4/PS5 users: Consider emulating a mouse cursor with DualShock touch pad or a spare analog stick as a mouse-emulation fallback. + - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + run examples/libs/synergy/uSynergy.c (on your console/tablet/phone app) + in order to share your PC mouse/keyboard. + - See https://github.com/ocornut/imgui/wiki/Useful-Extensions#remoting for other remoting solutions. + - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag. + Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs Dear ImGui to move your mouse cursor along with navigation movements. + When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantSetMousePos' to notify you that it wants the mouse cursor to be moved. + When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the backends in examples/ do that. + (If you set the NavEnableSetMousePos flag but don't honor 'io.WantSetMousePos' properly, Dear ImGui will misbehave as it will see your mouse moving back & forth!) + (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want + to set a boolean to ignore your other external mouse positions until the external source is moved again.) PROGRAMMER GUIDE @@ -237,7 +288,7 @@ CODE // Build and load the texture atlas into a texture // (In the examples/ app this is usually done within the ImGui_ImplXXX_Init() function from one of the demo Renderer) int width, height; - unsigned char* pixels = NULL; + unsigned char* pixels = nullptr; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // At this point you've got the texture data and you need to upload that to your graphic system: @@ -254,9 +305,9 @@ CODE io.DeltaTime = 1.0f/60.0f; // set the time elapsed since the previous frame (in seconds) io.DisplaySize.x = 1920.0f; // set the current display width io.DisplaySize.y = 1280.0f; // set the current display height here - io.MousePos = my_mouse_pos; // set the mouse position - io.MouseDown[0] = my_mouse_buttons[0]; // set the mouse button states - io.MouseDown[1] = my_mouse_buttons[1]; + io.AddMousePosEvent(mouse_x, mouse_y); // update mouse position + io.AddMouseButtonEvent(0, mouse_b[0]); // update mouse button states + io.AddMouseButtonEvent(1, mouse_b[1]); // update mouse button states // Call NewFrame(), after this point you can use ImGui::* functions anytime // (So you want to try calling NewFrame() as early as you can in your main loop to be able to use Dear ImGui everywhere) @@ -288,12 +339,14 @@ CODE --------------------------------------------- The backends in impl_impl_XXX.cpp files contain many working implementations of a rendering function. - void void MyImGuiRenderFunction(ImDrawData* draw_data) + void MyImGuiRenderFunction(ImDrawData* draw_data) { // TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + // TODO: Setup texture sampling state: sample with bilinear filtering (NOT point/nearest filtering). Use 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines;' to allow point/nearest filtering. // TODO: Setup viewport covering draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize // TODO: Setup orthographic projection matrix cover draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize // TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color. + ImVec2 clip_off = draw_data->DisplayPos; for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; @@ -308,9 +361,11 @@ CODE } else { - // The texture for the draw call is specified by pcmd->GetTexID(). - // The vast majority of draw calls will use the Dear ImGui texture atlas, which value you have set yourself during initialization. - MyEngineBindTexture((MyTexture*)pcmd->GetTexID()); + // Project scissor/clipping rectangles into framebuffer space + ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y); + ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y); + if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) + continue; // We are using scissoring to clip some objects. All low-level graphics API should support it. // - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches @@ -321,57 +376,21 @@ CODE // - In the interest of supporting multi-viewport applications (see 'docking' branch on github), // always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space. // - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min) - ImVec2 pos = draw_data->DisplayPos; - MyEngineScissor((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y)); + MyEngineSetScissor(clip_min.x, clip_min.y, clip_max.x, clip_max.y); + + // The texture for the draw call is specified by pcmd->GetTexID(). + // The vast majority of draw calls will use the Dear ImGui texture atlas, which value you have set yourself during initialization. + MyEngineBindTexture((MyTexture*)pcmd->GetTexID()); // Render 'pcmd->ElemCount/3' indexed triangles. // By default the indices ImDrawIdx are 16-bit, you can change them to 32-bit in imconfig.h if your engine doesn't support 16-bit indices. - MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer, vtx_buffer); + MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset, vtx_buffer, pcmd->VtxOffset); } - idx_buffer += pcmd->ElemCount; } } } - USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS - ------------------------------------------ - - The gamepad/keyboard navigation is fairly functional and keeps being improved. - - Gamepad support is particularly useful to use Dear ImGui on a console system (e.g. PS4, Switch, XB1) without a mouse! - - You can ask questions and report issues at https://github.com/ocornut/imgui/issues/787 - - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. - - Keyboard: - - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. - NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays. - - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag - will be set. For more advanced uses, you may want to read from: - - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. - - io.NavVisible: true when the navigation cursor is visible (and usually goes false when mouse is used). - - or query focus information with e.g. IsWindowFocused(ImGuiFocusedFlags_AnyWindow), IsItemFocused() etc. functions. - Please reach out if you think the game vs navigation input sharing could be improved. - - Gamepad: - - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. - - Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + fill the io.NavInputs[] fields before calling NewFrame(). - Note that io.NavInputs[] is cleared by EndFrame(). - - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. For each entry of io.NavInputs[], set the following values: - 0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks. - - We use a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone. - Your code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.). - - You can download PNG/PSD files depicting the gamepad controls for common controllers at: http://dearimgui.org/controls_sheets - - If you need to share inputs between your game and the imgui parts, the easiest approach is to go all-or-nothing, with a buttons combo - to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. - - Mouse: - - PS4 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. - - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (on your console/tablet/phone app) to share your PC mouse/keyboard. - - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag. - Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs dear imgui to move your mouse cursor along with navigation movements. - When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantSetMousePos' to notify you that it wants the mouse cursor to be moved. - When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the backends in examples/ do that. - (If you set the NavEnableSetMousePos flag but don't honor 'io.WantSetMousePos' properly, imgui will misbehave as it will see your mouse moving back and forth!) - (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want - to set a boolean to ignore your other external mouse positions until the external source is moved again.) - - API BREAKING CHANGES ==================== @@ -380,6 +399,105 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2023/06/28 (1.89.7) - overlapping items: obsoleted 'SetItemAllowOverlap()' (called after item) in favor of calling 'SetNextItemAllowOverlap()' (called before item). 'SetItemAllowOverlap()' didn't and couldn't work reliably since 1.89 (2022-11-15). + - 2023/06/28 (1.89.7) - overlapping items: renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap', 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'. Kept redirecting enums (will obsolete). + - 2023/06/28 (1.89.7) - overlapping items: IsItemHovered() now by default return false when querying an item using AllowOverlap mode which is being overlapped. Use ImGuiHoveredFlags_AllowWhenOverlappedByItem to revert to old behavior. + - 2023/06/20 (1.89.7) - moved io.HoverDelayShort/io.HoverDelayNormal to style.HoverDelayShort/style.HoverDelayNormal. As the fields were added in 1.89 and expected to be left unchanged by most users, or only tweaked once during app initialization, we are exceptionally accepting the breakage. + - 2023/05/30 (1.89.6) - backends: renamed "imgui_impl_sdlrenderer.cpp" to "imgui_impl_sdlrenderer2.cpp" and "imgui_impl_sdlrenderer.h" to "imgui_impl_sdlrenderer2.h". This is in prevision for the future release of SDL3. + - 2023/05/22 (1.89.6) - listbox: commented out obsolete/redirecting functions that were marked obsolete more than two years ago: + - ListBoxHeader() -> use BeginListBox() (note how two variants of ListBoxHeader() existed. Check commented versions in imgui.h for reference) + - ListBoxFooter() -> use EndListBox() + - 2023/05/15 (1.89.6) - clipper: commented out obsolete redirection constructor 'ImGuiListClipper(int items_count, float items_height = -1.0f)' that was marked obsolete in 1.79. Use default constructor + clipper.Begin(). + - 2023/05/15 (1.89.6) - clipper: renamed ImGuiListClipper::ForceDisplayRangeByIndices() to ImGuiListClipper::IncludeRangeByIndices(). + - 2023/03/14 (1.89.4) - commented out redirecting enums/functions names that were marked obsolete two years ago: + - ImGuiSliderFlags_ClampOnInput -> use ImGuiSliderFlags_AlwaysClamp + - ImGuiInputTextFlags_AlwaysInsertMode -> use ImGuiInputTextFlags_AlwaysOverwrite + - ImDrawList::AddBezierCurve() -> use ImDrawList::AddBezierCubic() + - ImDrawList::PathBezierCurveTo() -> use ImDrawList::PathBezierCubicCurveTo() + - 2023/03/09 (1.89.4) - renamed PushAllowKeyboardFocus()/PopAllowKeyboardFocus() to PushTabStop()/PopTabStop(). Kept inline redirection functions (will obsolete). + - 2023/03/09 (1.89.4) - tooltips: Added 'bool' return value to BeginTooltip() for API consistency. Please only submit contents and call EndTooltip() if BeginTooltip() returns true. In reality the function will _currently_ always return true, but further changes down the line may change this, best to clarify API sooner. + - 2023/02/15 (1.89.4) - moved the optional "courtesy maths operators" implementation from imgui_internal.h in imgui.h. + Even though we encourage using your own maths types and operators by setting up IM_VEC2_CLASS_EXTRA, + it has been frequently requested by people to use our own. We had an opt-in define which was + previously fulfilled in imgui_internal.h. It is now fulfilled in imgui.h. (#6164) + - OK: #define IMGUI_DEFINE_MATH_OPERATORS / #include "imgui.h" / #include "imgui_internal.h" + - Error: #include "imgui.h" / #define IMGUI_DEFINE_MATH_OPERATORS / #include "imgui_internal.h" + - 2023/02/07 (1.89.3) - backends: renamed "imgui_impl_sdl.cpp" to "imgui_impl_sdl2.cpp" and "imgui_impl_sdl.h" to "imgui_impl_sdl2.h". (#6146) This is in prevision for the future release of SDL3. + - 2022/10/26 (1.89) - commented out redirecting OpenPopupContextItem() which was briefly the name of OpenPopupOnItemClick() from 1.77 to 1.79. + - 2022/10/12 (1.89) - removed runtime patching of invalid "%f"/"%0.f" format strings for DragInt()/SliderInt(). This was obsoleted in 1.61 (May 2018). See 1.61 changelog for details. + - 2022/09/26 (1.89) - renamed and merged keyboard modifiers key enums and flags into a same set. Kept inline redirection enums (will obsolete). + - ImGuiKey_ModCtrl and ImGuiModFlags_Ctrl -> ImGuiMod_Ctrl + - ImGuiKey_ModShift and ImGuiModFlags_Shift -> ImGuiMod_Shift + - ImGuiKey_ModAlt and ImGuiModFlags_Alt -> ImGuiMod_Alt + - ImGuiKey_ModSuper and ImGuiModFlags_Super -> ImGuiMod_Super + the ImGuiKey_ModXXX were introduced in 1.87 and mostly used by backends. + the ImGuiModFlags_XXX have been exposed in imgui.h but not really used by any public api only by third-party extensions. + exceptionally commenting out the older ImGuiKeyModFlags_XXX names ahead of obsolescence schedule to reduce confusion and because they were not meant to be used anyway. + - 2022/09/20 (1.89) - ImGuiKey is now a typed enum, allowing ImGuiKey_XXX symbols to be named in debuggers. + this will require uses of legacy backend-dependent indices to be casted, e.g. + - with imgui_impl_glfw: IsKeyPressed(GLFW_KEY_A) -> IsKeyPressed((ImGuiKey)GLFW_KEY_A); + - with imgui_impl_win32: IsKeyPressed('A') -> IsKeyPressed((ImGuiKey)'A') + - etc. However if you are upgrading code you might well use the better, backend-agnostic IsKeyPressed(ImGuiKey_A) now! + - 2022/09/12 (1.89) - removed the bizarre legacy default argument for 'TreePush(const void* ptr = NULL)', always pass a pointer value explicitly. NULL/nullptr is ok but require cast, e.g. TreePush((void*)nullptr); + - 2022/09/05 (1.89) - commented out redirecting functions/enums names that were marked obsolete in 1.77 and 1.78 (June 2020): + - DragScalar(), DragScalarN(), DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(): For old signatures ending with (..., const char* format, float power = 1.0f) -> use (..., format ImGuiSliderFlags_Logarithmic) if power != 1.0f. + - SliderScalar(), SliderScalarN(), SliderFloat(), SliderFloat2(), SliderFloat3(), SliderFloat4(): For old signatures ending with (..., const char* format, float power = 1.0f) -> use (..., format ImGuiSliderFlags_Logarithmic) if power != 1.0f. + - BeginPopupContextWindow(const char*, ImGuiMouseButton, bool) -> use BeginPopupContextWindow(const char*, ImGuiPopupFlags) + - 2022/09/02 (1.89) - obsoleted using SetCursorPos()/SetCursorScreenPos() to extend parent window/cell boundaries. + this relates to when moving the cursor position beyond current boundaries WITHOUT submitting an item. + - previously this would make the window content size ~200x200: + Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End(); + - instead, please submit an item: + Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + Dummy(ImVec2(0,0)) + End(); + - alternative: + Begin(...) + Dummy(ImVec2(200,200)) + End(); + - content size is now only extended when submitting an item! + - with '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' this will now be detected and assert. + - without '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' this will silently be fixed until we obsolete it. + - 2022/08/03 (1.89) - changed signature of ImageButton() function. Kept redirection function (will obsolete). + - added 'const char* str_id' parameter + removed 'int frame_padding = -1' parameter. + - old signature: bool ImageButton(ImTextureID tex_id, ImVec2 size, ImVec2 uv0 = ImVec2(0,0), ImVec2 uv1 = ImVec2(1,1), int frame_padding = -1, ImVec4 bg_col = ImVec4(0,0,0,0), ImVec4 tint_col = ImVec4(1,1,1,1)); + - used the ImTextureID value to create an ID. This was inconsistent with other functions, led to ID conflicts, and caused problems with engines using transient ImTextureID values. + - had a FramePadding override which was inconsistent with other functions and made the already-long signature even longer. + - new signature: bool ImageButton(const char* str_id, ImTextureID tex_id, ImVec2 size, ImVec2 uv0 = ImVec2(0,0), ImVec2 uv1 = ImVec2(1,1), ImVec4 bg_col = ImVec4(0,0,0,0), ImVec4 tint_col = ImVec4(1,1,1,1)); + - requires an explicit identifier. You may still use e.g. PushID() calls and then pass an empty identifier. + - always uses style.FramePadding for padding, to be consistent with other buttons. You may use PushStyleVar() to alter this. + - 2022/07/08 (1.89) - inputs: removed io.NavInputs[] and ImGuiNavInput enum (following 1.87 changes). + - Official backends from 1.87+ -> no issue. + - Official backends from 1.60 to 1.86 -> will build and convert gamepad inputs, unless IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Need updating! + - Custom backends not writing to io.NavInputs[] -> no issue. + - Custom backends writing to io.NavInputs[] -> will build and convert gamepad inputs, unless IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Need fixing! + - TL;DR: Backends should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values instead of filling io.NavInput[]. + - 2022/06/15 (1.88) - renamed IMGUI_DISABLE_METRICS_WINDOW to IMGUI_DISABLE_DEBUG_TOOLS for correctness. kept support for old define (will obsolete). + - 2022/05/03 (1.88) - backends: osx: removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend automatically handling event capture. All ImGui_ImplOSX_HandleEvent() calls should be removed as they are now unnecessary. + - 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO. + - 2022/01/20 (1.87) - inputs: reworded gamepad IO. + - Backend writing to io.NavInputs[] -> backend should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values. + - 2022/01/19 (1.87) - sliders, drags: removed support for legacy arithmetic operators (+,+-,*,/) when inputing text. This doesn't break any api/code but a feature that used to be accessible by end-users (which seemingly no one used). + - 2022/01/17 (1.87) - inputs: reworked mouse IO. + - Backend writing to io.MousePos -> backend should call io.AddMousePosEvent() + - Backend writing to io.MouseDown[] -> backend should call io.AddMouseButtonEvent() + - Backend writing to io.MouseWheel -> backend should call io.AddMouseWheelEvent() + - Backend writing to io.MouseHoveredViewport -> backend should call io.AddMouseViewportEvent() [Docking branch w/ multi-viewports only] + note: for all calls to IO new functions, the Dear ImGui context should be bound/current. + read https://github.com/ocornut/imgui/issues/4921 for details. + - 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details. + - IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX) + - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) + - Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent() (+ call io.SetKeyEventNativeData() if you want legacy user code to stil function with legacy key codes). + - Backend writing to io.KeyCtrl, io.KeyShift.. -> backend should call io.AddKeyEvent() with ImGuiMod_XXX values. *IF YOU PULLED CODE BETWEEN 2021/01/10 and 2021/01/27: We used to have a io.AddKeyModsEvent() function which was now replaced by io.AddKeyEvent() with ImGuiMod_XXX values.* + - one case won't work with backward compatibility: if your custom backend used ImGuiKey as mock native indices (e.g. "io.KeyMap[ImGuiKey_A] = ImGuiKey_A") because those values are now larger than the legacy KeyDown[] array. Will assert. + - inputs: added ImGuiKey_ModCtrl/ImGuiKey_ModShift/ImGuiKey_ModAlt/ImGuiKey_ModSuper values to submit keyboard modifiers using io.AddKeyEvent(), instead of writing directly to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper. + - 2022/01/05 (1.87) - inputs: renamed ImGuiKey_KeyPadEnter to ImGuiKey_KeypadEnter to align with new symbols. Kept redirection enum. + - 2022/01/05 (1.87) - removed io.ImeSetInputScreenPosFn() in favor of more flexible io.SetPlatformImeDataFn(). Removed 'void* io.ImeWindowHandle' in favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'. + - 2022/01/01 (1.87) - commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019) + - ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen() + - ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x + - ImGui::TreeAdvanceToLabelPos() -> use ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetTreeNodeToLabelSpacing()); + - ImFontAtlas::CustomRect -> use ImFontAtlasCustomRect + - ImGuiColorEditFlags_RGB/HSV/HEX -> use ImGuiColorEditFlags_DisplayRGB/HSV/Hex + - 2021/12/20 (1.86) - backends: removed obsolete Marmalade backend (imgui_impl_marmalade.cpp) + example. Find last supported version at https://github.com/ocornut/imgui/wiki/Bindings + - 2021/11/04 (1.86) - removed CalcListClipping() function. Prefer using ImGuiListClipper which can return non-contiguous ranges. Please open an issue if you think you really need this function. - 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead for generally 'GetContentRegionAvail().x' is more useful. - 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019): - ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList() @@ -677,7 +795,7 @@ CODE ================================ Read all answers online: - https://www.dearimgui.org/faq or https://github.com/ocornut/imgui/blob/master/docs/FAQ.md (same url) + https://www.dearimgui.com/faq or https://github.com/ocornut/imgui/blob/master/docs/FAQ.md (same url) Read all answers locally (with a text editor or ideally a Markdown viewer): docs/FAQ.md Some answers are copied down here to facilitate searching in code. @@ -701,7 +819,7 @@ CODE Q: What is this library called? Q: Which version should I get? >> This library is called "Dear ImGui", please don't call it "ImGui" :) - >> See https://www.dearimgui.org/faq for details. + >> See https://www.dearimgui.com/faq for details. Q&A: Integration ================ @@ -711,26 +829,28 @@ CODE Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application? A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags! - >> See https://www.dearimgui.org/faq for a fully detailed answer. You really want to read this. + >> See https://www.dearimgui.com/faq for a fully detailed answer. You really want to read this. Q. How can I enable keyboard controls? Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display) Q: I integrated Dear ImGui in my engine and little squares are showing instead of text... Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around... Q: I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries... - >> See https://www.dearimgui.org/faq + >> See https://www.dearimgui.com/faq Q&A: Usage ---------- - Q: Why is my widget not reacting when I click on it? - Q: How can I have widgets with an empty label? - Q: How can I have multiple widgets with the same label? - Q: How can I display an image? What is ImTextureID, how does it works? + Q: About the ID Stack system.. + - Why is my widget not reacting when I click on it? + - How can I have widgets with an empty label? + - How can I have multiple widgets with the same label? + - How can I have multiple windows with the same label? + Q: How can I display an image? What is ImTextureID, how does it work? Q: How can I use my own math types instead of ImVec2/ImVec4? Q: How can I interact with standard C++ types (such as std::string and std::vector)? Q: How can I display custom shapes? (using low-level ImDrawList API) - >> See https://www.dearimgui.org/faq + >> See https://www.dearimgui.com/faq Q&A: Fonts, Text ================ @@ -740,7 +860,7 @@ CODE Q: How can I easily use icons in my application? Q: How can I load multiple fonts? Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic? - >> See https://www.dearimgui.org/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md + >> See https://www.dearimgui.com/faq and https://github.com/ocornut/imgui/edit/master/docs/FONTS.md Q&A: Concerns ============= @@ -749,7 +869,7 @@ CODE Q: Can you create elaborate/serious tools with Dear ImGui? Q: Can you reskin the look of Dear ImGui? Q: Why using C++ (as opposed to C)? - >> See https://www.dearimgui.org/faq + >> See https://www.dearimgui.com/faq Q&A: Community ============== @@ -776,16 +896,15 @@ CODE #define _CRT_SECURE_NO_WARNINGS #endif -#include "imgui.h" -#ifndef IMGUI_DISABLE - #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS #endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE #include "imgui_internal.h" // System includes -#include // toupper #include // vsnprintf, sscanf, printf #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier #include // intptr_t @@ -832,7 +951,7 @@ CODE #if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later #pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types #endif -#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). +#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to an 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). #pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6). #pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). #endif @@ -855,7 +974,7 @@ CODE #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #elif defined(__GNUC__) -// We disable -Wpragmas because GCC doesn't provide an has_warning equivalent and some forks/patches may not following the warning/version association. +// We disable -Wpragmas because GCC doesn't provide a has_warning equivalent and some forks/patches may not follow the warning/version association. #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size @@ -870,7 +989,6 @@ CODE // Debug options #define IMGUI_DEBUG_NAV_SCORING 0 // Display navigation scoring preview when hovering items. Display last moving direction matches when holding CTRL #define IMGUI_DEBUG_NAV_RECTS 0 // Display the reference navigation rectangle for each window -#define IMGUI_DEBUG_INI_SETTINGS 0 // Save additional comments in .ini file (particularly helps for Docking, but makes saving slower) // When using CTRL+TAB (or Gamepad Square+L/R) we delay the visual a little in order to reduce visual noise doing a fast switch. static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in @@ -879,7 +997,10 @@ static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time // Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by backend) static const float WINDOWS_HOVER_PADDING = 4.0f; // Extend outside window for hovering/resizing (maxxed with TouchPadding) and inside windows for borders. Affect FindHoveredWindow(). static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time. -static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved. +static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 0.70f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved. + +// Tooltip offset +static const ImVec2 TOOLTIP_DEFAULT_OFFSET = ImVec2(16, 10); // Multiplied by g.Style.MouseCursorScale //------------------------------------------------------------------------- // [SECTION] FORWARD DECLARATIONS @@ -901,9 +1022,9 @@ static void WindowSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSetti static void WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf); // Platform Dependents default implementation for IO functions -static const char* GetClipboardTextFn_DefaultImpl(void* user_data); -static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text); -static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); +static const char* GetClipboardTextFn_DefaultImpl(void* user_data_ctx); +static void SetClipboardTextFn_DefaultImpl(void* user_data_ctx, const char* text); +static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport, ImGuiPlatformImeData* data); namespace ImGui { @@ -913,16 +1034,20 @@ static void NavUpdateWindowing(); static void NavUpdateWindowingOverlay(); static void NavUpdateCancelRequest(); static void NavUpdateCreateMoveRequest(); +static void NavUpdateCreateTabbingRequest(); static float NavUpdatePageUpPageDown(); static inline void NavUpdateAnyRequestFlag(); +static void NavUpdateCreateWrappingRequest(); static void NavEndFrame(); static bool NavScoreItem(ImGuiNavItemData* result); static void NavApplyItemToResult(ImGuiNavItemData* result); static void NavProcessItem(); +static void NavProcessItemForTabbingRequest(ImGuiID id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags); static ImVec2 NavCalcPreferredRefPos(); static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window); static void NavRestoreLayer(ImGuiNavLayer layer); +static void NavRestoreHighlightAfterMove(); static int FindWindowFocusIndex(ImGuiWindow* window); // Error Checking and Debug Tools @@ -931,15 +1056,20 @@ static void ErrorCheckEndFrameSanityChecks(); static void UpdateDebugToolItemPicker(); static void UpdateDebugToolStackQueries(); -// Misc -static void UpdateSettings(); +// Inputs +static void UpdateKeyboardInputs(); static void UpdateMouseInputs(); static void UpdateMouseWheel(); -static void UpdateTabFocus(); +static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt); + +// Misc +static void UpdateSettings(); static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect); static void RenderWindowOuterBorders(ImGuiWindow* window); -static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size); +static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size); static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open); +static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col); +static void RenderDimmedBackgrounds(); // Viewports static void UpdateViewportsNewFrame(); @@ -1017,24 +1147,34 @@ ImGuiStyle::ImGuiStyle() ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1). ScrollbarSize = 14.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar - GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar + GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. TabBorderSize = 0.0f; // Thickness of border around tabs. - TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. + SeparatorTextBorderSize = 3.0f; // Thickkness of border in SeparatorText() + SeparatorTextAlign = ImVec2(0.0f,0.5f);// Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center). + SeparatorTextPadding = ImVec2(20.0f,3.f);// Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y. DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. - AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. + AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + // Behaviors + HoverStationaryDelay = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary. + HoverDelayShort = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayShort). Usually used along with HoverStationaryDelay. + HoverDelayNormal = 0.40f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayNormal). " + HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse. + HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad. + // Default theme ImGui::StyleColorsDark(this); } @@ -1063,6 +1203,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor) LogSliderDeadzone = ImFloor(LogSliderDeadzone * scale_factor); TabRounding = ImFloor(TabRounding * scale_factor); TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImFloor(TabMinWidthForCloseButton * scale_factor) : FLT_MAX; + SeparatorTextPadding = ImFloor(SeparatorTextPadding * scale_factor); DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor); DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor); MouseCursorScale = ImFloor(MouseCursorScale * scale_factor); @@ -1072,7 +1213,7 @@ ImGuiIO::ImGuiIO() { // Most fields are initialized with zero memset(this, 0, sizeof(*this)); - IM_ASSERT(IM_ARRAYSIZE(ImGuiIO::MouseDown) == ImGuiMouseButton_COUNT && IM_ARRAYSIZE(ImGuiIO::MouseClicked) == ImGuiMouseButton_COUNT); // Our pre-C++11 IM_STATIC_ASSERT() macros triggers warning on modern compilers so we don't use it here. + IM_STATIC_ASSERT(IM_ARRAYSIZE(ImGuiIO::MouseDown) == ImGuiMouseButton_COUNT && IM_ARRAYSIZE(ImGuiIO::MouseClicked) == ImGuiMouseButton_COUNT); // Settings ConfigFlags = ImGuiConfigFlags_None; @@ -1082,12 +1223,10 @@ ImGuiIO::ImGuiIO() IniSavingRate = 5.0f; IniFilename = "imgui.ini"; // Important: "imgui.ini" is relative to current working dir, most apps will want to lock this to an absolute path (e.g. same path as executables). LogFilename = "imgui_log.txt"; - MouseDoubleClickTime = 0.30f; - MouseDoubleClickMaxDist = 6.0f; +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO for (int i = 0; i < ImGuiKey_COUNT; i++) KeyMap[i] = -1; - KeyRepeatDelay = 0.275f; - KeyRepeatRate = 0.050f; +#endif UserData = NULL; Fonts = NULL; @@ -1096,6 +1235,12 @@ ImGuiIO::ImGuiIO() FontAllowUserScaling = false; DisplayFramebufferScale = ImVec2(1.0f, 1.0f); + MouseDoubleClickTime = 0.30f; + MouseDoubleClickMaxDist = 6.0f; + MouseDragThreshold = 6.0f; + KeyRepeatDelay = 0.275f; + KeyRepeatRate = 0.050f; + // Miscellaneous options MouseDrawCursor = false; #ifdef __APPLE__ @@ -1103,49 +1248,62 @@ ImGuiIO::ImGuiIO() #else ConfigMacOSXBehaviors = false; #endif + ConfigInputTrickleEventQueue = true; ConfigInputTextCursorBlink = true; + ConfigInputTextEnterKeepActive = false; + ConfigDragClickToInputText = false; ConfigWindowsResizeFromEdges = true; ConfigWindowsMoveFromTitleBarOnly = false; ConfigMemoryCompactTimer = 60.0f; + ConfigDebugBeginReturnValueOnce = false; + ConfigDebugBeginReturnValueLoop = false; // Platform Functions + // Note: Initialize() will setup default clipboard/ime handlers. BackendPlatformName = BackendRendererName = NULL; BackendPlatformUserData = BackendRendererUserData = BackendLanguageUserData = NULL; - GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations - SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; - ClipboardUserData = NULL; - ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; - ImeWindowHandle = NULL; // Input (NB: we already have memset zero the entire structure!) MousePos = ImVec2(-FLT_MAX, -FLT_MAX); MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); - MouseDragThreshold = 6.0f; + MouseSource = ImGuiMouseSource_Mouse; for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; - for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f; - for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f; + for (int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; } + AppAcceptingEvents = true; + BackendUsingLegacyKeyArrays = (ImS8)-1; + BackendUsingLegacyNavInputArray = true; // assume using legacy array until proven wrong } // Pass in translated ASCII characters for text input. // - with glfw you can get those from the callback set in glfwSetCharCallback() // - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message +// FIXME: Should in theory be called "AddCharacterEvent()" to be consistent with new API void ImGuiIO::AddInputCharacter(unsigned int c) { - if (c != 0) - InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID); + IM_ASSERT(Ctx != NULL); + ImGuiContext& g = *Ctx; + if (c == 0 || !AppAcceptingEvents) + return; + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_Text; + e.Source = ImGuiInputSource_Keyboard; + e.EventId = g.InputEventsNextEventId++; + e.Text.Char = c; + g.InputEventsQueue.push_back(e); } // UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so // we should save the high surrogate. void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c) { - if (c == 0 && InputQueueSurrogate == 0) + if ((c == 0 && InputQueueSurrogate == 0) || !AppAcceptingEvents) return; if ((c & 0xFC00) == 0xD800) // High surrogate, must save { if (InputQueueSurrogate != 0) - InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID); + AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID); InputQueueSurrogate = c; return; } @@ -1155,7 +1313,7 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c) { if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate { - InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID); + AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID); } else { @@ -1168,41 +1326,248 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c) InputQueueSurrogate = 0; } - InputQueueCharacters.push_back(cp); + AddInputCharacter((unsigned)cp); } void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) { + if (!AppAcceptingEvents) + return; while (*utf8_chars != 0) { unsigned int c = 0; utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL); - if (c != 0) - InputQueueCharacters.push_back((ImWchar)c); + AddInputCharacter(c); } } +// FIXME: Perhaps we could clear queued events as well? void ImGuiIO::ClearInputCharacters() { InputQueueCharacters.resize(0); } +// FIXME: Perhaps we could clear queued events as well? void ImGuiIO::ClearInputKeys() { +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO memset(KeysDown, 0, sizeof(KeysDown)); - for (int n = 0; n < IM_ARRAYSIZE(KeysDownDuration); n++) - KeysDownDuration[n] = KeysDownDurationPrev[n] = -1.0f; +#endif + for (int n = 0; n < IM_ARRAYSIZE(KeysData); n++) + { + KeysData[n].Down = false; + KeysData[n].DownDuration = -1.0f; + KeysData[n].DownDurationPrev = -1.0f; + } KeyCtrl = KeyShift = KeyAlt = KeySuper = false; - KeyMods = KeyModsPrev = ImGuiKeyModFlags_None; - for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++) - NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f; + KeyMods = ImGuiMod_None; + MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + for (int n = 0; n < IM_ARRAYSIZE(MouseDown); n++) + { + MouseDown[n] = false; + MouseDownDuration[n] = MouseDownDurationPrev[n] = -1.0f; + } + MouseWheel = MouseWheelH = 0.0f; +} + +static ImGuiInputEvent* FindLatestInputEvent(ImGuiContext* ctx, ImGuiInputEventType type, int arg = -1) +{ + ImGuiContext& g = *ctx; + for (int n = g.InputEventsQueue.Size - 1; n >= 0; n--) + { + ImGuiInputEvent* e = &g.InputEventsQueue[n]; + if (e->Type != type) + continue; + if (type == ImGuiInputEventType_Key && e->Key.Key != arg) + continue; + if (type == ImGuiInputEventType_MouseButton && e->MouseButton.Button != arg) + continue; + return e; + } + return NULL; +} + +// Queue a new key down/up event. +// - ImGuiKey key: Translated key (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character) +// - bool down: Is the key down? use false to signify a key release. +// - float analog_value: 0.0f..1.0f +// IMPORTANT: THIS FUNCTION AND OTHER "ADD" GRABS THE CONTEXT FROM OUR INSTANCE. +// WE NEED TO ENSURE THAT ALL FUNCTION CALLS ARE FULLFILLING THIS, WHICH IS WHY GetKeyData() HAS AN EXPLICIT CONTEXT. +void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value) +{ + //if (e->Down) { IMGUI_DEBUG_LOG_IO("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); } + IM_ASSERT(Ctx != NULL); + if (key == ImGuiKey_None || !AppAcceptingEvents) + return; + ImGuiContext& g = *Ctx; + IM_ASSERT(ImGui::IsNamedKeyOrModKey(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API. + IM_ASSERT(ImGui::IsAliasKey(key) == false); // Backend cannot submit ImGuiKey_MouseXXX values they are automatically inferred from AddMouseXXX() events. + IM_ASSERT(key != ImGuiMod_Shortcut); // We could easily support the translation here but it seems saner to not accept it (TestEngine perform a translation itself) + + // Verify that backend isn't mixing up using new io.AddKeyEvent() api and old io.KeysDown[] + io.KeyMap[] data. +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + IM_ASSERT((BackendUsingLegacyKeyArrays == -1 || BackendUsingLegacyKeyArrays == 0) && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!"); + if (BackendUsingLegacyKeyArrays == -1) + for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++) + IM_ASSERT(KeyMap[n] == -1 && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!"); + BackendUsingLegacyKeyArrays = 0; +#endif + if (ImGui::IsGamepadKey(key)) + BackendUsingLegacyNavInputArray = false; + + // Filter duplicate (in particular: key mods and gamepad analog values are commonly spammed) + const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_Key, (int)key); + const ImGuiKeyData* key_data = ImGui::GetKeyData(&g, key); + const bool latest_key_down = latest_event ? latest_event->Key.Down : key_data->Down; + const float latest_key_analog = latest_event ? latest_event->Key.AnalogValue : key_data->AnalogValue; + if (latest_key_down == down && latest_key_analog == analog_value) + return; + + // Add event + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_Key; + e.Source = ImGui::IsGamepadKey(key) ? ImGuiInputSource_Gamepad : ImGuiInputSource_Keyboard; + e.EventId = g.InputEventsNextEventId++; + e.Key.Key = key; + e.Key.Down = down; + e.Key.AnalogValue = analog_value; + g.InputEventsQueue.push_back(e); +} + +void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down) +{ + if (!AppAcceptingEvents) + return; + AddKeyAnalogEvent(key, down, down ? 1.0f : 0.0f); +} + +// [Optional] Call after AddKeyEvent(). +// Specify native keycode, scancode + Specify index for legacy <1.87 IsKeyXXX() functions with native indices. +// If you are writing a backend in 2022 or don't use IsKeyXXX() with native values that are not ImGuiKey values, you can avoid calling this. +void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index) +{ + if (key == ImGuiKey_None) + return; + IM_ASSERT(ImGui::IsNamedKey(key)); // >= 512 + IM_ASSERT(native_legacy_index == -1 || ImGui::IsLegacyKey((ImGuiKey)native_legacy_index)); // >= 0 && <= 511 + IM_UNUSED(native_keycode); // Yet unused + IM_UNUSED(native_scancode); // Yet unused + + // Build native->imgui map so old user code can still call key functions with native 0..511 values. +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + const int legacy_key = (native_legacy_index != -1) ? native_legacy_index : native_keycode; + if (!ImGui::IsLegacyKey((ImGuiKey)legacy_key)) + return; + KeyMap[legacy_key] = key; + KeyMap[key] = legacy_key; +#else + IM_UNUSED(key); + IM_UNUSED(native_legacy_index); +#endif +} + +// Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen. +void ImGuiIO::SetAppAcceptingEvents(bool accepting_events) +{ + AppAcceptingEvents = accepting_events; +} + +// Queue a mouse move event +void ImGuiIO::AddMousePosEvent(float x, float y) +{ + IM_ASSERT(Ctx != NULL); + ImGuiContext& g = *Ctx; + if (!AppAcceptingEvents) + return; + + // Apply same flooring as UpdateMouseInputs() + ImVec2 pos((x > -FLT_MAX) ? ImFloorSigned(x) : x, (y > -FLT_MAX) ? ImFloorSigned(y) : y); + + // Filter duplicate + const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MousePos); + const ImVec2 latest_pos = latest_event ? ImVec2(latest_event->MousePos.PosX, latest_event->MousePos.PosY) : g.IO.MousePos; + if (latest_pos.x == pos.x && latest_pos.y == pos.y) + return; + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_MousePos; + e.Source = ImGuiInputSource_Mouse; + e.EventId = g.InputEventsNextEventId++; + e.MousePos.PosX = pos.x; + e.MousePos.PosY = pos.y; + e.MouseWheel.MouseSource = g.InputEventsNextMouseSource; + g.InputEventsQueue.push_back(e); +} + +void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down) +{ + IM_ASSERT(Ctx != NULL); + ImGuiContext& g = *Ctx; + IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT); + if (!AppAcceptingEvents) + return; + + // Filter duplicate + const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MouseButton, (int)mouse_button); + const bool latest_button_down = latest_event ? latest_event->MouseButton.Down : g.IO.MouseDown[mouse_button]; + if (latest_button_down == down) + return; + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_MouseButton; + e.Source = ImGuiInputSource_Mouse; + e.EventId = g.InputEventsNextEventId++; + e.MouseButton.Button = mouse_button; + e.MouseButton.Down = down; + e.MouseWheel.MouseSource = g.InputEventsNextMouseSource; + g.InputEventsQueue.push_back(e); +} + +// Queue a mouse wheel event (some mouse/API may only have a Y component) +void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y) +{ + IM_ASSERT(Ctx != NULL); + ImGuiContext& g = *Ctx; + + // Filter duplicate (unlike most events, wheel values are relative and easy to filter) + if (!AppAcceptingEvents || (wheel_x == 0.0f && wheel_y == 0.0f)) + return; + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_MouseWheel; + e.Source = ImGuiInputSource_Mouse; + e.EventId = g.InputEventsNextEventId++; + e.MouseWheel.WheelX = wheel_x; + e.MouseWheel.WheelY = wheel_y; + e.MouseWheel.MouseSource = g.InputEventsNextMouseSource; + g.InputEventsQueue.push_back(e); +} + +// This is not a real event, the data is latched in order to be stored in actual Mouse events. +// This is so that duplicate events (e.g. Windows sending extraneous WM_MOUSEMOVE) gets filtered and are not leading to actual source changes. +void ImGuiIO::AddMouseSourceEvent(ImGuiMouseSource source) +{ + IM_ASSERT(Ctx != NULL); + ImGuiContext& g = *Ctx; + g.InputEventsNextMouseSource = source; } void ImGuiIO::AddFocusEvent(bool focused) { - // We intentionally overwrite this and process in NewFrame(), in order to give a chance - // to multi-viewports backends to queue AddFocusEvent(false),AddFocusEvent(true) in same frame. - AppFocusLost = !focused; + IM_ASSERT(Ctx != NULL); + ImGuiContext& g = *Ctx; + + // Filter duplicate + const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_Focus); + const bool latest_focused = latest_event ? latest_event->AppFocused.Focused : !g.IO.AppFocusLost; + if (latest_focused == focused || (ConfigDebugIgnoreFocusLoss && !focused)) + return; + + ImGuiInputEvent e; + e.Type = ImGuiInputEventType_Focus; + e.EventId = g.InputEventsNextEventId++; + e.AppFocused.Focused = focused; + g.InputEventsQueue.push_back(e); } //----------------------------------------------------------------------------- @@ -1333,14 +1698,14 @@ ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, int ImStricmp(const char* str1, const char* str2) { int d; - while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } + while ((d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; } return d; } int ImStrnicmp(const char* str1, const char* str2, size_t count) { int d = 0; - while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } + while (count > 0 && (d = ImToUpper(*str2) - ImToUpper(*str1)) == 0 && *str1) { str1++; str2++; count--; } return d; } @@ -1407,14 +1772,14 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char if (!needle_end) needle_end = needle + strlen(needle); - const char un0 = (char)toupper(*needle); + const char un0 = (char)ImToUpper(*needle); while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end)) { - if (toupper(*haystack) == un0) + if (ImToUpper(*haystack) == un0) { const char* b = needle + 1; for (const char* a = haystack + 1; b < needle_end; a++, b++) - if (toupper(*a) != toupper(*b)) + if (ImToUpper(*a) != ImToUpper(*b)) break; if (b == needle_end) return haystack; @@ -1458,8 +1823,12 @@ const char* ImStrSkipBlank(const char* str) // designed using two-passes worst case, which probably could be improved using the stbsp_vsprintfcb() function.) #ifdef IMGUI_USE_STB_SPRINTF #define STB_SPRINTF_IMPLEMENTATION +#ifdef IMGUI_STB_SPRINTF_FILENAME +#include IMGUI_STB_SPRINTF_FILENAME +#else #include "stb_sprintf.h" #endif +#endif #if defined(_MSC_VER) && !defined(vsnprintf) #define vsnprintf _vsnprintf @@ -1499,6 +1868,43 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) } #endif // #ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS +void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) +{ + ImGuiContext& g = *GImGui; + va_list args; + va_start(args, fmt); + if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) + { + const char* buf = va_arg(args, const char*); // Skip formatting when using "%s" + *out_buf = buf; + if (out_buf_end) { *out_buf_end = buf + strlen(buf); } + } + else + { + int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args); + *out_buf = g.TempBuffer.Data; + if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; } + } + va_end(args); +} + +void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) +{ + ImGuiContext& g = *GImGui; + if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) + { + const char* buf = va_arg(args, const char*); // Skip formatting when using "%s" + *out_buf = buf; + if (out_buf_end) { *out_buf_end = buf + strlen(buf); } + } + else + { + int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args); + *out_buf = g.TempBuffer.Data; + if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; } + } +} + // CRC32 needs a 1KB lookup table (not cache friendly) // Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily: // - avoid an unnecessary branch/memory tap, - keep the ImHashXXX functions usable by static constructors, - make it thread-safe. @@ -1525,7 +1931,7 @@ static const ImU32 GCrc32LookupTable[256] = // Known size hash // It is ok to call ImHashData on a string with known length but the ### operator won't be supported. // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. -ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed) +ImGuiID ImHashData(const void* data_p, size_t data_size, ImGuiID seed) { ImU32 crc = ~seed; const unsigned char* data = (const unsigned char*)data_p; @@ -1541,7 +1947,7 @@ ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed) // - If we reach ### in the string we discard the hash so far and reset to the seed. // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build) // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. -ImGuiID ImHashStr(const char* data_p, size_t data_size, ImU32 seed) +ImGuiID ImHashStr(const char* data_p, size_t data_size, ImGuiID seed) { seed = ~seed; ImU32 crc = seed; @@ -1583,7 +1989,7 @@ ImFileHandle ImFileOpen(const char* filename, const char* mode) // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32! const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0); const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0); - ImVector buf; + ImVector buf; buf.resize(filename_wsize + mode_wsize); ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize); ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize); @@ -1646,6 +2052,8 @@ void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_f // [SECTION] MISC HELPERS/UTILITIES (ImText* functions) //----------------------------------------------------------------------------- +IM_MSVC_RUNTIME_CHECKS_OFF + // Convert UTF-8 to 32-bit character, process single character input. // A nearly-branchless UTF-8 decoder, based on work of Christopher Wellons (https://github.com/skeeto/branchless-utf8). // We handle UTF-8 decoding error by skipping forward. @@ -1657,7 +2065,7 @@ int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* static const int shiftc[] = { 0, 18, 12, 6, 0 }; static const int shifte[] = { 0, 6, 4, 2, 0 }; int len = lengths[*(const unsigned char*)in_text >> 3]; - int wanted = len + !len; + int wanted = len + (len ? 0 : 1); if (in_text_end == NULL) in_text_end = in_text + wanted; // Max length, nulls will be taken into account. @@ -1709,8 +2117,6 @@ int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const cha { unsigned int c; in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); - if (c == 0) - break; *buf_out++ = (ImWchar)c; } *buf_out = 0; @@ -1726,8 +2132,6 @@ int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end) { unsigned int c; in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); - if (c == 0) - break; char_count++; } return char_count; @@ -1821,6 +2225,7 @@ int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_e } return bytes_count; } +IM_MSVC_RUNTIME_CHECKS_RESTORE //----------------------------------------------------------------------------- // [SECTION] MISC HELPERS/UTILITIES (Color functions) @@ -1940,7 +2345,7 @@ void ImGuiStorage::BuildSortByKey() { struct StaticFunc { - static int IMGUI_CDECL PairCompareByID(const void* lhs, const void* rhs) + static int IMGUI_CDECL PairComparerByID(const void* lhs, const void* rhs) { // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that. if (((const ImGuiStoragePair*)lhs)->key > ((const ImGuiStoragePair*)rhs)->key) return +1; @@ -1948,8 +2353,7 @@ void ImGuiStorage::BuildSortByKey() return 0; } }; - if (Data.Size > 1) - ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), StaticFunc::PairCompareByID); + ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), StaticFunc::PairComparerByID); } int ImGuiStorage::GetInt(ImGuiID key, int default_val) const @@ -2061,18 +2465,15 @@ void ImGuiStorage::SetAllInt(int v) //----------------------------------------------------------------------------- // Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" -ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) +ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) //-V1077 { + InputBuf[0] = 0; + CountGrep = 0; if (default_filter) { ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf)); Build(); } - else - { - InputBuf[0] = 0; - CountGrep = 0; - } } bool ImGuiTextFilter::Draw(const char* label, float width) @@ -2159,7 +2560,7 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const } //----------------------------------------------------------------------------- -// [SECTION] ImGuiTextBuffer +// [SECTION] ImGuiTextBuffer, ImGuiTextIndex //----------------------------------------------------------------------------- // On some platform vsnprintf() takes va_list by reference and modifies it. @@ -2227,6 +2628,20 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) va_end(args_copy); } +void ImGuiTextIndex::append(const char* base, int old_size, int new_size) +{ + IM_ASSERT(old_size >= 0 && new_size >= old_size && new_size >= EndOffset); + if (old_size == new_size) + return; + if (EndOffset == 0 || base[EndOffset - 1] == '\n') + LineOffsets.push_back(EndOffset); + const char* base_end = base + new_size; + for (const char* p = base + old_size; (p = (const char*)memchr(p, '\n', base_end - p)) != 0; ) + if (++p < base_end) // Don't push a trailing offset on last \n + LineOffsets.push_back((int)(intptr_t)(p - base)); + EndOffset = ImMax(EndOffset, new_size); +} + //----------------------------------------------------------------------------- // [SECTION] ImGuiListClipper // This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed @@ -2241,9 +2656,10 @@ static bool GetSkipItemForListClipping() return (g.CurrentTable ? g.CurrentTable->HostSkipItems : g.CurrentWindow->SkipItems); } -// Helper to calculate coarse clipping of large list of evenly sized items. -// NB: Prefer using the ImGuiListClipper higher-level helper if you can! Read comments and instructions there on how those use this sort of pattern. -// NB: 'items_count' is only used to clamp the result, if you don't know your count you can use INT_MAX +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +// Legacy helper to calculate coarse clipping of large list of evenly sized items. +// This legacy API is not ideal because it assumes we will return a single contiguous rectangle. +// Prefer using ImGuiListClipper which can returns non-contiguous ranges. void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) { ImGuiContext& g = *GImGui; @@ -2262,20 +2678,23 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items } // We create the union of the ClipRect and the scoring rect which at worst should be 1 page away from ClipRect - ImRect unclipped_rect = window->ClipRect; + // We don't include g.NavId's rectangle in there (unless g.NavJustMovedToId is set) because the rectangle enlargement can get costly. + ImRect rect = window->ClipRect; if (g.NavMoveScoringItems) - unclipped_rect.Add(g.NavScoringRect); + rect.Add(g.NavScoringNoClipRect); if (g.NavJustMovedToId && window->NavLastIds[0] == g.NavJustMovedToId) - unclipped_rect.Add(ImRect(window->Pos + window->NavRectRel[0].Min, window->Pos + window->NavRectRel[0].Max)); // Could store and use NavJustMovedToRectRel + rect.Add(WindowRectRelToAbs(window, window->NavRectRel[0])); // Could store and use NavJustMovedToRectRel const ImVec2 pos = window->DC.CursorPos; - int start = (int)((unclipped_rect.Min.y - pos.y) / items_height); - int end = (int)((unclipped_rect.Max.y - pos.y) / items_height); + int start = (int)((rect.Min.y - pos.y) / items_height); + int end = (int)((rect.Max.y - pos.y) / items_height); // When performing a navigation request, ensure we have one item extra in the direction we are moving to - if (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Up) + // FIXME: Verify this works with tabbing + const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) start--; - if (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Down) + if (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) end++; start = ImClamp(start, 0, items_count); @@ -2283,17 +2702,42 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items *out_items_display_start = start; *out_items_display_end = end; } +#endif -static void SetCursorPosYAndSetupForPrevLine(float pos_y, float line_height) +static void ImGuiListClipper_SortAndFuseRanges(ImVector& ranges, int offset = 0) +{ + if (ranges.Size - offset <= 1) + return; + + // Helper to order ranges and fuse them together if possible (bubble sort is fine as we are only sorting 2-3 entries) + for (int sort_end = ranges.Size - offset - 1; sort_end > 0; --sort_end) + for (int i = offset; i < sort_end + offset; ++i) + if (ranges[i].Min > ranges[i + 1].Min) + ImSwap(ranges[i], ranges[i + 1]); + + // Now fuse ranges together as much as possible. + for (int i = 1 + offset; i < ranges.Size; i++) + { + IM_ASSERT(!ranges[i].PosToIndexConvert && !ranges[i - 1].PosToIndexConvert); + if (ranges[i - 1].Max < ranges[i].Min) + continue; + ranges[i - 1].Min = ImMin(ranges[i - 1].Min, ranges[i].Min); + ranges[i - 1].Max = ImMax(ranges[i - 1].Max, ranges[i].Max); + ranges.erase(ranges.Data + i); + i--; + } +} + +static void ImGuiListClipper_SeekCursorAndSetupPrevLine(float pos_y, float line_height) { // Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor. // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. - // The clipper should probably have a 4th step to display the last item in a regular manner. + // The clipper should probably have a final step to display the last item in a regular manner, maybe with an opt-out flag for data sets which may have costly seek? ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; float off_y = pos_y - window->DC.CursorPos.y; window->DC.CursorPos.y = pos_y; - window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y); + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y - g.Style.ItemSpacing.y); window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage. window->DC.PrevLineSize.y = (line_height - g.Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. if (ImGuiOldColumns* columns = window->DC.CurrentColumns) @@ -2309,24 +2753,33 @@ static void SetCursorPosYAndSetupForPrevLine(float pos_y, float line_height) } } +static void ImGuiListClipper_SeekCursorForItem(ImGuiListClipper* clipper, int item_n) +{ + // StartPosY starts from ItemsFrozen hence the subtraction + // Perform the add and multiply with double to allow seeking through larger ranges + ImGuiListClipperData* data = (ImGuiListClipperData*)clipper->TempData; + float pos_y = (float)((double)clipper->StartPosY + data->LossynessOffset + (double)(item_n - data->ItemsFrozen) * clipper->ItemsHeight); + ImGuiListClipper_SeekCursorAndSetupPrevLine(pos_y, clipper->ItemsHeight); +} + ImGuiListClipper::ImGuiListClipper() { memset(this, 0, sizeof(*this)); - ItemsCount = -1; } ImGuiListClipper::~ImGuiListClipper() { - IM_ASSERT(ItemsCount == -1 && "Forgot to call End(), or to Step() until false?"); + End(); } -// Use case A: Begin() called from constructor with items_height<0, then called again from Step() in StepNo 1 -// Use case B: Begin() called from constructor with items_height>0 -// FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style. void ImGuiListClipper::Begin(int items_count, float items_height) { - ImGuiContext& g = *GImGui; + if (Ctx == NULL) + Ctx = ImGui::GetCurrentContext(); + + ImGuiContext& g = *Ctx; ImGuiWindow* window = g.CurrentWindow; + IMGUI_DEBUG_LOG_CLIPPER("Clipper: Begin(%d,%.2f) in '%s'\n", items_count, items_height, window->Name); if (ImGuiTable* table = g.CurrentTable) if (table->IsInsideRow) @@ -2335,127 +2788,196 @@ void ImGuiListClipper::Begin(int items_count, float items_height) StartPosY = window->DC.CursorPos.y; ItemsHeight = items_height; ItemsCount = items_count; - ItemsFrozen = 0; - StepNo = 0; DisplayStart = -1; DisplayEnd = 0; + + // Acquire temporary buffer + if (++g.ClipperTempDataStacked > g.ClipperTempData.Size) + g.ClipperTempData.resize(g.ClipperTempDataStacked, ImGuiListClipperData()); + ImGuiListClipperData* data = &g.ClipperTempData[g.ClipperTempDataStacked - 1]; + data->Reset(this); + data->LossynessOffset = window->DC.CursorStartPosLossyness.y; + TempData = data; } void ImGuiListClipper::End() { - if (ItemsCount < 0) // Already ended - return; + if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData) + { + // In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user. + ImGuiContext& g = *Ctx; + IMGUI_DEBUG_LOG_CLIPPER("Clipper: End() in '%s'\n", g.CurrentWindow->Name); + if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0) + ImGuiListClipper_SeekCursorForItem(this, ItemsCount); - // In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user. - if (ItemsCount < INT_MAX && DisplayStart >= 0) - SetCursorPosYAndSetupForPrevLine(StartPosY + (ItemsCount - ItemsFrozen) * ItemsHeight, ItemsHeight); + // Restore temporary buffer and fix back pointers which may be invalidated when nesting + IM_ASSERT(data->ListClipper == this); + data->StepNo = data->Ranges.Size; + if (--g.ClipperTempDataStacked > 0) + { + data = &g.ClipperTempData[g.ClipperTempDataStacked - 1]; + data->ListClipper->TempData = data; + } + TempData = NULL; + } ItemsCount = -1; - StepNo = 3; } -bool ImGuiListClipper::Step() +void ImGuiListClipper::IncludeRangeByIndices(int item_begin, int item_end) { - ImGuiContext& g = *GImGui; + ImGuiListClipperData* data = (ImGuiListClipperData*)TempData; + IM_ASSERT(DisplayStart < 0); // Only allowed after Begin() and if there has not been a specified range yet. + IM_ASSERT(item_begin <= item_end); + if (item_begin < item_end) + data->Ranges.push_back(ImGuiListClipperRange::FromIndices(item_begin, item_end)); +} + +static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper) +{ + ImGuiContext& g = *clipper->Ctx; ImGuiWindow* window = g.CurrentWindow; + ImGuiListClipperData* data = (ImGuiListClipperData*)clipper->TempData; + IM_ASSERT(data != NULL && "Called ImGuiListClipper::Step() too many times, or before ImGuiListClipper::Begin() ?"); ImGuiTable* table = g.CurrentTable; if (table && table->IsInsideRow) ImGui::TableEndRow(table); // No items - if (ItemsCount == 0 || GetSkipItemForListClipping()) - { - End(); + if (clipper->ItemsCount == 0 || GetSkipItemForListClipping()) return false; - } - // Step 0: Let you process the first element (regardless of it being visible or not, so we can measure the element height) - if (StepNo == 0) + // While we are in frozen row state, keep displaying items one by one, unclipped + // FIXME: Could be stored as a table-agnostic state. + if (data->StepNo == 0 && table != NULL && !table->IsUnfrozenRows) { - // While we are in frozen row state, keep displaying items one by one, unclipped - // FIXME: Could be stored as a table-agnostic state. - if (table != NULL && !table->IsUnfrozenRows) - { - DisplayStart = ItemsFrozen; - DisplayEnd = ItemsFrozen + 1; - ItemsFrozen++; - return true; - } - - StartPosY = window->DC.CursorPos.y; - if (ItemsHeight <= 0.0f) - { - // Submit the first item so we can measure its height (generally it is 0..1) - DisplayStart = ItemsFrozen; - DisplayEnd = ItemsFrozen + 1; - StepNo = 1; - return true; - } - - // Already has item height (given by user in Begin): skip to calculating step - DisplayStart = DisplayEnd; - StepNo = 2; - } - - // Step 1: the clipper infer height from first element - if (StepNo == 1) - { - IM_ASSERT(ItemsHeight <= 0.0f); - if (table) - { - const float pos_y1 = table->RowPosY1; // Using this instead of StartPosY to handle clipper straddling the frozen row - const float pos_y2 = table->RowPosY2; // Using this instead of CursorPos.y to take account of tallest cell. - ItemsHeight = pos_y2 - pos_y1; - window->DC.CursorPos.y = pos_y2; - } - else - { - ItemsHeight = window->DC.CursorPos.y - StartPosY; - } - IM_ASSERT(ItemsHeight > 0.0f && "Unable to calculate item height! First item hasn't moved the cursor vertically!"); - StepNo = 2; - } - - // Reached end of list - if (DisplayEnd >= ItemsCount) - { - End(); - return false; - } - - // Step 2: calculate the actual range of elements to display, and position the cursor before the first element - if (StepNo == 2) - { - IM_ASSERT(ItemsHeight > 0.0f); - - int already_submitted = DisplayEnd; - ImGui::CalcListClipping(ItemsCount - already_submitted, ItemsHeight, &DisplayStart, &DisplayEnd); - DisplayStart += already_submitted; - DisplayEnd += already_submitted; - - // Seek cursor - if (DisplayStart > already_submitted) - SetCursorPosYAndSetupForPrevLine(StartPosY + (DisplayStart - ItemsFrozen) * ItemsHeight, ItemsHeight); - - StepNo = 3; + clipper->DisplayStart = data->ItemsFrozen; + clipper->DisplayEnd = ImMin(data->ItemsFrozen + 1, clipper->ItemsCount); + if (clipper->DisplayStart < clipper->DisplayEnd) + data->ItemsFrozen++; return true; } - // Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), - // Advance the cursor to the end of the list and then returns 'false' to end the loop. - if (StepNo == 3) + // Step 0: Let you process the first element (regardless of it being visible or not, so we can measure the element height) + bool calc_clipping = false; + if (data->StepNo == 0) { - // Seek cursor - if (ItemsCount < INT_MAX) - SetCursorPosYAndSetupForPrevLine(StartPosY + (ItemsCount - ItemsFrozen) * ItemsHeight, ItemsHeight); // advance cursor - ItemsCount = -1; - return false; + clipper->StartPosY = window->DC.CursorPos.y; + if (clipper->ItemsHeight <= 0.0f) + { + // Submit the first item (or range) so we can measure its height (generally the first range is 0..1) + data->Ranges.push_front(ImGuiListClipperRange::FromIndices(data->ItemsFrozen, data->ItemsFrozen + 1)); + clipper->DisplayStart = ImMax(data->Ranges[0].Min, data->ItemsFrozen); + clipper->DisplayEnd = ImMin(data->Ranges[0].Max, clipper->ItemsCount); + data->StepNo = 1; + return true; + } + calc_clipping = true; // If on the first step with known item height, calculate clipping. } - IM_ASSERT(0); + // Step 1: Let the clipper infer height from first range + if (clipper->ItemsHeight <= 0.0f) + { + IM_ASSERT(data->StepNo == 1); + if (table) + IM_ASSERT(table->RowPosY1 == clipper->StartPosY && table->RowPosY2 == window->DC.CursorPos.y); + + clipper->ItemsHeight = (window->DC.CursorPos.y - clipper->StartPosY) / (float)(clipper->DisplayEnd - clipper->DisplayStart); + bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y); + if (affected_by_floating_point_precision) + clipper->ItemsHeight = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y; // FIXME: Technically wouldn't allow multi-line entries. + + IM_ASSERT(clipper->ItemsHeight > 0.0f && "Unable to calculate item height! First item hasn't moved the cursor vertically!"); + calc_clipping = true; // If item height had to be calculated, calculate clipping afterwards. + } + + // Step 0 or 1: Calculate the actual ranges of visible elements. + const int already_submitted = clipper->DisplayEnd; + if (calc_clipping) + { + if (g.LogEnabled) + { + // If logging is active, do not perform any clipping + data->Ranges.push_back(ImGuiListClipperRange::FromIndices(0, clipper->ItemsCount)); + } + else + { + // Add range selected to be included for navigation + const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + if (is_nav_request) + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0)); + if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && g.NavTabbingDir == -1) + data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount)); + + // Add focused/active item + ImRect nav_rect_abs = ImGui::WindowRectRelToAbs(window, window->NavRectRel[0]); + if (g.NavId != 0 && window->NavLastIds[0] == g.NavId) + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(nav_rect_abs.Min.y, nav_rect_abs.Max.y, 0, 0)); + + // Add visible range + const int off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0; + const int off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0; + data->Ranges.push_back(ImGuiListClipperRange::FromPositions(window->ClipRect.Min.y, window->ClipRect.Max.y, off_min, off_max)); + } + + // Convert position ranges to item index ranges + // - Very important: when a starting position is after our maximum item, we set Min to (ItemsCount - 1). This allows us to handle most forms of wrapping. + // - Due to how Selectable extra padding they tend to be "unaligned" with exact unit in the item list, + // which with the flooring/ceiling tend to lead to 2 items instead of one being submitted. + for (int i = 0; i < data->Ranges.Size; i++) + if (data->Ranges[i].PosToIndexConvert) + { + int m1 = (int)(((double)data->Ranges[i].Min - window->DC.CursorPos.y - data->LossynessOffset) / clipper->ItemsHeight); + int m2 = (int)((((double)data->Ranges[i].Max - window->DC.CursorPos.y - data->LossynessOffset) / clipper->ItemsHeight) + 0.999999f); + data->Ranges[i].Min = ImClamp(already_submitted + m1 + data->Ranges[i].PosToIndexOffsetMin, already_submitted, clipper->ItemsCount - 1); + data->Ranges[i].Max = ImClamp(already_submitted + m2 + data->Ranges[i].PosToIndexOffsetMax, data->Ranges[i].Min + 1, clipper->ItemsCount); + data->Ranges[i].PosToIndexConvert = false; + } + ImGuiListClipper_SortAndFuseRanges(data->Ranges, data->StepNo); + } + + // Step 0+ (if item height is given in advance) or 1+: Display the next range in line. + if (data->StepNo < data->Ranges.Size) + { + clipper->DisplayStart = ImMax(data->Ranges[data->StepNo].Min, already_submitted); + clipper->DisplayEnd = ImMin(data->Ranges[data->StepNo].Max, clipper->ItemsCount); + if (clipper->DisplayStart > already_submitted) //-V1051 + ImGuiListClipper_SeekCursorForItem(clipper, clipper->DisplayStart); + data->StepNo++; + return true; + } + + // After the last step: Let the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), + // Advance the cursor to the end of the list and then returns 'false' to end the loop. + if (clipper->ItemsCount < INT_MAX) + ImGuiListClipper_SeekCursorForItem(clipper, clipper->ItemsCount); + return false; } +bool ImGuiListClipper::Step() +{ + ImGuiContext& g = *Ctx; + bool need_items_height = (ItemsHeight <= 0.0f); + bool ret = ImGuiListClipper_StepInternal(this); + if (ret && (DisplayStart == DisplayEnd)) + ret = false; + if (g.CurrentTable && g.CurrentTable->IsUnfrozenRows == false) + IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): inside frozen table row.\n"); + if (need_items_height && ItemsHeight > 0.0f) + IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): computed ItemsHeight: %.2f.\n", ItemsHeight); + if (ret) + { + IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): display %d to %d.\n", DisplayStart, DisplayEnd); + } + else + { + IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): End.\n"); + End(); + } + return ret; +} + //----------------------------------------------------------------------------- // [SECTION] STYLING //----------------------------------------------------------------------------- @@ -2522,6 +3044,11 @@ void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) void ImGui::PopStyleColor(int count) { ImGuiContext& g = *GImGui; + if (g.ColorStack.Size < count) + { + IM_ASSERT_USER_ERROR(g.ColorStack.Size > count, "Calling PopStyleColor() too many times: stack underflow."); + count = g.ColorStack.Size; + } while (count > 0) { ImGuiColorMod& backup = g.ColorStack.back(); @@ -2531,15 +3058,7 @@ void ImGui::PopStyleColor(int count) } } -struct ImGuiStyleVarInfo -{ - ImGuiDataType Type; - ImU32 Count; - ImU32 Offset; - void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } -}; - -static const ImGuiStyleVarInfo GStyleVarInfo[] = +static const ImGuiDataVarInfo GStyleVarInfo[] = { { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha @@ -2566,51 +3085,59 @@ static const ImGuiStyleVarInfo GStyleVarInfo[] = { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextBorderSize) },// ImGuiStyleVar_SeparatorTextBorderSize + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign + { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding }; -static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) +const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx) { IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT); - IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT); + IM_STATIC_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT); return &GStyleVarInfo[idx]; } void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) { - const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + ImGuiContext& g = *GImGui; + const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx); if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1) { - ImGuiContext& g = *GImGui; float* pvar = (float*)var_info->GetVarPtr(&g.Style); g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar)); *pvar = val; return; } - IM_ASSERT(0 && "Called PushStyleVar() float variant but variable is not a float!"); + IM_ASSERT_USER_ERROR(0, "Called PushStyleVar() variant with wrong type!"); } void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) { - const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + ImGuiContext& g = *GImGui; + const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx); if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2) { - ImGuiContext& g = *GImGui; ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style); g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar)); *pvar = val; return; } - IM_ASSERT(0 && "Called PushStyleVar() ImVec2 variant but variable is not a ImVec2!"); + IM_ASSERT_USER_ERROR(0, "Called PushStyleVar() variant with wrong type!"); } void ImGui::PopStyleVar(int count) { ImGuiContext& g = *GImGui; + if (g.StyleVarStack.Size < count) + { + IM_ASSERT_USER_ERROR(g.StyleVarStack.Size > count, "Calling PopStyleVar() too many times: stack underflow."); + count = g.StyleVarStack.Size; + } while (count > 0) { // We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it. ImGuiStyleMod& backup = g.StyleVarStack.back(); - const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx); + const ImGuiDataVarInfo* info = GetStyleVarInfo(backup.VarIdx); void* data = info->GetVarPtr(&g.Style); if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; } else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; } @@ -2747,6 +3274,9 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end // Default clip_rect uses (pos_min,pos_max) // Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges) +// FIXME-OPT: Since we have or calculate text_size we could coarse clip whole block immediately, especally for text above draw_list->DrawList. +// Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take +// better advantage of the render function taking size into account for coarse clipping. void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) { // Perform CPU side clipping for single clipped element to avoid using scissor state @@ -2790,7 +3320,6 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons LogRenderedText(&pos_min, text, text_display_end); } - // Another overly complex function until we reorganize everything into a nice all-in-one helper. // This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display. // This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move. @@ -2814,30 +3343,12 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con const ImFont* font = draw_list->_Data->Font; const float font_size = draw_list->_Data->FontSize; + const float font_scale = font_size / font->FontSize; const char* text_end_ellipsis = NULL; - - ImWchar ellipsis_char = font->EllipsisChar; - int ellipsis_char_count = 1; - if (ellipsis_char == (ImWchar)-1) - { - ellipsis_char = font->DotChar; - ellipsis_char_count = 3; - } - const ImFontGlyph* glyph = font->FindGlyph(ellipsis_char); - - float ellipsis_glyph_width = glyph->X1; // Width of the glyph with no padding on either side - float ellipsis_total_width = ellipsis_glyph_width; // Full width of entire ellipsis - - if (ellipsis_char_count > 1) - { - // Full ellipsis size without free spacing after it. - const float spacing_between_dots = 1.0f * (draw_list->_Data->FontSize / font->FontSize); - ellipsis_glyph_width = glyph->X1 - glyph->X0 + spacing_between_dots; - ellipsis_total_width = ellipsis_glyph_width * (float)ellipsis_char_count - spacing_between_dots; - } + const float ellipsis_width = font->EllipsisWidth * font_scale; // We can now claim the space between pos_max.x and ellipsis_max.x - const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_total_width) - pos_min.x, 1.0f); + const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_width) - pos_min.x, 1.0f); float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x; if (text == text_end_ellipsis && text_end_ellipsis < text_end_full) { @@ -2854,13 +3365,10 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con // Render text, render ellipsis RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f)); - float ellipsis_x = pos_min.x + text_size_clipped_x; - if (ellipsis_x + ellipsis_total_width <= ellipsis_max_x) - for (int i = 0; i < ellipsis_char_count; i++) - { - font->RenderChar(draw_list, font_size, ImVec2(ellipsis_x, pos_min.y), GetColorU32(ImGuiCol_Text), ellipsis_char); - ellipsis_x += ellipsis_glyph_width; - } + ImVec2 ellipsis_pos = ImFloor(ImVec2(pos_min.x + text_size_clipped_x, pos_min.y)); + if (ellipsis_pos.x + ellipsis_width <= ellipsis_max_x) + for (int i = 0; i < font->EllipsisCharCount; i++, ellipsis_pos.x += font->EllipsisCharStep * font_scale) + font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar); } else { @@ -2929,14 +3437,260 @@ void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFl } } +void ImGui::RenderMouseCursor(ImVec2 base_pos, float base_scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(mouse_cursor > ImGuiMouseCursor_None && mouse_cursor < ImGuiMouseCursor_COUNT); + ImFontAtlas* font_atlas = g.DrawListSharedData.Font->ContainerAtlas; + for (int n = 0; n < g.Viewports.Size; n++) + { + // We scale cursor with current viewport/monitor, however Windows 10 for its own hardware cursor seems to be using a different scale factor. + ImVec2 offset, size, uv[4]; + if (!font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2])) + continue; + ImGuiViewportP* viewport = g.Viewports[n]; + const ImVec2 pos = base_pos - offset; + const float scale = base_scale; + if (!viewport->GetMainRect().Overlaps(ImRect(pos, pos + ImVec2(size.x + 2, size.y + 2) * scale))) + continue; + ImDrawList* draw_list = GetForegroundDrawList(viewport); + ImTextureID tex_id = font_atlas->TexID; + draw_list->PushTextureID(tex_id); + draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow); + draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow); + draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border); + draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill); + draw_list->PopTextureID(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] INITIALIZATION, SHUTDOWN +//----------------------------------------------------------------------------- + +// Internal state access - if you want to share Dear ImGui state between modules (e.g. DLL) or allocate it yourself +// Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module +ImGuiContext* ImGui::GetCurrentContext() +{ + return GImGui; +} + +void ImGui::SetCurrentContext(ImGuiContext* ctx) +{ +#ifdef IMGUI_SET_CURRENT_CONTEXT_FUNC + IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx); // For custom thread-based hackery you may want to have control over this. +#else + GImGui = ctx; +#endif +} + +void ImGui::SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data) +{ + GImAllocatorAllocFunc = alloc_func; + GImAllocatorFreeFunc = free_func; + GImAllocatorUserData = user_data; +} + +// This is provided to facilitate copying allocators from one static/DLL boundary to another (e.g. retrieve default allocator of your executable address space) +void ImGui::GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data) +{ + *p_alloc_func = GImAllocatorAllocFunc; + *p_free_func = GImAllocatorFreeFunc; + *p_user_data = GImAllocatorUserData; +} + +ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas) +{ + ImGuiContext* prev_ctx = GetCurrentContext(); + ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas); + SetCurrentContext(ctx); + Initialize(); + if (prev_ctx != NULL) + SetCurrentContext(prev_ctx); // Restore previous context if any, else keep new one. + return ctx; +} + +void ImGui::DestroyContext(ImGuiContext* ctx) +{ + ImGuiContext* prev_ctx = GetCurrentContext(); + if (ctx == NULL) //-V1051 + ctx = prev_ctx; + SetCurrentContext(ctx); + Shutdown(); + SetCurrentContext((prev_ctx != ctx) ? prev_ctx : NULL); + IM_DELETE(ctx); +} + +// IMPORTANT: ###xxx suffixes must be same in ALL languages +static const ImGuiLocEntry GLocalizationEntriesEnUS[] = +{ + { ImGuiLocKey_VersionStr, "Dear ImGui " IMGUI_VERSION " (" IM_STRINGIFY(IMGUI_VERSION_NUM) ")" }, + { ImGuiLocKey_TableSizeOne, "Size column to fit###SizeOne" }, + { ImGuiLocKey_TableSizeAllFit, "Size all columns to fit###SizeAll" }, + { ImGuiLocKey_TableSizeAllDefault, "Size all columns to default###SizeAll" }, + { ImGuiLocKey_TableResetOrder, "Reset order###ResetOrder" }, + { ImGuiLocKey_WindowingMainMenuBar, "(Main menu bar)" }, + { ImGuiLocKey_WindowingPopup, "(Popup)" }, + { ImGuiLocKey_WindowingUntitled, "(Untitled)" }, +}; + +void ImGui::Initialize() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(!g.Initialized && !g.SettingsLoaded); + + // Add .ini handle for ImGuiWindow and ImGuiTable types + { + ImGuiSettingsHandler ini_handler; + ini_handler.TypeName = "Window"; + ini_handler.TypeHash = ImHashStr("Window"); + ini_handler.ClearAllFn = WindowSettingsHandler_ClearAll; + ini_handler.ReadOpenFn = WindowSettingsHandler_ReadOpen; + ini_handler.ReadLineFn = WindowSettingsHandler_ReadLine; + ini_handler.ApplyAllFn = WindowSettingsHandler_ApplyAll; + ini_handler.WriteAllFn = WindowSettingsHandler_WriteAll; + AddSettingsHandler(&ini_handler); + } + TableSettingsAddSettingsHandler(); + + // Setup default localization table + LocalizeRegisterEntries(GLocalizationEntriesEnUS, IM_ARRAYSIZE(GLocalizationEntriesEnUS)); + + // Setup default platform clipboard/IME handlers. + g.IO.GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations + g.IO.SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; + g.IO.ClipboardUserData = (void*)&g; // Default implementation use the ImGuiContext as user data (ideally those would be arguments to the function) + g.IO.SetPlatformImeDataFn = SetPlatformImeDataFn_DefaultImpl; + + // Create default viewport + ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)(); + g.Viewports.push_back(viewport); + g.TempBuffer.resize(1024 * 3 + 1, 0); + +#ifdef IMGUI_HAS_DOCK +#endif + + g.Initialized = true; +} + +// This function is merely here to free heap allocations. +void ImGui::Shutdown() +{ + // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) + ImGuiContext& g = *GImGui; + if (g.IO.Fonts && g.FontAtlasOwnedByContext) + { + g.IO.Fonts->Locked = false; + IM_DELETE(g.IO.Fonts); + } + g.IO.Fonts = NULL; + g.DrawListSharedData.TempBuffer.clear(); + + // Cleanup of other data are conditional on actually having initialized Dear ImGui. + if (!g.Initialized) + return; + + // Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file) + if (g.SettingsLoaded && g.IO.IniFilename != NULL) + SaveIniSettingsToDisk(g.IO.IniFilename); + + CallContextHooks(&g, ImGuiContextHookType_Shutdown); + + // Clear everything else + g.Windows.clear_delete(); + g.WindowsFocusOrder.clear(); + g.WindowsTempSortBuffer.clear(); + g.CurrentWindow = NULL; + g.CurrentWindowStack.clear(); + g.WindowsById.Clear(); + g.NavWindow = NULL; + g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL; + g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL; + g.MovingWindow = NULL; + + g.KeysRoutingTable.Clear(); + + g.ColorStack.clear(); + g.StyleVarStack.clear(); + g.FontStack.clear(); + g.OpenPopupStack.clear(); + g.BeginPopupStack.clear(); + + g.Viewports.clear_delete(); + + g.TabBars.Clear(); + g.CurrentTabBarStack.clear(); + g.ShrinkWidthBuffer.clear(); + + g.ClipperTempData.clear_destruct(); + + g.Tables.Clear(); + g.TablesTempData.clear_destruct(); + g.DrawChannelsTempMergeBuffer.clear(); + + g.ClipboardHandlerData.clear(); + g.MenusIdSubmittedThisFrame.clear(); + g.InputTextState.ClearFreeMemory(); + g.InputTextDeactivatedState.ClearFreeMemory(); + + g.SettingsWindows.clear(); + g.SettingsHandlers.clear(); + + if (g.LogFile) + { +#ifndef IMGUI_DISABLE_TTY_FUNCTIONS + if (g.LogFile != stdout) +#endif + ImFileClose(g.LogFile); + g.LogFile = NULL; + } + g.LogBuffer.clear(); + g.DebugLogBuf.clear(); + g.DebugLogIndex.clear(); + + g.Initialized = false; +} + +// No specific ordering/dependency support, will see as needed +ImGuiID ImGui::AddContextHook(ImGuiContext* ctx, const ImGuiContextHook* hook) +{ + ImGuiContext& g = *ctx; + IM_ASSERT(hook->Callback != NULL && hook->HookId == 0 && hook->Type != ImGuiContextHookType_PendingRemoval_); + g.Hooks.push_back(*hook); + g.Hooks.back().HookId = ++g.HookIdNext; + return g.HookIdNext; +} + +// Deferred removal, avoiding issue with changing vector while iterating it +void ImGui::RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_id) +{ + ImGuiContext& g = *ctx; + IM_ASSERT(hook_id != 0); + for (int n = 0; n < g.Hooks.Size; n++) + if (g.Hooks[n].HookId == hook_id) + g.Hooks[n].Type = ImGuiContextHookType_PendingRemoval_; +} + +// Call context hooks (used by e.g. test engine) +// We assume a small number of hooks so all stored in same array +void ImGui::CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType hook_type) +{ + ImGuiContext& g = *ctx; + for (int n = 0; n < g.Hooks.Size; n++) + if (g.Hooks[n].Type == hook_type) + g.Hooks[n].Callback(&g, &g.Hooks[n]); +} + + //----------------------------------------------------------------------------- // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!) //----------------------------------------------------------------------------- // ImGuiWindow is mostly a dumb struct. It merely has a constructor and a few helper methods -ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst(NULL) +ImGuiWindow::ImGuiWindow(ImGuiContext* ctx, const char* name) : DrawListInst(NULL) { memset(this, 0, sizeof(*this)); + Ctx = ctx; Name = ImStrdup(name); NameBufLen = (int)strlen(name) + 1; ID = ImHashStr(name); @@ -2946,15 +3700,16 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); AutoFitFramesX = AutoFitFramesY = -1; AutoPosLastDirection = ImGuiDir_None; - SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; + SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = 0; SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); LastFrameActive = -1; LastTimeActive = -1.0f; FontWindowScale = 1.0f; SettingsOffset = -1; DrawList = &DrawListInst; - DrawList->_Data = &context->DrawListSharedData; + DrawList->_Data = &Ctx->DrawListSharedData; DrawList->_OwnerName = Name; + NavPreferredScoringPosRel[0] = NavPreferredScoringPosRel[1] = ImVec2(FLT_MAX, FLT_MAX); } ImGuiWindow::~ImGuiWindow() @@ -2968,8 +3723,7 @@ ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) { ImGuiID seed = IDStack.back(); ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); - ImGui::KeepAliveID(id); - ImGuiContext& g = *GImGui; + ImGuiContext& g = *Ctx; if (g.DebugHookIdInfo == id) ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); return id; @@ -2979,8 +3733,7 @@ ImGuiID ImGuiWindow::GetID(const void* ptr) { ImGuiID seed = IDStack.back(); ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); - ImGui::KeepAliveID(id); - ImGuiContext& g = *GImGui; + ImGuiContext& g = *Ctx; if (g.DebugHookIdInfo == id) ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL); return id; @@ -2990,38 +3743,7 @@ ImGuiID ImGuiWindow::GetID(int n) { ImGuiID seed = IDStack.back(); ImGuiID id = ImHashData(&n, sizeof(n), seed); - ImGui::KeepAliveID(id); - ImGuiContext& g = *GImGui; - if (g.DebugHookIdInfo == id) - ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); - return id; -} - -ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) -{ - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); - ImGuiContext& g = *GImGui; - if (g.DebugHookIdInfo == id) - ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); - return id; -} - -ImGuiID ImGuiWindow::GetIDNoKeepAlive(const void* ptr) -{ - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); - ImGuiContext& g = *GImGui; - if (g.DebugHookIdInfo == id) - ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL); - return id; -} - -ImGuiID ImGuiWindow::GetIDNoKeepAlive(int n) -{ - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHashData(&n, sizeof(n), seed); - ImGuiContext& g = *GImGui; + ImGuiContext& g = *Ctx; if (g.DebugHookIdInfo == id) ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); return id; @@ -3031,9 +3753,8 @@ ImGuiID ImGuiWindow::GetIDNoKeepAlive(int n) ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) { ImGuiID seed = IDStack.back(); - const int r_rel[4] = { (int)(r_abs.Min.x - Pos.x), (int)(r_abs.Min.y - Pos.y), (int)(r_abs.Max.x - Pos.x), (int)(r_abs.Max.y - Pos.y) }; + ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs); ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed); - ImGui::KeepAliveID(id); return id; } @@ -3043,7 +3764,10 @@ static void SetCurrentWindow(ImGuiWindow* window) g.CurrentWindow = window; g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ? g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL; if (window) + { g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); + ImGui::NavUpdateCurrentWindowIsScrollPushableX(); + } } void ImGui::GcCompactTransientMiscBuffers() @@ -3083,9 +3807,31 @@ void ImGui::GcAwakeTransientWindowBuffers(ImGuiWindow* window) void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { ImGuiContext& g = *GImGui; + + // Clear previous active id + if (g.ActiveId != 0) + { + // While most behaved code would make an effort to not steal active id during window move/drag operations, + // we at least need to be resilient to it. Canceling the move is rather aggressive and users of 'master' branch + // may prefer the weird ill-defined half working situation ('docking' did assert), so may need to rework that. + if (g.MovingWindow != NULL && g.ActiveId == g.MovingWindow->MoveId) + { + IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() cancel MovingWindow\n"); + g.MovingWindow = NULL; + } + + // This could be written in a more general way (e.g associate a hook to ActiveId), + // but since this is currently quite an exception we'll leave it as is. + // One common scenario leading to this is: pressing Key ->NavMoveRequestApplyResult() -> ClearActiveId() + if (g.InputTextState.ID == g.ActiveId) + InputTextDeactivateHook(g.ActiveId); + } + + // Set active id g.ActiveIdIsJustActivated = (g.ActiveId != id); if (g.ActiveIdIsJustActivated) { + IMGUI_DEBUG_LOG_ACTIVEID("SetActiveID() old:0x%08X (window \"%s\") -> new:0x%08X (window \"%s\")\n", g.ActiveId, g.ActiveIdWindow ? g.ActiveIdWindow->Name : "", id, window ? window->Name : ""); g.ActiveIdTimer = 0.0f; g.ActiveIdHasBeenPressedBefore = false; g.ActiveIdHasBeenEditedBefore = false; @@ -3104,15 +3850,17 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) if (id) { g.ActiveIdIsAlive = id; - g.ActiveIdSource = (g.NavActivateId == id || g.NavActivateInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse; + g.ActiveIdSource = (g.NavActivateId == id || g.NavJustMovedToId == id) ? g.NavInputSource : ImGuiInputSource_Mouse; + IM_ASSERT(g.ActiveIdSource != ImGuiInputSource_None); } // Clear declaration of inputs claimed by the widget // (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet) - g.ActiveIdUsingMouseWheel = false; g.ActiveIdUsingNavDirMask = 0x00; + g.ActiveIdUsingAllKeyboardKeys = false; +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO g.ActiveIdUsingNavInputMask = 0x00; - g.ActiveIdUsingKeyInputMask = 0x00; +#endif } void ImGui::ClearActiveID() @@ -3125,7 +3873,6 @@ void ImGui::SetHoveredID(ImGuiID id) ImGuiContext& g = *GImGui; g.HoveredId = id; g.HoveredIdAllowOverlap = false; - g.HoveredIdUsingMouseWheel = false; if (id != 0 && g.HoveredIdPreviousFrame != id) g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f; } @@ -3136,6 +3883,8 @@ ImGuiID ImGui::GetHoveredID() return g.HoveredId ? g.HoveredId : g.HoveredIdPreviousFrame; } +// This is called by ItemAdd(). +// Code not using ItemAdd() may need to call this manually otherwise ActiveId will be cleared. In IMGUI_VERSION_NUM < 18717 this was called by GetID(). void ImGui::KeepAliveID(ImGuiID id) { ImGuiContext& g = *GImGui; @@ -3148,17 +3897,23 @@ void ImGui::KeepAliveID(ImGuiID id) void ImGui::MarkItemEdited(ImGuiID id) { // This marking is solely to be able to provide info for IsItemDeactivatedAfterEdit(). - // ActiveId might have been released by the time we call this (as in the typical press/release button behavior) but still need need to fill the data. + // ActiveId might have been released by the time we call this (as in the typical press/release button behavior) but still need to fill the data. ImGuiContext& g = *GImGui; - IM_ASSERT(g.ActiveId == id || g.ActiveId == 0 || g.DragDropActive); - IM_UNUSED(id); // Avoid unused variable warnings when asserts are compiled out. + if (g.ActiveId == id || g.ActiveId == 0) + { + g.ActiveIdHasBeenEditedThisFrame = true; + g.ActiveIdHasBeenEditedBefore = true; + } + + // We accept a MarkItemEdited() on drag and drop targets (see https://github.com/ocornut/imgui/issues/1875#issuecomment-978243343) + // We accept 'ActiveIdPreviousFrame == id' for InputText() returning an edit after it has been taken ActiveId away (#4714) + IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id); + //IM_ASSERT(g.CurrentWindow->DC.LastItemId == id); - g.ActiveIdHasBeenEditedThisFrame = true; - g.ActiveIdHasBeenEditedBefore = true; g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited; } -static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags) +bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags) { // An active popup disable hovering on other windows (apart from its own children) // FIXME-OPT: This could be cached/stored within the window. @@ -3168,15 +3923,31 @@ static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFla if (focused_root_window->WasActive && focused_root_window != window->RootWindow) { // For the purpose of those flags we differentiate "standard popup" from "modal popup" - // NB: The order of those two tests is important because Modal windows are also Popups. + // NB: The 'else' is important because Modal windows are also Popups. + bool want_inhibit = false; if (focused_root_window->Flags & ImGuiWindowFlags_Modal) - return false; - if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - return false; + want_inhibit = true; + else if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + want_inhibit = true; + + // Inhibit hover unless the window is within the stack of our modal/popup + if (want_inhibit) + if (!IsWindowWithinBeginStackOf(window->RootWindow, focused_root_window)) + return false; } return true; } +static inline float CalcDelayFromHoveredFlags(ImGuiHoveredFlags flags) +{ + ImGuiContext& g = *GImGui; + if (flags & ImGuiHoveredFlags_DelayShort) + return g.Style.HoverDelayShort; + if (flags & ImGuiHoveredFlags_DelayNormal) + return g.Style.HoverDelayNormal; + return 0.0f; +} + // This is roughly matching the behavior of internal-facing ItemHoverable() // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered() // - this should work even for non-interactive items that have no ID, so we cannot use LastItemId @@ -3184,66 +3955,112 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (g.NavDisableMouseHover && !g.NavDisableHighlight) + IM_ASSERT((flags & ~ImGuiHoveredFlags_AllowedMaskForIsItemHovered) == 0 && "Invalid flags for IsItemHovered()!"); + + if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride)) { if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) return false; - return IsItemFocused(); + if (!IsItemFocused()) + return false; + + if (flags & ImGuiHoveredFlags_ForTooltip) + flags |= g.Style.HoverFlagsForTooltipNav; + } + else + { + // Test for bounding box overlap, as updated as ItemAdd() + ImGuiItemStatusFlags status_flags = g.LastItemData.StatusFlags; + if (!(status_flags & ImGuiItemStatusFlags_HoveredRect)) + return false; + + if (flags & ImGuiHoveredFlags_ForTooltip) + flags |= g.Style.HoverFlagsForTooltipMouse; + + IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy)) == 0); // Flags not supported by this function + + // Done with rectangle culling so we can perform heavier checks now + // Test if we are hovering the right window (our window could be behind another window) + // [2021/03/02] Reworked / reverted the revert, finally. Note we want e.g. BeginGroup/ItemAdd/EndGroup to work as well. (#3851) + // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable + // to use IsItemHovered() after EndChild() itself. Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was + // the test that has been running for a long while. + if (g.HoveredWindow != window && (status_flags & ImGuiItemStatusFlags_HoveredWindow) == 0) + if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByWindow) == 0) + return false; + + // Test if another item is active (e.g. being dragged) + const ImGuiID id = g.LastItemData.ID; + if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0) + if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) + return false; + + // Test if interactions on this window are blocked by an active popup or modal. + // The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here. + if (!IsWindowContentHoverable(window, flags) && !(g.LastItemData.InFlags & ImGuiItemFlags_NoWindowHoverableCheck)) + return false; + + // Test if the item is disabled + if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) + return false; + + // Special handling for calling after Begin() which represent the title bar or tab. + // When the window is skipped/collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case. + if (id == window->MoveId && window->WriteAccessed) + return false; + + // Test if using AllowOverlap and overlapped + if ((g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap) && id != 0) + if ((flags & ImGuiHoveredFlags_AllowWhenOverlappedByItem) == 0) + if (g.HoveredIdPreviousFrame != g.LastItemData.ID) + return false; } - // Test for bounding box overlap, as updated as ItemAdd() - ImGuiItemStatusFlags status_flags = g.LastItemData.StatusFlags; - if (!(status_flags & ImGuiItemStatusFlags_HoveredRect)) - return false; - IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy)) == 0); // Flags not supported by this function + // Handle hover delay + // (some ideas: https://www.nngroup.com/articles/timing-exposing-content) + const float delay = CalcDelayFromHoveredFlags(flags); + if (delay > 0.0f || (flags & ImGuiHoveredFlags_Stationary)) + { + ImGuiID hover_delay_id = (g.LastItemData.ID != 0) ? g.LastItemData.ID : window->GetIDFromRectangle(g.LastItemData.Rect); + if ((flags & ImGuiHoveredFlags_NoSharedDelay) && (g.HoverItemDelayIdPreviousFrame != hover_delay_id)) + g.HoverItemDelayTimer = 0.0f; + g.HoverItemDelayId = hover_delay_id; - // Test if we are hovering the right window (our window could be behind another window) - // [2021/03/02] Reworked / reverted the revert, finally. Note we want e.g. BeginGroup/ItemAdd/EndGroup to work as well. (#3851) - // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable - // to use IsItemHovered() after EndChild() itself. Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was - // the test that has been running for a long while. - if (g.HoveredWindow != window && (status_flags & ImGuiItemStatusFlags_HoveredWindow) == 0) - if ((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0) + // When changing hovered item we requires a bit of stationary delay before activating hover timer, + // but once unlocked on a given item we also moving. + //if (g.HoverDelayTimer >= delay && (g.HoverDelayTimer - g.IO.DeltaTime < delay || g.MouseStationaryTimer - g.IO.DeltaTime < g.Style.HoverStationaryDelay)) { IMGUI_DEBUG_LOG("HoverDelayTimer = %f/%f, MouseStationaryTimer = %f\n", g.HoverDelayTimer, delay, g.MouseStationaryTimer); } + if ((flags & ImGuiHoveredFlags_Stationary) != 0 && g.HoverItemUnlockedStationaryId != hover_delay_id) return false; - // Test if another item is active (e.g. being dragged) - if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0) - if (g.ActiveId != 0 && g.ActiveId != g.LastItemData.ID && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) + if (g.HoverItemDelayTimer < delay) return false; + } - // Test if interactions on this window are blocked by an active popup or modal. - // The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here. - if (!IsWindowContentHoverable(window, flags)) - return false; - - // Test if the item is disabled - if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) - return false; - - // Special handling for calling after Begin() which represent the title bar or tab. - // When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case. - if (g.LastItemData.ID == window->MoveId && window->WriteAccessed) - return false; return true; } // Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). -bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) +// (this does not rely on LastItemData it can be called from a ButtonBehavior() call not following an ItemAdd() call) +// FIXME-LEGACY: the 'ImGuiItemFlags item_flags' parameter was added on 2023-06-28. +// If you used this ii your legacy/custom widgets code: +// - Commonly: if your ItemHoverable() call comes after an ItemAdd() call: pass 'item_flags = g.LastItemData.InFlags'. +// - Rare: otherwise you may pass 'item_flags = 0' (ImGuiItemFlags_None) unless you want to benefit from special behavior handled by ItemHoverable. +bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags) { ImGuiContext& g = *GImGui; - if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) - return false; - ImGuiWindow* window = g.CurrentWindow; if (g.HoveredWindow != window) return false; - if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap) - return false; if (!IsMouseHoveringRect(bb.Min, bb.Max)) return false; - if (g.NavDisableMouseHover) + + if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) return false; - if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) + if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap) + return false; + + // Done with rectangle culling so we can perform heavier checks now. + if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) { g.HoveredIdDisabled = true; return false; @@ -3252,14 +4069,28 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) // We exceptionally allow this function to be called with id==0 to allow using it for easy high-level // hover test in widgets code. We could also decide to split this function is two. if (id != 0) + { + // Drag source doesn't report as hovered + if (g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover)) + return false; + SetHoveredID(id); + // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. + // This allows using patterns where a later submitted widget overlaps a previous one. Generally perceived as a front-to-back hit-test. + if (item_flags & ImGuiItemflags_AllowOverlap) + { + g.HoveredIdAllowOverlap = true; + if (g.HoveredIdPreviousFrame != id) + return false; + } + } + // When disabled we'll return false but still set HoveredId - ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags); if (item_flags & ImGuiItemFlags_Disabled) { // Release active id if turning disabled - if (g.ActiveId == id) + if (g.ActiveId == id && id != 0) ClearActiveID(); g.HoveredIdDisabled = true; return false; @@ -3270,17 +4101,20 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) // [DEBUG] Item Picker tool! // We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making // the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered - // items if we perform the test in ItemAdd(), but that would incur a small runtime cost. - // #define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX in imconfig.h if you want this check to also be performed in ItemAdd(). + // items if we performed the test in ItemAdd(), but that would incur a small runtime cost. if (g.DebugItemPickerActive && g.HoveredIdPreviousFrame == id) GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255)); if (g.DebugItemPickerBreakId == id) IM_DEBUG_BREAK(); } + if (g.NavDisableMouseHover) + return false; + return true; } +// FIXME: This is inlined/duplicated in ItemAdd() bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id) { ImGuiContext& g = *GImGui; @@ -3292,46 +4126,15 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id) return false; } -// Called by ItemAdd() -// Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out. -// [WIP] This will eventually be refactored and moved into NavProcessItem() -void ImGui::ItemInputable(ImGuiWindow* window, ImGuiID id) +// This is also inlined in ItemAdd() +// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set g.LastItemData.DisplayRect. +void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags, const ImRect& item_rect) { ImGuiContext& g = *GImGui; - IM_ASSERT(id != 0 && id == g.LastItemData.ID); - - // Increment counters - // FIXME: ImGuiItemFlags_Disabled should disable more. - const bool is_tab_stop = (g.LastItemData.InFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; - if (is_tab_stop) - { - window->DC.FocusCounterTabStop++; - if (g.NavId == id) - g.NavIdTabCounter = window->DC.FocusCounterTabStop; - } - - // Process TAB/Shift-TAB to tab *OUT* of the currently focused item. - // (Note that we can always TAB out of a widget that doesn't allow tabbing in) - if (g.ActiveId == id && g.TabFocusPressed && g.TabFocusRequestNextWindow == NULL) - { - g.TabFocusRequestNextWindow = window; - g.TabFocusRequestNextCounterTabStop = window->DC.FocusCounterTabStop + (g.IO.KeyShift ? (is_tab_stop ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items. - } - - // Handle focus requests - if (g.TabFocusRequestCurrWindow == window) - { - if (is_tab_stop && window->DC.FocusCounterTabStop == g.TabFocusRequestCurrCounterTabStop) - { - g.NavJustTabbedId = id; // FIXME-NAV: aim to eventually set in NavUpdate() once we finish the refactor - g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_FocusedByTabbing; - return; - } - - // If another item is about to be focused, we clear our own active id - if (g.ActiveId == id) - ClearActiveID(); - } + g.LastItemData.ID = item_id; + g.LastItemData.InFlags = in_flags; + g.LastItemData.StatusFlags = item_flags; + g.LastItemData.Rect = g.LastItemData.NavRect = item_rect; } float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) @@ -3393,86 +4196,6 @@ const char* ImGui::GetVersion() return IMGUI_VERSION; } -// Internal state access - if you want to share Dear ImGui state between modules (e.g. DLL) or allocate it yourself -// Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module -ImGuiContext* ImGui::GetCurrentContext() -{ - return GImGui; -} - -void ImGui::SetCurrentContext(ImGuiContext* ctx) -{ -#ifdef IMGUI_SET_CURRENT_CONTEXT_FUNC - IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx); // For custom thread-based hackery you may want to have control over this. -#else - GImGui = ctx; -#endif -} - -void ImGui::SetAllocatorFunctions(ImGuiMemAllocFunc alloc_func, ImGuiMemFreeFunc free_func, void* user_data) -{ - GImAllocatorAllocFunc = alloc_func; - GImAllocatorFreeFunc = free_func; - GImAllocatorUserData = user_data; -} - -// This is provided to facilitate copying allocators from one static/DLL boundary to another (e.g. retrieve default allocator of your executable address space) -void ImGui::GetAllocatorFunctions(ImGuiMemAllocFunc* p_alloc_func, ImGuiMemFreeFunc* p_free_func, void** p_user_data) -{ - *p_alloc_func = GImAllocatorAllocFunc; - *p_free_func = GImAllocatorFreeFunc; - *p_user_data = GImAllocatorUserData; -} - -ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas) -{ - ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas); - if (GImGui == NULL) - SetCurrentContext(ctx); - Initialize(ctx); - return ctx; -} - -void ImGui::DestroyContext(ImGuiContext* ctx) -{ - if (ctx == NULL) - ctx = GImGui; - Shutdown(ctx); - if (GImGui == ctx) - SetCurrentContext(NULL); - IM_DELETE(ctx); -} - -// No specific ordering/dependency support, will see as needed -ImGuiID ImGui::AddContextHook(ImGuiContext* ctx, const ImGuiContextHook* hook) -{ - ImGuiContext& g = *ctx; - IM_ASSERT(hook->Callback != NULL && hook->HookId == 0 && hook->Type != ImGuiContextHookType_PendingRemoval_); - g.Hooks.push_back(*hook); - g.Hooks.back().HookId = ++g.HookIdNext; - return g.HookIdNext; -} - -// Deferred removal, avoiding issue with changing vector while iterating it -void ImGui::RemoveContextHook(ImGuiContext* ctx, ImGuiID hook_id) -{ - ImGuiContext& g = *ctx; - IM_ASSERT(hook_id != 0); - for (int n = 0; n < g.Hooks.Size; n++) - if (g.Hooks[n].HookId == hook_id) - g.Hooks[n].Type = ImGuiContextHookType_PendingRemoval_; -} - -// Call context hooks (used by e.g. test engine) -// We assume a small number of hooks so all stored in same array -void ImGui::CallContextHooks(ImGuiContext* ctx, ImGuiContextHookType hook_type) -{ - ImGuiContext& g = *ctx; - for (int n = 0; n < g.Hooks.Size; n++) - if (g.Hooks[n].Type == hook_type) - g.Hooks[n].Callback(&g, &g.Hooks[n]); -} - ImGuiIO& ImGui::GetIO() { IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?"); @@ -3559,7 +4282,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window) g.NavDisableHighlight = true; g.ActiveIdClickOffset = g.IO.MouseClickedPos[0] - window->RootWindow->Pos; g.ActiveIdNoClearOnFocusLoss = true; - SetActiveIdUsingNavAndKeys(); + SetActiveIdUsingAllKeyboardKeys(); bool can_move_window = true; if ((window->Flags & ImGuiWindowFlags_NoMove) || (window->RootWindow->Flags & ImGuiWindowFlags_NoMove)) @@ -3586,11 +4309,7 @@ void ImGui::UpdateMouseMovingWindowNewFrame() if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos)) { ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y) - { - MarkIniSettingsDirty(moving_window); - SetWindowPos(moving_window, pos, ImGuiCond_Always); - } + SetWindowPos(moving_window, pos, ImGuiCond_Always); FocusWindow(g.MovingWindow); } else @@ -3645,10 +4364,10 @@ void ImGui::UpdateMouseMovingWindowEndFrame() if (g.HoveredIdDisabled) g.MovingWindow = NULL; } - else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL) + else if (root_window == NULL && g.NavWindow != NULL) { // Clicking on void disable focus - FocusWindow(NULL); + FocusWindow(NULL, ImGuiFocusRequestFlags_UnlessBelowModal); } } @@ -3660,7 +4379,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame() // Find the top-most window between HoveredWindow and the top-most Modal Window. // This is where we can trim the popup stack. ImGuiWindow* modal = GetTopMostPopupModal(); - bool hovered_window_above_modal = g.HoveredWindow && IsWindowAbove(g.HoveredWindow, modal); + bool hovered_window_above_modal = g.HoveredWindow && (modal == NULL || IsWindowAbove(g.HoveredWindow, modal)); ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal, true); } } @@ -3670,198 +4389,6 @@ static bool IsWindowActiveAndVisible(ImGuiWindow* window) return (window->Active) && (!window->Hidden); } -static void ImGui::UpdateMouseInputs() -{ - ImGuiContext& g = *GImGui; - - // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well) - if (IsMousePosValid(&g.IO.MousePos)) - g.IO.MousePos = g.MouseLastValidPos = ImFloor(g.IO.MousePos); - - // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta - if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev)) - g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; - else - g.IO.MouseDelta = ImVec2(0.0f, 0.0f); - - // If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true. - if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) - g.NavDisableMouseHover = false; - - g.IO.MousePosPrev = g.IO.MousePos; - for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) - { - g.IO.MouseClicked[i] = g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] < 0.0f; - g.IO.MouseReleased[i] = !g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] >= 0.0f; - g.IO.MouseDownDurationPrev[i] = g.IO.MouseDownDuration[i]; - g.IO.MouseDownDuration[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownDuration[i] < 0.0f ? 0.0f : g.IO.MouseDownDuration[i] + g.IO.DeltaTime) : -1.0f; - g.IO.MouseDoubleClicked[i] = false; - if (g.IO.MouseClicked[i]) - { - if ((float)(g.Time - g.IO.MouseClickedTime[i]) < g.IO.MouseDoubleClickTime) - { - ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f); - if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) - g.IO.MouseDoubleClicked[i] = true; - g.IO.MouseClickedTime[i] = -g.IO.MouseDoubleClickTime * 2.0f; // Mark as "old enough" so the third click isn't turned into a double-click - } - else - { - g.IO.MouseClickedTime[i] = g.Time; - } - g.IO.MouseClickedPos[i] = g.IO.MousePos; - g.IO.MouseDownWasDoubleClick[i] = g.IO.MouseDoubleClicked[i]; - g.IO.MouseDragMaxDistanceAbs[i] = ImVec2(0.0f, 0.0f); - g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; - } - else if (g.IO.MouseDown[i]) - { - // Maintain the maximum distance we reaching from the initial click position, which is used with dragging threshold - ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f); - g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(delta_from_click_pos)); - g.IO.MouseDragMaxDistanceAbs[i].x = ImMax(g.IO.MouseDragMaxDistanceAbs[i].x, delta_from_click_pos.x < 0.0f ? -delta_from_click_pos.x : delta_from_click_pos.x); - g.IO.MouseDragMaxDistanceAbs[i].y = ImMax(g.IO.MouseDragMaxDistanceAbs[i].y, delta_from_click_pos.y < 0.0f ? -delta_from_click_pos.y : delta_from_click_pos.y); - } - if (!g.IO.MouseDown[i] && !g.IO.MouseReleased[i]) - g.IO.MouseDownWasDoubleClick[i] = false; - if (g.IO.MouseClicked[i]) // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation - g.NavDisableMouseHover = false; - } -} - -static void StartLockWheelingWindow(ImGuiWindow* window) -{ - ImGuiContext& g = *GImGui; - if (g.WheelingWindow == window) - return; - g.WheelingWindow = window; - g.WheelingWindowRefMousePos = g.IO.MousePos; - g.WheelingWindowTimer = WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER; -} - -void ImGui::UpdateMouseWheel() -{ - ImGuiContext& g = *GImGui; - - // Reset the locked window if we move the mouse or after the timer elapses - if (g.WheelingWindow != NULL) - { - g.WheelingWindowTimer -= g.IO.DeltaTime; - if (IsMousePosValid() && ImLengthSqr(g.IO.MousePos - g.WheelingWindowRefMousePos) > g.IO.MouseDragThreshold * g.IO.MouseDragThreshold) - g.WheelingWindowTimer = 0.0f; - if (g.WheelingWindowTimer <= 0.0f) - { - g.WheelingWindow = NULL; - g.WheelingWindowTimer = 0.0f; - } - } - - if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f) - return; - - if ((g.ActiveId != 0 && g.ActiveIdUsingMouseWheel) || (g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrameUsingMouseWheel)) - return; - - ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow; - if (!window || window->Collapsed) - return; - - // Zoom / Scale window - // FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned. - if (g.IO.MouseWheel != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling) - { - StartLockWheelingWindow(window); - const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); - const float scale = new_font_scale / window->FontWindowScale; - window->FontWindowScale = new_font_scale; - if (window == window->RootWindow) - { - const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; - SetWindowPos(window, window->Pos + offset, 0); - window->Size = ImFloor(window->Size * scale); - window->SizeFull = ImFloor(window->SizeFull * scale); - } - return; - } - - // Mouse wheel scrolling - // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent - if (g.IO.KeyCtrl) - return; - - // As a standard behavior holding SHIFT while using Vertical Mouse Wheel triggers Horizontal scroll instead - // (we avoid doing it on OSX as it the OS input layer handles this already) - const bool swap_axis = g.IO.KeyShift && !g.IO.ConfigMacOSXBehaviors; - const float wheel_y = swap_axis ? 0.0f : g.IO.MouseWheel; - const float wheel_x = swap_axis ? g.IO.MouseWheel : g.IO.MouseWheelH; - - // Vertical Mouse Wheel scrolling - if (wheel_y != 0.0f) - { - StartLockWheelingWindow(window); - while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)))) - window = window->ParentWindow; - if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)) - { - float max_step = window->InnerRect.GetHeight() * 0.67f; - float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step)); - SetScrollY(window, window->Scroll.y - wheel_y * scroll_step); - } - } - - // Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held - if (wheel_x != 0.0f) - { - StartLockWheelingWindow(window); - while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)))) - window = window->ParentWindow; - if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)) - { - float max_step = window->InnerRect.GetWidth() * 0.67f; - float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step)); - SetScrollX(window, window->Scroll.x - wheel_x * scroll_step); - } - } -} - -void ImGui::UpdateTabFocus() -{ - ImGuiContext& g = *GImGui; - - // Pressing TAB activate widget focus - g.TabFocusPressed = false; - if (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) - if (!g.IO.KeyCtrl && !g.IO.KeyAlt && IsKeyPressedMap(ImGuiKey_Tab) && !IsActiveIdUsingKey(ImGuiKey_Tab)) - g.TabFocusPressed = true; - if (g.ActiveId == 0 && g.TabFocusPressed) - { - // - This path is only taken when no widget are active/tabbed-into yet. - // Subsequent tabbing will be processed by FocusableItemRegister() - // - Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also - // manipulate the Next fields here even though they will be turned into Curr fields below. - g.TabFocusRequestNextWindow = g.NavWindow; - if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX) - g.TabFocusRequestNextCounterTabStop = g.NavIdTabCounter + (g.IO.KeyShift ? -1 : 0); - else - g.TabFocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0; - } - - // Turn queued focus request into current one - g.TabFocusRequestCurrWindow = NULL; - g.TabFocusRequestCurrCounterTabStop = INT_MAX; - if (g.TabFocusRequestNextWindow != NULL) - { - ImGuiWindow* window = g.TabFocusRequestNextWindow; - g.TabFocusRequestCurrWindow = window; - if (g.TabFocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1) - g.TabFocusRequestCurrCounterTabStop = ImModPositive(g.TabFocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1); - g.TabFocusRequestNextWindow = NULL; - g.TabFocusRequestNextCounterTabStop = INT_MAX; - } - - g.NavIdTabCounter = INT_MAX; -} - // The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app) void ImGui::UpdateHoveredWindowAndCaptureFlags() { @@ -3878,7 +4405,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() // Modal windows prevents mouse from hovering behind them. ImGuiWindow* modal_window = GetTopMostPopupModal(); - if (modal_window && g.HoveredWindow && !IsWindowChildOf(g.HoveredWindow->RootWindow, modal_window, true)) + if (modal_window && g.HoveredWindow && !IsWindowWithinBeginStackOf(g.HoveredWindow->RootWindow, modal_window)) clear_hovered_windows = true; // Disabled mouse? @@ -3939,17 +4466,6 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() io.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false; } -ImGuiKeyModFlags ImGui::GetMergedKeyModFlags() -{ - ImGuiContext& g = *GImGui; - ImGuiKeyModFlags key_mod_flags = ImGuiKeyModFlags_None; - if (g.IO.KeyCtrl) { key_mod_flags |= ImGuiKeyModFlags_Ctrl; } - if (g.IO.KeyShift) { key_mod_flags |= ImGuiKeyModFlags_Shift; } - if (g.IO.KeyAlt) { key_mod_flags |= ImGuiKeyModFlags_Alt; } - if (g.IO.KeySuper) { key_mod_flags |= ImGuiKeyModFlags_Super; } - return key_mod_flags; -} - void ImGui::NewFrame() { IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?"); @@ -3983,6 +4499,11 @@ void ImGui::NewFrame() g.FramerateSecPerFrameCount = ImMin(g.FramerateSecPerFrameCount + 1, IM_ARRAYSIZE(g.FramerateSecPerFrame)); g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)g.FramerateSecPerFrameCount)) : FLT_MAX; + // Process input queue (trickle as many events as possible), turn events into writes to IO structure + g.InputEventsTrail.resize(0); + UpdateInputEvents(g.IO.ConfigInputTrickleEventQueue); + + // Update viewports (after processing input queue, so io.MouseHoveredViewport is set) UpdateViewportsNewFrame(); // Setup current font and draw list shared data @@ -4026,15 +4547,20 @@ void ImGui::NewFrame() if (g.HoveredId && g.ActiveId != g.HoveredId) g.HoveredIdNotActiveTimer += g.IO.DeltaTime; g.HoveredIdPreviousFrame = g.HoveredId; - g.HoveredIdPreviousFrameUsingMouseWheel = g.HoveredIdUsingMouseWheel; g.HoveredId = 0; g.HoveredIdAllowOverlap = false; - g.HoveredIdUsingMouseWheel = false; g.HoveredIdDisabled = false; - // Update ActiveId data (clear reference to active widget if the widget isn't alive anymore) - if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) + // Clear ActiveID if the item is not alive anymore. + // In 1.87, the common most call to KeepAliveID() was moved from GetID() to ItemAdd(). + // As a result, custom widget using ButtonBehavior() _without_ ItemAdd() need to call KeepAliveID() themselves. + if (g.ActiveId != 0 && g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId) + { + IMGUI_DEBUG_LOG_ACTIVEID("NewFrame(): ClearActiveID() because it isn't marked alive anymore!\n"); ClearActiveID(); + } + + // Update ActiveId data (clear reference to active widget if the widget isn't alive anymore) if (g.ActiveId) g.ActiveIdTimer += g.IO.DeltaTime; g.LastActiveIdTimer += g.IO.DeltaTime; @@ -4050,8 +4576,53 @@ void ImGui::NewFrame() if (g.ActiveId == 0) { g.ActiveIdUsingNavDirMask = 0x00; + g.ActiveIdUsingAllKeyboardKeys = false; +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO g.ActiveIdUsingNavInputMask = 0x00; - g.ActiveIdUsingKeyInputMask = 0x00; +#endif + } + +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + if (g.ActiveId == 0) + g.ActiveIdUsingNavInputMask = 0; + else if (g.ActiveIdUsingNavInputMask != 0) + { + // If your custom widget code used: { g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel); } + // Since IMGUI_VERSION_NUM >= 18804 it should be: { SetKeyOwner(ImGuiKey_Escape, g.ActiveId); SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId); } + if (g.ActiveIdUsingNavInputMask & (1 << ImGuiNavInput_Cancel)) + SetKeyOwner(ImGuiKey_Escape, g.ActiveId); + if (g.ActiveIdUsingNavInputMask & ~(1 << ImGuiNavInput_Cancel)) + IM_ASSERT(0); // Other values unsupported + } +#endif + + // Record when we have been stationary as this state is preserved while over same item. + // FIXME: The way this is expressed means user cannot alter HoverStationaryDelay during the frame to use varying values. + // To allow this we should store HoverItemMaxStationaryTime+ID and perform the >= check in IsItemHovered() function. + if (g.HoverItemDelayId != 0 && g.MouseStationaryTimer >= g.Style.HoverStationaryDelay) + g.HoverItemUnlockedStationaryId = g.HoverItemDelayId; + else if (g.HoverItemDelayId == 0) + g.HoverItemUnlockedStationaryId = 0; + if (g.HoveredWindow != NULL && g.MouseStationaryTimer >= g.Style.HoverStationaryDelay) + g.HoverWindowUnlockedStationaryId = g.HoveredWindow->ID; + else if (g.HoveredWindow == NULL) + g.HoverWindowUnlockedStationaryId = 0; + + // Update hover delay for IsItemHovered() with delays and tooltips + g.HoverItemDelayIdPreviousFrame = g.HoverItemDelayId; + if (g.HoverItemDelayId != 0) + { + g.HoverItemDelayTimer += g.IO.DeltaTime; + g.HoverItemDelayClearTimer = 0.0f; + g.HoverItemDelayId = 0; + } + else if (g.HoverItemDelayTimer > 0.0f) + { + // This gives a little bit of leeway before clearing the hover timer, allowing mouse to cross gaps + // We could expose 0.25f as style.HoverClearDelay but I am not sure of the logic yet, this is particularly subtle. + g.HoverItemDelayClearTimer += g.IO.DeltaTime; + if (g.HoverItemDelayClearTimer >= ImMax(0.25f, g.IO.DeltaTime * 2.0f)) // ~7 frames at 30 Hz + allow for low framerate + g.HoverItemDelayTimer = g.HoverItemDelayClearTimer = 0.0f; // May want a decaying timer, in which case need to clamp at max first, based on max of caller last requested timer. } // Drag and drop @@ -4066,20 +4637,13 @@ void ImGui::NewFrame() //if (g.IO.AppFocusLost) // ClosePopupsExceptModals(); - // Clear buttons state when focus is lost - // (this is useful so e.g. releasing Alt after focus loss on Alt-Tab doesn't trigger the Alt menu toggle) - if (g.IO.AppFocusLost) - { - g.IO.ClearInputKeys(); - g.IO.AppFocusLost = false; - } - // Update keyboard input state - // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools - g.IO.KeyMods = GetMergedKeyModFlags(); - memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); - for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) - g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f; + UpdateKeyboardInputs(); + + //IM_ASSERT(g.IO.KeyCtrl == IsKeyDown(ImGuiKey_LeftCtrl) || IsKeyDown(ImGuiKey_RightCtrl)); + //IM_ASSERT(g.IO.KeyShift == IsKeyDown(ImGuiKey_LeftShift) || IsKeyDown(ImGuiKey_RightShift)); + //IM_ASSERT(g.IO.KeyAlt == IsKeyDown(ImGuiKey_LeftAlt) || IsKeyDown(ImGuiKey_RightAlt)); + //IM_ASSERT(g.IO.KeySuper == IsKeyDown(ImGuiKey_LeftSuper) || IsKeyDown(ImGuiKey_RightSuper)); // Update gamepad/keyboard navigation NavUpdate(); @@ -4102,14 +4666,14 @@ void ImGui::NewFrame() g.MouseCursor = ImGuiMouseCursor_Arrow; g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1; - g.PlatformImePos = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default + + // Platform IME data: reset for the frame + g.PlatformImeDataPrev = g.PlatformImeData; + g.PlatformImeData.WantVisible = false; // Mouse wheel scrolling, scale UpdateMouseWheel(); - // Update legacy TAB focus - UpdateTabFocus(); - // Mark all windows as not visible and compact unused memory. IM_ASSERT(g.WindowsFocusOrder.Size <= g.Windows.Size); const float memory_compact_start_time = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer; @@ -4117,9 +4681,10 @@ void ImGui::NewFrame() { ImGuiWindow* window = g.Windows[i]; window->WasActive = window->Active; - window->BeginCount = 0; window->Active = false; window->WriteAccessed = false; + window->BeginCountPreviousFrame = window->BeginCount; + window->BeginCount = 0; // Garbage collect transient buffers of recently unused windows if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time) @@ -4130,16 +4695,16 @@ void ImGui::NewFrame() for (int i = 0; i < g.TablesLastTimeActive.Size; i++) if (g.TablesLastTimeActive[i] >= 0.0f && g.TablesLastTimeActive[i] < memory_compact_start_time) TableGcCompactTransientBuffers(g.Tables.GetByIndex(i)); - for (int i = 0; i < g.TablesTempDataStack.Size; i++) - if (g.TablesTempDataStack[i].LastTimeActive >= 0.0f && g.TablesTempDataStack[i].LastTimeActive < memory_compact_start_time) - TableGcCompactTransientBuffers(&g.TablesTempDataStack[i]); + for (int i = 0; i < g.TablesTempData.Size; i++) + if (g.TablesTempData[i].LastTimeActive >= 0.0f && g.TablesTempData[i].LastTimeActive < memory_compact_start_time) + TableGcCompactTransientBuffers(&g.TablesTempData[i]); if (g.GcCompactAll) GcCompactTransientMiscBuffers(); g.GcCompactAll = false; // Closing the focused window restore focus to the first active root window in descending z-order if (g.NavWindow && !g.NavWindow->WasActive) - FocusTopMostWindowUnderOne(NULL, NULL); + FocusTopMostWindowUnderOne(NULL, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild); // No window should be open at the beginning of the frame. // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. @@ -4152,123 +4717,32 @@ void ImGui::NewFrame() // [DEBUG] Update debug features UpdateDebugToolItemPicker(); UpdateDebugToolStackQueries(); + if (g.DebugLocateFrames > 0 && --g.DebugLocateFrames == 0) + g.DebugLocateId = 0; + if (g.DebugLogClipperAutoDisableFrames > 0 && --g.DebugLogClipperAutoDisableFrames == 0) + { + DebugLog("(Auto-disabled ImGuiDebugLogFlags_EventClipper to avoid spamming)\n"); + g.DebugLogFlags &= ~ImGuiDebugLogFlags_EventClipper; + } // Create implicit/fallback window - which we will only render it if the user has added something to it. // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. - // This fallback is particularly important as it avoid ImGui:: calls from crashing. + // This fallback is particularly important as it prevents ImGui:: calls from crashing. g.WithinFrameScopeWithImplicitWindow = true; SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver); Begin("Debug##Default"); IM_ASSERT(g.CurrentWindow->IsFallbackWindow == true); + // [DEBUG] When io.ConfigDebugBeginReturnValue is set, we make Begin()/BeginChild() return false at different level of the window-stack, + // allowing to validate correct Begin/End behavior in user code. + if (g.IO.ConfigDebugBeginReturnValueLoop) + g.DebugBeginReturnValueCullDepth = (g.DebugBeginReturnValueCullDepth == -1) ? 0 : ((g.DebugBeginReturnValueCullDepth + ((g.FrameCount % 4) == 0 ? 1 : 0)) % 10); + else + g.DebugBeginReturnValueCullDepth = -1; + CallContextHooks(&g, ImGuiContextHookType_NewFramePost); } -void ImGui::Initialize(ImGuiContext* context) -{ - ImGuiContext& g = *context; - IM_ASSERT(!g.Initialized && !g.SettingsLoaded); - - // Add .ini handle for ImGuiWindow type - { - ImGuiSettingsHandler ini_handler; - ini_handler.TypeName = "Window"; - ini_handler.TypeHash = ImHashStr("Window"); - ini_handler.ClearAllFn = WindowSettingsHandler_ClearAll; - ini_handler.ReadOpenFn = WindowSettingsHandler_ReadOpen; - ini_handler.ReadLineFn = WindowSettingsHandler_ReadLine; - ini_handler.ApplyAllFn = WindowSettingsHandler_ApplyAll; - ini_handler.WriteAllFn = WindowSettingsHandler_WriteAll; - g.SettingsHandlers.push_back(ini_handler); - } - - // Add .ini handle for ImGuiTable type - TableSettingsInstallHandler(context); - - // Create default viewport - ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)(); - g.Viewports.push_back(viewport); - -#ifdef IMGUI_HAS_DOCK -#endif - - g.Initialized = true; -} - -// This function is merely here to free heap allocations. -void ImGui::Shutdown(ImGuiContext* context) -{ - // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) - ImGuiContext& g = *context; - if (g.IO.Fonts && g.FontAtlasOwnedByContext) - { - g.IO.Fonts->Locked = false; - IM_DELETE(g.IO.Fonts); - } - g.IO.Fonts = NULL; - - // Cleanup of other data are conditional on actually having initialized Dear ImGui. - if (!g.Initialized) - return; - - // Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file) - if (g.SettingsLoaded && g.IO.IniFilename != NULL) - { - ImGuiContext* backup_context = GImGui; - SetCurrentContext(&g); - SaveIniSettingsToDisk(g.IO.IniFilename); - SetCurrentContext(backup_context); - } - - CallContextHooks(&g, ImGuiContextHookType_Shutdown); - - // Clear everything else - g.Windows.clear_delete(); - g.WindowsFocusOrder.clear(); - g.WindowsTempSortBuffer.clear(); - g.CurrentWindow = NULL; - g.CurrentWindowStack.clear(); - g.WindowsById.Clear(); - g.NavWindow = NULL; - g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL; - g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL; - g.MovingWindow = NULL; - g.ColorStack.clear(); - g.StyleVarStack.clear(); - g.FontStack.clear(); - g.OpenPopupStack.clear(); - g.BeginPopupStack.clear(); - - g.Viewports.clear_delete(); - - g.TabBars.Clear(); - g.CurrentTabBarStack.clear(); - g.ShrinkWidthBuffer.clear(); - - g.Tables.Clear(); - g.TablesTempDataStack.clear_destruct(); - g.DrawChannelsTempMergeBuffer.clear(); - - g.ClipboardHandlerData.clear(); - g.MenusIdSubmittedThisFrame.clear(); - g.InputTextState.ClearFreeMemory(); - - g.SettingsWindows.clear(); - g.SettingsHandlers.clear(); - - if (g.LogFile) - { -#ifndef IMGUI_DISABLE_TTY_FUNCTIONS - if (g.LogFile != stdout) -#endif - ImFileClose(g.LogFile); - g.LogFile = NULL; - } - g.LogBuffer.clear(); - - g.Initialized = false; -} - // FIXME: Add a more explicit sort order in the window structure. static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs) { @@ -4287,8 +4761,7 @@ static void AddWindowToSortBuffer(ImVector* out_sorted_windows, Im if (window->Active) { int count = window->DC.ChildWindows.Size; - if (count > 1) - ImQsort(window->DC.ChildWindows.Data, (size_t)count, sizeof(ImGuiWindow*), ChildWindowComparer); + ImQsort(window->DC.ChildWindows.Data, (size_t)count, sizeof(ImGuiWindow*), ChildWindowComparer); for (int i = 0; i < count; i++) { ImGuiWindow* child = window->DC.ChildWindows[i]; @@ -4300,11 +4773,10 @@ static void AddWindowToSortBuffer(ImVector* out_sorted_windows, Im static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list) { - // Remove trailing command if unused. - // Technically we could return directly instead of popping, but this make things looks neat in Metrics/Debugger window as well. - draw_list->_PopUnusedDrawCmd(); if (draw_list->CmdBuffer.Size == 0) return; + if (draw_list->CmdBuffer.Size == 1 && draw_list->CmdBuffer[0].ElemCount == 0 && draw_list->CmdBuffer[0].UserCallback == NULL) + return; // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. // May trigger for you if you are using PrimXXX functions incorrectly. @@ -4348,11 +4820,15 @@ static void AddWindowToDrawData(ImGuiWindow* window, int layer) } } -// Layer is locked for the root window, however child windows may use a different viewport (e.g. extruding menu) -static void AddRootWindowToDrawData(ImGuiWindow* window) +static inline int GetWindowDisplayLayer(ImGuiWindow* window) { - int layer = (window->Flags & ImGuiWindowFlags_Tooltip) ? 1 : 0; - AddWindowToDrawData(window, layer); + return (window->Flags & ImGuiWindowFlags_Tooltip) ? 1 : 0; +} + +// Layer is locked for the root window, however child windows may use a different viewport (e.g. extruding menu) +static inline void AddRootWindowToDrawData(ImGuiWindow* window) +{ + AddWindowToDrawData(window, GetWindowDisplayLayer(window)); } void ImDrawDataBuilder::FlattenIntoSingleLayer() @@ -4386,8 +4862,10 @@ static void SetupViewportDrawData(ImGuiViewportP* viewport, ImVectorFramebufferScale = io.DisplayFramebufferScale; for (int n = 0; n < draw_lists->Size; n++) { - draw_data->TotalVtxCount += draw_lists->Data[n]->VtxBuffer.Size; - draw_data->TotalIdxCount += draw_lists->Data[n]->IdxBuffer.Size; + ImDrawList* draw_list = draw_lists->Data[n]; + draw_list->_PopUnusedDrawCmd(); + draw_data->TotalVtxCount += draw_list->VtxBuffer.Size; + draw_data->TotalIdxCount += draw_list->IdxBuffer.Size; } } @@ -4411,6 +4889,88 @@ void ImGui::PopClipRect() window->ClipRect = window->DrawList->_ClipRectStack.back(); } +static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + ImGuiViewportP* viewport = (ImGuiViewportP*)GetMainViewport(); + ImRect viewport_rect = viewport->GetMainRect(); + + // Draw behind window by moving the draw command at the FRONT of the draw list + { + // We've already called AddWindowToDrawData() which called DrawList->ChannelsMerge() on DockNodeHost windows, + // and draw list have been trimmed already, hence the explicit recreation of a draw command if missing. + // FIXME: This is creating complication, might be simpler if we could inject a drawlist in drawdata at a given position and not attempt to manipulate ImDrawCmd order. + ImDrawList* draw_list = window->RootWindow->DrawList; + if (draw_list->CmdBuffer.Size == 0) + draw_list->AddDrawCmd(); + draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // Ensure ImDrawCmd are not merged + draw_list->AddRectFilled(viewport_rect.Min, viewport_rect.Max, col); + ImDrawCmd cmd = draw_list->CmdBuffer.back(); + IM_ASSERT(cmd.ElemCount == 6); + draw_list->CmdBuffer.pop_back(); + draw_list->CmdBuffer.push_front(cmd); + draw_list->PopClipRect(); + draw_list->AddDrawCmd(); // We need to create a command as CmdBuffer.back().IdxOffset won't be correct if we append to same command. + } +} + +ImGuiWindow* ImGui::FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* parent_window) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* bottom_most_visible_window = parent_window; + for (int i = FindWindowDisplayIndex(parent_window); i >= 0; i--) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_ChildWindow) + continue; + if (!IsWindowWithinBeginStackOf(window, parent_window)) + break; + if (IsWindowActiveAndVisible(window) && GetWindowDisplayLayer(window) <= GetWindowDisplayLayer(parent_window)) + bottom_most_visible_window = window; + } + return bottom_most_visible_window; +} + +static void ImGui::RenderDimmedBackgrounds() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* modal_window = GetTopMostAndVisiblePopupModal(); + if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f) + return; + const bool dim_bg_for_modal = (modal_window != NULL); + const bool dim_bg_for_window_list = (g.NavWindowingTargetAnim != NULL && g.NavWindowingTargetAnim->Active); + if (!dim_bg_for_modal && !dim_bg_for_window_list) + return; + + if (dim_bg_for_modal) + { + // Draw dimming behind modal or a begin stack child, whichever comes first in draw order. + ImGuiWindow* dim_behind_window = FindBottomMostVisibleWindowWithinBeginStack(modal_window); + RenderDimmedBackgroundBehindWindow(dim_behind_window, GetColorU32(ImGuiCol_ModalWindowDimBg, g.DimBgRatio)); + } + else if (dim_bg_for_window_list) + { + // Draw dimming behind CTRL+Tab target window + RenderDimmedBackgroundBehindWindow(g.NavWindowingTargetAnim, GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio)); + + // Draw border around CTRL+Tab target window + ImGuiWindow* window = g.NavWindowingTargetAnim; + ImGuiViewport* viewport = GetMainViewport(); + float distance = g.FontSize; + ImRect bb = window->Rect(); + bb.Expand(distance); + if (bb.GetWidth() >= viewport->Size.x && bb.GetHeight() >= viewport->Size.y) + bb.Expand(-distance - 1.0f); // If a window fits the entire viewport, adjust its highlight inward + if (window->DrawList->CmdBuffer.Size == 0) + window->DrawList->AddDrawCmd(); + window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size); + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f); + window->DrawList->PopClipRect(); + } +} + // This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal. void ImGui::EndFrame() { @@ -4426,11 +4986,24 @@ void ImGui::EndFrame() ErrorCheckEndFrameSanityChecks(); - // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) - if (g.IO.ImeSetInputScreenPosFn && (g.PlatformImeLastPos.x == FLT_MAX || ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f)) + // Notify Platform/OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) + ImGuiPlatformImeData* ime_data = &g.PlatformImeData; + if (g.IO.SetPlatformImeDataFn && memcmp(ime_data, &g.PlatformImeDataPrev, sizeof(ImGuiPlatformImeData)) != 0) { - g.IO.ImeSetInputScreenPosFn((int)g.PlatformImePos.x, (int)g.PlatformImePos.y); - g.PlatformImeLastPos = g.PlatformImePos; + IMGUI_DEBUG_LOG_IO("[io] Calling io.SetPlatformImeDataFn(): WantVisible: %d, InputPos (%.2f,%.2f)\n", ime_data->WantVisible, ime_data->InputPos.x, ime_data->InputPos.y); + ImGuiViewport* viewport = GetMainViewport(); +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + if (viewport->PlatformHandleRaw == NULL && g.IO.ImeWindowHandle != NULL) + { + viewport->PlatformHandleRaw = g.IO.ImeWindowHandle; + g.IO.SetPlatformImeDataFn(viewport, ime_data); + viewport->PlatformHandleRaw = NULL; + } + else +#endif + { + g.IO.SetPlatformImeDataFn(viewport, ime_data); + } } // Hide implicit/fallback "Debug" window if it hasn't been used @@ -4487,10 +5060,9 @@ void ImGui::EndFrame() g.IO.Fonts->Locked = false; // Clear Input data for next frame + g.IO.AppFocusLost = false; g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; g.IO.InputQueueCharacters.resize(0); - g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it. - memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs)); CallContextHooks(&g, ImGuiContextHookType_EndFramePost); } @@ -4505,6 +5077,7 @@ void ImGui::Render() if (g.FrameCountEnded != g.FrameCount) EndFrame(); + const bool first_render_of_frame = (g.FrameCountRendered != g.FrameCount); g.FrameCountRendered = g.FrameCount; g.IO.MetricsRenderWindows = 0; @@ -4519,6 +5092,10 @@ void ImGui::Render() AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetBackgroundDrawList(viewport)); } + // Draw modal/window whitening backgrounds + if (first_render_of_frame) + RenderDimmedBackgrounds(); + // Add ImDrawList to render ImGuiWindow* windows_to_render_top_most[2]; windows_to_render_top_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL; @@ -4534,6 +5111,10 @@ void ImGui::Render() if (windows_to_render_top_most[n] && IsWindowActiveAndVisible(windows_to_render_top_most[n])) // NavWindowingTarget is always temporarily displayed as the top-most window AddRootWindowToDrawData(windows_to_render_top_most[n]); + // Draw software mouse cursor if requested by io.MouseDrawCursor flag + if (g.IO.MouseDrawCursor && first_render_of_frame && g.MouseCursor != ImGuiMouseCursor_None) + RenderMouseCursor(g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32(0, 0, 0, 48)); + // Setup ImDrawData structures for end-user g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = 0; for (int n = 0; n < g.Viewports.Size; n++) @@ -4541,10 +5122,6 @@ void ImGui::Render() ImGuiViewportP* viewport = g.Viewports[n]; viewport->DrawDataBuilder.FlattenIntoSingleLayer(); - // Draw software mouse cursor if requested by io.MouseDrawCursor flag - if (g.IO.MouseDrawCursor) - RenderMouseCursor(GetForegroundDrawList(viewport), g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32(0, 0, 0, 48)); - // Add foreground ImDrawList (for each active viewport) if (viewport->DrawLists[1] != NULL) AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport)); @@ -4642,231 +5219,6 @@ static void FindHoveredWindow() g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window; } -// Test if mouse cursor is hovering given rectangle -// NB- Rectangle is clipped by our current clip setting -// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) -bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) -{ - ImGuiContext& g = *GImGui; - - // Clip - ImRect rect_clipped(r_min, r_max); - if (clip) - rect_clipped.ClipWith(g.CurrentWindow->ClipRect); - - // Expand for touch input - const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); - if (!rect_for_touch.Contains(g.IO.MousePos)) - return false; - return true; -} - -int ImGui::GetKeyIndex(ImGuiKey imgui_key) -{ - IM_ASSERT(imgui_key >= 0 && imgui_key < ImGuiKey_COUNT); - ImGuiContext& g = *GImGui; - return g.IO.KeyMap[imgui_key]; -} - -// Note that dear imgui doesn't know the semantic of each entry of io.KeysDown[]! -// Use your own indices/enums according to how your backend/engine stored them into io.KeysDown[]! -bool ImGui::IsKeyDown(int user_key_index) -{ - if (user_key_index < 0) - return false; - ImGuiContext& g = *GImGui; - IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - return g.IO.KeysDown[user_key_index]; -} - -// t0 = previous time (e.g.: g.Time - g.IO.DeltaTime) -// t1 = current time (e.g.: g.Time) -// An event is triggered at: -// t = 0.0f t = repeat_delay, t = repeat_delay + repeat_rate*N -int ImGui::CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate) -{ - if (t1 == 0.0f) - return 1; - if (t0 >= t1) - return 0; - if (repeat_rate <= 0.0f) - return (t0 < repeat_delay) && (t1 >= repeat_delay); - const int count_t0 = (t0 < repeat_delay) ? -1 : (int)((t0 - repeat_delay) / repeat_rate); - const int count_t1 = (t1 < repeat_delay) ? -1 : (int)((t1 - repeat_delay) / repeat_rate); - const int count = count_t1 - count_t0; - return count; -} - -int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate) -{ - ImGuiContext& g = *GImGui; - if (key_index < 0) - return 0; - IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - const float t = g.IO.KeysDownDuration[key_index]; - return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate); -} - -bool ImGui::IsKeyPressed(int user_key_index, bool repeat) -{ - ImGuiContext& g = *GImGui; - if (user_key_index < 0) - return false; - IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - const float t = g.IO.KeysDownDuration[user_key_index]; - if (t == 0.0f) - return true; - if (repeat && t > g.IO.KeyRepeatDelay) - return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0; - return false; -} - -bool ImGui::IsKeyReleased(int user_key_index) -{ - ImGuiContext& g = *GImGui; - if (user_key_index < 0) return false; - IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - return g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index]; -} - -bool ImGui::IsMouseDown(ImGuiMouseButton button) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - return g.IO.MouseDown[button]; -} - -bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - const float t = g.IO.MouseDownDuration[button]; - if (t == 0.0f) - return true; - - if (repeat && t > g.IO.KeyRepeatDelay) - { - // FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold. - int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f); - if (amount > 0) - return true; - } - return false; -} - -bool ImGui::IsMouseReleased(ImGuiMouseButton button) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - return g.IO.MouseReleased[button]; -} - -bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - return g.IO.MouseDoubleClicked[button]; -} - -// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame. -// [Internal] This doesn't test if the button is pressed -bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - if (lock_threshold < 0.0f) - lock_threshold = g.IO.MouseDragThreshold; - return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; -} - -bool ImGui::IsMouseDragging(ImGuiMouseButton button, float lock_threshold) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - if (!g.IO.MouseDown[button]) - return false; - return IsMouseDragPastThreshold(button, lock_threshold); -} - -ImVec2 ImGui::GetMousePos() -{ - ImGuiContext& g = *GImGui; - return g.IO.MousePos; -} - -// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! -ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() -{ - ImGuiContext& g = *GImGui; - if (g.BeginPopupStack.Size > 0) - return g.OpenPopupStack[g.BeginPopupStack.Size - 1].OpenMousePos; - return g.IO.MousePos; -} - -// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position. -bool ImGui::IsMousePosValid(const ImVec2* mouse_pos) -{ - // The assert is only to silence a false-positive in XCode Static Analysis. - // Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions). - IM_ASSERT(GImGui != NULL); - const float MOUSE_INVALID = -256000.0f; - ImVec2 p = mouse_pos ? *mouse_pos : GImGui->IO.MousePos; - return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID; -} - -bool ImGui::IsAnyMouseDown() -{ - ImGuiContext& g = *GImGui; - for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++) - if (g.IO.MouseDown[n]) - return true; - return false; -} - -// Return the delta from the initial clicking position while the mouse button is clicked or was just released. -// This is locked and return 0.0f until the mouse moves past a distance threshold at least once. -// NB: This is only valid if IsMousePosValid(). backends in theory should always keep mouse position valid when dragging even outside the client window. -ImVec2 ImGui::GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - if (lock_threshold < 0.0f) - lock_threshold = g.IO.MouseDragThreshold; - if (g.IO.MouseDown[button] || g.IO.MouseReleased[button]) - if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) - if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MouseClickedPos[button])) - return g.IO.MousePos - g.IO.MouseClickedPos[button]; - return ImVec2(0.0f, 0.0f); -} - -void ImGui::ResetMouseDragDelta(ImGuiMouseButton button) -{ - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr - g.IO.MouseClickedPos[button] = g.IO.MousePos; -} - -ImGuiMouseCursor ImGui::GetMouseCursor() -{ - return GImGui->MouseCursor; -} - -void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) -{ - GImGui->MouseCursor = cursor_type; -} - -void ImGui::CaptureKeyboardFromApp(bool capture) -{ - GImGui->WantCaptureKeyboardNextFrame = capture ? 1 : 0; -} - -void ImGui::CaptureMouseFromApp(bool capture) -{ - GImGui->WantCaptureMouseNextFrame = capture ? 1 : 0; -} - bool ImGui::IsItemActive() { ImGuiContext& g = *GImGui; @@ -4947,7 +5299,7 @@ bool ImGui::IsAnyItemFocused() bool ImGui::IsItemVisible() { ImGuiContext& g = *GImGui; - return g.CurrentWindow->ClipRect.Overlaps(g.LastItemData.Rect); + return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) != 0; } bool ImGui::IsItemEdited() @@ -4956,38 +5308,45 @@ bool ImGui::IsItemEdited() return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Edited) != 0; } +// Allow next item to be overlapped by subsequent items. +// This works by requiring HoveredId to match for two subsequent frames, +// so if a following items overwrite it our interactions will naturally be disabled. +void ImGui::SetNextItemAllowOverlap() +{ + ImGuiContext& g = *GImGui; + g.NextItemData.ItemFlags |= ImGuiItemflags_AllowOverlap; +} + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. -// FIXME: Although this is exposed, its interaction and ideal idiom with using ImGuiButtonFlags_AllowItemOverlap flag are extremely confusing, need rework. +// FIXME-LEGACY: Use SetNextItemAllowOverlap() *before* your item instead. void ImGui::SetItemAllowOverlap() { ImGuiContext& g = *GImGui; ImGuiID id = g.LastItemData.ID; if (g.HoveredId == id) g.HoveredIdAllowOverlap = true; - if (g.ActiveId == id) + if (g.ActiveId == id) // Before we made this obsolete, most calls to SetItemAllowOverlap() used to avoid this path by testing g.ActiveId != id. g.ActiveIdAllowOverlap = true; } +#endif -void ImGui::SetItemUsingMouseWheel() -{ - ImGuiContext& g = *GImGui; - ImGuiID id = g.LastItemData.ID; - if (g.HoveredId == id) - g.HoveredIdUsingMouseWheel = true; - if (g.ActiveId == id) - g.ActiveIdUsingMouseWheel = true; -} - -void ImGui::SetActiveIdUsingNavAndKeys() +// FIXME: It might be undesirable that this will likely disable KeyOwner-aware shortcuts systems. Consider a more fine-tuned version for the two users of this function. +void ImGui::SetActiveIdUsingAllKeyboardKeys() { ImGuiContext& g = *GImGui; IM_ASSERT(g.ActiveId != 0); - g.ActiveIdUsingNavDirMask = ~(ImU32)0; - g.ActiveIdUsingNavInputMask = ~(ImU32)0; - g.ActiveIdUsingKeyInputMask = ~(ImU64)0; + g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_COUNT) - 1; + g.ActiveIdUsingAllKeyboardKeys = true; NavMoveRequestCancel(); } +ImGuiID ImGui::GetItemID() +{ + ImGuiContext& g = *GImGui; + return g.LastItemData.ID; +} + ImVec2 ImGui::GetItemRectMin() { ImGuiContext& g = *GImGui; @@ -5019,21 +5378,22 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b ImVec2 size = ImFloor(size_arg); const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); if (size.x <= 0.0f) - size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) + size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too many issues) if (size.y <= 0.0f) size.y = ImMax(content_avail.y + size.y, 4.0f); SetNextWindowSize(size); // Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value. + const char* temp_window_name; if (name) - ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%s_%08X", parent_window->Name, name, id); + ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s_%08X", parent_window->Name, name, id); else - ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id); + ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%08X", parent_window->Name, id); const float backup_border_size = g.Style.ChildBorderSize; if (!border) g.Style.ChildBorderSize = 0.0f; - bool ret = Begin(g.TempBuffer, NULL, flags); + bool ret = Begin(temp_window_name, NULL, flags); g.Style.ChildBorderSize = backup_border_size; ImGuiWindow* child_window = g.CurrentWindow; @@ -5046,12 +5406,16 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b parent_window->DC.CursorPos = child_window->Pos; // Process navigation-in immediately so NavInit can run on first frame - if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavHasScroll)) + // Can enter a child if (A) it has navigatable items or (B) it can be scrolled. + const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id); + if (g.ActiveId == temp_id_for_activation) + ClearActiveID(); + if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY)) { FocusWindow(child_window); NavInitWindow(child_window, false); - SetActiveID(id + 1, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item - g.ActiveIdSource = ImGuiInputSource_Nav; + SetActiveID(temp_id_for_activation, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item + g.ActiveIdSource = g.NavInputSource; } return ret; } @@ -5093,7 +5457,7 @@ void ImGui::EndChild() ImGuiWindow* parent_window = g.CurrentWindow; ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz); ItemSize(sz); - if ((window->DC.NavLayersActiveMask != 0 || window->DC.NavHasScroll) && !(window->Flags & ImGuiWindowFlags_NavFlattened)) + if ((window->DC.NavLayersActiveMask != 0 || window->DC.NavWindowHasScrollY) && !(window->Flags & ImGuiWindowFlags_NavFlattened)) { ItemAdd(bb, window->ChildId); RenderNavHighlight(bb, window->ChildId); @@ -5106,6 +5470,10 @@ void ImGui::EndChild() { // Not navigable into ItemAdd(bb, 0); + + // But when flattened we directly reach items, adjust active layer mask accordingly + if (window->Flags & ImGuiWindowFlags_NavFlattened) + parent_window->DC.NavLayersActiveMaskNext |= window->DC.NavLayersActiveMaskNext; } if (g.HoveredWindow == window) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; @@ -5161,32 +5529,45 @@ static void ApplyWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settin window->Collapsed = settings->Collapsed; } -static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) +static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags) { ImGuiContext& g = *GImGui; - //IMGUI_DEBUG_LOG("CreateNewWindow '%s', flags = 0x%08X\n", name, flags); - // Create window the first time - ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name); - window->Flags = flags; - g.WindowsById.SetVoidPtr(window->ID, window); + const bool new_is_explicit_child = (new_flags & ImGuiWindowFlags_ChildWindow) != 0 && ((new_flags & ImGuiWindowFlags_Popup) == 0 || (new_flags & ImGuiWindowFlags_ChildMenu) != 0); + const bool child_flag_changed = new_is_explicit_child != window->IsExplicitChild; + if ((just_created || child_flag_changed) && !new_is_explicit_child) + { + IM_ASSERT(!g.WindowsFocusOrder.contains(window)); + g.WindowsFocusOrder.push_back(window); + window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1); + } + else if (!just_created && child_flag_changed && new_is_explicit_child) + { + IM_ASSERT(g.WindowsFocusOrder[window->FocusOrder] == window); + for (int n = window->FocusOrder + 1; n < g.WindowsFocusOrder.Size; n++) + g.WindowsFocusOrder[n]->FocusOrder--; + g.WindowsFocusOrder.erase(g.WindowsFocusOrder.Data + window->FocusOrder); + window->FocusOrder = -1; + } + window->IsExplicitChild = new_is_explicit_child; +} - // Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. +static void InitOrLoadWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings) +{ + // Initial window state with e.g. default/arbitrary window position + // Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); window->Pos = main_viewport->Pos + ImVec2(60, 60); + window->SetWindowPosAllowFlags = window->SetWindowSizeAllowFlags = window->SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; - // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. - if (!(flags & ImGuiWindowFlags_NoSavedSettings)) - if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) - { - // Retrieve settings from .ini file - window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings); - SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); - ApplyWindowSettings(window, settings); - } - window->DC.CursorStartPos = window->DC.CursorMaxPos = window->Pos; // So first call to CalcContentSize() doesn't return crazy values + if (settings != NULL) + { + SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); + ApplyWindowSettings(window, settings); + } + window->DC.CursorStartPos = window->DC.CursorMaxPos = window->DC.IdealMaxPos = window->Pos; // So first call to CalcWindowContentSizes() doesn't return crazy values - if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) + if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) { window->AutoFitFramesX = window->AutoFitFramesY = 2; window->AutoFitOnlyGrows = false; @@ -5199,17 +5580,29 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) window->AutoFitFramesY = 2; window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0); } +} - if (!(flags & ImGuiWindowFlags_ChildWindow)) - { - g.WindowsFocusOrder.push_back(window); - window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1); - } +static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags) +{ + // Create window the first time + //IMGUI_DEBUG_LOG("CreateNewWindow '%s', flags = 0x%08X\n", name, flags); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name); + window->Flags = flags; + g.WindowsById.SetVoidPtr(window->ID, window); + + ImGuiWindowSettings* settings = NULL; + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) + if ((settings = ImGui::FindWindowSettingsByWindow(window)) != 0) + window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings); + + InitOrLoadWindowSettings(window, settings); if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus) g.Windows.push_front(window); // Quite slow but rare and only once else g.Windows.push_back(window); + return window; } @@ -5241,9 +5634,9 @@ static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow* window, const ImVec2& s if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) { ImGuiWindow* window_for_height = window; - const float decoration_up_height = window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight(); new_size = ImMax(new_size, g.Style.WindowMinSize); - new_size.y = ImMax(new_size.y, decoration_up_height + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows + const float minimum_height = window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f); + new_size.y = ImMax(new_size.y, minimum_height); // Reduce artifacts with very small windows } return new_size; } @@ -5272,9 +5665,10 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont { ImGuiContext& g = *GImGui; ImGuiStyle& style = g.Style; - const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); + const float decoration_w_without_scrollbars = window->DecoOuterSizeX1 + window->DecoOuterSizeX2 - window->ScrollbarSizes.x; + const float decoration_h_without_scrollbars = window->DecoOuterSizeY1 + window->DecoOuterSizeY2 - window->ScrollbarSizes.y; ImVec2 size_pad = window->WindowPadding * 2.0f; - ImVec2 size_desired = size_contents + size_pad + ImVec2(0.0f, decoration_up_height); + ImVec2 size_desired = size_contents + size_pad + ImVec2(decoration_w_without_scrollbars, decoration_h_without_scrollbars); if (window->Flags & ImGuiWindowFlags_Tooltip) { // Tooltip always resize @@ -5289,15 +5683,14 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont if (is_popup || is_menu) // Popups and menus bypass style.WindowMinSize by default, but we give then a non-zero minimum size to facilitate understanding problematic cases (e.g. empty popups) size_min = ImMin(size_min, ImVec2(4.0f, 4.0f)); - // FIXME-VIEWPORT-WORKAREA: May want to use GetWorkSize() instead of Size depending on the type of windows? - ImVec2 avail_size = ImGui::GetMainViewport()->Size; + ImVec2 avail_size = ImGui::GetMainViewport()->WorkSize; ImVec2 size_auto_fit = ImClamp(size_desired, size_min, ImMax(size_min, avail_size - style.DisplaySafeAreaPadding * 2.0f)); // When the window cannot fit all contents (either because of constraints, either because screen is too small), // we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding. ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit); - bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - 0.0f < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar); - bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - decoration_up_height < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar); + bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - decoration_w_without_scrollbars < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar); + bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - decoration_h_without_scrollbars < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar); if (will_have_scrollbar_x) size_auto_fit.y += style.ScrollbarSize; if (will_have_scrollbar_y) @@ -5316,11 +5709,11 @@ ImVec2 ImGui::CalcWindowNextAutoFitSize(ImGuiWindow* window) return size_final; } -static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) +static ImGuiCol GetWindowBgColorIdx(ImGuiWindow* window) { - if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) + if (window->Flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) return ImGuiCol_PopupBg; - if (flags & ImGuiWindowFlags_ChildWindow) + if (window->Flags & ImGuiWindowFlags_ChildWindow) return ImGuiCol_ChildBg; return ImGuiCol_WindowBg; } @@ -5404,7 +5797,7 @@ ImGuiID ImGui::GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir) } // Handle resize for: Resize Grips, Borders, Gamepad -// Return true when using auto-fit (double click on resize grip) +// Return true when using auto-fit (double-click on resize grip) static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect) { ImGuiContext& g = *GImGui; @@ -5412,7 +5805,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) return false; - if (window->WasActive == false) // Early out to avoid running this code for e.g. an hidden implicit/fallback Debug window. + if (window->WasActive == false) // Early out to avoid running this code for e.g. a hidden implicit/fallback Debug window. return false; bool ret_auto_fit = false; @@ -5421,6 +5814,11 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s const float grip_hover_inner_size = IM_FLOOR(grip_draw_size * 0.75f); const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f; + ImRect clamp_rect = visibility_rect; + const bool window_move_from_title_bar = g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar); + if (window_move_from_title_bar) + clamp_rect.Min.y -= window->TitleBarHeight(); + ImVec2 pos_target(FLT_MAX, FLT_MAX); ImVec2 size_target(FLT_MAX, FLT_MAX); @@ -5440,12 +5838,13 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x); if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y); ImGuiID resize_grip_id = window->GetID(resize_grip_n); // == GetWindowResizeCornerID() + ItemAdd(resize_rect, resize_grip_id, NULL, ImGuiItemFlags_NoNav); ButtonBehavior(resize_rect, resize_grip_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); //GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255)); if (hovered || held) g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; - if (held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0) + if (held && g.IO.MouseClickedCount[0] == 2 && resize_grip_n == 0) { // Manual auto-fit when double-clicking size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit); @@ -5456,8 +5855,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s { // Resize from any of the four corners // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position - ImVec2 clamp_min = ImVec2(def.CornerPosN.x == 1.0f ? visibility_rect.Min.x : -FLT_MAX, def.CornerPosN.y == 1.0f ? visibility_rect.Min.y : -FLT_MAX); - ImVec2 clamp_max = ImVec2(def.CornerPosN.x == 0.0f ? visibility_rect.Max.x : +FLT_MAX, def.CornerPosN.y == 0.0f ? visibility_rect.Max.y : +FLT_MAX); + ImVec2 clamp_min = ImVec2(def.CornerPosN.x == 1.0f ? clamp_rect.Min.x : -FLT_MAX, (def.CornerPosN.y == 1.0f || (def.CornerPosN.y == 0.0f && window_move_from_title_bar)) ? clamp_rect.Min.y : -FLT_MAX); + ImVec2 clamp_max = ImVec2(def.CornerPosN.x == 0.0f ? clamp_rect.Max.x : +FLT_MAX, def.CornerPosN.y == 0.0f ? clamp_rect.Max.y : +FLT_MAX); ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(def.InnerDir * grip_hover_outer_size, def.InnerDir * -grip_hover_inner_size, def.CornerPosN); // Corner of the window corresponding to our corner grip corner_target = ImClamp(corner_target, clamp_min, clamp_max); CalcResizePosSizeFromAnyCorner(window, corner_target, def.CornerPosN, &pos_target, &size_target); @@ -5475,7 +5874,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s bool hovered, held; ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_HOVER_PADDING); ImGuiID border_id = window->GetID(border_n + 4); // == GetWindowResizeBorderID() - ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren); + ItemAdd(border_rect, border_id, NULL, ImGuiItemFlags_NoNav); + ButtonBehavior(border_rect, border_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255)); if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) { @@ -5485,8 +5885,8 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s } if (held) { - ImVec2 clamp_min(border_n == ImGuiDir_Right ? visibility_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down ? visibility_rect.Min.y : -FLT_MAX); - ImVec2 clamp_max(border_n == ImGuiDir_Left ? visibility_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? visibility_rect.Max.y : +FLT_MAX); + ImVec2 clamp_min(border_n == ImGuiDir_Right ? clamp_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down || (border_n == ImGuiDir_Up && window_move_from_title_bar) ? clamp_rect.Min.y : -FLT_MAX); + ImVec2 clamp_max(border_n == ImGuiDir_Left ? clamp_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? clamp_rect.Max.y : +FLT_MAX); ImVec2 border_target = window->Pos; border_target[axis] = g.IO.MousePos[axis] - g.ActiveIdClickOffset[axis] + WINDOWS_HOVER_PADDING; border_target = ImClamp(border_target, clamp_min, clamp_max); @@ -5499,23 +5899,31 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s window->DC.NavLayerCurrent = ImGuiNavLayer_Main; // Navigation resize (keyboard/gamepad) + // FIXME: This cannot be moved to NavUpdateWindowing() because CalcWindowSizeAfterConstraint() need to callback into user. + // Not even sure the callback works here. if (g.NavWindowingTarget && g.NavWindowingTarget->RootWindow == window) { - ImVec2 nav_resize_delta; + ImVec2 nav_resize_dir; if (g.NavInputSource == ImGuiInputSource_Keyboard && g.IO.KeyShift) - nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down); + nav_resize_dir = GetKeyMagnitude2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow); if (g.NavInputSource == ImGuiInputSource_Gamepad) - nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_Down); - if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f) + nav_resize_dir = GetKeyMagnitude2d(ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown); + if (nav_resize_dir.x != 0.0f || nav_resize_dir.y != 0.0f) { const float NAV_RESIZE_SPEED = 600.0f; - nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); - nav_resize_delta = ImMax(nav_resize_delta, visibility_rect.Min - window->Pos - window->Size); + const float resize_step = NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y); + g.NavWindowingAccumDeltaSize += nav_resize_dir * resize_step; + g.NavWindowingAccumDeltaSize = ImMax(g.NavWindowingAccumDeltaSize, clamp_rect.Min - window->Pos - window->Size); // We need Pos+Size >= clmap_rect.Min, so Size >= clmap_rect.Min - Pos, so size_delta >= clmap_rect.Min - window->Pos - window->Size g.NavWindowingToggleLayer = false; g.NavDisableMouseHover = true; resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive); - // FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck. - size_target = CalcWindowSizeAfterConstraint(window, window->SizeFull + nav_resize_delta); + ImVec2 accum_floored = ImFloor(g.NavWindowingAccumDeltaSize); + if (accum_floored.x != 0.0f || accum_floored.y != 0.0f) + { + // FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck. + size_target = CalcWindowSizeAfterConstraint(window, window->SizeFull + accum_floored); + g.NavWindowingAccumDeltaSize -= accum_floored; + } } } @@ -5535,7 +5943,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s return ret_auto_fit; } -static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& visibility_rect) +static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_rect) { ImGuiContext& g = *GImGui; ImVec2 size_for_clamping = window->Size; @@ -5570,7 +5978,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) // Draw background and borders // Draw and handle scrollbars -void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size) +void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size) { ImGuiContext& g = *GImGui; ImGuiStyle& style = g.Style; @@ -5581,13 +5989,13 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar window->SkipItems = false; // Draw window + handle manual resize - // As we highlight the title bar when want_focus is set, multiple reappearing windows will have have their title bar highlighted on their reappearing frame. + // As we highlight the title bar when want_focus is set, multiple reappearing windows will have their title bar highlighted on their reappearing frame. const float window_rounding = window->WindowRounding; const float window_border_size = window->WindowBorderSize; if (window->Collapsed) { // Title bar only - float backup_border_size = style.FrameBorderSize; + const float backup_border_size = style.FrameBorderSize; g.Style.FrameBorderSize = window->WindowBorderSize; ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed); RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding); @@ -5598,7 +6006,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar // Window background if (!(flags & ImGuiWindowFlags_NoBackground)) { - ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); + ImU32 bg_col = GetColorU32(GetWindowBgColorIdx(window)); bool override_alpha = false; float alpha = 1.0f; if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasBgAlpha) @@ -5635,21 +6043,25 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar Scrollbar(ImGuiAxis_Y); // Render resize grips (after their input handling so we don't have a frame of latency) - if (!(flags & ImGuiWindowFlags_NoResize)) + if (handle_borders_and_resize_grips && !(flags & ImGuiWindowFlags_NoResize)) { for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) { + const ImU32 col = resize_grip_col[resize_grip_n]; + if ((col & IM_COL32_A_MASK) == 0) + continue; const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN); window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, window_border_size))); window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, window_border_size) : ImVec2(window_border_size, resize_grip_draw_size))); window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); - window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]); + window->DrawList->PathFillConvex(col); } } // Borders - RenderWindowOuterBorders(window); + if (handle_borders_and_resize_grips) + RenderWindowOuterBorders(window); } } @@ -5664,6 +6076,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl const bool has_collapse_button = !(flags & ImGuiWindowFlags_NoCollapse) && (style.WindowMenuButtonPosition != ImGuiDir_None); // Close & Collapse button are on the Menu NavLayer and don't default focus (unless there's nothing else on that layer) + // FIXME-NAV: Might want (or not?) to set the equivalent of ImGuiButtonFlags_NoNavFocus so that mouse clicks on standard title bar items don't necessarily set nav/keyboard ref? const ImGuiItemFlags item_flags_backup = g.CurrentItemFlags; g.CurrentItemFlags |= ImGuiItemFlags_NoNavDefaultFocus; window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; @@ -5758,6 +6171,42 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags } } +// When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing) +// should be positioned behind that modal window, unless the window was created inside the modal begin-stack. +// In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent. +// - WindowA // FindBlockingModal() returns Modal1 +// - WindowB // .. returns Modal1 +// - Modal1 // .. returns Modal2 +// - WindowC // .. returns Modal2 +// - WindowD // .. returns Modal2 +// - Modal2 // .. returns Modal2 +// - WindowE // .. returns NULL +// Notes: +// - FindBlockingModal(NULL) == NULL is generally equivalent to GetTopMostPopupModal() == NULL. +// Only difference is here we check for ->Active/WasActive but it may be unecessary. +ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size <= 0) + return NULL; + + // Find a modal that has common parent with specified window. Specified window should be positioned behind that modal. + for (int i = 0; i < g.OpenPopupStack.Size; i++) + { + ImGuiWindow* popup_window = g.OpenPopupStack.Data[i].Window; + if (popup_window == NULL || !(popup_window->Flags & ImGuiWindowFlags_Modal)) + continue; + if (!popup_window->Active && !popup_window->WasActive) // Check WasActive, because this code may run before popup renders on current frame, also check Active to handle newly created windows. + continue; + if (window == NULL) // FindBlockingModal(NULL) test for if FocusWindow(NULL) is naturally possible via a mouse click. + return popup_window; + if (IsWindowWithinBeginStackOf(window, popup_window)) // Window may be over modal + continue; + return popup_window; // Place window right below first block modal + } + return NULL; +} + // Push a new Dear ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -5805,6 +6254,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update Flags, LastFrameActive, BeginOrderXXX fields if (first_begin_of_the_frame) { + UpdateWindowInFocusOrderList(window, window_just_created, flags); window->Flags = (ImGuiWindowFlags)flags; window->LastFrameActive = current_frame; window->LastTimeActive = (float)g.Time; @@ -5831,22 +6281,33 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImGuiWindowStackData window_stack_data; window_stack_data.Window = window; window_stack_data.ParentLastItemDataBackup = g.LastItemData; - window_stack_data.StackSizesOnBegin.SetToCurrentState(); + window_stack_data.StackSizesOnBegin.SetToContextState(&g); g.CurrentWindowStack.push_back(window_stack_data); + if (flags & ImGuiWindowFlags_ChildMenu) + g.BeginMenuCount++; + + // Update ->RootWindow and others pointers (before any possible call to FocusWindow) + if (first_begin_of_the_frame) + { + UpdateWindowParentAndRootLinks(window, flags, parent_window); + window->ParentWindowInBeginStack = parent_window_in_stack; + } + + // Add to focus scope stack + PushFocusScope(window->ID); + window->NavRootFocusScopeId = g.CurrentFocusScopeId; g.CurrentWindow = NULL; + // Add to popup stack if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size]; popup_ref.Window = window; + popup_ref.ParentNavLayer = parent_window_in_stack->DC.NavLayerCurrent; g.BeginPopupStack.push_back(popup_ref); window->PopupId = popup_ref.PopupId; } - // Update ->RootWindow and others pointers (before any possible call to FocusWindow) - if (first_begin_of_the_frame) - UpdateWindowParentAndRootLinks(window, flags, parent_window); - // Process SetNextWindow***() calls // (FIXME: Consider splitting the HasXXX flags into X/Y components bool window_pos_set_by_api = false; @@ -5902,6 +6363,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Initialize const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) + const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0); window->Active = true; window->HasCloseButton = (p_open != NULL); window->ClipRect = ImVec4(-FLT_MAX, -FLT_MAX, +FLT_MAX, +FLT_MAX); @@ -5928,7 +6390,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS // Update contents size from last frame for auto-fitting (or use explicit size) - const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0); CalcWindowContentSizes(window, &window->ContentSize, &window->ContentSizeIdeal); if (window->HiddenFramesCanSkipItems > 0) window->HiddenFramesCanSkipItems--; @@ -5958,6 +6419,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SELECT VIEWPORT // FIXME-VIEWPORT: In the docking/viewport branch, this is the point where we select the current viewport (which may affect the style) + + ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport(); + SetWindowViewport(window, viewport); SetCurrentWindow(window); // LOCK BORDER SIZE AND PADDING FOR THE FRAME (so that altering them doesn't cause inconsistencies) @@ -5974,17 +6438,22 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x); window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y; + bool use_current_size_for_scrollbar_x = window_just_created; + bool use_current_size_for_scrollbar_y = window_just_created; + // Collapse window by double-clicking on title bar // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse)) { // We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar. ImRect title_bar_rect = window->TitleBarRect(); - if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0]) + if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseClickedCount[0] == 2) window->WantCollapseToggle = true; if (window->WantCollapseToggle) { window->Collapsed = !window->Collapsed; + if (!window->Collapsed) + use_current_size_for_scrollbar_y = true; MarkIniSettingsDirty(window); } } @@ -5996,10 +6465,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SIZE + // Outer Decoration Sizes + // (we need to clear ScrollbarSize immediatly as CalcWindowAutoFitSize() needs it and can be called from other locations). + const ImVec2 scrollbar_sizes_from_last_frame = window->ScrollbarSizes; + window->DecoOuterSizeX1 = 0.0f; + window->DecoOuterSizeX2 = 0.0f; + window->DecoOuterSizeY1 = window->TitleBarHeight() + window->MenuBarHeight(); + window->DecoOuterSizeY2 = 0.0f; + window->ScrollbarSizes = ImVec2(0.0f, 0.0f); + // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSizeIdeal); - bool use_current_size_for_scrollbar_x = window_just_created; - bool use_current_size_for_scrollbar_y = window_just_created; if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window->Collapsed) { // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. @@ -6036,9 +6512,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->SizeFull = CalcWindowSizeAfterConstraint(window, window->SizeFull); window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; - // Decoration size - const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); - // POSITION // Popup latch its initial position, will position itself when it appears next frame @@ -6071,7 +6544,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Calculate the range of allowed position for that window (to be movable and visible past safe area padding) // When clamping to stay visible, we will enforce that window->Pos stays inside of visibility_rect. - ImGuiViewportP* viewport = (ImGuiViewportP*)(void*)GetMainViewport(); ImRect viewport_rect(viewport->GetMainRect()); ImRect viewport_work_rect(viewport->GetWorkRect()); ImVec2 visibility_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); @@ -6079,9 +6551,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Clamp position/size so window stays visible within its viewport or monitor // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. - if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) + if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow)) if (viewport_rect.GetWidth() > 0.0f && viewport_rect.GetHeight() > 0.0f) - ClampWindowRect(window, visibility_rect); + ClampWindowPos(window, visibility_rect); window->Pos = ImFloor(window->Pos); // Lock window rounding for the frame (so that altering them doesn't cause inconsistencies) @@ -6102,6 +6574,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) want_focus = true; } + // [Test Engine] Register whole window in the item system (before submitting further decorations) +#ifdef IMGUI_ENABLE_TEST_ENGINE + if (g.TestEngineHookItems) + { + IM_ASSERT(window->IDStack.Size == 1); + window->IDStack.Size = 0; // As window->IDStack[0] == window->ID here, make sure TestEngine doesn't erroneously see window as parent of itself. + IMGUI_TEST_ENGINE_ITEM_ADD(window->ID, window->Rect(), NULL); + IMGUI_TEST_ENGINE_ITEM_INFO(window->ID, window->Name, (g.HoveredWindow == window) ? ImGuiItemStatusFlags_HoveredRect : 0); + window->IDStack.Size = 1; + } +#endif + // Handle manual resize: Resize Grips, Borders, Gamepad int border_held = -1; ImU32 resize_grip_col[4] = {}; @@ -6118,9 +6602,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (!window->Collapsed) { // When reading the current size we need to read it after size constraints have been applied. - // When we use InnerRect here we are intentionally reading last frame size, same for ScrollbarSizes values before we set them again. - ImVec2 avail_size_from_current_frame = ImVec2(window->SizeFull.x, window->SizeFull.y - decoration_up_height); - ImVec2 avail_size_from_last_frame = window->InnerRect.GetSize() + window->ScrollbarSizes; + // Intentionally use previous frame values for InnerRect and ScrollbarSizes. + // And when we use window->DecorationUp here it doesn't have ScrollbarSizes.y applied yet. + ImVec2 avail_size_from_current_frame = ImVec2(window->SizeFull.x, window->SizeFull.y - (window->DecoOuterSizeY1 + window->DecoOuterSizeY2)); + ImVec2 avail_size_from_last_frame = window->InnerRect.GetSize() + scrollbar_sizes_from_last_frame; ImVec2 needed_size_from_last_frame = window_just_created ? ImVec2(0, 0) : window->ContentSize + window->WindowPadding * 2.0f; float size_x_for_scrollbars = use_current_size_for_scrollbar_x ? avail_size_from_current_frame.x : avail_size_from_last_frame.x; float size_y_for_scrollbars = use_current_size_for_scrollbar_y ? avail_size_from_current_frame.y : avail_size_from_last_frame.y; @@ -6130,10 +6615,14 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->ScrollbarX && !window->ScrollbarY) window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); + + // Amend the partially filled window->DecorationXXX values. + window->DecoOuterSizeX2 += window->ScrollbarSizes.x; + window->DecoOuterSizeY2 += window->ScrollbarSizes.y; } // UPDATE RECTANGLES (1- THOSE NOT AFFECTED BY SCROLLING) - // Update various regions. Variables they depends on should be set above in this function. + // Update various regions. Variables they depend on should be set above in this function. // We set this up after processing the resize grip so that our rectangles doesn't lag by a frame. // Outer rectangle @@ -6150,13 +6639,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Inner rectangle // Not affected by window border size. Used by: // - InnerClipRect - // - ScrollToBringRectIntoView() + // - ScrollToRectEx() // - NavUpdatePageUpPageDown() // - Scrollbar() - window->InnerRect.Min.x = window->Pos.x; - window->InnerRect.Min.y = window->Pos.y + decoration_up_height; - window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x; - window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y; + window->InnerRect.Min.x = window->Pos.x + window->DecoOuterSizeX1; + window->InnerRect.Min.y = window->Pos.y + window->DecoOuterSizeY1; + window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->DecoOuterSizeX2; + window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->DecoOuterSizeY2; // Inner clipping rectangle. // Will extend a little bit outside the normal work region. @@ -6189,6 +6678,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Apply scrolling window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); + window->DecoInnerSizeX1 = window->DecoInnerSizeY1 = 0.0f; // DRAWING @@ -6197,24 +6687,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); PushClipRect(host_rect.Min, host_rect.Max, false); - // Draw modal window background (darkens what is behind them, all viewports) - const bool dim_bg_for_modal = (flags & ImGuiWindowFlags_Modal) && window == GetTopMostPopupModal() && window->HiddenFramesCannotSkipItems <= 0; - const bool dim_bg_for_window_list = g.NavWindowingTargetAnim && (window == g.NavWindowingTargetAnim->RootWindow); - if (dim_bg_for_modal || dim_bg_for_window_list) - { - const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio); - window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, dim_bg_col); - } - - // Draw navigation selection/windowing rectangle background - if (dim_bg_for_window_list && window == g.NavWindowingTargetAnim) - { - ImRect bb = window->Rect(); - bb.Expand(g.FontSize); - if (!bb.Contains(viewport_rect)) // Avoid drawing if the window covers all the viewport anyway - window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding); - } - // Child windows can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call (since 1.71) // When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order. // FIXME: User code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected (github #4493) @@ -6226,8 +6698,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // - We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping childs ImGuiWindow* previous_child = parent_window->DC.ChildWindows.Size >= 2 ? parent_window->DC.ChildWindows[parent_window->DC.ChildWindows.Size - 2] : NULL; bool previous_child_overlapping = previous_child ? previous_child->Rect().Overlaps(window->Rect()) : false; - bool parent_is_empty = parent_window->DrawList->VtxBuffer.Size > 0; - if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_is_empty && !previous_child_overlapping) + bool parent_is_empty = (parent_window->DrawList->VtxBuffer.Size == 0); + if (window->DrawList->CmdBuffer.back().ElemCount == 0 && !parent_is_empty && !previous_child_overlapping) render_decorations_in_parent = true; } if (render_decorations_in_parent) @@ -6236,26 +6708,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Handle title bar, scrollbar, resize grips and resize borders const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow; const bool title_bar_is_highlight = want_focus || (window_to_highlight && window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight); - RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, resize_grip_count, resize_grip_col, resize_grip_draw_size); + const bool handle_borders_and_resize_grips = true; // This exists to facilitate merge with 'docking' branch. + RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, handle_borders_and_resize_grips, resize_grip_count, resize_grip_col, resize_grip_draw_size); if (render_decorations_in_parent) window->DrawList = &window->DrawListInst; } - // Draw navigation selection/windowing rectangle border - if (g.NavWindowingTargetAnim == window) - { - float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding); - ImRect bb = window->Rect(); - bb.Expand(g.FontSize); - if (bb.Contains(viewport_rect)) // If a window fits the entire viewport, adjust its highlight inward - { - bb.Expand(-g.FontSize - 1.0f); - rounding = window->WindowRounding; - } - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, 0, 3.0f); - } - // UPDATE RECTANGLES (2- THOSE AFFECTED BY SCROLLING) // Work rectangle. @@ -6265,8 +6724,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // - BeginTabBar() for right-most edge const bool allow_scrollbar_x = !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar); const bool allow_scrollbar_y = !(flags & ImGuiWindowFlags_NoScrollbar); - const float work_rect_size_x = (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : ImMax(allow_scrollbar_x ? window->ContentSize.x : 0.0f, window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x)); - const float work_rect_size_y = (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : ImMax(allow_scrollbar_y ? window->ContentSize.y : 0.0f, window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y)); + const float work_rect_size_x = (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : ImMax(allow_scrollbar_x ? window->ContentSize.x : 0.0f, window->Size.x - window->WindowPadding.x * 2.0f - (window->DecoOuterSizeX1 + window->DecoOuterSizeX2))); + const float work_rect_size_y = (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : ImMax(allow_scrollbar_y ? window->ContentSize.y : 0.0f, window->Size.y - window->WindowPadding.y * 2.0f - (window->DecoOuterSizeY1 + window->DecoOuterSizeY2))); window->WorkRect.Min.x = ImFloor(window->InnerRect.Min.x - window->Scroll.x + ImMax(window->WindowPadding.x, window->WindowBorderSize)); window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize)); window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x; @@ -6277,29 +6736,37 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it. // Used by: // - Mouse wheel scrolling + many other things - window->ContentRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x; - window->ContentRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + decoration_up_height; - window->ContentRegionRect.Max.x = window->ContentRegionRect.Min.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x)); - window->ContentRegionRect.Max.y = window->ContentRegionRect.Min.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y)); + window->ContentRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x + window->DecoOuterSizeX1; + window->ContentRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->DecoOuterSizeY1; + window->ContentRegionRect.Max.x = window->ContentRegionRect.Min.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->WindowPadding.x * 2.0f - (window->DecoOuterSizeX1 + window->DecoOuterSizeX2))); + window->ContentRegionRect.Max.y = window->ContentRegionRect.Min.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->WindowPadding.y * 2.0f - (window->DecoOuterSizeY1 + window->DecoOuterSizeY2))); // Setup drawing context // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) - window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x; + window->DC.Indent.x = window->DecoOuterSizeX1 + window->WindowPadding.x - window->Scroll.x; window->DC.GroupOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f; - window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.Indent.x + window->DC.ColumnsOffset.x, decoration_up_height + window->WindowPadding.y - window->Scroll.y); + + // Record the loss of precision of CursorStartPos which can happen due to really large scrolling amount. + // This is used by clipper to compensate and fix the most common use case of large scroll area. Easy and cheap, next best thing compared to switching everything to double or ImU64. + double start_pos_highp_x = (double)window->Pos.x + window->WindowPadding.x - (double)window->Scroll.x + window->DecoOuterSizeX1 + window->DC.ColumnsOffset.x; + double start_pos_highp_y = (double)window->Pos.y + window->WindowPadding.y - (double)window->Scroll.y + window->DecoOuterSizeY1; + window->DC.CursorStartPos = ImVec2((float)start_pos_highp_x, (float)start_pos_highp_y); + window->DC.CursorStartPosLossyness = ImVec2((float)(start_pos_highp_x - window->DC.CursorStartPos.x), (float)(start_pos_highp_y - window->DC.CursorStartPos.y)); window->DC.CursorPos = window->DC.CursorStartPos; window->DC.CursorPosPrevLine = window->DC.CursorPos; window->DC.CursorMaxPos = window->DC.CursorStartPos; window->DC.IdealMaxPos = window->DC.CursorStartPos; window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; + window->DC.IsSameLine = window->DC.IsSetPos = false; window->DC.NavLayerCurrent = ImGuiNavLayer_Main; window->DC.NavLayersActiveMask = window->DC.NavLayersActiveMaskNext; window->DC.NavLayersActiveMaskNext = 0x00; + window->DC.NavIsScrollPushableX = true; window->DC.NavHideHighlightOneFrame = false; - window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f); + window->DC.NavWindowHasScrollY = (window->ScrollMax.y > 0.0f); window->DC.MenuBarAppending = false; window->DC.MenuColumns.Update(style.ItemSpacing.x, window_just_activated_by_user); @@ -6310,7 +6777,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.CurrentColumns = NULL; window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; - window->DC.FocusCounterTabStop = -1; window->DC.ItemWidth = window->ItemWidthDefault; window->DC.TextWrapPos = -1.0f; // disabled @@ -6323,11 +6789,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->AutoFitFramesY--; // Apply focus (we need to call FocusWindow() AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) + // We ImGuiFocusRequestFlags_UnlessBelowModal to: + // - Avoid focusing a window that is created outside of a modal. This will prevent active modal from being closed. + // - Position window behind the modal that is not a begin-parent of this window. if (want_focus) - { - FocusWindow(window); + FocusWindow(window, ImGuiFocusRequestFlags_UnlessBelowModal); + if (want_focus && window == g.NavWindow) NavInitWindow(window, false); // <-- this is in the way for us to be able to defer and sort reappearing FocusWindow() calls - } // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) @@ -6342,20 +6810,24 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) /* //if (g.NavWindow == window && g.ActiveId == 0) if (g.ActiveId == window->MoveId) - if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) + if (g.IO.KeyCtrl && IsKeyPressed(ImGuiKey_C)) LogToClipboard(); */ // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin(). // This is useful to allow creating context menus on title bar only, etc. - g.LastItemData.ID = window->MoveId; - g.LastItemData.InFlags = g.CurrentItemFlags; - g.LastItemData.StatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; - g.LastItemData.Rect = title_bar_rect; + SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect); + // [DEBUG] +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + if (g.DebugLocateId != 0 && (window->ID == g.DebugLocateId || window->MoveId == g.DebugLocateId)) + DebugLocateItemResolveWithLastItem(); +#endif + + // [Test Engine] Register title bar / tab with MoveId. #ifdef IMGUI_ENABLE_TEST_ENGINE if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) - IMGUI_TEST_ENGINE_ITEM_ADD(g.LastItemData.Rect, g.LastItemData.ID); + IMGUI_TEST_ENGINE_ITEM_ADD(g.LastItemData.ID, g.LastItemData.Rect, &g.LastItemData); #endif } else @@ -6364,9 +6836,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetCurrentWindow(window); } - // Pull/inherit current state - window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : window->GetID("#FOCUSSCOPE"); // Inherit from parent only // -V595 - PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) @@ -6383,9 +6852,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar). IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) // FIXME: Doesn't make sense for ChildWindow?? - if (!g.LogEnabled) + { + const bool nav_request = (flags & ImGuiWindowFlags_NavFlattened) && (g.NavAnyRequest && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); + if (!g.LogEnabled && !nav_request) if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y) window->HiddenFramesCanSkipItems = 1; + } // Hide along with parent or if parent is collapsed if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0)) @@ -6399,7 +6871,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->HiddenFramesCanSkipItems = 1; // Update the Hidden flag - window->Hidden = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0) || (window->HiddenFramesForRenderOnly > 0); + bool hidden_regular = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0); + window->Hidden = hidden_regular || (window->HiddenFramesForRenderOnly > 0); // Disable inputs for requested number of frames if (window->DisableInputsFrames > 0) @@ -6410,12 +6883,21 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Update the SkipItems flag, used to early out of all items functions (no layout required) bool skip_items = false; - if (window->Collapsed || !window->Active || window->Hidden) + if (window->Collapsed || !window->Active || hidden_regular) if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesCannotSkipItems <= 0) skip_items = true; window->SkipItems = skip_items; } + // [DEBUG] io.ConfigDebugBeginReturnValue override return value to test Begin/End and BeginChild/EndChild behaviors. + // (The implicit fallback window is NOT automatically ended allowing it to always be able to receive commands without crashing) + if (!window->IsFallbackWindow && ((g.IO.ConfigDebugBeginReturnValueOnce && window_just_created) || (g.IO.ConfigDebugBeginReturnValueLoop && g.DebugBeginReturnValueCullDepth == g.CurrentWindowStack.Size))) + { + if (window->AutoFitFramesX > 0) { window->AutoFitFramesX++; } + if (window->AutoFitFramesY > 0) { window->AutoFitFramesY++; } + return false; + } + return !window->SkipItems; } @@ -6440,16 +6922,22 @@ void ImGui::End() if (window->DC.CurrentColumns) EndColumns(); PopClipRect(); // Inner window clip rectangle + PopFocusScope(); // Stop logging if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging LogFinish(); + if (window->DC.IsSetPos) + ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); + // Pop from window stack g.LastItemData = g.CurrentWindowStack.back().ParentLastItemDataBackup; + if (window->Flags & ImGuiWindowFlags_ChildMenu) + g.BeginMenuCount--; if (window->Flags & ImGuiWindowFlags_Popup) g.BeginPopupStack.pop_back(); - g.CurrentWindowStack.back().StackSizesOnBegin.CompareWithCurrentState(); + g.CurrentWindowStack.back().StackSizesOnBegin.CompareWithContextState(&g); g.CurrentWindowStack.pop_back(); SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window); } @@ -6504,27 +6992,67 @@ void ImGui::BringWindowToDisplayBack(ImGuiWindow* window) } } +void ImGui::BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* behind_window) +{ + IM_ASSERT(window != NULL && behind_window != NULL); + ImGuiContext& g = *GImGui; + window = window->RootWindow; + behind_window = behind_window->RootWindow; + int pos_wnd = FindWindowDisplayIndex(window); + int pos_beh = FindWindowDisplayIndex(behind_window); + if (pos_wnd < pos_beh) + { + size_t copy_bytes = (pos_beh - pos_wnd - 1) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_wnd], &g.Windows.Data[pos_wnd + 1], copy_bytes); + g.Windows[pos_beh - 1] = window; + } + else + { + size_t copy_bytes = (pos_wnd - pos_beh) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_beh + 1], &g.Windows.Data[pos_beh], copy_bytes); + g.Windows[pos_beh] = window; + } +} + +int ImGui::FindWindowDisplayIndex(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + return g.Windows.index_from_ptr(g.Windows.find(window)); +} + // Moving window to front of display and set focus (which happens to be back of our sorted list) -void ImGui::FocusWindow(ImGuiWindow* window) +void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags) { ImGuiContext& g = *GImGui; + // Modal check? + if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case. + if (ImGuiWindow* blocking_modal = FindBlockingModal(window)) + { + IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "", blocking_modal->Name); + if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) + BringWindowToDisplayBehind(window, blocking_modal); // Still bring to right below modal. + return; + } + + // Find last focused child (if any) and focus it instead. + if ((flags & ImGuiFocusRequestFlags_RestoreFocusedChild) && window != NULL) + window = NavRestoreLastChildNavWindow(window); + + // Apply focus if (g.NavWindow != window) { - g.NavWindow = window; + SetNavWindow(window); if (window && g.NavDisableMouseHover) g.NavMousePosDirty = true; g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId - g.NavFocusScopeId = 0; - g.NavIdIsAlive = false; g.NavLayer = ImGuiNavLayer_Main; - g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false; - NavUpdateAnyRequestFlag(); - //IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL); - } + g.NavFocusScopeId = window ? window->NavRootFocusScopeId : 0; + g.NavIdIsAlive = false; - // Close popups if any - ClosePopupsOverWindow(window, false); + // Close popups if any + ClosePopupsOverWindow(window, false); + } // Move the root window to the top of the pile IM_ASSERT(window == NULL || window->RootWindow != NULL); @@ -6548,9 +7076,10 @@ void ImGui::FocusWindow(ImGuiWindow* window) BringWindowToDisplayFront(display_front_window); } -void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window) +void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags) { ImGuiContext& g = *GImGui; + IM_UNUSED(filter_viewport); // Unused in master branch. int start_idx = g.WindowsFocusOrder.Size - 1; if (under_this_window != NULL) { @@ -6568,15 +7097,15 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind // We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user. ImGuiWindow* window = g.WindowsFocusOrder[i]; IM_ASSERT(window == window->RootWindow); - if (window != ignore_window && window->WasActive) - if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) - { - ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window); - FocusWindow(focus_window); - return; - } + if (window == ignore_window || !window->WasActive) + continue; + if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) + { + FocusWindow(window, flags); + return; + } } - FocusWindow(NULL); + FocusWindow(NULL, flags); } // Important: this alone doesn't alter current ImDrawList state. This is called by PushFont/PopFont only. @@ -6669,13 +7198,12 @@ void ImGui::EndDisabled() g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar(); } -// FIXME: Look into renaming this once we have settled the new Focus/Activation/TabStop system. -void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) +void ImGui::PushTabStop(bool tab_stop) { - PushItemFlag(ImGuiItemFlags_NoTabStop, !allow_keyboard_focus); + PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); } -void ImGui::PopAllowKeyboardFocus() +void ImGui::PopTabStop() { PopItemFlag(); } @@ -6706,9 +7234,14 @@ void ImGui::PopTextWrapPos() static ImGuiWindow* GetCombinedRootWindow(ImGuiWindow* window, bool popup_hierarchy) { - window = window->RootWindow; - if (popup_hierarchy) - window = window->RootWindowPopupTree; + ImGuiWindow* last_window = NULL; + while (last_window != window) + { + last_window = window; + window = window->RootWindow; + if (popup_hierarchy) + window = window->RootWindowPopupTree; + } return window; } @@ -6728,9 +7261,28 @@ bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, return false; } +bool ImGui::IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent) +{ + if (window->RootWindow == potential_parent) + return true; + while (window != NULL) + { + if (window == potential_parent) + return true; + window = window->ParentWindowInBeginStack; + } + return false; +} + bool ImGui::IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below) { ImGuiContext& g = *GImGui; + + // It would be saner to ensure that display layer is always reflected in the g.Windows[] order, which would likely requires altering all manipulations of that array + const int display_layer_delta = GetWindowDisplayLayer(potential_above) - GetWindowDisplayLayer(potential_below); + if (display_layer_delta != 0) + return display_layer_delta > 0; + for (int i = g.Windows.Size - 1; i >= 0; i--) { ImGuiWindow* candidate_window = g.Windows[i]; @@ -6744,7 +7296,8 @@ bool ImGui::IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_b bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { - IM_ASSERT((flags & (ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled)) == 0); // Flags not supported by this function + IM_ASSERT((flags & ~ImGuiHoveredFlags_AllowedMaskForIsWindowHovered) == 0 && "Invalid flags for IsWindowHovered()!"); + ImGuiContext& g = *GImGui; ImGuiWindow* ref_window = g.HoveredWindow; ImGuiWindow* cur_window = g.CurrentWindow; @@ -6772,6 +7325,17 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != ref_window->MoveId) return false; + + // When changing hovered window we requires a bit of stationary delay before activating hover timer. + // FIXME: We don't support delay other than stationary one for now, other delay would need a way + // to fullfill the possibility that multiple IsWindowHovered() with varying flag could return true + // for different windows of the hierarchy. Possibly need a Hash(Current+Flags) ==> (Timer) cache. + // We can implement this for _Stationary because the data is linked to HoveredWindow rather than CurrentWindow. + if (flags & ImGuiHoveredFlags_ForTooltip) + flags |= g.Style.HoverFlagsForTooltipMouse; + if ((flags & ImGuiHoveredFlags_Stationary) != 0 && g.HoverWindowUnlockedStationaryId != ref_window->ID) + return false; + return true; } @@ -6785,8 +7349,8 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) return false; if (flags & ImGuiFocusedFlags_AnyWindow) return true; - IM_ASSERT(cur_window); // Not inside a Begin()/End() + IM_ASSERT(cur_window); // Not inside a Begin()/End() const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0; if (flags & ImGuiHoveredFlags_RootWindow) cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy); @@ -6838,6 +7402,9 @@ void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) const ImVec2 old_pos = window->Pos; window->Pos = ImFloor(pos); ImVec2 offset = window->Pos - old_pos; + if (offset.x == 0.0f && offset.y == 0.0f) + return; + MarkIniSettingsDirty(window); window->DC.CursorPos += offset; // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor window->DC.CursorMaxPos += offset; // And more importantly we need to offset CursorMaxPos/CursorStartPos this so ContentSize calculation doesn't get affected. window->DC.IdealMaxPos += offset; @@ -6872,26 +7439,19 @@ void ImGui::SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond con window->SetWindowSizeAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); // Set - if (size.x > 0.0f) - { - window->AutoFitFramesX = 0; + ImVec2 old_size = window->SizeFull; + window->AutoFitFramesX = (size.x <= 0.0f) ? 2 : 0; + window->AutoFitFramesY = (size.y <= 0.0f) ? 2 : 0; + if (size.x <= 0.0f) + window->AutoFitOnlyGrows = false; + else window->SizeFull.x = IM_FLOOR(size.x); - } - else - { - window->AutoFitFramesX = 2; + if (size.y <= 0.0f) window->AutoFitOnlyGrows = false; - } - if (size.y > 0.0f) - { - window->AutoFitFramesY = 0; + else window->SizeFull.y = IM_FLOOR(size.y); - } - else - { - window->AutoFitFramesY = 2; - window->AutoFitOnlyGrows = false; - } + if (old_size.x != window->SizeFull.x || old_size.y != window->SizeFull.y) + MarkIniSettingsDirty(window); } void ImGui::SetWindowSize(const ImVec2& size, ImGuiCond cond) @@ -6923,6 +7483,12 @@ void ImGui::SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const I window->HitTestHoleOffset = ImVec2ih(pos - window->Pos); } +void ImGui::SetWindowHiddendAndSkipItemsForCurrentFrame(ImGuiWindow* window) +{ + window->Hidden = window->SkipItems = true; + window->HiddenFramesCanSkipItems = 1; +} + void ImGui::SetWindowCollapsed(bool collapsed, ImGuiCond cond) { SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond); @@ -7060,42 +7626,80 @@ void ImGui::SetWindowFontScale(float scale) g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); } -void ImGui::ActivateItem(ImGuiID id) +void ImGui::PushFocusScope(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.FocusScopeStack.push_back(id); + g.CurrentFocusScopeId = id; +} + +void ImGui::PopFocusScope() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.FocusScopeStack.Size > 0); // Too many PopFocusScope() ? + g.FocusScopeStack.pop_back(); + g.CurrentFocusScopeId = g.FocusScopeStack.Size ? g.FocusScopeStack.back() : 0; +} + +// Focus = move navigation cursor, set scrolling, set focus window. +void ImGui::FocusItem() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IMGUI_DEBUG_LOG_FOCUS("FocusItem(0x%08x) in window \"%s\"\n", g.LastItemData.ID, window->Name); + if (g.DragDropActive || g.MovingWindow != NULL) // FIXME: Opt-in flags for this? + { + IMGUI_DEBUG_LOG_FOCUS("FocusItem() ignored while DragDropActive!\n"); + return; + } + + ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSelect; + ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; + SetNavWindow(window); + NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_Up, move_flags, scroll_flags); + NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal); +} + +void ImGui::ActivateItemByID(ImGuiID id) { ImGuiContext& g = *GImGui; g.NavNextActivateId = id; g.NavNextActivateFlags = ImGuiActivateFlags_None; } -void ImGui::PushFocusScope(ImGuiID id) -{ - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - g.FocusScopeStack.push_back(window->DC.NavFocusScopeIdCurrent); - window->DC.NavFocusScopeIdCurrent = id; -} - -void ImGui::PopFocusScope() -{ - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT(g.FocusScopeStack.Size > 0); // Too many PopFocusScope() ? - window->DC.NavFocusScopeIdCurrent = g.FocusScopeStack.back(); - g.FocusScopeStack.pop_back(); -} - +// Note: this will likely be called ActivateItem() once we rework our Focus/Activation system! +// But ActivateItem() should function without altering scroll/focus? void ImGui::SetKeyboardFocusHere(int offset) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; IM_ASSERT(offset >= -1); // -1 is allowed but not below - g.NavWindow = window; + IMGUI_DEBUG_LOG_FOCUS("SetKeyboardFocusHere(%d) in window \"%s\"\n", offset, window->Name); + + // It makes sense in the vast majority of cases to never interrupt a drag and drop. + // When we refactor this function into ActivateItem() we may want to make this an option. + // MovingWindow is protected from most user inputs using SetActiveIdUsingNavAndKeys(), but + // is also automatically dropped in the event g.ActiveId is stolen. + if (g.DragDropActive || g.MovingWindow != NULL) + { + IMGUI_DEBUG_LOG_FOCUS("SetKeyboardFocusHere() ignored while DragDropActive!\n"); + return; + } + + SetNavWindow(window); + + ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; - NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_None, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. + NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. if (offset == -1) - NavMoveRequestResolveWithLastItem(); + { + NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal); + } else - g.NavTabbingInputableRemaining = offset + 1; + { + g.NavTabbingDir = 1; + g.NavTabbingCounter = offset + 1; + } } void ImGui::SetItemDefaultFocus() @@ -7104,16 +7708,15 @@ void ImGui::SetItemDefaultFocus() ImGuiWindow* window = g.CurrentWindow; if (!window->Appearing) return; - if (g.NavWindow != window->RootWindowForNav || (!g.NavInitRequest && g.NavInitResultId == 0) || g.NavLayer != window->DC.NavLayerCurrent) + if (g.NavWindow != window->RootWindowForNav || (!g.NavInitRequest && g.NavInitResult.ID == 0) || g.NavLayer != window->DC.NavLayerCurrent) return; g.NavInitRequest = false; - g.NavInitResultId = g.LastItemData.ID; - g.NavInitResultRectRel = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos); + NavApplyItemToResult(&g.NavInitResult); NavUpdateAnyRequestFlag(); - // Scroll could be done in NavInitRequestApplyResult() via a opt-in flag (we however don't want regular init requests to scroll) - if (!IsItemVisible()) + // Scroll could be done in NavInitRequestApplyResult() via an opt-in flag (we however don't want regular init requests to scroll) + if (!window->ClipRect.Contains(g.LastItemData.Rect)) ScrollToRectEx(window, g.LastItemData.Rect, ImGuiScrollFlags_None); } @@ -7133,7 +7736,7 @@ void ImGui::PushID(const char* str_id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - ImGuiID id = window->GetIDNoKeepAlive(str_id); + ImGuiID id = window->GetID(str_id); window->IDStack.push_back(id); } @@ -7141,7 +7744,7 @@ void ImGui::PushID(const char* str_id_begin, const char* str_id_end) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - ImGuiID id = window->GetIDNoKeepAlive(str_id_begin, str_id_end); + ImGuiID id = window->GetID(str_id_begin, str_id_end); window->IDStack.push_back(id); } @@ -7149,7 +7752,7 @@ void ImGui::PushID(const void* ptr_id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - ImGuiID id = window->GetIDNoKeepAlive(ptr_id); + ImGuiID id = window->GetID(ptr_id); window->IDStack.push_back(id); } @@ -7157,7 +7760,7 @@ void ImGui::PushID(int int_id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - ImGuiID id = window->GetIDNoKeepAlive(int_id); + ImGuiID id = window->GetID(int_id); window->IDStack.push_back(id); } @@ -7177,13 +7780,21 @@ void ImGui::PushOverrideID(ImGuiID id) ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed) { ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); - KeepAliveID(id); ImGuiContext& g = *GImGui; if (g.DebugHookIdInfo == id) DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); return id; } +ImGuiID ImGui::GetIDWithSeed(int n, ImGuiID seed) +{ + ImGuiID id = ImHashData(&n, sizeof(n), seed); + ImGuiContext& g = *GImGui; + if (g.DebugHookIdInfo == id) + DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); + return id; +} + void ImGui::PopID() { ImGuiWindow* window = GImGui->CurrentWindow; @@ -7222,15 +7833,1295 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) } +//----------------------------------------------------------------------------- +// [SECTION] INPUTS +//----------------------------------------------------------------------------- +// - GetKeyData() [Internal] +// - GetKeyIndex() [Internal] +// - GetKeyName() +// - GetKeyChordName() [Internal] +// - CalcTypematicRepeatAmount() [Internal] +// - GetTypematicRepeatRate() [Internal] +// - GetKeyPressedAmount() [Internal] +// - GetKeyMagnitude2d() [Internal] +//----------------------------------------------------------------------------- +// - UpdateKeyRoutingTable() [Internal] +// - GetRoutingIdFromOwnerId() [Internal] +// - GetShortcutRoutingData() [Internal] +// - CalcRoutingScore() [Internal] +// - SetShortcutRouting() [Internal] +// - TestShortcutRouting() [Internal] +//----------------------------------------------------------------------------- +// - IsKeyDown() +// - IsKeyPressed() +// - IsKeyReleased() +//----------------------------------------------------------------------------- +// - IsMouseDown() +// - IsMouseClicked() +// - IsMouseReleased() +// - IsMouseDoubleClicked() +// - GetMouseClickedCount() +// - IsMouseHoveringRect() [Internal] +// - IsMouseDragPastThreshold() [Internal] +// - IsMouseDragging() +// - GetMousePos() +// - GetMousePosOnOpeningCurrentPopup() +// - IsMousePosValid() +// - IsAnyMouseDown() +// - GetMouseDragDelta() +// - ResetMouseDragDelta() +// - GetMouseCursor() +// - SetMouseCursor() +//----------------------------------------------------------------------------- +// - UpdateAliasKey() +// - GetMergedModsFromKeys() +// - UpdateKeyboardInputs() +// - UpdateMouseInputs() +//----------------------------------------------------------------------------- +// - LockWheelingWindow [Internal] +// - FindBestWheelingWindow [Internal] +// - UpdateMouseWheel() [Internal] +//----------------------------------------------------------------------------- +// - SetNextFrameWantCaptureKeyboard() +// - SetNextFrameWantCaptureMouse() +//----------------------------------------------------------------------------- +// - GetInputSourceName() [Internal] +// - DebugPrintInputEvent() [Internal] +// - UpdateInputEvents() [Internal] +//----------------------------------------------------------------------------- +// - GetKeyOwner() [Internal] +// - TestKeyOwner() [Internal] +// - SetKeyOwner() [Internal] +// - SetItemKeyOwner() [Internal] +// - Shortcut() [Internal] +//----------------------------------------------------------------------------- + +ImGuiKeyData* ImGui::GetKeyData(ImGuiContext* ctx, ImGuiKey key) +{ + ImGuiContext& g = *ctx; + + // Special storage location for mods + if (key & ImGuiMod_Mask_) + key = ConvertSingleModFlagToKey(ctx, key); + +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + IM_ASSERT(key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_NamedKey_END); + if (IsLegacyKey(key) && g.IO.KeyMap[key] != -1) + key = (ImGuiKey)g.IO.KeyMap[key]; // Remap native->imgui or imgui->native +#else + IM_ASSERT(IsNamedKey(key) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend & user code."); +#endif + return &g.IO.KeysData[key - ImGuiKey_KeysData_OFFSET]; +} + +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO +ImGuiKey ImGui::GetKeyIndex(ImGuiKey key) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(IsNamedKey(key)); + const ImGuiKeyData* key_data = GetKeyData(key); + return (ImGuiKey)(key_data - g.IO.KeysData); +} +#endif + +// Those names a provided for debugging purpose and are not meant to be saved persistently not compared. +static const char* const GKeyNames[] = +{ + "Tab", "LeftArrow", "RightArrow", "UpArrow", "DownArrow", "PageUp", "PageDown", + "Home", "End", "Insert", "Delete", "Backspace", "Space", "Enter", "Escape", + "LeftCtrl", "LeftShift", "LeftAlt", "LeftSuper", "RightCtrl", "RightShift", "RightAlt", "RightSuper", "Menu", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", + "Apostrophe", "Comma", "Minus", "Period", "Slash", "Semicolon", "Equal", "LeftBracket", + "Backslash", "RightBracket", "GraveAccent", "CapsLock", "ScrollLock", "NumLock", "PrintScreen", + "Pause", "Keypad0", "Keypad1", "Keypad2", "Keypad3", "Keypad4", "Keypad5", "Keypad6", + "Keypad7", "Keypad8", "Keypad9", "KeypadDecimal", "KeypadDivide", "KeypadMultiply", + "KeypadSubtract", "KeypadAdd", "KeypadEnter", "KeypadEqual", + "GamepadStart", "GamepadBack", + "GamepadFaceLeft", "GamepadFaceRight", "GamepadFaceUp", "GamepadFaceDown", + "GamepadDpadLeft", "GamepadDpadRight", "GamepadDpadUp", "GamepadDpadDown", + "GamepadL1", "GamepadR1", "GamepadL2", "GamepadR2", "GamepadL3", "GamepadR3", + "GamepadLStickLeft", "GamepadLStickRight", "GamepadLStickUp", "GamepadLStickDown", + "GamepadRStickLeft", "GamepadRStickRight", "GamepadRStickUp", "GamepadRStickDown", + "MouseLeft", "MouseRight", "MouseMiddle", "MouseX1", "MouseX2", "MouseWheelX", "MouseWheelY", + "ModCtrl", "ModShift", "ModAlt", "ModSuper", // ReservedForModXXX are showing the ModXXX names. +}; +IM_STATIC_ASSERT(ImGuiKey_NamedKey_COUNT == IM_ARRAYSIZE(GKeyNames)); + +const char* ImGui::GetKeyName(ImGuiKey key) +{ + ImGuiContext& g = *GImGui; +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + IM_ASSERT((IsNamedKeyOrModKey(key) || key == ImGuiKey_None) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend and user code."); +#else + if (IsLegacyKey(key)) + { + if (g.IO.KeyMap[key] == -1) + return "N/A"; + IM_ASSERT(IsNamedKey((ImGuiKey)g.IO.KeyMap[key])); + key = (ImGuiKey)g.IO.KeyMap[key]; + } +#endif + if (key == ImGuiKey_None) + return "None"; + if (key & ImGuiMod_Mask_) + key = ConvertSingleModFlagToKey(&g, key); + if (!IsNamedKey(key)) + return "Unknown"; + + return GKeyNames[key - ImGuiKey_NamedKey_BEGIN]; +} + +// ImGuiMod_Shortcut is translated to either Ctrl or Super. +void ImGui::GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size) +{ + ImGuiContext& g = *GImGui; + if (key_chord & ImGuiMod_Shortcut) + key_chord = ConvertShortcutMod(key_chord); + ImFormatString(out_buf, (size_t)out_buf_size, "%s%s%s%s%s", + (key_chord & ImGuiMod_Ctrl) ? "Ctrl+" : "", + (key_chord & ImGuiMod_Shift) ? "Shift+" : "", + (key_chord & ImGuiMod_Alt) ? "Alt+" : "", + (key_chord & ImGuiMod_Super) ? (g.IO.ConfigMacOSXBehaviors ? "Cmd+" : "Super+") : "", + GetKeyName((ImGuiKey)(key_chord & ~ImGuiMod_Mask_))); +} + +// t0 = previous time (e.g.: g.Time - g.IO.DeltaTime) +// t1 = current time (e.g.: g.Time) +// An event is triggered at: +// t = 0.0f t = repeat_delay, t = repeat_delay + repeat_rate*N +int ImGui::CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate) +{ + if (t1 == 0.0f) + return 1; + if (t0 >= t1) + return 0; + if (repeat_rate <= 0.0f) + return (t0 < repeat_delay) && (t1 >= repeat_delay); + const int count_t0 = (t0 < repeat_delay) ? -1 : (int)((t0 - repeat_delay) / repeat_rate); + const int count_t1 = (t1 < repeat_delay) ? -1 : (int)((t1 - repeat_delay) / repeat_rate); + const int count = count_t1 - count_t0; + return count; +} + +void ImGui::GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate) +{ + ImGuiContext& g = *GImGui; + switch (flags & ImGuiInputFlags_RepeatRateMask_) + { + case ImGuiInputFlags_RepeatRateNavMove: *repeat_delay = g.IO.KeyRepeatDelay * 0.72f; *repeat_rate = g.IO.KeyRepeatRate * 0.80f; return; + case ImGuiInputFlags_RepeatRateNavTweak: *repeat_delay = g.IO.KeyRepeatDelay * 0.72f; *repeat_rate = g.IO.KeyRepeatRate * 0.30f; return; + case ImGuiInputFlags_RepeatRateDefault: default: *repeat_delay = g.IO.KeyRepeatDelay * 1.00f; *repeat_rate = g.IO.KeyRepeatRate * 1.00f; return; + } +} + +// Return value representing the number of presses in the last time period, for the given repeat rate +// (most often returns 0 or 1. The result is generally only >1 when RepeatRate is smaller than DeltaTime, aka large DeltaTime or fast RepeatRate) +int ImGui::GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float repeat_rate) +{ + ImGuiContext& g = *GImGui; + const ImGuiKeyData* key_data = GetKeyData(key); + if (!key_data->Down) // In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on key ownership) + return 0; + const float t = key_data->DownDuration; + return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate); +} + +// Return 2D vector representing the combination of four cardinal direction, with analog value support (for e.g. ImGuiKey_GamepadLStick* values). +ImVec2 ImGui::GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down) +{ + return ImVec2( + GetKeyData(key_right)->AnalogValue - GetKeyData(key_left)->AnalogValue, + GetKeyData(key_down)->AnalogValue - GetKeyData(key_up)->AnalogValue); +} + +// Rewrite routing data buffers to strip old entries + sort by key to make queries not touch scattered data. +// Entries D,A,B,B,A,C,B --> A,A,B,B,B,C,D +// Index A:1 B:2 C:5 D:0 --> A:0 B:2 C:5 D:6 +// See 'Metrics->Key Owners & Shortcut Routing' to visualize the result of that operation. +static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) +{ + ImGuiContext& g = *GImGui; + rt->EntriesNext.resize(0); + for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) + { + const int new_routing_start_idx = rt->EntriesNext.Size; + ImGuiKeyRoutingData* routing_entry; + for (int old_routing_idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; old_routing_idx != -1; old_routing_idx = routing_entry->NextEntryIndex) + { + routing_entry = &rt->Entries[old_routing_idx]; + routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry + routing_entry->RoutingNext = ImGuiKeyOwner_None; + routing_entry->RoutingNextScore = 255; + if (routing_entry->RoutingCurr == ImGuiKeyOwner_None) + continue; + rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer + + // Apply routing to owner if there's no owner already (RoutingCurr == None at this point) + if (routing_entry->Mods == g.IO.KeyMods) + { + ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); + if (owner_data->OwnerCurr == ImGuiKeyOwner_None) + owner_data->OwnerCurr = routing_entry->RoutingCurr; + } + } + + // Rewrite linked-list + rt->Index[key - ImGuiKey_NamedKey_BEGIN] = (ImGuiKeyRoutingIndex)(new_routing_start_idx < rt->EntriesNext.Size ? new_routing_start_idx : -1); + for (int n = new_routing_start_idx; n < rt->EntriesNext.Size; n++) + rt->EntriesNext[n].NextEntryIndex = (ImGuiKeyRoutingIndex)((n + 1 < rt->EntriesNext.Size) ? n + 1 : -1); + } + rt->Entries.swap(rt->EntriesNext); // Swap new and old indexes +} + +// owner_id may be None/Any, but routing_id needs to be always be set, so we default to GetCurrentFocusScope(). +static inline ImGuiID GetRoutingIdFromOwnerId(ImGuiID owner_id) +{ + ImGuiContext& g = *GImGui; + return (owner_id != ImGuiKeyOwner_None && owner_id != ImGuiKeyOwner_Any) ? owner_id : g.CurrentFocusScopeId; +} + +ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord) +{ + // Majority of shortcuts will be Key + any number of Mods + // We accept _Single_ mod with ImGuiKey_None. + // - Shortcut(ImGuiKey_S | ImGuiMod_Ctrl); // Legal + // - Shortcut(ImGuiKey_S | ImGuiMod_Ctrl | ImGuiMod_Shift); // Legal + // - Shortcut(ImGuiMod_Ctrl); // Legal + // - Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift); // Not legal + ImGuiContext& g = *GImGui; + ImGuiKeyRoutingTable* rt = &g.KeysRoutingTable; + ImGuiKeyRoutingData* routing_data; + if (key_chord & ImGuiMod_Shortcut) + key_chord = ConvertShortcutMod(key_chord); + ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); + ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_); + if (key == ImGuiKey_None) + key = ConvertSingleModFlagToKey(&g, mods); + IM_ASSERT(IsNamedKey(key)); + + // Get (in the majority of case, the linked list will have one element so this should be 2 reads. + // Subsequent elements will be contiguous in memory as list is sorted/rebuilt in NewFrame). + for (ImGuiKeyRoutingIndex idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; idx != -1; idx = routing_data->NextEntryIndex) + { + routing_data = &rt->Entries[idx]; + if (routing_data->Mods == mods) + return routing_data; + } + + // Add to linked-list + ImGuiKeyRoutingIndex routing_data_idx = (ImGuiKeyRoutingIndex)rt->Entries.Size; + rt->Entries.push_back(ImGuiKeyRoutingData()); + routing_data = &rt->Entries[routing_data_idx]; + routing_data->Mods = (ImU16)mods; + routing_data->NextEntryIndex = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; // Setup linked list + rt->Index[key - ImGuiKey_NamedKey_BEGIN] = routing_data_idx; + return routing_data; +} + +// Current score encoding (lower is highest priority): +// - 0: ImGuiInputFlags_RouteGlobalHigh +// - 1: ImGuiInputFlags_RouteFocused (if item active) +// - 2: ImGuiInputFlags_RouteGlobal +// - 3+: ImGuiInputFlags_RouteFocused (if window in focus-stack) +// - 254: ImGuiInputFlags_RouteGlobalLow +// - 255: never route +// 'flags' should include an explicit routing policy +static int CalcRoutingScore(ImGuiWindow* location, ImGuiID owner_id, ImGuiInputFlags flags) +{ + if (flags & ImGuiInputFlags_RouteFocused) + { + ImGuiContext& g = *GImGui; + ImGuiWindow* focused = g.NavWindow; + + // ActiveID gets top priority + // (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it) + if (owner_id != 0 && g.ActiveId == owner_id) + return 1; + + // Score based on distance to focused window (lower is better) + // Assuming both windows are submitting a routing request, + // - When Window....... is focused -> Window scores 3 (best), Window/ChildB scores 255 (no match) + // - When Window/ChildB is focused -> Window scores 4, Window/ChildB scores 3 (best) + // Assuming only WindowA is submitting a routing request, + // - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score. + if (focused != NULL && focused->RootWindow == location->RootWindow) + for (int next_score = 3; focused != NULL; next_score++) + { + if (focused == location) + { + IM_ASSERT(next_score < 255); + return next_score; + } + focused = (focused->RootWindow != focused) ? focused->ParentWindow : NULL; // FIXME: This could be later abstracted as a focus path + } + return 255; + } + + // ImGuiInputFlags_RouteGlobalHigh is default, so calls without flags are not conditional + if (flags & ImGuiInputFlags_RouteGlobal) + return 2; + if (flags & ImGuiInputFlags_RouteGlobalLow) + return 254; + return 0; +} + +// Request a desired route for an input chord (key + mods). +// Return true if the route is available this frame. +// - Routes and key ownership are attributed at the beginning of next frame based on best score and mod state. +// (Conceptually this does a "Submit for next frame" + "Test for current frame". +// As such, it could be called TrySetXXX or SubmitXXX, or the Submit and Test operations should be separate.) +// - Using 'owner_id == ImGuiKeyOwner_Any/0': auto-assign an owner based on current focus scope (each window has its focus scope by default) +// - Using 'owner_id == ImGuiKeyOwner_None': allows disabling/locking a shortcut. +bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags) +{ + ImGuiContext& g = *GImGui; + if ((flags & ImGuiInputFlags_RouteMask_) == 0) + flags |= ImGuiInputFlags_RouteGlobalHigh; // IMPORTANT: This is the default for SetShortcutRouting() but NOT Shortcut() + else + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteMask_)); // Check that only 1 routing flag is used + + if (flags & ImGuiInputFlags_RouteUnlessBgFocused) + if (g.NavWindow == NULL) + return false; + if (flags & ImGuiInputFlags_RouteAlways) + return true; + + const int score = CalcRoutingScore(g.CurrentWindow, owner_id, flags); + if (score == 255) + return false; + + // Submit routing for NEXT frame (assuming score is sufficient) + // FIXME: Could expose a way to use a "serve last" policy for same score resolution (using <= instead of <). + ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); + const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id); + //const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score <= routing_data->RoutingNextScore) : (score < routing_data->RoutingNextScore); + if (score < routing_data->RoutingNextScore) + { + routing_data->RoutingNext = routing_id; + routing_data->RoutingNextScore = (ImU8)score; + } + + // Return routing state for CURRENT frame + return routing_data->RoutingCurr == routing_id; +} + +// Currently unused by core (but used by tests) +// Note: this cannot be turned into GetShortcutRouting() because we do the owner_id->routing_id translation, name would be more misleading. +bool ImGui::TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id) +{ + const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id); + ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); // FIXME: Could avoid creating entry. + return routing_data->RoutingCurr == routing_id; +} + +// Note that Dear ImGui doesn't know the meaning/semantic of ImGuiKey from 0..511: they are legacy native keycodes. +// Consider transitioning from 'IsKeyDown(MY_ENGINE_KEY_A)' (<1.87) to IsKeyDown(ImGuiKey_A) (>= 1.87) +bool ImGui::IsKeyDown(ImGuiKey key) +{ + return IsKeyDown(key, ImGuiKeyOwner_Any); +} + +bool ImGui::IsKeyDown(ImGuiKey key, ImGuiID owner_id) +{ + const ImGuiKeyData* key_data = GetKeyData(key); + if (!key_data->Down) + return false; + if (!TestKeyOwner(key, owner_id)) + return false; + return true; +} + +bool ImGui::IsKeyPressed(ImGuiKey key, bool repeat) +{ + return IsKeyPressed(key, ImGuiKeyOwner_Any, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None); +} + +// Important: unless legacy IsKeyPressed(ImGuiKey, bool repeat=true) which DEFAULT to repeat, this requires EXPLICIT repeat. +bool ImGui::IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags) +{ + const ImGuiKeyData* key_data = GetKeyData(key); + if (!key_data->Down) // In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on key ownership) + return false; + const float t = key_data->DownDuration; + if (t < 0.0f) + return false; + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByIsKeyPressed) == 0); // Passing flags not supported by this function! + + bool pressed = (t == 0.0f); + if (!pressed && ((flags & ImGuiInputFlags_Repeat) != 0)) + { + float repeat_delay, repeat_rate; + GetTypematicRepeatRate(flags, &repeat_delay, &repeat_rate); + pressed = (t > repeat_delay) && GetKeyPressedAmount(key, repeat_delay, repeat_rate) > 0; + } + if (!pressed) + return false; + if (!TestKeyOwner(key, owner_id)) + return false; + return true; +} + +bool ImGui::IsKeyReleased(ImGuiKey key) +{ + return IsKeyReleased(key, ImGuiKeyOwner_Any); +} + +bool ImGui::IsKeyReleased(ImGuiKey key, ImGuiID owner_id) +{ + const ImGuiKeyData* key_data = GetKeyData(key); + if (key_data->DownDurationPrev < 0.0f || key_data->Down) + return false; + if (!TestKeyOwner(key, owner_id)) + return false; + return true; +} + +bool ImGui::IsMouseDown(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDown[button] && TestKeyOwner(MouseButtonToKey(button), ImGuiKeyOwner_Any); // should be same as IsKeyDown(MouseButtonToKey(button), ImGuiKeyOwner_Any), but this allows legacy code hijacking the io.Mousedown[] array. +} + +bool ImGui::IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDown[button] && TestKeyOwner(MouseButtonToKey(button), owner_id); // Should be same as IsKeyDown(MouseButtonToKey(button), owner_id), but this allows legacy code hijacking the io.Mousedown[] array. +} + +bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat) +{ + return IsMouseClicked(button, ImGuiKeyOwner_Any, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None); +} + +bool ImGui::IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (!g.IO.MouseDown[button]) // In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on key ownership) + return false; + const float t = g.IO.MouseDownDuration[button]; + if (t < 0.0f) + return false; + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByIsKeyPressed) == 0); // Passing flags not supported by this function! + + const bool repeat = (flags & ImGuiInputFlags_Repeat) != 0; + const bool pressed = (t == 0.0f) || (repeat && t > g.IO.KeyRepeatDelay && CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0); + if (!pressed) + return false; + + if (!TestKeyOwner(MouseButtonToKey(button), owner_id)) + return false; + + return true; +} + +bool ImGui::IsMouseReleased(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseReleased[button] && TestKeyOwner(MouseButtonToKey(button), ImGuiKeyOwner_Any); // Should be same as IsKeyReleased(MouseButtonToKey(button), ImGuiKeyOwner_Any) +} + +bool ImGui::IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseReleased[button] && TestKeyOwner(MouseButtonToKey(button), owner_id); // Should be same as IsKeyReleased(MouseButtonToKey(button), owner_id) +} + +bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseClickedCount[button] == 2 && TestKeyOwner(MouseButtonToKey(button), ImGuiKeyOwner_Any); +} + +int ImGui::GetMouseClickedCount(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseClickedCount[button]; +} + +// Test if mouse cursor is hovering given rectangle +// NB- Rectangle is clipped by our current clip setting +// NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) +bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) +{ + ImGuiContext& g = *GImGui; + + // Clip + ImRect rect_clipped(r_min, r_max); + if (clip) + rect_clipped.ClipWith(g.CurrentWindow->ClipRect); + + // Expand for touch input + const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); + if (!rect_for_touch.Contains(g.IO.MousePos)) + return false; + return true; +} + +// Return if a mouse click/drag went past the given threshold. Valid to call during the MouseReleased frame. +// [Internal] This doesn't test if the button is pressed +bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; +} + +bool ImGui::IsMouseDragging(ImGuiMouseButton button, float lock_threshold) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (!g.IO.MouseDown[button]) + return false; + return IsMouseDragPastThreshold(button, lock_threshold); +} + +ImVec2 ImGui::GetMousePos() +{ + ImGuiContext& g = *GImGui; + return g.IO.MousePos; +} + +// NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! +ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() +{ + ImGuiContext& g = *GImGui; + if (g.BeginPopupStack.Size > 0) + return g.OpenPopupStack[g.BeginPopupStack.Size - 1].OpenMousePos; + return g.IO.MousePos; +} + +// We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position. +bool ImGui::IsMousePosValid(const ImVec2* mouse_pos) +{ + // The assert is only to silence a false-positive in XCode Static Analysis. + // Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions). + IM_ASSERT(GImGui != NULL); + const float MOUSE_INVALID = -256000.0f; + ImVec2 p = mouse_pos ? *mouse_pos : GImGui->IO.MousePos; + return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID; +} + +// [WILL OBSOLETE] This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid. +bool ImGui::IsAnyMouseDown() +{ + ImGuiContext& g = *GImGui; + for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++) + if (g.IO.MouseDown[n]) + return true; + return false; +} + +// Return the delta from the initial clicking position while the mouse button is clicked or was just released. +// This is locked and return 0.0f until the mouse moves past a distance threshold at least once. +// NB: This is only valid if IsMousePosValid(). backends in theory should always keep mouse position valid when dragging even outside the client window. +ImVec2 ImGui::GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + if (g.IO.MouseDown[button] || g.IO.MouseReleased[button]) + if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) + if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MouseClickedPos[button])) + return g.IO.MousePos - g.IO.MouseClickedPos[button]; + return ImVec2(0.0f, 0.0f); +} + +void ImGui::ResetMouseDragDelta(ImGuiMouseButton button) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr + g.IO.MouseClickedPos[button] = g.IO.MousePos; +} + +// Get desired mouse cursor shape. +// Important: this is meant to be used by a platform backend, it is reset in ImGui::NewFrame(), +// updated during the frame, and locked in EndFrame()/Render(). +// If you use software rendering by setting io.MouseDrawCursor then Dear ImGui will render those for you +ImGuiMouseCursor ImGui::GetMouseCursor() +{ + ImGuiContext& g = *GImGui; + return g.MouseCursor; +} + +void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) +{ + ImGuiContext& g = *GImGui; + g.MouseCursor = cursor_type; +} + +static void UpdateAliasKey(ImGuiKey key, bool v, float analog_value) +{ + IM_ASSERT(ImGui::IsAliasKey(key)); + ImGuiKeyData* key_data = ImGui::GetKeyData(key); + key_data->Down = v; + key_data->AnalogValue = analog_value; +} + +// [Internal] Do not use directly +static ImGuiKeyChord GetMergedModsFromKeys() +{ + ImGuiKeyChord mods = 0; + if (ImGui::IsKeyDown(ImGuiMod_Ctrl)) { mods |= ImGuiMod_Ctrl; } + if (ImGui::IsKeyDown(ImGuiMod_Shift)) { mods |= ImGuiMod_Shift; } + if (ImGui::IsKeyDown(ImGuiMod_Alt)) { mods |= ImGuiMod_Alt; } + if (ImGui::IsKeyDown(ImGuiMod_Super)) { mods |= ImGuiMod_Super; } + return mods; +} + +static void ImGui::UpdateKeyboardInputs() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + // Import legacy keys or verify they are not used +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + if (io.BackendUsingLegacyKeyArrays == 0) + { + // Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written to externally. + for (int n = 0; n < ImGuiKey_LegacyNativeKey_END; n++) + IM_ASSERT((io.KeysDown[n] == false || IsKeyDown((ImGuiKey)n)) && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!"); + } + else + { + if (g.FrameCount == 0) + for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++) + IM_ASSERT(g.IO.KeyMap[n] == -1 && "Backend is not allowed to write to io.KeyMap[0..511]!"); + + // Build reverse KeyMap (Named -> Legacy) + for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++) + if (io.KeyMap[n] != -1) + { + IM_ASSERT(IsLegacyKey((ImGuiKey)io.KeyMap[n])); + io.KeyMap[io.KeyMap[n]] = n; + } + + // Import legacy keys into new ones + for (int n = ImGuiKey_LegacyNativeKey_BEGIN; n < ImGuiKey_LegacyNativeKey_END; n++) + if (io.KeysDown[n] || io.BackendUsingLegacyKeyArrays == 1) + { + const ImGuiKey key = (ImGuiKey)(io.KeyMap[n] != -1 ? io.KeyMap[n] : n); + IM_ASSERT(io.KeyMap[n] == -1 || IsNamedKey(key)); + io.KeysData[key].Down = io.KeysDown[n]; + if (key != n) + io.KeysDown[key] = io.KeysDown[n]; // Allow legacy code using io.KeysDown[GetKeyIndex()] with old backends + io.BackendUsingLegacyKeyArrays = 1; + } + if (io.BackendUsingLegacyKeyArrays == 1) + { + GetKeyData(ImGuiMod_Ctrl)->Down = io.KeyCtrl; + GetKeyData(ImGuiMod_Shift)->Down = io.KeyShift; + GetKeyData(ImGuiMod_Alt)->Down = io.KeyAlt; + GetKeyData(ImGuiMod_Super)->Down = io.KeySuper; + } + } + +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; + if (io.BackendUsingLegacyNavInputArray && nav_gamepad_active) + { + #define MAP_LEGACY_NAV_INPUT_TO_KEY1(_KEY, _NAV1) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f); io.KeysData[_KEY].AnalogValue = io.NavInputs[_NAV1]; } while (0) + #define MAP_LEGACY_NAV_INPUT_TO_KEY2(_KEY, _NAV1, _NAV2) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f) || (io.NavInputs[_NAV2] > 0.0f); io.KeysData[_KEY].AnalogValue = ImMax(io.NavInputs[_NAV1], io.NavInputs[_NAV2]); } while (0) + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceDown, ImGuiNavInput_Activate); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceRight, ImGuiNavInput_Cancel); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceLeft, ImGuiNavInput_Menu); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceUp, ImGuiNavInput_Input); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadLeft, ImGuiNavInput_DpadLeft); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadRight, ImGuiNavInput_DpadRight); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadUp, ImGuiNavInput_DpadUp); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadDown, ImGuiNavInput_DpadDown); + MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadL1, ImGuiNavInput_FocusPrev, ImGuiNavInput_TweakSlow); + MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadR1, ImGuiNavInput_FocusNext, ImGuiNavInput_TweakFast); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickLeft, ImGuiNavInput_LStickLeft); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickRight, ImGuiNavInput_LStickRight); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickUp, ImGuiNavInput_LStickUp); + MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickDown, ImGuiNavInput_LStickDown); + #undef NAV_MAP_KEY + } +#endif +#endif + + // Update aliases + for (int n = 0; n < ImGuiMouseButton_COUNT; n++) + UpdateAliasKey(MouseButtonToKey(n), io.MouseDown[n], io.MouseDown[n] ? 1.0f : 0.0f); + UpdateAliasKey(ImGuiKey_MouseWheelX, io.MouseWheelH != 0.0f, io.MouseWheelH); + UpdateAliasKey(ImGuiKey_MouseWheelY, io.MouseWheel != 0.0f, io.MouseWheel); + + // Synchronize io.KeyMods and io.KeyXXX values. + // - New backends (1.87+): send io.AddKeyEvent(ImGuiMod_XXX) -> -> (here) deriving io.KeyMods + io.KeyXXX from key array. + // - Legacy backends: set io.KeyXXX bools -> (above) set key array from io.KeyXXX -> (here) deriving io.KeyMods + io.KeyXXX from key array. + // So with legacy backends the 4 values will do a unnecessary back-and-forth but it makes the code simpler and future facing. + io.KeyMods = GetMergedModsFromKeys(); + io.KeyCtrl = (io.KeyMods & ImGuiMod_Ctrl) != 0; + io.KeyShift = (io.KeyMods & ImGuiMod_Shift) != 0; + io.KeyAlt = (io.KeyMods & ImGuiMod_Alt) != 0; + io.KeySuper = (io.KeyMods & ImGuiMod_Super) != 0; + + // Clear gamepad data if disabled + if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0) + for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++) + { + io.KeysData[i - ImGuiKey_KeysData_OFFSET].Down = false; + io.KeysData[i - ImGuiKey_KeysData_OFFSET].AnalogValue = 0.0f; + } + + // Update keys + for (int i = 0; i < ImGuiKey_KeysData_SIZE; i++) + { + ImGuiKeyData* key_data = &io.KeysData[i]; + key_data->DownDurationPrev = key_data->DownDuration; + key_data->DownDuration = key_data->Down ? (key_data->DownDuration < 0.0f ? 0.0f : key_data->DownDuration + io.DeltaTime) : -1.0f; + } + + // Update keys/input owner (named keys only): one entry per key + for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) + { + ImGuiKeyData* key_data = &io.KeysData[key - ImGuiKey_KeysData_OFFSET]; + ImGuiKeyOwnerData* owner_data = &g.KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; + owner_data->OwnerCurr = owner_data->OwnerNext; + if (!key_data->Down) // Important: ownership is released on the frame after a release. Ensure a 'MouseDown -> CloseWindow -> MouseUp' chain doesn't lead to someone else seeing the MouseUp. + owner_data->OwnerNext = ImGuiKeyOwner_None; + owner_data->LockThisFrame = owner_data->LockUntilRelease = owner_data->LockUntilRelease && key_data->Down; // Clear LockUntilRelease when key is not Down anymore + } + + UpdateKeyRoutingTable(&g.KeysRoutingTable); +} + +static void ImGui::UpdateMouseInputs() +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + // Mouse Wheel swapping flag + // As a standard behavior holding SHIFT while using Vertical Mouse Wheel triggers Horizontal scroll instead + // - We avoid doing it on OSX as it the OS input layer handles this already. + // - FIXME: However this means when running on OSX over Emscripten, Shift+WheelY will incur two swapping (1 in OS, 1 here), canceling the feature. + // - FIXME: When we can distinguish e.g. touchpad scroll events from mouse ones, we'll set this accordingly based on input source. + io.MouseWheelRequestAxisSwap = io.KeyShift && !io.ConfigMacOSXBehaviors; + + // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well) + if (IsMousePosValid(&io.MousePos)) + io.MousePos = g.MouseLastValidPos = ImFloorSigned(io.MousePos); + + // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta + if (IsMousePosValid(&io.MousePos) && IsMousePosValid(&io.MousePosPrev)) + io.MouseDelta = io.MousePos - io.MousePosPrev; + else + io.MouseDelta = ImVec2(0.0f, 0.0f); + + // Update stationary timer. + // FIXME: May need to rework again to have some tolerance for occasional small movement, while being functional on high-framerates. + const float mouse_stationary_threshold = (io.MouseSource == ImGuiMouseSource_Mouse) ? 2.0f : 3.0f; // Slightly higher threshold for ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen, may need rework. + const bool mouse_stationary = (ImLengthSqr(io.MouseDelta) <= mouse_stationary_threshold * mouse_stationary_threshold); + g.MouseStationaryTimer = mouse_stationary ? (g.MouseStationaryTimer + io.DeltaTime) : 0.0f; + //IMGUI_DEBUG_LOG("%.4f\n", g.MouseStationaryTimer); + + // If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true. + if (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f) + g.NavDisableMouseHover = false; + + io.MousePosPrev = io.MousePos; + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + { + io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f; + io.MouseClickedCount[i] = 0; // Will be filled below + io.MouseReleased[i] = !io.MouseDown[i] && io.MouseDownDuration[i] >= 0.0f; + io.MouseDownDurationPrev[i] = io.MouseDownDuration[i]; + io.MouseDownDuration[i] = io.MouseDown[i] ? (io.MouseDownDuration[i] < 0.0f ? 0.0f : io.MouseDownDuration[i] + io.DeltaTime) : -1.0f; + if (io.MouseClicked[i]) + { + bool is_repeated_click = false; + if ((float)(g.Time - io.MouseClickedTime[i]) < io.MouseDoubleClickTime) + { + ImVec2 delta_from_click_pos = IsMousePosValid(&io.MousePos) ? (io.MousePos - io.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f); + if (ImLengthSqr(delta_from_click_pos) < io.MouseDoubleClickMaxDist * io.MouseDoubleClickMaxDist) + is_repeated_click = true; + } + if (is_repeated_click) + io.MouseClickedLastCount[i]++; + else + io.MouseClickedLastCount[i] = 1; + io.MouseClickedTime[i] = g.Time; + io.MouseClickedPos[i] = io.MousePos; + io.MouseClickedCount[i] = io.MouseClickedLastCount[i]; + io.MouseDragMaxDistanceSqr[i] = 0.0f; + } + else if (io.MouseDown[i]) + { + // Maintain the maximum distance we reaching from the initial click position, which is used with dragging threshold + float delta_sqr_click_pos = IsMousePosValid(&io.MousePos) ? ImLengthSqr(io.MousePos - io.MouseClickedPos[i]) : 0.0f; + io.MouseDragMaxDistanceSqr[i] = ImMax(io.MouseDragMaxDistanceSqr[i], delta_sqr_click_pos); + } + + // We provide io.MouseDoubleClicked[] as a legacy service + io.MouseDoubleClicked[i] = (io.MouseClickedCount[i] == 2); + + // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation + if (io.MouseClicked[i]) + g.NavDisableMouseHover = false; + } +} + +static void LockWheelingWindow(ImGuiWindow* window, float wheel_amount) +{ + ImGuiContext& g = *GImGui; + if (window) + g.WheelingWindowReleaseTimer = ImMin(g.WheelingWindowReleaseTimer + ImAbs(wheel_amount) * WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER, WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER); + else + g.WheelingWindowReleaseTimer = 0.0f; + if (g.WheelingWindow == window) + return; + IMGUI_DEBUG_LOG_IO("[io] LockWheelingWindow() \"%s\"\n", window ? window->Name : "NULL"); + g.WheelingWindow = window; + g.WheelingWindowRefMousePos = g.IO.MousePos; + if (window == NULL) + { + g.WheelingWindowStartFrame = -1; + g.WheelingAxisAvg = ImVec2(0.0f, 0.0f); + } +} + +static ImGuiWindow* FindBestWheelingWindow(const ImVec2& wheel) +{ + // For each axis, find window in the hierarchy that may want to use scrolling + ImGuiContext& g = *GImGui; + ImGuiWindow* windows[2] = { NULL, NULL }; + for (int axis = 0; axis < 2; axis++) + if (wheel[axis] != 0.0f) + for (ImGuiWindow* window = windows[axis] = g.HoveredWindow; window->Flags & ImGuiWindowFlags_ChildWindow; window = windows[axis] = window->ParentWindow) + { + // Bubble up into parent window if: + // - a child window doesn't allow any scrolling. + // - a child window has the ImGuiWindowFlags_NoScrollWithMouse flag. + //// - a child window doesn't need scrolling because it is already at the edge for the direction we are going in (FIXME-WIP) + const bool has_scrolling = (window->ScrollMax[axis] != 0.0f); + const bool inputs_disabled = (window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs); + //const bool scrolling_past_limits = (wheel_v < 0.0f) ? (window->Scroll[axis] <= 0.0f) : (window->Scroll[axis] >= window->ScrollMax[axis]); + if (has_scrolling && !inputs_disabled) // && !scrolling_past_limits) + break; // select this window + } + if (windows[0] == NULL && windows[1] == NULL) + return NULL; + + // If there's only one window or only one axis then there's no ambiguity + if (windows[0] == windows[1] || windows[0] == NULL || windows[1] == NULL) + return windows[1] ? windows[1] : windows[0]; + + // If candidate are different windows we need to decide which one to prioritize + // - First frame: only find a winner if one axis is zero. + // - Subsequent frames: only find a winner when one is more than the other. + if (g.WheelingWindowStartFrame == -1) + g.WheelingWindowStartFrame = g.FrameCount; + if ((g.WheelingWindowStartFrame == g.FrameCount && wheel.x != 0.0f && wheel.y != 0.0f) || (g.WheelingAxisAvg.x == g.WheelingAxisAvg.y)) + { + g.WheelingWindowWheelRemainder = wheel; + return NULL; + } + return (g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? windows[0] : windows[1]; +} + +// Called by NewFrame() +void ImGui::UpdateMouseWheel() +{ + // Reset the locked window if we move the mouse or after the timer elapses. + // FIXME: Ideally we could refactor to have one timer for "changing window w/ same axis" and a shorter timer for "changing window or axis w/ other axis" (#3795) + ImGuiContext& g = *GImGui; + if (g.WheelingWindow != NULL) + { + g.WheelingWindowReleaseTimer -= g.IO.DeltaTime; + if (IsMousePosValid() && ImLengthSqr(g.IO.MousePos - g.WheelingWindowRefMousePos) > g.IO.MouseDragThreshold * g.IO.MouseDragThreshold) + g.WheelingWindowReleaseTimer = 0.0f; + if (g.WheelingWindowReleaseTimer <= 0.0f) + LockWheelingWindow(NULL, 0.0f); + } + + ImVec2 wheel; + wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_None) ? g.IO.MouseWheelH : 0.0f; + wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_None) ? g.IO.MouseWheel : 0.0f; + + //IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y); + ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow; + if (!mouse_window || mouse_window->Collapsed) + return; + + // Zoom / Scale window + // FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned. + if (wheel.y != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling) + { + LockWheelingWindow(mouse_window, wheel.y); + ImGuiWindow* window = mouse_window; + const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); + const float scale = new_font_scale / window->FontWindowScale; + window->FontWindowScale = new_font_scale; + if (window == window->RootWindow) + { + const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; + SetWindowPos(window, window->Pos + offset, 0); + window->Size = ImFloor(window->Size * scale); + window->SizeFull = ImFloor(window->SizeFull * scale); + } + return; + } + if (g.IO.KeyCtrl) + return; + + // Mouse wheel scrolling + // Read about io.MouseWheelRequestAxisSwap and its issue on Mac+Emscripten in UpdateMouseInputs() + if (g.IO.MouseWheelRequestAxisSwap) + wheel = ImVec2(wheel.y, 0.0f); + + // Maintain a rough average of moving magnitude on both axises + // FIXME: should by based on wall clock time rather than frame-counter + g.WheelingAxisAvg.x = ImExponentialMovingAverage(g.WheelingAxisAvg.x, ImAbs(wheel.x), 30); + g.WheelingAxisAvg.y = ImExponentialMovingAverage(g.WheelingAxisAvg.y, ImAbs(wheel.y), 30); + + // In the rare situation where FindBestWheelingWindow() had to defer first frame of wheeling due to ambiguous main axis, reinject it now. + wheel += g.WheelingWindowWheelRemainder; + g.WheelingWindowWheelRemainder = ImVec2(0.0f, 0.0f); + if (wheel.x == 0.0f && wheel.y == 0.0f) + return; + + // Mouse wheel scrolling: find target and apply + // - don't renew lock if axis doesn't apply on the window. + // - select a main axis when both axises are being moved. + if (ImGuiWindow* window = (g.WheelingWindow ? g.WheelingWindow : FindBestWheelingWindow(wheel))) + if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs)) + { + bool do_scroll[2] = { wheel.x != 0.0f && window->ScrollMax.x != 0.0f, wheel.y != 0.0f && window->ScrollMax.y != 0.0f }; + if (do_scroll[ImGuiAxis_X] && do_scroll[ImGuiAxis_Y]) + do_scroll[(g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? ImGuiAxis_Y : ImGuiAxis_X] = false; + if (do_scroll[ImGuiAxis_X]) + { + LockWheelingWindow(window, wheel.x); + float max_step = window->InnerRect.GetWidth() * 0.67f; + float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step)); + SetScrollX(window, window->Scroll.x - wheel.x * scroll_step); + } + if (do_scroll[ImGuiAxis_Y]) + { + LockWheelingWindow(window, wheel.y); + float max_step = window->InnerRect.GetHeight() * 0.67f; + float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step)); + SetScrollY(window, window->Scroll.y - wheel.y * scroll_step); + } + } +} + +void ImGui::SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard) +{ + ImGuiContext& g = *GImGui; + g.WantCaptureKeyboardNextFrame = want_capture_keyboard ? 1 : 0; +} + +void ImGui::SetNextFrameWantCaptureMouse(bool want_capture_mouse) +{ + ImGuiContext& g = *GImGui; + g.WantCaptureMouseNextFrame = want_capture_mouse ? 1 : 0; +} + +#ifndef IMGUI_DISABLE_DEBUG_TOOLS +static const char* GetInputSourceName(ImGuiInputSource source) +{ + const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Clipboard" }; + IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT); + return input_source_names[source]; +} +static const char* GetMouseSourceName(ImGuiMouseSource source) +{ + const char* mouse_source_names[] = { "Mouse", "TouchScreen", "Pen" }; + IM_ASSERT(IM_ARRAYSIZE(mouse_source_names) == ImGuiMouseSource_COUNT && source >= 0 && source < ImGuiMouseSource_COUNT); + return mouse_source_names[source]; +} +static void DebugPrintInputEvent(const char* prefix, const ImGuiInputEvent* e) +{ + ImGuiContext& g = *GImGui; + if (e->Type == ImGuiInputEventType_MousePos) { if (e->MousePos.PosX == -FLT_MAX && e->MousePos.PosY == -FLT_MAX) IMGUI_DEBUG_LOG_IO("[io] %s: MousePos (-FLT_MAX, -FLT_MAX)\n", prefix); else IMGUI_DEBUG_LOG_IO("[io] %s: MousePos (%.1f, %.1f) (%s)\n", prefix, e->MousePos.PosX, e->MousePos.PosY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; } + if (e->Type == ImGuiInputEventType_MouseButton) { IMGUI_DEBUG_LOG_IO("[io] %s: MouseButton %d %s (%s)\n", prefix, e->MouseButton.Button, e->MouseButton.Down ? "Down" : "Up", GetMouseSourceName(e->MouseWheel.MouseSource)); return; } + if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG_IO("[io] %s: MouseWheel (%.3f, %.3f) (%s)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY, GetMouseSourceName(e->MouseWheel.MouseSource)); return; } + if (e->Type == ImGuiInputEventType_Key) { IMGUI_DEBUG_LOG_IO("[io] %s: Key \"%s\" %s\n", prefix, ImGui::GetKeyName(e->Key.Key), e->Key.Down ? "Down" : "Up"); return; } + if (e->Type == ImGuiInputEventType_Text) { IMGUI_DEBUG_LOG_IO("[io] %s: Text: %c (U+%08X)\n", prefix, e->Text.Char, e->Text.Char); return; } + if (e->Type == ImGuiInputEventType_Focus) { IMGUI_DEBUG_LOG_IO("[io] %s: AppFocused %d\n", prefix, e->AppFocused.Focused); return; } +} +#endif + +// Process input queue +// We always call this with the value of 'bool g.IO.ConfigInputTrickleEventQueue'. +// - trickle_fast_inputs = false : process all events, turn into flattened input state (e.g. successive down/up/down/up will be lost) +// - trickle_fast_inputs = true : process as many events as possible (successive down/up/down/up will be trickled over several frames so nothing is lost) (new feature in 1.87) +void ImGui::UpdateInputEvents(bool trickle_fast_inputs) +{ + ImGuiContext& g = *GImGui; + ImGuiIO& io = g.IO; + + // Only trickle chars<>key when working with InputText() + // FIXME: InputText() could parse event trail? + // FIXME: Could specialize chars<>keys trickling rules for control keys (those not typically associated to characters) + const bool trickle_interleaved_keys_and_text = (trickle_fast_inputs && g.WantTextInputNextFrame == 1); + + bool mouse_moved = false, mouse_wheeled = false, key_changed = false, text_inputted = false; + int mouse_button_changed = 0x00; + ImBitArray key_changed_mask; + + int event_n = 0; + for (; event_n < g.InputEventsQueue.Size; event_n++) + { + ImGuiInputEvent* e = &g.InputEventsQueue[event_n]; + if (e->Type == ImGuiInputEventType_MousePos) + { + // Trickling Rule: Stop processing queued events if we already handled a mouse button change + ImVec2 event_pos(e->MousePos.PosX, e->MousePos.PosY); + if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || text_inputted)) + break; + io.MousePos = event_pos; + io.MouseSource = e->MousePos.MouseSource; + mouse_moved = true; + } + else if (e->Type == ImGuiInputEventType_MouseButton) + { + // Trickling Rule: Stop processing queued events if we got multiple action on the same button + const ImGuiMouseButton button = e->MouseButton.Button; + IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); + if (trickle_fast_inputs && ((mouse_button_changed & (1 << button)) || mouse_wheeled)) + break; + if (trickle_fast_inputs && e->MouseButton.MouseSource == ImGuiMouseSource_TouchScreen && mouse_moved) // #2702: TouchScreen have no initial hover. + break; + io.MouseDown[button] = e->MouseButton.Down; + io.MouseSource = e->MouseButton.MouseSource; + mouse_button_changed |= (1 << button); + } + else if (e->Type == ImGuiInputEventType_MouseWheel) + { + // Trickling Rule: Stop processing queued events if we got multiple action on the event + if (trickle_fast_inputs && (mouse_moved || mouse_button_changed != 0)) + break; + io.MouseWheelH += e->MouseWheel.WheelX; + io.MouseWheel += e->MouseWheel.WheelY; + io.MouseSource = e->MouseWheel.MouseSource; + mouse_wheeled = true; + } + else if (e->Type == ImGuiInputEventType_Key) + { + // Trickling Rule: Stop processing queued events if we got multiple action on the same button + ImGuiKey key = e->Key.Key; + IM_ASSERT(key != ImGuiKey_None); + ImGuiKeyData* key_data = GetKeyData(key); + const int key_data_index = (int)(key_data - g.IO.KeysData); + if (trickle_fast_inputs && key_data->Down != e->Key.Down && (key_changed_mask.TestBit(key_data_index) || text_inputted || mouse_button_changed != 0)) + break; + key_data->Down = e->Key.Down; + key_data->AnalogValue = e->Key.AnalogValue; + key_changed = true; + key_changed_mask.SetBit(key_data_index); + + // Allow legacy code using io.KeysDown[GetKeyIndex()] with new backends +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + io.KeysDown[key_data_index] = key_data->Down; + if (io.KeyMap[key_data_index] != -1) + io.KeysDown[io.KeyMap[key_data_index]] = key_data->Down; +#endif + } + else if (e->Type == ImGuiInputEventType_Text) + { + // Trickling Rule: Stop processing queued events if keys/mouse have been interacted with + if (trickle_fast_inputs && ((key_changed && trickle_interleaved_keys_and_text) || mouse_button_changed != 0 || mouse_moved || mouse_wheeled)) + break; + unsigned int c = e->Text.Char; + io.InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID); + if (trickle_interleaved_keys_and_text) + text_inputted = true; + } + else if (e->Type == ImGuiInputEventType_Focus) + { + // We intentionally overwrite this and process in NewFrame(), in order to give a chance + // to multi-viewports backends to queue AddFocusEvent(false) + AddFocusEvent(true) in same frame. + const bool focus_lost = !e->AppFocused.Focused; + io.AppFocusLost = focus_lost; + } + else + { + IM_ASSERT(0 && "Unknown event!"); + } + } + + // Record trail (for domain-specific applications wanting to access a precise trail) + //if (event_n != 0) IMGUI_DEBUG_LOG_IO("Processed: %d / Remaining: %d\n", event_n, g.InputEventsQueue.Size - event_n); + for (int n = 0; n < event_n; n++) + g.InputEventsTrail.push_back(g.InputEventsQueue[n]); + + // [DEBUG] +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + if (event_n != 0 && (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO)) + for (int n = 0; n < g.InputEventsQueue.Size; n++) + DebugPrintInputEvent(n < event_n ? "Processed" : "Remaining", &g.InputEventsQueue[n]); +#endif + + // Remaining events will be processed on the next frame + if (event_n == g.InputEventsQueue.Size) + g.InputEventsQueue.resize(0); + else + g.InputEventsQueue.erase(g.InputEventsQueue.Data, g.InputEventsQueue.Data + event_n); + + // Clear buttons state when focus is lost + // - this is useful so e.g. releasing Alt after focus loss on Alt-Tab doesn't trigger the Alt menu toggle. + // - we clear in EndFrame() and not now in order allow application/user code polling this flag + // (e.g. custom backend may want to clear additional data, custom widgets may want to react with a "canceling" event). + if (g.IO.AppFocusLost) + g.IO.ClearInputKeys(); +} + +ImGuiID ImGui::GetKeyOwner(ImGuiKey key) +{ + if (!IsNamedKeyOrModKey(key)) + return ImGuiKeyOwner_None; + + ImGuiContext& g = *GImGui; + ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); + ImGuiID owner_id = owner_data->OwnerCurr; + + if (g.ActiveIdUsingAllKeyboardKeys && owner_id != g.ActiveId && owner_id != ImGuiKeyOwner_Any) + if (key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END) + return ImGuiKeyOwner_None; + + return owner_id; +} + +// TestKeyOwner(..., ID) : (owner == None || owner == ID) +// TestKeyOwner(..., None) : (owner == None) +// TestKeyOwner(..., Any) : no owner test +// All paths are also testing for key not being locked, for the rare cases that key have been locked with using ImGuiInputFlags_LockXXX flags. +bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id) +{ + if (!IsNamedKeyOrModKey(key)) + return true; + + ImGuiContext& g = *GImGui; + if (g.ActiveIdUsingAllKeyboardKeys && owner_id != g.ActiveId && owner_id != ImGuiKeyOwner_Any) + if (key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END) + return false; + + ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); + if (owner_id == ImGuiKeyOwner_Any) + return (owner_data->LockThisFrame == false); + + // Note: SetKeyOwner() sets OwnerCurr. It is not strictly required for most mouse routing overlap (because of ActiveId/HoveredId + // are acting as filter before this has a chance to filter), but sane as soon as user tries to look into things. + // Setting OwnerCurr in SetKeyOwner() is more consistent than testing OwnerNext here: would be inconsistent with getter and other functions. + if (owner_data->OwnerCurr != owner_id) + { + if (owner_data->LockThisFrame) + return false; + if (owner_data->OwnerCurr != ImGuiKeyOwner_None) + return false; + } + + return true; +} + +// _LockXXX flags are useful to lock keys away from code which is not input-owner aware. +// When using _LockXXX flags, you can use ImGuiKeyOwner_Any to lock keys from everyone. +// - SetKeyOwner(..., None) : clears owner +// - SetKeyOwner(..., Any, !Lock) : illegal (assert) +// - SetKeyOwner(..., Any or None, Lock) : set lock +void ImGui::SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags) +{ + IM_ASSERT(IsNamedKeyOrModKey(key) && (owner_id != ImGuiKeyOwner_Any || (flags & (ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease)))); // Can only use _Any with _LockXXX flags (to eat a key away without an ID to retrieve it) + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetKeyOwner) == 0); // Passing flags not supported by this function! + + ImGuiContext& g = *GImGui; + ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); + owner_data->OwnerCurr = owner_data->OwnerNext = owner_id; + + // We cannot lock by default as it would likely break lots of legacy code. + // In the case of using LockUntilRelease while key is not down we still lock during the frame (no key_data->Down test) + owner_data->LockUntilRelease = (flags & ImGuiInputFlags_LockUntilRelease) != 0; + owner_data->LockThisFrame = (flags & ImGuiInputFlags_LockThisFrame) != 0 || (owner_data->LockUntilRelease); +} + +// Rarely used helper +void ImGui::SetKeyOwnersForKeyChord(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags) +{ + if (key_chord & ImGuiMod_Ctrl) { SetKeyOwner(ImGuiMod_Ctrl, owner_id, flags); } + if (key_chord & ImGuiMod_Shift) { SetKeyOwner(ImGuiMod_Shift, owner_id, flags); } + if (key_chord & ImGuiMod_Alt) { SetKeyOwner(ImGuiMod_Alt, owner_id, flags); } + if (key_chord & ImGuiMod_Super) { SetKeyOwner(ImGuiMod_Super, owner_id, flags); } + if (key_chord & ImGuiMod_Shortcut) { SetKeyOwner(ImGuiMod_Shortcut, owner_id, flags); } + if (key_chord & ~ImGuiMod_Mask_) { SetKeyOwner((ImGuiKey)(key_chord & ~ImGuiMod_Mask_), owner_id, flags); } +} + +// This is more or less equivalent to: +// if (IsItemHovered() || IsItemActive()) +// SetKeyOwner(key, GetItemID()); +// Extensive uses of that (e.g. many calls for a single item) may want to manually perform the tests once and then call SetKeyOwner() multiple times. +// More advanced usage scenarios may want to call SetKeyOwner() manually based on different condition. +// Worth noting is that only one item can be hovered and only one item can be active, therefore this usage pattern doesn't need to bother with routing and priority. +void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiID id = g.LastItemData.ID; + if (id == 0 || (g.HoveredId != id && g.ActiveId != id)) + return; + if ((flags & ImGuiInputFlags_CondMask_) == 0) + flags |= ImGuiInputFlags_CondDefault_; + if ((g.HoveredId == id && (flags & ImGuiInputFlags_CondHovered)) || (g.ActiveId == id && (flags & ImGuiInputFlags_CondActive))) + { + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetItemKeyOwner) == 0); // Passing flags not supported by this function! + SetKeyOwner(key, id, flags & ~ImGuiInputFlags_CondMask_); + } +} + +bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags) +{ + ImGuiContext& g = *GImGui; + + // When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any. + if ((flags & ImGuiInputFlags_RouteMask_) == 0) + flags |= ImGuiInputFlags_RouteFocused; + if (!SetShortcutRouting(key_chord, owner_id, flags)) + return false; + + if (key_chord & ImGuiMod_Shortcut) + key_chord = ConvertShortcutMod(key_chord); + ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_); + if (g.IO.KeyMods != mods) + return false; + + // Special storage location for mods + ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); + if (key == ImGuiKey_None) + key = ConvertSingleModFlagToKey(&g, mods); + + if (!IsKeyPressed(key, owner_id, (flags & (ImGuiInputFlags_Repeat | (ImGuiInputFlags)ImGuiInputFlags_RepeatRateMask_)))) + return false; + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByShortcut) == 0); // Passing flags not supported by this function! + + return true; +} + + //----------------------------------------------------------------------------- // [SECTION] ERROR CHECKING //----------------------------------------------------------------------------- // Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui. // Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit -// If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. your user code -// may see different structures than what imgui.cpp sees, which is problematic. -// We usually require settings to be in imconfig.h to make sure that they are accessible to all compilation units involved with Dear ImGui. +// If this triggers you have an issue: +// - Most commonly: mismatched headers and compiled code version. +// - Or: mismatched configuration #define, compilation settings, packing pragma etc. +// The configuration settings mentioned in imconfig.h must be set for all compilation units involved with Dear ImGui, +// which is way it is required you put them in your imconfig file (and not just before including imgui.h). +// Otherwise it is possible that different compilation units would see different structure layout bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx) { bool error = false; @@ -7244,6 +9135,38 @@ bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, si return !error; } +// Until 1.89 (IMGUI_VERSION_NUM < 18814) it was legal to use SetCursorPos() to extend the boundary of a parent (e.g. window or table cell) +// This is causing issues and ambiguity and we need to retire that. +// See https://github.com/ocornut/imgui/issues/5548 for more details. +// [Scenario 1] +// Previously this would make the window content size ~200x200: +// Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End(); // NOT OK +// Instead, please submit an item: +// Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + Dummy(ImVec2(0,0)) + End(); // OK +// Alternative: +// Begin(...) + Dummy(ImVec2(200,200)) + End(); // OK +// [Scenario 2] +// For reference this is one of the issue what we aim to fix with this change: +// BeginGroup() + SomeItem("foobar") + SetCursorScreenPos(GetCursorScreenPos()) + EndGroup() +// The previous logic made SetCursorScreenPos(GetCursorScreenPos()) have a side-effect! It would erroneously incorporate ItemSpacing.y after the item into content size, making the group taller! +// While this code is a little twisted, no-one would expect SetXXX(GetXXX()) to have a side-effect. Using vertical alignment patterns could trigger this issue. +void ImGui::ErrorCheckUsingSetCursorPosToExtendParentBoundaries() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(window->DC.IsSetPos); + window->DC.IsSetPos = false; +#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + if (window->DC.CursorPos.x <= window->DC.CursorMaxPos.x && window->DC.CursorPos.y <= window->DC.CursorMaxPos.y) + return; + if (window->SkipItems) + return; + IM_ASSERT(0 && "Code uses SetCursorPos()/SetCursorScreenPos() to extend window/parent boundaries. Please submit an item e.g. Dummy() to validate extent."); +#else + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); +#endif +} + static void ImGui::ErrorCheckNewFrameSanityChecks() { ImGuiContext& g = *GImGui; @@ -7256,6 +9179,13 @@ static void ImGui::ErrorCheckNewFrameSanityChecks() // #define IM_ASSERT(EXPR) do { if (SomeCode(EXPR)) SomeMoreCode(); } while (0) // Correct! if (true) IM_ASSERT(1); else IM_ASSERT(0); + // Emscripten backends are often imprecise in their submission of DeltaTime. (#6114, #3644) + // Ideally the Emscripten app/backend should aim to fix or smooth this value and avoid feeding zero, but we tolerate it. +#ifdef __EMSCRIPTEN__ + if (g.IO.DeltaTime <= 0.0f && g.FrameCount > 0) + g.IO.DeltaTime = 0.00001f; +#endif + // Check user data // (We pass an error message in the assert expression to make it visible to programmers who are not using a debugger, as most assert handlers display their argument) IM_ASSERT(g.Initialized); @@ -7264,16 +9194,19 @@ static void ImGui::ErrorCheckNewFrameSanityChecks() IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!"); IM_ASSERT(g.IO.Fonts->IsBuilt() && "Font Atlas not built! Make sure you called ImGui_ImplXXXX_NewFrame() function for renderer backend, which should call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8()"); IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!"); - IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!"); + IM_ASSERT(g.Style.CircleTessellationMaxError > 0.0f && "Invalid style setting!"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting!"); // Allows us to avoid a few clamps in color computations IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting."); IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right); - for (int n = 0; n < ImGuiKey_COUNT; n++) - IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); + IM_ASSERT(g.Style.ColorButtonPosition == ImGuiDir_Left || g.Style.ColorButtonPosition == ImGuiDir_Right); +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_COUNT; n++) + IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < ImGuiKey_LegacyNativeKey_END && "io.KeyMap[] contains an out of bound value (need to be 0..511, or -1 for unmapped key)"); // Check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only added in 1.60 WIP) - if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) + if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && g.IO.BackendUsingLegacyKeyArrays == 1) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); +#endif // Check: the io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly. if (g.IO.ConfigWindowsResizeFromEdges && !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseCursors)) @@ -7288,13 +9221,13 @@ static void ImGui::ErrorCheckEndFrameSanityChecks() // One possible reason leading to this assert is that your backends update inputs _AFTER_ NewFrame(). // It is known that when some modal native windows called mid-frame takes focus away, some backends such as GLFW will // send key release events mid-frame. This would normally trigger this assertion and lead to sheared inputs. - // We silently accommodate for this case by ignoring/ the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0), + // We silently accommodate for this case by ignoring the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0), // while still correctly asserting on mid-frame key press events. - const ImGuiKeyModFlags key_mod_flags = GetMergedKeyModFlags(); - IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); - IM_UNUSED(key_mod_flags); + const ImGuiKeyChord key_mods = GetMergedModsFromKeys(); + IM_ASSERT((key_mods == 0 || g.IO.KeyMods == key_mods) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); + IM_UNUSED(key_mods); - // Recover from errors + // [EXPERIMENTAL] Recover from errors: You may call this yourself before EndFrame(). //ErrorCheckEndFrameRecover(); // Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you @@ -7303,7 +9236,9 @@ static void ImGui::ErrorCheckEndFrameSanityChecks() { if (g.CurrentWindowStack.Size > 1) { + ImGuiWindow* window = g.CurrentWindowStack.back().Window; // <-- This window was not Ended! IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size == 1, "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?"); + IM_UNUSED(window); while (g.CurrentWindowStack.Size > 1) End(); } @@ -7334,7 +9269,6 @@ void ImGui::ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, voi IM_ASSERT(window->IsFallbackWindow); break; } - IM_ASSERT(window == g.CurrentWindow); if (window->Flags & ImGuiWindowFlags_ChildWindow) { if (log_callback) log_callback(user_data, "Recovered from missing EndChild() for '%s'", window->Name); @@ -7401,7 +9335,12 @@ void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name); PopStyleVar(); } - while (g.FocusScopeStack.Size > stack_sizes->SizeOfFocusScopeStack) //-V1044 + while (g.FontStack.Size > stack_sizes->SizeOfFontStack) //-V1044 + { + if (log_callback) log_callback(user_data, "Recovered from missing PopFont() in '%s'", window->Name); + PopFont(); + } + while (g.FocusScopeStack.Size > stack_sizes->SizeOfFocusScopeStack + 1) //-V1044 { if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name); PopFocusScope(); @@ -7409,9 +9348,9 @@ void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo } // Save current stack sizes for later compare -void ImGuiStackSizes::SetToCurrentState() +void ImGuiStackSizes::SetToContextState(ImGuiContext* ctx) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *ctx; ImGuiWindow* window = g.CurrentWindow; SizeOfIDStack = (short)window->IDStack.Size; SizeOfColorStack = (short)g.ColorStack.Size; @@ -7425,9 +9364,9 @@ void ImGuiStackSizes::SetToCurrentState() } // Compare to detect usage errors -void ImGuiStackSizes::CompareWithCurrentState() +void ImGuiStackSizes::CompareWithContextState(ImGuiContext* ctx) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *ctx; ImGuiWindow* window = g.CurrentWindow; IM_UNUSED(window); @@ -7477,7 +9416,7 @@ void ImGuiStackSizes::CompareWithCurrentState() // - GetWindowContentRegionMin(), GetWindowContentRegionMax() // - BeginGroup() // - EndGroup() -// Also see in imgui_widgets: tab bars, columns. +// Also see in imgui_widgets: tab bars, and in imgui_tables: tables, columns. //----------------------------------------------------------------------------- // Advance cursor given item size for layout. @@ -7494,14 +9433,16 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y) // In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor, // but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect. const float offset_to_match_baseline_y = (text_baseline_y >= 0) ? ImMax(0.0f, window->DC.CurrLineTextBaseOffset - text_baseline_y) : 0.0f; - const float line_height = ImMax(window->DC.CurrLineSize.y, size.y + offset_to_match_baseline_y); + + const float line_y1 = window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y; + const float line_height = ImMax(window->DC.CurrLineSize.y, /*ImMax(*/window->DC.CursorPos.y - line_y1/*, 0.0f)*/ + size.y + offset_to_match_baseline_y); // Always align ourselves on pixel boundaries //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x; - window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y; + window->DC.CursorPosPrevLine.y = line_y1; window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line - window->DC.CursorPos.y = IM_FLOOR(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y); // Next line + window->DC.CursorPos.y = IM_FLOOR(line_y1 + line_height + g.Style.ItemSpacing.y); // Next line window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y); //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] @@ -7510,17 +9451,13 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y) window->DC.CurrLineSize.y = 0.0f; window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y); window->DC.CurrLineTextBaseOffset = 0.0f; + window->DC.IsSameLine = window->DC.IsSetPos = false; // Horizontal layout mode if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) SameLine(); } -void ImGui::ItemSize(const ImRect& bb, float text_baseline_y) -{ - ItemSize(bb.GetSize(), text_baseline_y); -} - // Declare item bounding box for clipping and interaction. // Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface // declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction. @@ -7534,12 +9471,14 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu g.LastItemData.ID = id; g.LastItemData.Rect = bb; g.LastItemData.NavRect = nav_bb_arg ? *nav_bb_arg : bb; - g.LastItemData.InFlags = g.CurrentItemFlags | extra_flags; + g.LastItemData.InFlags = g.CurrentItemFlags | g.NextItemData.ItemFlags | extra_flags; g.LastItemData.StatusFlags = ImGuiItemStatusFlags_None; // Directional navigation processing if (id != 0) { + KeepAliveID(id); + // Runs prior to clipping early-out // (a) So that NavInitRequest can be honored, for newly opened windows to select a default widget // (b) So that we can scroll up/down past clipped items. This adds a small O(N) cost to regular navigation requests @@ -7549,40 +9488,51 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu // to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick). // We intentionally don't check if g.NavWindow != NULL because g.NavAnyRequest should only be set when it is non null. // If we crash on a NULL g.NavWindow we need to fix the bug elsewhere. - window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent); - if (g.NavId == id || g.NavAnyRequest) - if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) - if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) - NavProcessItem(); - - // [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd() -#ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX - if (id == g.DebugItemPickerBreakId) + if (!(g.LastItemData.InFlags & ImGuiItemFlags_NoNav)) { - IM_DEBUG_BREAK(); - g.DebugItemPickerBreakId = 0; + window->DC.NavLayersActiveMaskNext |= (1 << window->DC.NavLayerCurrent); + if (g.NavId == id || g.NavAnyRequest) + if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) + if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) + NavProcessItem(); } -#endif + + // [DEBUG] People keep stumbling on this problem and using "" as identifier in the root of a window instead of "##something". + // Empty identifier are valid and useful in a small amount of cases, but 99.9% of the time you want to use "##something". + // READ THE FAQ: https://dearimgui.com/faq + IM_ASSERT(id != window->ID && "Cannot have an empty ID at the root of a window. If you need an empty label, use ## and read the FAQ about how the ID Stack works!"); } g.NextItemData.Flags = ImGuiNextItemDataFlags_None; + g.NextItemData.ItemFlags = ImGuiItemFlags_None; #ifdef IMGUI_ENABLE_TEST_ENGINE if (id != 0) - IMGUI_TEST_ENGINE_ITEM_ADD(nav_bb_arg ? *nav_bb_arg : bb, id); + IMGUI_TEST_ENGINE_ITEM_ADD(id, g.LastItemData.NavRect, &g.LastItemData); #endif // Clipping test - const bool is_clipped = IsClippedEx(bb, id); - if (is_clipped) - return false; - //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] + // (FIXME: This is a modified copy of IsClippedEx() so we can reuse the is_rect_visible value) + //const bool is_clipped = IsClippedEx(bb, id); + //if (is_clipped) + // return false; + const bool is_rect_visible = bb.Overlaps(window->ClipRect); + if (!is_rect_visible) + if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId)) + if (!g.LogEnabled) + return false; - // [WIP] Tab stop handling (previously was using internal FocusableItemRegister() api) - // FIXME-NAV: We would now want to move this before the clipping test, but this would require being able to scroll and currently this would mean an extra frame. (#4079, #343) - if (extra_flags & ImGuiItemFlags_Inputable) - ItemInputable(window, id); + // [DEBUG] +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + if (id != 0 && id == g.DebugLocateId) + DebugLocateItemResolveWithLastItem(); +#endif + //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] + //if ((g.LastItemData.InFlags & ImGuiItemFlags_NoNav) == 0) + // window->DrawList->AddRect(g.LastItemData.NavRect.Min, g.LastItemData.NavRect.Max, IM_COL32(255,255,0,255)); // [DEBUG] // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them) + if (is_rect_visible) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Visible; if (IsMouseHoveringRect(bb.Min, bb.Max)) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; return true; @@ -7595,25 +9545,28 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu // spacing_w >= 0 : enforce spacing amount void ImGui::SameLine(float offset_from_start_x, float spacing_w) { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; if (window->SkipItems) return; - ImGuiContext& g = *GImGui; if (offset_from_start_x != 0.0f) { - if (spacing_w < 0.0f) spacing_w = 0.0f; + if (spacing_w < 0.0f) + spacing_w = 0.0f; window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + offset_from_start_x + spacing_w + window->DC.GroupOffset.x + window->DC.ColumnsOffset.x; window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; } else { - if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x; + if (spacing_w < 0.0f) + spacing_w = g.Style.ItemSpacing.x; window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w; window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; } window->DC.CurrLineSize = window->DC.PrevLineSize; window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; + window->DC.IsSameLine = true; } ImVec2 ImGui::GetCursorScreenPos() @@ -7622,11 +9575,15 @@ ImVec2 ImGui::GetCursorScreenPos() return window->DC.CursorPos; } +// 2022/08/05: Setting cursor position also extend boundaries (via modifying CursorMaxPos) used to compute window size, group size etc. +// I believe this was is a judicious choice but it's probably being relied upon (it has been the case since 1.31 and 1.50) +// It would be sane if we requested user to use SetCursorPos() + Dummy(ImVec2(0,0)) to extend CursorMaxPos... void ImGui::SetCursorScreenPos(const ImVec2& pos) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos = pos; - window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); + //window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); + window->DC.IsSetPos = true; } // User generally sees positions in window coordinates. Internally we store CursorPos in absolute screen coordinates because it is more convenient. @@ -7653,21 +9610,24 @@ void ImGui::SetCursorPos(const ImVec2& local_pos) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos = window->Pos - window->Scroll + local_pos; - window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); + //window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); + window->DC.IsSetPos = true; } void ImGui::SetCursorPosX(float x) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + x; - window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); + //window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); + window->DC.IsSetPos = true; } void ImGui::SetCursorPosY(float y) { ImGuiWindow* window = GetCurrentWindow(); window->DC.CursorPos.y = window->Pos.y - window->Scroll.y + y; - window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); + //window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); + window->DC.IsSetPos = true; } ImVec2 ImGui::GetCursorStartPos() @@ -7758,7 +9718,8 @@ float ImGui::CalcItemWidth() // The 4.0f here may be changed to match CalcItemWidth() and/or BeginChild() (right now we have a mismatch which is harmless but undesirable) ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_w, float default_h) { - ImGuiWindow* window = GImGui->CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; ImVec2 region_max; if (size.x < 0.0f || size.y < 0.0f) @@ -7883,6 +9844,9 @@ void ImGui::EndGroup() ImGuiGroupData& group_data = g.GroupStack.back(); IM_ASSERT(group_data.WindowID == window->ID); // EndGroup() in wrong window? + if (window->DC.IsSetPos) + ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); + ImRect group_bb(group_data.BackupCursorPos, ImMax(window->DC.CursorMaxPos, group_data.BackupCursorPos)); window->DC.CursorPos = group_data.BackupCursorPos; @@ -7902,10 +9866,10 @@ void ImGui::EndGroup() window->DC.CurrLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. ItemSize(group_bb.GetSize()); - ItemAdd(group_bb, 0); + ItemAdd(group_bb, 0, NULL, ImGuiItemFlags_NoTabStop); // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive(), IsItemDeactivated() etc. will be functional on the entire group. - // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but would put a little more burden on individual widgets. + // It would be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but would put a little more burden on individual widgets. // Also if you grep for LastItemId you'll notice it is only used in that context. // (The two tests not the same because ActiveIdIsAlive is an ID itself, in order to be able to handle ActiveId being overwritten during the frame.) const bool group_contains_curr_active_id = (group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId; @@ -7955,38 +9919,24 @@ static float CalcScrollEdgeSnap(float target, float snap_min, float snap_max, fl static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) { ImVec2 scroll = window->Scroll; - if (window->ScrollTarget.x < FLT_MAX) + ImVec2 decoration_size(window->DecoOuterSizeX1 + window->DecoInnerSizeX1 + window->DecoOuterSizeX2, window->DecoOuterSizeY1 + window->DecoInnerSizeY1 + window->DecoOuterSizeY2); + for (int axis = 0; axis < 2; axis++) { - float decoration_total_width = window->ScrollbarSizes.x; - float center_x_ratio = window->ScrollTargetCenterRatio.x; - float scroll_target_x = window->ScrollTarget.x; - if (window->ScrollTargetEdgeSnapDist.x > 0.0f) + if (window->ScrollTarget[axis] < FLT_MAX) { - float snap_x_min = 0.0f; - float snap_x_max = window->ScrollMax.x + window->SizeFull.x - decoration_total_width; - scroll_target_x = CalcScrollEdgeSnap(scroll_target_x, snap_x_min, snap_x_max, window->ScrollTargetEdgeSnapDist.x, center_x_ratio); + float center_ratio = window->ScrollTargetCenterRatio[axis]; + float scroll_target = window->ScrollTarget[axis]; + if (window->ScrollTargetEdgeSnapDist[axis] > 0.0f) + { + float snap_min = 0.0f; + float snap_max = window->ScrollMax[axis] + window->SizeFull[axis] - decoration_size[axis]; + scroll_target = CalcScrollEdgeSnap(scroll_target, snap_min, snap_max, window->ScrollTargetEdgeSnapDist[axis], center_ratio); + } + scroll[axis] = scroll_target - center_ratio * (window->SizeFull[axis] - decoration_size[axis]); } - scroll.x = scroll_target_x - center_x_ratio * (window->SizeFull.x - decoration_total_width); - } - if (window->ScrollTarget.y < FLT_MAX) - { - float decoration_total_height = window->TitleBarHeight() + window->MenuBarHeight() + window->ScrollbarSizes.y; - float center_y_ratio = window->ScrollTargetCenterRatio.y; - float scroll_target_y = window->ScrollTarget.y; - if (window->ScrollTargetEdgeSnapDist.y > 0.0f) - { - float snap_y_min = 0.0f; - float snap_y_max = window->ScrollMax.y + window->SizeFull.y - decoration_total_height; - scroll_target_y = CalcScrollEdgeSnap(scroll_target_y, snap_y_min, snap_y_max, window->ScrollTargetEdgeSnapDist.y, center_y_ratio); - } - scroll.y = scroll_target_y - center_y_ratio * (window->SizeFull.y - decoration_total_height); - } - scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f)); - scroll.y = IM_FLOOR(ImMax(scroll.y, 0.0f)); - if (!window->Collapsed && !window->SkipItems) - { - scroll.x = ImMin(scroll.x, window->ScrollMax.x); - scroll.y = ImMin(scroll.y, window->ScrollMax.y); + scroll[axis] = IM_FLOOR(ImMax(scroll[axis], 0.0f)); + if (!window->Collapsed && !window->SkipItems) + scroll[axis] = ImMin(scroll[axis], window->ScrollMax[axis]); } return scroll; } @@ -8007,8 +9957,11 @@ void ImGui::ScrollToRect(ImGuiWindow* window, const ImRect& item_rect, ImGuiScro ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGuiScrollFlags flags) { ImGuiContext& g = *GImGui; - ImRect window_rect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1)); - //GetForegroundDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG] + ImRect scroll_rect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1)); + scroll_rect.Min.x = ImMin(scroll_rect.Min.x + window->DecoInnerSizeX1, scroll_rect.Max.x); + scroll_rect.Min.y = ImMin(scroll_rect.Min.y + window->DecoInnerSizeY1, scroll_rect.Max.y); + //GetForegroundDrawList(window)->AddRect(item_rect.Min, item_rect.Max, IM_COL32(255,0,0,255), 0.0f, 0, 5.0f); // [DEBUG] + //GetForegroundDrawList(window)->AddRect(scroll_rect.Min, scroll_rect.Max, IM_COL32_WHITE); // [DEBUG] // Check that only one behavior is selected per axis IM_ASSERT((flags & ImGuiScrollFlags_MaskX_) == 0 || ImIsPowerOfTwo(flags & ImGuiScrollFlags_MaskX_)); @@ -8021,35 +9974,39 @@ ImVec2 ImGui::ScrollToRectEx(ImGuiWindow* window, const ImRect& item_rect, ImGui if ((flags & ImGuiScrollFlags_MaskY_) == 0) flags |= window->Appearing ? ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeY; - const bool fully_visible_x = item_rect.Min.x >= window_rect.Min.x && item_rect.Max.x <= window_rect.Max.x; - const bool fully_visible_y = item_rect.Min.y >= window_rect.Min.y && item_rect.Max.y <= window_rect.Max.y; - const bool can_be_fully_visible_x = item_rect.GetWidth() <= window_rect.GetWidth(); - const bool can_be_fully_visible_y = item_rect.GetHeight() <= window_rect.GetHeight(); + const bool fully_visible_x = item_rect.Min.x >= scroll_rect.Min.x && item_rect.Max.x <= scroll_rect.Max.x; + const bool fully_visible_y = item_rect.Min.y >= scroll_rect.Min.y && item_rect.Max.y <= scroll_rect.Max.y; + const bool can_be_fully_visible_x = (item_rect.GetWidth() + g.Style.ItemSpacing.x * 2.0f) <= scroll_rect.GetWidth() || (window->AutoFitFramesX > 0) || (window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0; + const bool can_be_fully_visible_y = (item_rect.GetHeight() + g.Style.ItemSpacing.y * 2.0f) <= scroll_rect.GetHeight() || (window->AutoFitFramesY > 0) || (window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0; if ((flags & ImGuiScrollFlags_KeepVisibleEdgeX) && !fully_visible_x) { - if (item_rect.Min.x < window_rect.Min.x || !can_be_fully_visible_x) + if (item_rect.Min.x < scroll_rect.Min.x || !can_be_fully_visible_x) SetScrollFromPosX(window, item_rect.Min.x - g.Style.ItemSpacing.x - window->Pos.x, 0.0f); - else if (item_rect.Max.x >= window_rect.Max.x) + else if (item_rect.Max.x >= scroll_rect.Max.x) SetScrollFromPosX(window, item_rect.Max.x + g.Style.ItemSpacing.x - window->Pos.x, 1.0f); } else if (((flags & ImGuiScrollFlags_KeepVisibleCenterX) && !fully_visible_x) || (flags & ImGuiScrollFlags_AlwaysCenterX)) { - float target_x = can_be_fully_visible_x ? ImFloor((item_rect.Min.x + item_rect.Max.x - window->InnerRect.GetWidth()) * 0.5f) : item_rect.Min.x; - SetScrollFromPosX(window, target_x - window->Pos.x, 0.0f); + if (can_be_fully_visible_x) + SetScrollFromPosX(window, ImFloor((item_rect.Min.x + item_rect.Max.x) * 0.5f) - window->Pos.x, 0.5f); + else + SetScrollFromPosX(window, item_rect.Min.x - window->Pos.x, 0.0f); } if ((flags & ImGuiScrollFlags_KeepVisibleEdgeY) && !fully_visible_y) { - if (item_rect.Min.y < window_rect.Min.y || !can_be_fully_visible_y) + if (item_rect.Min.y < scroll_rect.Min.y || !can_be_fully_visible_y) SetScrollFromPosY(window, item_rect.Min.y - g.Style.ItemSpacing.y - window->Pos.y, 0.0f); - else if (item_rect.Max.y >= window_rect.Max.y) + else if (item_rect.Max.y >= scroll_rect.Max.y) SetScrollFromPosY(window, item_rect.Max.y + g.Style.ItemSpacing.y - window->Pos.y, 1.0f); } else if (((flags & ImGuiScrollFlags_KeepVisibleCenterY) && !fully_visible_y) || (flags & ImGuiScrollFlags_AlwaysCenterY)) { - float target_y = can_be_fully_visible_y ? ImFloor((item_rect.Min.y + item_rect.Max.y - window->InnerRect.GetHeight()) * 0.5f) : item_rect.Min.y; - SetScrollFromPosY(window, target_y - window->Pos.y, 0.0f); + if (can_be_fully_visible_y) + SetScrollFromPosY(window, ImFloor((item_rect.Min.y + item_rect.Max.y) * 0.5f) - window->Pos.y, 0.5f); + else + SetScrollFromPosY(window, item_rect.Min.y - window->Pos.y, 0.0f); } ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); @@ -8124,7 +10081,7 @@ void ImGui::SetScrollY(float scroll_y) // - local_pos = (absolution_pos - window->Pos) // - So local_x/local_y are 0.0f for a position at the upper-left corner of a window, // and generally local_x/local_y are >(padding+decoration) && <(size-padding-decoration) when in the visible area. -// - They mostly exists because of legacy API. +// - They mostly exist because of legacy API. // Following the rules above, when trying to work with scrolling code, consider that: // - SetScrollFromPosY(0.0f) == SetScrollY(0.0f + scroll.y) == has no effect! // - SetScrollFromPosY(-scroll.y) == SetScrollY(-scroll.y + scroll.y) == SetScrollY(0.0f) == reset scroll. Of course writing SetScrollY(0.0f) directly then makes more sense @@ -8132,7 +10089,7 @@ void ImGui::SetScrollY(float scroll_y) void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio) { IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f); - window->ScrollTarget.x = IM_FLOOR(local_x + window->Scroll.x); // Convert local position to scroll offset + window->ScrollTarget.x = IM_FLOOR(local_x - window->DecoOuterSizeX1 - window->DecoInnerSizeX1 + window->Scroll.x); // Convert local position to scroll offset window->ScrollTargetCenterRatio.x = center_x_ratio; window->ScrollTargetEdgeSnapDist.x = 0.0f; } @@ -8140,9 +10097,7 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio) { IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); - const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); // FIXME: Would be nice to have a more standardized access to our scrollable/client rect; - local_y -= decoration_up_height; - window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y); // Convert local position to scroll offset + window->ScrollTarget.y = IM_FLOOR(local_y - window->DecoOuterSizeY1 - window->DecoInnerSizeY1 + window->Scroll.y); // Convert local position to scroll offset window->ScrollTargetCenterRatio.y = center_y_ratio; window->ScrollTargetEdgeSnapDist.y = 0.0f; } @@ -8189,41 +10144,55 @@ void ImGui::SetScrollHereY(float center_y_ratio) // [SECTION] TOOLTIPS //----------------------------------------------------------------------------- -void ImGui::BeginTooltip() +bool ImGui::BeginTooltip() { - BeginTooltipEx(ImGuiWindowFlags_None, ImGuiTooltipFlags_None); + return BeginTooltipEx(ImGuiTooltipFlags_None, ImGuiWindowFlags_None); } -void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags) +bool ImGui::BeginItemTooltip() +{ + if (!IsItemHovered(ImGuiHoveredFlags_ForTooltip)) + return false; + return BeginTooltipEx(ImGuiTooltipFlags_None, ImGuiWindowFlags_None); +} + +bool ImGui::BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags) { ImGuiContext& g = *GImGui; if (g.DragDropWithinSource || g.DragDropWithinTarget) { - // The default tooltip position is a little offset to give space to see the context menu (it's also clamped within the current viewport/monitor) - // In the context of a dragging tooltip we try to reduce that offset and we enforce following the cursor. - // Whatever we do we want to call SetNextWindowPos() to enforce a tooltip position and disable clipping the tooltip without our display area, like regular tooltip do. + // Drag and Drop tooltips are positioning differently than other tooltips: + // - offset visibility to increase visibility around mouse. + // - never clamp within outer viewport boundary. + // We call SetNextWindowPos() to enforce position and disable clamping. + // See FindBestWindowPosForPopup() for positionning logic of other tooltips (not drag and drop ones). //ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding; - ImVec2 tooltip_pos = g.IO.MousePos + ImVec2(16 * g.Style.MouseCursorScale, 8 * g.Style.MouseCursorScale); + ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET * g.Style.MouseCursorScale; SetNextWindowPos(tooltip_pos); SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f); //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :( - tooltip_flags |= ImGuiTooltipFlags_OverridePreviousTooltip; + tooltip_flags |= ImGuiTooltipFlags_OverridePrevious; } char window_name[16]; ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount); - if (tooltip_flags & ImGuiTooltipFlags_OverridePreviousTooltip) + if (tooltip_flags & ImGuiTooltipFlags_OverridePrevious) if (ImGuiWindow* window = FindWindowByName(window_name)) if (window->Active) { // Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one. - window->Hidden = true; - window->HiddenFramesCanSkipItems = 1; // FIXME: This may not be necessary? + SetWindowHiddendAndSkipItemsForCurrentFrame(window); ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount); } ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize; - Begin(window_name, NULL, flags | extra_flags); + Begin(window_name, NULL, flags | extra_window_flags); + // 2023-03-09: Added bool return value to the API, but currently always returning true. + // If this ever returns false we need to update BeginDragDropSource() accordingly. + //if (!ret) + // End(); + //return ret; + return true; } void ImGui::EndTooltip() @@ -8232,13 +10201,6 @@ void ImGui::EndTooltip() End(); } -void ImGui::SetTooltipV(const char* fmt, va_list args) -{ - BeginTooltipEx(0, ImGuiTooltipFlags_OverridePreviousTooltip); - TextV(fmt, args); - EndTooltip(); -} - void ImGui::SetTooltip(const char* fmt, ...) { va_list args; @@ -8247,6 +10209,32 @@ void ImGui::SetTooltip(const char* fmt, ...) va_end(args); } +void ImGui::SetTooltipV(const char* fmt, va_list args) +{ + if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None)) + return; + TextV(fmt, args); + EndTooltip(); +} + +// Shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav'. +// Defaults to == ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort when using the mouse. +void ImGui::SetItemTooltip(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + if (IsItemHovered(ImGuiHoveredFlags_ForTooltip)) + SetTooltipV(fmt, args); + va_end(args); +} + +void ImGui::SetItemTooltipV(const char* fmt, va_list args) +{ + if (IsItemHovered(ImGuiHoveredFlags_ForTooltip)) + SetTooltipV(fmt, args); +} + + //----------------------------------------------------------------------------- // [SECTION] POPUPS //----------------------------------------------------------------------------- @@ -8292,6 +10280,7 @@ bool ImGui::IsPopupOpen(const char* str_id, ImGuiPopupFlags popup_flags) return IsPopupOpen(id, popup_flags); } +// Also see FindBlockingModal(NULL) ImGuiWindow* ImGui::GetTopMostPopupModal() { ImGuiContext& g = *GImGui; @@ -8302,10 +10291,23 @@ ImGuiWindow* ImGui::GetTopMostPopupModal() return NULL; } +// See Demo->Stacked Modal to confirm what this is for. +ImGuiWindow* ImGui::GetTopMostAndVisiblePopupModal() +{ + ImGuiContext& g = *GImGui; + for (int n = g.OpenPopupStack.Size - 1; n >= 0; n--) + if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window) + if ((popup->Flags & ImGuiWindowFlags_Modal) && IsWindowActiveAndVisible(popup)) + return popup; + return NULL; +} + void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags) { ImGuiContext& g = *GImGui; - OpenPopupEx(g.CurrentWindow->GetID(str_id), popup_flags); + ImGuiID id = g.CurrentWindow->GetID(str_id); + IMGUI_DEBUG_LOG_POPUP("[popup] OpenPopup(\"%s\" -> 0x%08X)\n", str_id, id); + OpenPopupEx(id, popup_flags); } void ImGui::OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags) @@ -8324,19 +10326,19 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags) const int current_stack_size = g.BeginPopupStack.Size; if (popup_flags & ImGuiPopupFlags_NoOpenOverExistingPopup) - if (IsPopupOpen(0u, ImGuiPopupFlags_AnyPopupId)) + if (IsPopupOpen((ImGuiID)0, ImGuiPopupFlags_AnyPopupId)) return; ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. popup_ref.PopupId = id; popup_ref.Window = NULL; - popup_ref.SourceWindow = g.NavWindow; + popup_ref.BackupNavWindow = g.NavWindow; // When popup closes focus may be restored to NavWindow (depend on window type). popup_ref.OpenFrameCount = g.FrameCount; popup_ref.OpenParentId = parent_window->IDStack.back(); popup_ref.OpenPopupPos = NavCalcPreferredRefPos(); popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos; - IMGUI_DEBUG_LOG_POPUP("OpenPopupEx(0x%08X)\n", id); + IMGUI_DEBUG_LOG_POPUP("[popup] OpenPopupEx(0x%08X)\n", id); if (g.OpenPopupStack.Size < current_stack_size + 1) { g.OpenPopupStack.push_back(popup_ref); @@ -8394,7 +10396,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to bool ref_window_is_descendent_of_popup = false; for (int n = popup_count_to_keep; n < g.OpenPopupStack.Size; n++) if (ImGuiWindow* popup_window = g.OpenPopupStack[n].Window) - if (popup_window->RootWindow == ref_window->RootWindow) + if (IsWindowWithinBeginStackOf(ref_window, popup_window)) { ref_window_is_descendent_of_popup = true; break; @@ -8405,7 +10407,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to } if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below { - IMGUI_DEBUG_LOG_POPUP("ClosePopupsOverWindow(\"%s\") -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep); + IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupsOverWindow(\"%s\")\n", ref_window ? ref_window->Name : ""); ClosePopupToLevel(popup_count_to_keep, restore_focus_to_window_under_popup); } } @@ -8418,7 +10420,7 @@ void ImGui::ClosePopupsExceptModals() for (popup_count_to_keep = g.OpenPopupStack.Size; popup_count_to_keep > 0; popup_count_to_keep--) { ImGuiWindow* window = g.OpenPopupStack[popup_count_to_keep - 1].Window; - if (!window || window->Flags & ImGuiWindowFlags_Modal) + if (!window || (window->Flags & ImGuiWindowFlags_Modal)) break; } if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below @@ -8428,27 +10430,21 @@ void ImGui::ClosePopupsExceptModals() void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup) { ImGuiContext& g = *GImGui; - IMGUI_DEBUG_LOG_POPUP("ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup); + IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup); IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size); // Trim open popup stack - ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow; ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window; + ImGuiWindow* popup_backup_nav_window = g.OpenPopupStack[remaining].BackupNavWindow; g.OpenPopupStack.resize(remaining); if (restore_focus_to_window_under_popup) { + ImGuiWindow* focus_window = (popup_window && popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : popup_backup_nav_window; if (focus_window && !focus_window->WasActive && popup_window) - { - // Fallback - FocusTopMostWindowUnderOne(popup_window, NULL); - } + FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild); // Fallback else - { - if (g.NavLayer == ImGuiNavLayer_Main && focus_window) - focus_window = NavRestoreLastChildNavWindow(focus_window); - FocusWindow(focus_window); - } + FocusWindow(focus_window, (g.NavLayer == ImGuiNavLayer_Main) ? ImGuiFocusRequestFlags_RestoreFocusedChild : ImGuiFocusRequestFlags_None); } } @@ -8467,13 +10463,13 @@ void ImGui::CloseCurrentPopup() ImGuiWindow* parent_popup_window = g.OpenPopupStack[popup_idx - 1].Window; bool close_parent = false; if (popup_window && (popup_window->Flags & ImGuiWindowFlags_ChildMenu)) - if (parent_popup_window == NULL || !(parent_popup_window->Flags & ImGuiWindowFlags_Modal)) + if (parent_popup_window && !(parent_popup_window->Flags & ImGuiWindowFlags_MenuBar)) close_parent = true; if (!close_parent) break; popup_idx--; } - IMGUI_DEBUG_LOG_POPUP("CloseCurrentPopup %d -> %d\n", g.BeginPopupStack.Size - 1, popup_idx); + IMGUI_DEBUG_LOG_POPUP("[popup] CloseCurrentPopup %d -> %d\n", g.BeginPopupStack.Size - 1, popup_idx); ClosePopupToLevel(popup_idx, true); // A common pattern is to close a popup when selecting a menu item/selectable that will open another window. @@ -8495,7 +10491,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) char name[20]; if (flags & ImGuiWindowFlags_ChildMenu) - ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth + ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginMenuCount); // Recycle windows based on depth else ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame @@ -8516,7 +10512,8 @@ bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags) return false; } flags |= ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings; - return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags); + ImGuiID id = g.CurrentWindow->GetID(str_id); + return BeginPopupEx(id, flags); } // If 'p_open' is specified for a modal popup window, the popup will have a regular close button which will close the popup. @@ -8595,7 +10592,7 @@ void ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiPopupFlags popup_flags // - You may want to handle the whole on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters). // This is essentially the same as: // id = str_id ? GetID(str_id) : GetItemID(); -// OpenPopupOnItemClick(str_id); +// OpenPopupOnItemClick(str_id, ImGuiPopupFlags_MouseButtonRight); // return BeginPopup(id); // Which is essentially the same as: // id = str_id ? GetID(str_id) : GetItemID(); @@ -8691,7 +10688,7 @@ ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& s const float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x); const float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); - // If there not enough room on one axis, there's no point in positioning on a side on this axis (e.g. when not enough width, use a top/bottom position to maximize available width) + // If there's not enough room on one axis, there's no point in positioning on a side on this axis (e.g. when not enough width, use a top/bottom position to maximize available width) if (avail_w < size.x && (dir == ImGuiDir_Left || dir == ImGuiDir_Right)) continue; if (avail_h < size.y && (dir == ImGuiDir_Up || dir == ImGuiDir_Down)) @@ -8756,20 +10753,24 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) } if (window->Flags & ImGuiWindowFlags_Popup) { - ImRect r_avoid = ImRect(window->Pos.x - 1, window->Pos.y - 1, window->Pos.x + 1, window->Pos.y + 1); - return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Default); + return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, ImRect(window->Pos, window->Pos), ImGuiPopupPositionPolicy_Default); // Ideally we'd disable r_avoid here } if (window->Flags & ImGuiWindowFlags_Tooltip) { - // Position tooltip (always follows mouse) - float sc = g.Style.MouseCursorScale; - ImVec2 ref_pos = NavCalcPreferredRefPos(); + // Position tooltip (always follows mouse + clamp within outer boundaries) + // Note that drag and drop tooltips are NOT using this path: BeginTooltipEx() manually sets their position. + // In theory we could handle both cases in same location, but requires a bit of shuffling as drag and drop tooltips are calling SetWindowPos() leading to 'window_pos_set_by_api' being set in Begin() + IM_ASSERT(g.CurrentWindow == window); + const float scale = g.Style.MouseCursorScale; + const ImVec2 ref_pos = NavCalcPreferredRefPos(); + const ImVec2 tooltip_pos = ref_pos + TOOLTIP_DEFAULT_OFFSET * scale; ImRect r_avoid; if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos)) r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); else - r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. - return FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip); + r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * scale, ref_pos.y + 24 * scale); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. + //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255, 0, 255, 255)); + return FindBestWindowPosForPopupEx(tooltip_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid, ImGuiPopupPositionPolicy_Tooltip); } IM_ASSERT(0); return window->Pos; @@ -8779,8 +10780,28 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) // [SECTION] KEYBOARD/GAMEPAD NAVIGATION //----------------------------------------------------------------------------- -// FIXME-NAV: The existence of SetNavID vs SetFocusID properly needs to be clarified/reworked. -// In our terminology those should be interchangeable. Those two functions are merely a legacy artifact, so at minimum naming should be clarified. +// FIXME-NAV: The existence of SetNavID vs SetFocusID vs FocusWindow() needs to be clarified/reworked. +// In our terminology those should be interchangeable, yet right now this is super confusing. +// Those two functions are merely a legacy artifact, so at minimum naming should be clarified. + +void ImGui::SetNavWindow(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.NavWindow != window) + { + IMGUI_DEBUG_LOG_FOCUS("[focus] SetNavWindow(\"%s\")\n", window ? window->Name : ""); + g.NavWindow = window; + } + g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false; + NavUpdateAnyRequestFlag(); +} + +void ImGui::NavClearPreferredPosForAxis(ImGuiAxis axis) +{ + ImGuiContext& g = *GImGui; + g.NavWindow->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer][axis] = FLT_MAX; +} + void ImGui::SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel) { ImGuiContext& g = *GImGui; @@ -8791,8 +10812,10 @@ void ImGui::SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id g.NavFocusScopeId = focus_scope_id; g.NavWindow->NavLastIds[nav_layer] = id; g.NavWindow->NavRectRel[nav_layer] = rect_rel; - //g.NavDisableHighlight = false; - //g.NavDisableMouseHover = g.NavMousePosDirty = true; + + // Clear preferred scoring position (NavMoveRequestApplyResult() will tend to restore it) + NavClearPreferredPosForAxis(ImGuiAxis_X); + NavClearPreferredPosForAxis(ImGuiAxis_Y); } void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window) @@ -8800,55 +10823,45 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window) ImGuiContext& g = *GImGui; IM_ASSERT(id != 0); - // Assume that SetFocusID() is called in the context where its window->DC.NavLayerCurrent and window->DC.NavFocusScopeIdCurrent are valid. + if (g.NavWindow != window) + SetNavWindow(window); + + // Assume that SetFocusID() is called in the context where its window->DC.NavLayerCurrent and g.CurrentFocusScopeId are valid. // Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text) const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent; - if (g.NavWindow != window) - g.NavInitRequest = false; - g.NavWindow = window; g.NavId = id; g.NavLayer = nav_layer; - g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; + g.NavFocusScopeId = g.CurrentFocusScopeId; window->NavLastIds[nav_layer] = id; if (g.LastItemData.ID == id) - window->NavRectRel[nav_layer] = ImRect(g.LastItemData.NavRect.Min - window->Pos, g.LastItemData.NavRect.Max - window->Pos); + window->NavRectRel[nav_layer] = WindowRectAbsToRel(window, g.LastItemData.NavRect); - if (g.ActiveIdSource == ImGuiInputSource_Nav) + if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad) g.NavDisableMouseHover = true; else g.NavDisableHighlight = true; + + // Clear preferred scoring position (NavMoveRequestApplyResult() will tend to restore it) + NavClearPreferredPosForAxis(ImGuiAxis_X); + NavClearPreferredPosForAxis(ImGuiAxis_Y); } -ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy) +static ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy) { if (ImFabs(dx) > ImFabs(dy)) return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left; return (dy > 0.0f) ? ImGuiDir_Down : ImGuiDir_Up; } -static float inline NavScoreItemDistInterval(float a0, float a1, float b0, float b1) +static float inline NavScoreItemDistInterval(float cand_min, float cand_max, float curr_min, float curr_max) { - if (a1 < b0) - return a1 - b0; - if (b1 < a0) - return a0 - b1; + if (cand_max < curr_min) + return cand_max - curr_min; + if (curr_max < cand_min) + return cand_min - curr_max; return 0.0f; } -static void inline NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect& r, const ImRect& clip_rect) -{ - if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) - { - r.Min.y = ImClamp(r.Min.y, clip_rect.Min.y, clip_rect.Max.y); - r.Max.y = ImClamp(r.Max.y, clip_rect.Min.y, clip_rect.Max.y); - } - else // FIXME: PageUp/PageDown are leaving move_dir == None - { - r.Min.x = ImClamp(r.Min.x, clip_rect.Min.x, clip_rect.Max.x); - r.Max.x = ImClamp(r.Max.x, clip_rect.Min.x, clip_rect.Max.x); - } -} - // Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057 static bool ImGui::NavScoreItem(ImGuiNavItemData* result) { @@ -8871,10 +10884,6 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result) cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window } - // We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items) - // For example, this ensure that items in one column are not reached when moving vertically from items in another column. - NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect); - // Compute distance between boxes // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed. float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x); @@ -8913,32 +10922,41 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result) quadrant = (g.LastItemData.ID < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right; } + const ImGuiDir move_dir = g.NavMoveDir; #if IMGUI_DEBUG_NAV_SCORING - char buf[128]; - if (IsMouseHoveringRect(cand.Min, cand.Max)) + char buf[200]; + if (g.IO.KeyCtrl) // Hold CTRL to preview score in matching quadrant. CTRL+Arrow to rotate. { - ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]); - ImDrawList* draw_list = GetForegroundDrawList(window); - draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100)); - draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200)); - draw_list->AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40,0,0,150)); - draw_list->AddText(cand.Max, ~0U, buf); - } - else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate. - { - if (quadrant == g.NavMoveDir) + if (quadrant == move_dir) { ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center); ImDrawList* draw_list = GetForegroundDrawList(window); - draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); + draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 80)); + draw_list->AddRectFilled(cand.Min, cand.Min + CalcTextSize(buf), IM_COL32(255, 0, 0, 200)); draw_list->AddText(cand.Min, IM_COL32(255, 255, 255, 255), buf); } } + const bool debug_hovering = IsMouseHoveringRect(cand.Min, cand.Max); + const bool debug_tty = (g.IO.KeyCtrl && IsKeyPressed(ImGuiKey_Space)); + if (debug_hovering || debug_tty) + { + ImFormatString(buf, IM_ARRAYSIZE(buf), + "d-box (%7.3f,%7.3f) -> %7.3f\nd-center (%7.3f,%7.3f) -> %7.3f\nd-axial (%7.3f,%7.3f) -> %7.3f\nnav %c, quadrant %c", + dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "-WENS"[move_dir+1], "-WENS"[quadrant+1]); + if (debug_hovering) + { + ImDrawList* draw_list = GetForegroundDrawList(window); + draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255, 200, 0, 100)); + draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255, 255, 0, 200)); + draw_list->AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40, 0, 0, 200)); + draw_list->AddText(cand.Max, ~0U, buf); + } + if (debug_tty) { IMGUI_DEBUG_LOG_NAV("id 0x%08X\n%s\n", g.LastItemData.ID, buf); } + } #endif - // Is it in the quadrant we're interesting in moving to? + // Is it in the quadrant we're interested in moving to? bool new_best = false; - const ImGuiDir move_dir = g.NavMoveDir; if (quadrant == move_dir) { // Does it beat the current best candidate? @@ -8989,9 +11007,18 @@ static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result) ImGuiWindow* window = g.CurrentWindow; result->Window = window; result->ID = g.LastItemData.ID; - result->FocusScopeId = window->DC.NavFocusScopeIdCurrent; + result->FocusScopeId = g.CurrentFocusScopeId; result->InFlags = g.LastItemData.InFlags; - result->RectRel = ImRect(g.LastItemData.NavRect.Min - window->Pos, g.LastItemData.NavRect.Max - window->Pos); + result->RectRel = WindowRectAbsToRel(window, g.LastItemData.NavRect); +} + +// True when current work location may be scrolled horizontally when moving left / right. +// This is generally always true UNLESS within a column. We don't have a vertical equivalent. +void ImGui::NavUpdateCurrentWindowIsScrollPushableX() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + window->DC.NavIsScrollPushableX = (g.CurrentTable == NULL && window->DC.CurrentColumns == NULL); } // We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above) @@ -9001,18 +11028,24 @@ static void ImGui::NavProcessItem() ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; const ImGuiID id = g.LastItemData.ID; - const ImRect nav_bb = g.LastItemData.NavRect; const ImGuiItemFlags item_flags = g.LastItemData.InFlags; + // When inside a container that isn't scrollable with Left<>Right, clip NavRect accordingly (#2221) + if (window->DC.NavIsScrollPushableX == false) + { + g.LastItemData.NavRect.Min.x = ImClamp(g.LastItemData.NavRect.Min.x, window->ClipRect.Min.x, window->ClipRect.Max.x); + g.LastItemData.NavRect.Max.x = ImClamp(g.LastItemData.NavRect.Max.x, window->ClipRect.Min.x, window->ClipRect.Max.x); + } + const ImRect nav_bb = g.LastItemData.NavRect; + // Process Init Request - if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent) + if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent && (item_flags & ImGuiItemFlags_Disabled) == 0) { // Even if 'ImGuiItemFlags_NoNavDefaultFocus' is on (typically collapse/close button) we record the first ResultId so they can be used as a fallback - const bool candidate_for_nav_default_focus = (item_flags & (ImGuiItemFlags_NoNavDefaultFocus | ImGuiItemFlags_Disabled)) == 0; - if (candidate_for_nav_default_focus || g.NavInitResultId == 0) + const bool candidate_for_nav_default_focus = (item_flags & ImGuiItemFlags_NoNavDefaultFocus) == 0; + if (candidate_for_nav_default_focus || g.NavInitResult.ID == 0) { - g.NavInitResultId = id; - g.NavInitResultRectRel = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); + NavApplyItemToResult(&g.NavInitResult); } if (candidate_for_nav_default_focus) { @@ -9023,43 +11056,99 @@ static void ImGui::NavProcessItem() // Process Move Request (scoring for navigation) // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy) - if (g.NavMoveScoringItems) + if (g.NavMoveScoringItems && (item_flags & ImGuiItemFlags_Disabled) == 0) { - if (item_flags & ImGuiItemFlags_Inputable) - g.NavTabbingInputableRemaining--; - - if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav))) + const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) != 0; + if (is_tabbing) + { + NavProcessItemForTabbingRequest(id, item_flags, g.NavMoveFlags); + } + else if (g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) { ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; + if (NavScoreItem(result)) + NavApplyItemToResult(result); - if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) - { - if (g.NavTabbingInputableRemaining == 0) - NavMoveRequestResolveWithLastItem(); - } - else - { - if (NavScoreItem(result)) - NavApplyItemToResult(result); - - // Features like PageUp/PageDown need to maintain a separate score for the visible set of items. - const float VISIBLE_RATIO = 0.70f; - if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb)) - if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO) - if (NavScoreItem(&g.NavMoveResultLocalVisible)) - NavApplyItemToResult(&g.NavMoveResultLocalVisible); - } + // Features like PageUp/PageDown need to maintain a separate score for the visible set of items. + const float VISIBLE_RATIO = 0.70f; + if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb)) + if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO) + if (NavScoreItem(&g.NavMoveResultLocalVisible)) + NavApplyItemToResult(&g.NavMoveResultLocalVisible); } } - // Update window-relative bounding box of navigated item + // Update information for currently focused/navigated item if (g.NavId == id) { - g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window. + if (g.NavWindow != window) + SetNavWindow(window); // Always refresh g.NavWindow, because some operations such as FocusItem() may not have a window. g.NavLayer = window->DC.NavLayerCurrent; - g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent; + g.NavFocusScopeId = g.CurrentFocusScopeId; g.NavIdIsAlive = true; - window->NavRectRel[window->DC.NavLayerCurrent] = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); // Store item bounding box (relative to window position) + window->NavRectRel[window->DC.NavLayerCurrent] = WindowRectAbsToRel(window, nav_bb); // Store item bounding box (relative to window position) + } +} + +// Handle "scoring" of an item for a tabbing/focusing request initiated by NavUpdateCreateTabbingRequest(). +// Note that SetKeyboardFocusHere() API calls are considered tabbing requests! +// - Case 1: no nav/active id: set result to first eligible item, stop storing. +// - Case 2: tab forward: on ref id set counter, on counter elapse store result +// - Case 3: tab forward wrap: set result to first eligible item (preemptively), on ref id set counter, on next frame if counter hasn't elapsed store result. // FIXME-TABBING: Could be done as a next-frame forwarded request +// - Case 4: tab backward: store all results, on ref id pick prev, stop storing +// - Case 5: tab backward wrap: store all results, on ref id if no result keep storing until last // FIXME-TABBING: Could be done as next-frame forwarded requested +void ImGui::NavProcessItemForTabbingRequest(ImGuiID id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags) +{ + ImGuiContext& g = *GImGui; + + if ((move_flags & ImGuiNavMoveFlags_FocusApi) == 0) + if (g.NavLayer != g.CurrentWindow->DC.NavLayerCurrent) + return; + + // - Can always land on an item when using API call. + // - Tabbing with _NavEnableKeyboard (space/enter/arrows): goes through every item. + // - Tabbing without _NavEnableKeyboard: goes through inputable items only. + bool can_stop; + if (move_flags & ImGuiNavMoveFlags_FocusApi) + can_stop = true; + else + can_stop = (item_flags & ImGuiItemFlags_NoTabStop) == 0 && ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) || (item_flags & ImGuiItemFlags_Inputable)); + + // Always store in NavMoveResultLocal (unlike directional request which uses NavMoveResultOther on sibling/flattened windows) + ImGuiNavItemData* result = &g.NavMoveResultLocal; + if (g.NavTabbingDir == +1) + { + // Tab Forward or SetKeyboardFocusHere() with >= 0 + if (can_stop && g.NavTabbingResultFirst.ID == 0) + NavApplyItemToResult(&g.NavTabbingResultFirst); + if (can_stop && g.NavTabbingCounter > 0 && --g.NavTabbingCounter == 0) + NavMoveRequestResolveWithLastItem(result); + else if (g.NavId == id) + g.NavTabbingCounter = 1; + } + else if (g.NavTabbingDir == -1) + { + // Tab Backward + if (g.NavId == id) + { + if (result->ID) + { + g.NavMoveScoringItems = false; + NavUpdateAnyRequestFlag(); + } + } + else if (can_stop) + { + // Keep applying until reaching NavId + NavApplyItemToResult(result); + } + } + else if (g.NavTabbingDir == 0) + { + if (can_stop && g.NavId == id) + NavMoveRequestResolveWithLastItem(result); + if (can_stop && g.NavTabbingResultFirst.ID == 0) // Tab init + NavApplyItemToResult(&g.NavTabbingResultFirst); } } @@ -9086,18 +11175,19 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM g.NavMoveScrollFlags = scroll_flags; g.NavMoveForwardToNextFrame = false; g.NavMoveKeyMods = g.IO.KeyMods; - g.NavTabbingInputableRemaining = 0; g.NavMoveResultLocal.Clear(); g.NavMoveResultLocalVisible.Clear(); g.NavMoveResultOther.Clear(); + g.NavTabbingCounter = 0; + g.NavTabbingResultFirst.Clear(); NavUpdateAnyRequestFlag(); } -void ImGui::NavMoveRequestResolveWithLastItem() +void ImGui::NavMoveRequestResolveWithLastItem(ImGuiNavItemData* result) { ImGuiContext& g = *GImGui; g.NavMoveScoringItems = false; // Ensure request doesn't need more processing - NavApplyItemToResult(&g.NavMoveResultLocal); + NavApplyItemToResult(result); NavUpdateAnyRequestFlag(); } @@ -9126,10 +11216,12 @@ void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNav void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wrap_flags) { ImGuiContext& g = *GImGui; - IM_ASSERT(wrap_flags != 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY - // In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it, NavEndFrame() will do the same test + IM_ASSERT((wrap_flags & ImGuiNavMoveFlags_WrapMask_ ) != 0 && (wrap_flags & ~ImGuiNavMoveFlags_WrapMask_) == 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY + + // In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it: + // as NavEndFrame() will do the same test. It will end up calling NavUpdateCreateWrappingRequest(). if (g.NavWindow == window && g.NavMoveScoringItems && g.NavLayer == ImGuiNavLayer_Main) - g.NavMoveFlags |= wrap_flags; + g.NavMoveFlags = (g.NavMoveFlags & ~ImGuiNavMoveFlags_WrapMask_) | wrap_flags; } // FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0). @@ -9156,7 +11248,12 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer) { ImGuiContext& g = *GImGui; if (layer == ImGuiNavLayer_Main) - g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); + { + ImGuiWindow* prev_nav_window = g.NavWindow; + g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); // FIXME-NAV: Should clear ongoing nav requests? + if (prev_nav_window) + IMGUI_DEBUG_LOG_FOCUS("[focus] NavRestoreLayer: from \"%s\" to SetNavWindow(\"%s\")\n", prev_nav_window->Name, g.NavWindow->Name); + } ImGuiWindow* window = g.NavWindow; if (window->NavLastIds[layer] != 0) { @@ -9167,6 +11264,11 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer) g.NavLayer = layer; NavInitWindow(window, true); } +} + +void ImGui::NavRestoreHighlightAfterMove() +{ + ImGuiContext& g = *GImGui; g.NavDisableHighlight = false; g.NavDisableMouseHover = g.NavMousePosDirty = true; } @@ -9187,7 +11289,8 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit) if (window->Flags & ImGuiWindowFlags_NoNavInputs) { - g.NavId = g.NavFocusScopeId = 0; + g.NavId = 0; + g.NavFocusScopeId = window->NavRootFocusScopeId; return; } @@ -9197,76 +11300,68 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit) IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from NavInitWindow(), init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer); if (init_for_nav) { - SetNavID(0, g.NavLayer, 0, ImRect()); + SetNavID(0, g.NavLayer, window->NavRootFocusScopeId, ImRect()); g.NavInitRequest = true; g.NavInitRequestFromMove = false; - g.NavInitResultId = 0; - g.NavInitResultRectRel = ImRect(); + g.NavInitResult.ID = 0; NavUpdateAnyRequestFlag(); } else { g.NavId = window->NavLastIds[0]; - g.NavFocusScopeId = 0; + g.NavFocusScopeId = window->NavRootFocusScopeId; } } static ImVec2 ImGui::NavCalcPreferredRefPos() { ImGuiContext& g = *GImGui; - if (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow) + ImGuiWindow* window = g.NavWindow; + if (g.NavDisableHighlight || !g.NavDisableMouseHover || !window) { // Mouse (we need a fallback in case the mouse becomes invalid after being used) - if (IsMousePosValid(&g.IO.MousePos)) - return g.IO.MousePos; - return g.MouseLastValidPos; + // The +1.0f offset when stored by OpenPopupEx() allows reopening this or another popup (same or another mouse button) while not moving the mouse, it is pretty standard. + // In theory we could move that +1.0f offset in OpenPopupEx() + ImVec2 p = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : g.MouseLastValidPos; + return ImVec2(p.x + 1.0f, p.y); } else { - // When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item. - const ImRect& rect_rel = g.NavWindow->NavRectRel[g.NavLayer]; - ImVec2 pos = g.NavWindow->Pos + ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); + // When navigation is active and mouse is disabled, pick a position around the bottom left of the currently navigated item + // Take account of upcoming scrolling (maybe set mouse pos should be done in EndFrame?) + ImRect rect_rel = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]); + if (window->LastFrameActive != g.FrameCount && (window->ScrollTarget.x != FLT_MAX || window->ScrollTarget.y != FLT_MAX)) + { + ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); + rect_rel.Translate(window->Scroll - next_scroll); + } + ImVec2 pos = ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); ImGuiViewport* viewport = GetMainViewport(); return ImFloor(ImClamp(pos, viewport->Pos, viewport->Pos + viewport->Size)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta. } } -float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode) +float ImGui::GetNavTweakPressedAmount(ImGuiAxis axis) { ImGuiContext& g = *GImGui; - if (mode == ImGuiInputReadMode_Down) - return g.IO.NavInputs[n]; // Instant, read analog input (0.0f..1.0f, as provided by user) + float repeat_delay, repeat_rate; + GetTypematicRepeatRate(ImGuiInputFlags_RepeatRateNavTweak, &repeat_delay, &repeat_rate); - const float t = g.IO.NavInputsDownDuration[n]; - if (t < 0.0f && mode == ImGuiInputReadMode_Released) // Return 1.0f when just released, no repeat, ignore analog input. - return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f); - if (t < 0.0f) - return 0.0f; - if (mode == ImGuiInputReadMode_Pressed) // Return 1.0f when just pressed, no repeat, ignore analog input. - return (t == 0.0f) ? 1.0f : 0.0f; - if (mode == ImGuiInputReadMode_Repeat) - return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.80f); - if (mode == ImGuiInputReadMode_RepeatSlow) - return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 1.25f, g.IO.KeyRepeatRate * 2.00f); - if (mode == ImGuiInputReadMode_RepeatFast) - return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.30f); - return 0.0f; -} - -ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor, float fast_factor) -{ - ImVec2 delta(0.0f, 0.0f); - if (dir_sources & ImGuiNavDirSourceFlags_Keyboard) - delta += ImVec2(GetNavInputAmount(ImGuiNavInput_KeyRight_, mode) - GetNavInputAmount(ImGuiNavInput_KeyLeft_, mode), GetNavInputAmount(ImGuiNavInput_KeyDown_, mode) - GetNavInputAmount(ImGuiNavInput_KeyUp_, mode)); - if (dir_sources & ImGuiNavDirSourceFlags_PadDPad) - delta += ImVec2(GetNavInputAmount(ImGuiNavInput_DpadRight, mode) - GetNavInputAmount(ImGuiNavInput_DpadLeft, mode), GetNavInputAmount(ImGuiNavInput_DpadDown, mode) - GetNavInputAmount(ImGuiNavInput_DpadUp, mode)); - if (dir_sources & ImGuiNavDirSourceFlags_PadLStick) - delta += ImVec2(GetNavInputAmount(ImGuiNavInput_LStickRight, mode) - GetNavInputAmount(ImGuiNavInput_LStickLeft, mode), GetNavInputAmount(ImGuiNavInput_LStickDown, mode) - GetNavInputAmount(ImGuiNavInput_LStickUp, mode)); - if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow)) - delta *= slow_factor; - if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast)) - delta *= fast_factor; - return delta; + ImGuiKey key_less, key_more; + if (g.NavInputSource == ImGuiInputSource_Gamepad) + { + key_less = (axis == ImGuiAxis_X) ? ImGuiKey_GamepadDpadLeft : ImGuiKey_GamepadDpadUp; + key_more = (axis == ImGuiAxis_X) ? ImGuiKey_GamepadDpadRight : ImGuiKey_GamepadDpadDown; + } + else + { + key_less = (axis == ImGuiAxis_X) ? ImGuiKey_LeftArrow : ImGuiKey_UpArrow; + key_more = (axis == ImGuiAxis_X) ? ImGuiKey_RightArrow : ImGuiKey_DownArrow; + } + float amount = (float)GetKeyPressedAmount(key_more, repeat_delay, repeat_rate) - (float)GetKeyPressedAmount(key_less, repeat_delay, repeat_rate); + if (amount != 0.0f && IsKeyDown(key_less) && IsKeyDown(key_more)) // Cancel when opposite directions are held, regardless of repeat phase + amount = 0.0f; + return amount; } static void ImGui::NavUpdate() @@ -9275,69 +11370,43 @@ static void ImGui::NavUpdate() ImGuiIO& io = g.IO; io.WantSetMousePos = false; - //if (g.NavScoringDebugCount > 0) IMGUI_DEBUG_LOG("NavScoringDebugCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.NavScoringDebugCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest); + //if (g.NavScoringDebugCount > 0) IMGUI_DEBUG_LOG_NAV("[nav] NavScoringDebugCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.NavScoringDebugCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest); - // Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard) - // (do it before we map Keyboard input!) - const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; + // Set input source based on which keys are last pressed (as some features differs when used with Gamepad vs Keyboard) + // FIXME-NAV: Now that keys are separated maybe we can get rid of NavInputSource? const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; - if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad) - { - if (io.NavInputs[ImGuiNavInput_Activate] > 0.0f || io.NavInputs[ImGuiNavInput_Input] > 0.0f || io.NavInputs[ImGuiNavInput_Cancel] > 0.0f || io.NavInputs[ImGuiNavInput_Menu] > 0.0f - || io.NavInputs[ImGuiNavInput_DpadLeft] > 0.0f || io.NavInputs[ImGuiNavInput_DpadRight] > 0.0f || io.NavInputs[ImGuiNavInput_DpadUp] > 0.0f || io.NavInputs[ImGuiNavInput_DpadDown] > 0.0f) - g.NavInputSource = ImGuiInputSource_Gamepad; - } - - // Update Keyboard->Nav inputs mapping + const ImGuiKey nav_gamepad_keys_to_change_source[] = { ImGuiKey_GamepadFaceRight, ImGuiKey_GamepadFaceLeft, ImGuiKey_GamepadFaceUp, ImGuiKey_GamepadFaceDown, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown }; + if (nav_gamepad_active) + for (ImGuiKey key : nav_gamepad_keys_to_change_source) + if (IsKeyDown(key)) + g.NavInputSource = ImGuiInputSource_Gamepad; + const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; + const ImGuiKey nav_keyboard_keys_to_change_source[] = { ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_RightArrow, ImGuiKey_LeftArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow }; if (nav_keyboard_active) - { - #define NAV_MAP_KEY(_KEY, _NAV_INPUT) do { if (IsKeyDown(io.KeyMap[_KEY])) { io.NavInputs[_NAV_INPUT] = 1.0f; g.NavInputSource = ImGuiInputSource_Keyboard; } } while (0) - NAV_MAP_KEY(ImGuiKey_Space, ImGuiNavInput_Activate ); - NAV_MAP_KEY(ImGuiKey_Enter, ImGuiNavInput_Input ); - NAV_MAP_KEY(ImGuiKey_Escape, ImGuiNavInput_Cancel ); - NAV_MAP_KEY(ImGuiKey_LeftArrow, ImGuiNavInput_KeyLeft_ ); - NAV_MAP_KEY(ImGuiKey_RightArrow,ImGuiNavInput_KeyRight_); - NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_ ); - NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_ ); - if (io.KeyCtrl) - io.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f; - if (io.KeyShift) - io.NavInputs[ImGuiNavInput_TweakFast] = 1.0f; - #undef NAV_MAP_KEY - } - memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration)); - for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) - io.NavInputsDownDuration[i] = (io.NavInputs[i] > 0.0f) ? (io.NavInputsDownDuration[i] < 0.0f ? 0.0f : io.NavInputsDownDuration[i] + io.DeltaTime) : -1.0f; + for (ImGuiKey key : nav_keyboard_keys_to_change_source) + if (IsKeyDown(key)) + g.NavInputSource = ImGuiInputSource_Keyboard; // Process navigation init request (select first/default focus) - if (g.NavInitResultId != 0) + g.NavJustMovedToId = 0; + if (g.NavInitResult.ID != 0) NavInitRequestApplyResult(); g.NavInitRequest = false; g.NavInitRequestFromMove = false; - g.NavInitResultId = 0; - g.NavJustMovedToId = 0; + g.NavInitResult.ID = 0; // Process navigation move request if (g.NavMoveSubmitted) NavMoveRequestApplyResult(); - g.NavTabbingInputableRemaining = 0; + g.NavTabbingCounter = 0; g.NavMoveSubmitted = g.NavMoveScoringItems = false; - // Apply application mouse position movement, after we had a chance to process move request result. + // Schedule mouse position update (will be done at the bottom of this function, after 1) processing all move requests and 2) updating scrolling) + bool set_mouse_pos = false; if (g.NavMousePosDirty && g.NavIdIsAlive) - { - // Set mouse position given our knowledge of the navigated item position from last frame - if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) - if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow) - { - io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos(); - io.WantSetMousePos = true; - //IMGUI_DEBUG_LOG("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); - } - g.NavMousePosDirty = false; - } - g.NavIdIsAlive = false; - g.NavJustTabbedId = 0; + if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow) + set_mouse_pos = true; + g.NavMousePosDirty = false; IM_ASSERT(g.NavLayer == ImGuiNavLayer_Main || g.NavLayer == ImGuiNavLayer_Menu); // Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0 @@ -9357,14 +11426,14 @@ static void ImGui::NavUpdate() NavUpdateCancelRequest(); // Process manual activation request - g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavActivateInputId = 0; + g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = 0; g.NavActivateFlags = ImGuiActivateFlags_None; if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) { - bool activate_down = IsNavInputDown(ImGuiNavInput_Activate); - bool input_down = IsNavInputDown(ImGuiNavInput_Input); - bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed); - bool input_pressed = input_down && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed); + const bool activate_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Space)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadActivate)); + const bool activate_pressed = activate_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Space, false)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadActivate, false))); + const bool input_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Enter)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadInput)); + const bool input_pressed = input_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Enter, false)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadInput, false))); if (g.ActiveId == 0 && activate_pressed) { g.NavActivateId = g.NavId; @@ -9372,12 +11441,12 @@ static void ImGui::NavUpdate() } if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && input_pressed) { - g.NavActivateInputId = g.NavId; + g.NavActivateId = g.NavId; g.NavActivateFlags = ImGuiActivateFlags_PreferInput; } - if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down) + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_down || input_down)) g.NavActivateDownId = g.NavId; - if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed) + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && (activate_pressed || input_pressed)) g.NavActivatePressedId = g.NavId; } if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) @@ -9389,17 +11458,17 @@ static void ImGui::NavUpdate() // FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others) if (g.NavNextActivateId != 0) { - if (g.NavNextActivateFlags & ImGuiActivateFlags_PreferInput) - g.NavActivateInputId = g.NavNextActivateId; - else - g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavNextActivateId; + g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavNextActivateId; g.NavActivateFlags = g.NavNextActivateFlags; } g.NavNextActivateId = 0; // Process move requests NavUpdateCreateMoveRequest(); + if (g.NavMoveDir == ImGuiDir_None) + NavUpdateCreateTabbingRequest(); NavUpdateAnyRequestFlag(); + g.NavIdIsAlive = false; // Scrolling if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget) @@ -9408,7 +11477,7 @@ static void ImGui::NavUpdate() ImGuiWindow* window = g.NavWindow; const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported. const ImGuiDir move_dir = g.NavMoveDir; - if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && move_dir != ImGuiDir_None) + if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY && move_dir != ImGuiDir_None) { if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) SetScrollX(window, ImFloor(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed)); @@ -9416,30 +11485,43 @@ static void ImGui::NavUpdate() SetScrollY(window, ImFloor(window->Scroll.y + ((move_dir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed)); } - // *Normal* Manual scroll with NavScrollXXX keys + // *Normal* Manual scroll with LStick // Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds. - ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down, 1.0f / 10.0f, 10.0f); - if (scroll_dir.x != 0.0f && window->ScrollbarX) - SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed)); - if (scroll_dir.y != 0.0f) - SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed)); + if (nav_gamepad_active) + { + const ImVec2 scroll_dir = GetKeyMagnitude2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown); + const float tweak_factor = IsKeyDown(ImGuiKey_NavGamepadTweakSlow) ? 1.0f / 10.0f : IsKeyDown(ImGuiKey_NavGamepadTweakFast) ? 10.0f : 1.0f; + if (scroll_dir.x != 0.0f && window->ScrollbarX) + SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed * tweak_factor)); + if (scroll_dir.y != 0.0f) + SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed * tweak_factor)); + } } // Always prioritize mouse highlight if navigation is disabled if (!nav_keyboard_active && !nav_gamepad_active) { g.NavDisableHighlight = true; - g.NavDisableMouseHover = g.NavMousePosDirty = false; + g.NavDisableMouseHover = set_mouse_pos = false; + } + + // Update mouse position if requested + // (This will take into account the possibility that a Scroll was queued in the window to offset our absolute mouse position before scroll has been applied) + if (set_mouse_pos && (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) + { + io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos(); + io.WantSetMousePos = true; + //IMGUI_DEBUG_LOG_IO("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); } // [DEBUG] g.NavScoringDebugCount = 0; #if IMGUI_DEBUG_NAV_RECTS - if (g.NavWindow) + if (ImGuiWindow* debug_window = g.NavWindow) { - ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow); - if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG] - if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } + ImDrawList* draw_list = GetForegroundDrawList(debug_window); + int layer = g.NavLayer; /* for (int layer = 0; layer < 2; layer++)*/ { ImRect r = WindowRectRelToAbs(debug_window, debug_window->NavRectRel[layer]); draw_list->AddRect(r.Min, r.Max, IM_COL32(255, 200, 0, 255)); } + //if (1) { ImU32 col = (!debug_window->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } } #endif } @@ -9451,16 +11533,46 @@ void ImGui::NavInitRequestApplyResult() if (!g.NavWindow) return; + ImGuiNavItemData* result = &g.NavInitResult; + if (g.NavId != result->ID) + { + g.NavJustMovedToId = result->ID; + g.NavJustMovedToFocusScopeId = result->FocusScopeId; + g.NavJustMovedToKeyMods = 0; + } + // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called) // FIXME-NAV: On _NavFlattened windows, g.NavWindow will only be updated during subsequent frame. Not a problem currently. - IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name); - SetNavID(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel); + IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: ApplyResult: NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name); + SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel); g.NavIdIsAlive = true; // Mark as alive from previous frame as we got a result if (g.NavInitRequestFromMove) + NavRestoreHighlightAfterMove(); +} + +// Bias scoring rect ahead of scoring + update preferred pos (if missing) using source position +static void NavBiasScoringRect(ImRect& r, ImVec2& preferred_pos_rel, ImGuiDir move_dir, ImGuiNavMoveFlags move_flags) +{ + // Bias initial rect + ImGuiContext& g = *GImGui; + const ImVec2 rel_to_abs_offset = g.NavWindow->DC.CursorStartPos; + + // Initialize bias on departure if we don't have any. So mouse-click + arrow will record bias. + // - We default to L/U bias, so moving down from a large source item into several columns will land on left-most column. + // - But each successful move sets new bias on one axis, only cleared when using mouse. + if ((move_flags & ImGuiNavMoveFlags_Forwarded) == 0) { - g.NavDisableHighlight = false; - g.NavDisableMouseHover = g.NavMousePosDirty = true; + if (preferred_pos_rel.x == FLT_MAX) + preferred_pos_rel.x = ImMin(r.Min.x + 1.0f, r.Max.x) - rel_to_abs_offset.x; + if (preferred_pos_rel.y == FLT_MAX) + preferred_pos_rel.y = r.GetCenter().y - rel_to_abs_offset.y; } + + // Apply general bias on the other axis + if ((move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) && preferred_pos_rel.x != FLT_MAX) + r.Min.x = r.Max.x = preferred_pos_rel.x + rel_to_abs_offset.x; + else if ((move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) && preferred_pos_rel.y != FLT_MAX) + r.Min.y = r.Max.y = preferred_pos_rel.y + rel_to_abs_offset.y; } void ImGui::NavUpdateCreateMoveRequest() @@ -9468,6 +11580,8 @@ void ImGui::NavUpdateCreateMoveRequest() ImGuiContext& g = *GImGui; ImGuiIO& io = g.IO; ImGuiWindow* window = g.NavWindow; + const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; + const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; if (g.NavMoveForwardToNextFrame && window != NULL) { @@ -9485,29 +11599,36 @@ void ImGui::NavUpdateCreateMoveRequest() g.NavMoveScrollFlags = ImGuiScrollFlags_None; if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs)) { - const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat; - if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; } - if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; } - if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; } - if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsNavInputTest(ImGuiNavInput_DpadDown, read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_, read_mode))) { g.NavMoveDir = ImGuiDir_Down; } + const ImGuiInputFlags repeat_mode = ImGuiInputFlags_Repeat | (ImGuiInputFlags)ImGuiInputFlags_RepeatRateNavMove; + if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadLeft, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_LeftArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Left; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadRight, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_RightArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Right; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadUp, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_UpArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Up; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadDown, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_DownArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Down; } } g.NavMoveClipDir = g.NavMoveDir; + g.NavScoringNoClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX); } // Update PageUp/PageDown/Home/End scroll // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag? - const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; float scoring_rect_offset_y = 0.0f; if (window && g.NavMoveDir == ImGuiDir_None && nav_keyboard_active) scoring_rect_offset_y = NavUpdatePageUpPageDown(); - - // [DEBUG] Always send a request -#if IMGUI_DEBUG_NAV_SCORING - if (io.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) - g.NavMoveDirForDebug = (ImGuiDir)((g.NavMoveDirForDebug + 1) & 3); - if (io.KeyCtrl && g.NavMoveDir == ImGuiDir_None) + if (scoring_rect_offset_y != 0.0f) { - g.NavMoveDir = g.NavMoveDirForDebug; + g.NavScoringNoClipRect = window->InnerRect; + g.NavScoringNoClipRect.TranslateY(scoring_rect_offset_y); + } + + // [DEBUG] Always send a request when holding CTRL. Hold CTRL + Arrow change the direction. +#if IMGUI_DEBUG_NAV_SCORING + //if (io.KeyCtrl && IsKeyPressed(ImGuiKey_C)) + // g.NavMoveDirForDebug = (ImGuiDir)((g.NavMoveDirForDebug + 1) & 3); + if (io.KeyCtrl) + { + if (g.NavMoveDir == ImGuiDir_None) + g.NavMoveDir = g.NavMoveDirForDebug; + g.NavMoveClipDir = g.NavMoveDir; g.NavMoveFlags |= ImGuiNavMoveFlags_DebugNoResult; } #endif @@ -9517,28 +11638,39 @@ void ImGui::NavUpdateCreateMoveRequest() if (g.NavMoveDir != ImGuiDir_None) NavMoveRequestSubmit(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags, g.NavMoveScrollFlags); - // Moving with no reference triggers a init request (will be used as a fallback if the direction fails to find a match) + // Moving with no reference triggers an init request (will be used as a fallback if the direction fails to find a match) if (g.NavMoveSubmitted && g.NavId == 0) { - IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer); + IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", window ? window->Name : "", g.NavLayer); g.NavInitRequest = g.NavInitRequestFromMove = true; - g.NavInitResultId = 0; + g.NavInitResult.ID = 0; g.NavDisableHighlight = false; } // When using gamepad, we project the reference nav bounding box into window visible area. - // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative - // (can't focus a visible object like we can with the mouse). - if (g.NavMoveSubmitted && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main && window != NULL) + // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, + // since with gamepad all movements are relative (can't focus a visible object like we can with the mouse). + if (g.NavMoveSubmitted && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main && window != NULL)// && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded)) { - ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1)); - if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer])) + bool clamp_x = (g.NavMoveFlags & (ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapX)) == 0; + bool clamp_y = (g.NavMoveFlags & (ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapY)) == 0; + ImRect inner_rect_rel = WindowRectAbsToRel(window, ImRect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1))); + + // Take account of changing scroll to handle triggering a new move request on a scrolling frame. (#6171) + // Otherwise 'inner_rect_rel' would be off on the move result frame. + inner_rect_rel.Translate(CalcNextScrollFromScrollTargetAndClamp(window) - window->Scroll); + + if ((clamp_x || clamp_y) && !inner_rect_rel.Contains(window->NavRectRel[g.NavLayer])) { - IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n"); - float pad = window->CalcFontSize() * 0.5f; - window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item - window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel); - g.NavId = g.NavFocusScopeId = 0; + IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel for gamepad move\n"); + float pad_x = ImMin(inner_rect_rel.GetWidth(), window->CalcFontSize() * 0.5f); + float pad_y = ImMin(inner_rect_rel.GetHeight(), window->CalcFontSize() * 0.5f); // Terrible approximation for the intent of starting navigation from first fully visible item + inner_rect_rel.Min.x = clamp_x ? (inner_rect_rel.Min.x + pad_x) : -FLT_MAX; + inner_rect_rel.Max.x = clamp_x ? (inner_rect_rel.Max.x - pad_x) : +FLT_MAX; + inner_rect_rel.Min.y = clamp_y ? (inner_rect_rel.Min.y + pad_y) : -FLT_MAX; + inner_rect_rel.Max.y = clamp_y ? (inner_rect_rel.Max.y - pad_y) : +FLT_MAX; + window->NavRectRel[g.NavLayer].ClipWithFull(inner_rect_rel); + g.NavId = 0; } } @@ -9547,14 +11679,44 @@ void ImGui::NavUpdateCreateMoveRequest() if (window != NULL) { ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0); - scoring_rect = ImRect(window->Pos + nav_rect_rel.Min, window->Pos + nav_rect_rel.Max); + scoring_rect = WindowRectRelToAbs(window, nav_rect_rel); scoring_rect.TranslateY(scoring_rect_offset_y); - scoring_rect.Min.x = ImMin(scoring_rect.Min.x + 1.0f, scoring_rect.Max.x); - scoring_rect.Max.x = scoring_rect.Min.x; - IM_ASSERT(!scoring_rect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem(). + if (g.NavMoveSubmitted) + NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir, g.NavMoveFlags); + IM_ASSERT(!scoring_rect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allow us to remove extraneous ImFabs() calls in NavScoreItem(). //GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG] + //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG] } g.NavScoringRect = scoring_rect; + g.NavScoringNoClipRect.Add(scoring_rect); +} + +void ImGui::NavUpdateCreateTabbingRequest() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.NavWindow; + IM_ASSERT(g.NavMoveDir == ImGuiDir_None); + if (window == NULL || g.NavWindowingTarget != NULL || (window->Flags & ImGuiWindowFlags_NoNavInputs)) + return; + + const bool tab_pressed = IsKeyPressed(ImGuiKey_Tab, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat) && !g.IO.KeyCtrl && !g.IO.KeyAlt; + if (!tab_pressed) + return; + + // Initiate tabbing request + // (this is ALWAYS ENABLED, regardless of ImGuiConfigFlags_NavEnableKeyboard flag!) + // Initially this was designed to use counters and modulo arithmetic, but that could not work with unsubmitted items (list clipper). Instead we use a strategy close to other move requests. + // See NavProcessItemForTabbingRequest() for a description of the various forward/backward tabbing cases with and without wrapping. + const bool nav_keyboard_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; + if (nav_keyboard_active) + g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavDisableHighlight == true && g.ActiveId == 0) ? 0 : +1; + else + g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1; + ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate; + ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; + ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down; + NavMoveRequestSubmit(ImGuiDir_None, clip_dir, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. + g.NavTabbingCounter = -1; } // Apply result from previous frame navigation directional move request. Always called from NavUpdate() @@ -9569,16 +11731,21 @@ void ImGui::NavMoveRequestApplyResult() // Select which result to use ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : (g.NavMoveResultOther.ID != 0) ? &g.NavMoveResultOther : NULL; - // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) + // Tabbing forward wrap + if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && result == NULL) + if ((g.NavTabbingCounter == 1 || g.NavTabbingDir == 0) && g.NavTabbingResultFirst.ID) + result = &g.NavTabbingResultFirst; + + // In a situation when there are no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result) + const ImGuiAxis axis = (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X; if (result == NULL) { if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) - g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight; - if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0) - { - g.NavDisableHighlight = false; - g.NavDisableMouseHover = true; - } + g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight; + if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0) + NavRestoreHighlightAfterMove(); + NavClearPreferredPosForAxis(axis); // On a failed move, clear preferred pos for this axis. + IMGUI_DEBUG_LOG_NAV("[nav] NavMoveSubmitted but not led to a result!\n"); return; } @@ -9596,28 +11763,25 @@ void ImGui::NavMoveRequestApplyResult() // Scroll to keep newly navigated item fully into view. if (g.NavLayer == ImGuiNavLayer_Main) { - ImVec2 delta_scroll; + ImRect rect_abs = WindowRectRelToAbs(result->Window, result->RectRel); + ScrollToRectEx(result->Window, rect_abs, g.NavMoveScrollFlags); + if (g.NavMoveFlags & ImGuiNavMoveFlags_ScrollToEdgeY) { - // FIXME: Should remove this + // FIXME: Should remove this? Or make more precise: use ScrollToRectEx() with edge? float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f; - delta_scroll.y = result->Window->Scroll.y - scroll_target; SetScrollY(result->Window, scroll_target); } - else - { - ImRect rect_abs = ImRect(result->RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos); - delta_scroll = ScrollToRectEx(result->Window, rect_abs, g.NavMoveScrollFlags); - } - - // Offset our result position so mouse position can be applied immediately after in NavUpdate() - result->RectRel.TranslateX(-delta_scroll.x); - result->RectRel.TranslateY(-delta_scroll.y); } - ClearActiveID(); - g.NavWindow = result->Window; - if (g.NavId != result->ID) + if (g.NavWindow != result->Window) + { + IMGUI_DEBUG_LOG_FOCUS("[focus] NavMoveRequest: SetNavWindow(\"%s\")\n", result->Window->Name); + g.NavWindow = result->Window; + } + if (g.ActiveId != result->ID) + ClearActiveID(); + if (g.NavId != result->ID && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSelect) == 0) { // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId) g.NavJustMovedToId = result->ID; @@ -9625,31 +11789,36 @@ void ImGui::NavMoveRequestApplyResult() g.NavJustMovedToKeyMods = g.NavMoveKeyMods; } - // Focus + // Apply new NavID/Focus IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name); + ImVec2 preferred_scoring_pos_rel = g.NavWindow->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer]; SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel); - // Tabbing: Activates Inputable or Focus non-Inputable - if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable)) + // Restore last preferred position for current axis + // (storing in RootWindowForNav-> as the info is desirable at the beginning of a Move Request. In theory all storage should use RootWindowForNav..) + if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) == 0) { - g.NavNextActivateId = result->ID; - g.NavNextActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState; - g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight; + preferred_scoring_pos_rel[axis] = result->RectRel.GetCenter()[axis]; + g.NavWindow->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer] = preferred_scoring_pos_rel; } + // Tabbing: Activates Inputable, otherwise only Focus + if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable) == 0) + g.NavMoveFlags &= ~ImGuiNavMoveFlags_Activate; + // Activate if (g.NavMoveFlags & ImGuiNavMoveFlags_Activate) { g.NavNextActivateId = result->ID; g.NavNextActivateFlags = ImGuiActivateFlags_None; + g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight; + if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) + g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState; } // Enable nav highlight - if ((g.NavMoveFlags & ImGuiNavMoveFlags_DontSetNavHighlight) == 0) - { - g.NavDisableHighlight = false; - g.NavDisableMouseHover = g.NavMousePosDirty = true; - } + if ((g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0) + NavRestoreHighlightAfterMove(); } // Process NavCancel input (to close a popup, get back to parent, clear focus) @@ -9659,19 +11828,21 @@ void ImGui::NavMoveRequestApplyResult() static void ImGui::NavUpdateCancelRequest() { ImGuiContext& g = *GImGui; - if (!IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed)) + const bool nav_gamepad_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (g.IO.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; + const bool nav_keyboard_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; + if (!(nav_keyboard_active && IsKeyPressed(ImGuiKey_Escape, ImGuiKeyOwner_None)) && !(nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadCancel, ImGuiKeyOwner_None))) return; - IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n"); + IMGUI_DEBUG_LOG_NAV("[nav] NavUpdateCancelRequest()\n"); if (g.ActiveId != 0) { - if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel)) - ClearActiveID(); + ClearActiveID(); } else if (g.NavLayer != ImGuiNavLayer_Main) { // Leave the "menu" layer NavRestoreLayer(ImGuiNavLayer_Main); + NavRestoreHighlightAfterMove(); } else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow) { @@ -9681,20 +11852,20 @@ static void ImGui::NavUpdateCancelRequest() IM_ASSERT(child_window->ChildId != 0); ImRect child_rect = child_window->Rect(); FocusWindow(parent_window); - SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos)); + SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, WindowRectAbsToRel(parent_window, child_rect)); + NavRestoreHighlightAfterMove(); } - else if (g.OpenPopupStack.Size > 0) + else if (g.OpenPopupStack.Size > 0 && g.OpenPopupStack.back().Window != NULL && !(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) { // Close open popup/menu - if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) - ClosePopupToLevel(g.OpenPopupStack.Size - 1, true); + ClosePopupToLevel(g.OpenPopupStack.Size - 1, true); } else { // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) g.NavWindow->NavLastIds[0] = 0; - g.NavId = g.NavFocusScopeId = 0; + g.NavId = 0; } } @@ -9705,25 +11876,26 @@ static void ImGui::NavUpdateCancelRequest() static float ImGui::NavUpdatePageUpPageDown() { ImGuiContext& g = *GImGui; - ImGuiIO& io = g.IO; - ImGuiWindow* window = g.NavWindow; - if ((window->Flags & ImGuiWindowFlags_NoNavInputs) || g.NavWindowingTarget != NULL || g.NavLayer != ImGuiNavLayer_Main) + if ((window->Flags & ImGuiWindowFlags_NoNavInputs) || g.NavWindowingTarget != NULL) return 0.0f; - const bool page_up_held = IsKeyDown(io.KeyMap[ImGuiKey_PageUp]) && !IsActiveIdUsingKey(ImGuiKey_PageUp); - const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown); - const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home); - const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End); + const bool page_up_held = IsKeyDown(ImGuiKey_PageUp, ImGuiKeyOwner_None); + const bool page_down_held = IsKeyDown(ImGuiKey_PageDown, ImGuiKeyOwner_None); + const bool home_pressed = IsKeyPressed(ImGuiKey_Home, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat); + const bool end_pressed = IsKeyPressed(ImGuiKey_End, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat); if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out return 0.0f; - if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll) + if (g.NavLayer != ImGuiNavLayer_Main) + NavRestoreLayer(ImGuiNavLayer_Main); + + if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY) { // Fallback manual-scroll when window has no navigable item - if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true)) + if (IsKeyPressed(ImGuiKey_PageUp, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat)) SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight()); - else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true)) + else if (IsKeyPressed(ImGuiKey_PageDown, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat)) SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight()); else if (home_pressed) SetScrollY(window, 0.0f); @@ -9735,14 +11907,14 @@ static float ImGui::NavUpdatePageUpPageDown() ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer]; const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight()); float nav_scoring_rect_offset_y = 0.0f; - if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true)) + if (IsKeyPressed(ImGuiKey_PageUp, true)) { nav_scoring_rect_offset_y = -page_offset_y; g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item) g.NavMoveClipDir = ImGuiDir_Up; g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; } - else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true)) + else if (IsKeyPressed(ImGuiKey_PageDown, true)) { nav_scoring_rect_offset_y = +page_offset_y; g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item) @@ -9754,7 +11926,7 @@ static float ImGui::NavUpdatePageUpPageDown() // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdgeY flag, we don't scroll immediately to avoid scrolling happening before nav result. // Preserve current horizontal position if we have any. - nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y; + nav_rect_rel.Min.y = nav_rect_rel.Max.y = 0.0f; if (nav_rect_rel.IsInverted()) nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; g.NavMoveDir = ImGuiDir_Down; @@ -9763,7 +11935,7 @@ static float ImGui::NavUpdatePageUpPageDown() } else if (end_pressed) { - nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y; + nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ContentSize.y; if (nav_rect_rel.IsInverted()) nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; g.NavMoveDir = ImGuiDir_Up; @@ -9784,64 +11956,69 @@ static void ImGui::NavEndFrame() NavUpdateWindowingOverlay(); // Perform wrap-around in menus + // FIXME-NAV: Wrap may need to apply a weight bias on the other axis. e.g. 4x4 grid with 2 last items missing on last item won't handle LoopY/WrapY correctly. // FIXME-NAV: Wrap (not Loop) support could be handled by the scoring function and then WrapX would function without an extra frame. + if (g.NavWindow && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & ImGuiNavMoveFlags_WrapMask_) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0) + NavUpdateCreateWrappingRequest(); +} + +static void ImGui::NavUpdateCreateWrappingRequest() +{ + ImGuiContext& g = *GImGui; ImGuiWindow* window = g.NavWindow; + + bool do_forward = false; + ImRect bb_rel = window->NavRectRel[g.NavLayer]; + ImGuiDir clip_dir = g.NavMoveDir; + const ImGuiNavMoveFlags move_flags = g.NavMoveFlags; - const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY; - if (window && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & wanted_flags) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0) + //const ImGuiAxis move_axis = (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X; + if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) { - bool do_forward = false; - ImRect bb_rel = window->NavRectRel[g.NavLayer]; - ImGuiDir clip_dir = g.NavMoveDir; - if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) + bb_rel.Min.x = bb_rel.Max.x = window->ContentSize.x + window->WindowPadding.x; + if (move_flags & ImGuiNavMoveFlags_WrapX) { - bb_rel.Min.x = bb_rel.Max.x = - ImMax(window->SizeFull.x, window->ContentSize.x + window->WindowPadding.x * 2.0f) - window->Scroll.x; - if (move_flags & ImGuiNavMoveFlags_WrapX) - { - bb_rel.TranslateY(-bb_rel.GetHeight()); - clip_dir = ImGuiDir_Up; - } - do_forward = true; - } - if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) - { - bb_rel.Min.x = bb_rel.Max.x = -window->Scroll.x; - if (move_flags & ImGuiNavMoveFlags_WrapX) - { - bb_rel.TranslateY(+bb_rel.GetHeight()); - clip_dir = ImGuiDir_Down; - } - do_forward = true; - } - const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight(); - if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) - { - bb_rel.Min.y = bb_rel.Max.y = - ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y + decoration_up_height; - if (move_flags & ImGuiNavMoveFlags_WrapY) - { - bb_rel.TranslateX(-bb_rel.GetWidth()); - clip_dir = ImGuiDir_Left; - } - do_forward = true; - } - if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) - { - bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y + decoration_up_height; - if (move_flags & ImGuiNavMoveFlags_WrapY) - { - bb_rel.TranslateX(+bb_rel.GetWidth()); - clip_dir = ImGuiDir_Right; - } - do_forward = true; - } - if (do_forward) - { - window->NavRectRel[g.NavLayer] = bb_rel; - NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags); + bb_rel.TranslateY(-bb_rel.GetHeight()); // Previous row + clip_dir = ImGuiDir_Up; } + do_forward = true; } + if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) + { + bb_rel.Min.x = bb_rel.Max.x = -window->WindowPadding.x; + if (move_flags & ImGuiNavMoveFlags_WrapX) + { + bb_rel.TranslateY(+bb_rel.GetHeight()); // Next row + clip_dir = ImGuiDir_Down; + } + do_forward = true; + } + if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) + { + bb_rel.Min.y = bb_rel.Max.y = window->ContentSize.y + window->WindowPadding.y; + if (move_flags & ImGuiNavMoveFlags_WrapY) + { + bb_rel.TranslateX(-bb_rel.GetWidth()); // Previous column + clip_dir = ImGuiDir_Left; + } + do_forward = true; + } + if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY))) + { + bb_rel.Min.y = bb_rel.Max.y = -window->WindowPadding.y; + if (move_flags & ImGuiNavMoveFlags_WrapY) + { + bb_rel.TranslateX(+bb_rel.GetWidth()); // Next column + clip_dir = ImGuiDir_Right; + } + do_forward = true; + } + if (!do_forward) + return; + window->NavRectRel[g.NavLayer] = bb_rel; + NavClearPreferredPosForAxis(ImGuiAxis_X); + NavClearPreferredPosForAxis(ImGuiAxis_Y); + NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags); } static int ImGui::FindWindowFocusIndex(ImGuiWindow* window) @@ -9875,7 +12052,10 @@ static void NavUpdateWindowingHighlightWindow(int focus_change_dir) if (!window_target) window_target = FindWindowNavFocusable((focus_change_dir < 0) ? (g.WindowsFocusOrder.Size - 1) : 0, i_current, focus_change_dir); if (window_target) // Don't reset windowing target if there's a single window in the list + { g.NavWindowingTarget = g.NavWindowingTargetAnim = window_target; + g.NavWindowingAccumDeltaPos = g.NavWindowingAccumDeltaSize = ImVec2(0.0f, 0.0f); + } g.NavWindowingToggleLayer = false; } @@ -9891,7 +12071,7 @@ static void ImGui::NavUpdateWindowing() bool apply_toggle_layer = false; ImGuiWindow* modal_window = GetTopMostPopupModal(); - bool allow_windowing = (modal_window == NULL); + bool allow_windowing = (modal_window == NULL); // FIXME: This prevent CTRL+TAB from being usable with windows that are inside the Begin-stack of that modal. if (!allow_windowing) g.NavWindowingTarget = NULL; @@ -9903,17 +12083,26 @@ static void ImGui::NavUpdateWindowing() g.NavWindowingTargetAnim = NULL; } - // Start CTRL-TAB or Square+L/R window selection + // Start CTRL+Tab or Square+L/R window selection + const ImGuiID owner_id = ImHashStr("###NavUpdateWindowing"); + const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; - const bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed); - const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && nav_keyboard_active && io.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab); + const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, owner_id, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways); + const bool keyboard_prev_window = allow_windowing && g.ConfigNavWindowingKeyPrev && Shortcut(g.ConfigNavWindowingKeyPrev, owner_id, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways); + const bool start_windowing_with_gamepad = allow_windowing && nav_gamepad_active && !g.NavWindowingTarget && IsKeyPressed(ImGuiKey_NavGamepadMenu, 0, ImGuiInputFlags_None); + const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && (keyboard_next_window || keyboard_prev_window); // Note: enabled even without NavEnableKeyboard! if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1)) { g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f; + g.NavWindowingAccumDeltaPos = g.NavWindowingAccumDeltaSize = ImVec2(0.0f, 0.0f); g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad; + + // Register ownership of our mods. Using ImGuiInputFlags_RouteGlobalHigh in the Shortcut() calls instead would probably be correct but may have more side-effects. + if (keyboard_next_window || keyboard_prev_window) + SetKeyOwnersForKeyChord((g.ConfigNavWindowingKeyNext | g.ConfigNavWindowingKeyPrev) & ImGuiMod_Mask_, owner_id); } // Gamepad update @@ -9924,7 +12113,7 @@ static void ImGui::NavUpdateWindowing() g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // Select window to focus - const int focus_change_dir = (int)IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiInputReadMode_RepeatSlow) - (int)IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiInputReadMode_RepeatSlow); + const int focus_change_dir = (int)IsKeyPressed(ImGuiKey_GamepadL1) - (int)IsKeyPressed(ImGuiKey_GamepadR1); if (focus_change_dir != 0) { NavUpdateWindowingHighlightWindow(focus_change_dir); @@ -9932,7 +12121,7 @@ static void ImGui::NavUpdateWindowing() } // Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered top-most) - if (!IsNavInputDown(ImGuiNavInput_Menu)) + if (!IsKeyDown(ImGuiKey_NavGamepadMenu)) { g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore. if (g.NavWindowingToggleLayer && g.NavWindow) @@ -9947,17 +12136,19 @@ static void ImGui::NavUpdateWindowing() if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Keyboard) { // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise + ImGuiKeyChord shared_mods = ((g.ConfigNavWindowingKeyNext ? g.ConfigNavWindowingKeyNext : ImGuiMod_Mask_) & (g.ConfigNavWindowingKeyPrev ? g.ConfigNavWindowingKeyPrev : ImGuiMod_Mask_)) & ImGuiMod_Mask_; + IM_ASSERT(shared_mods != 0); // Next/Prev shortcut currently needs a shared modifier to "hold", otherwise Prev actions would keep cycling between two windows. g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f - if (IsKeyPressedMap(ImGuiKey_Tab, true)) - NavUpdateWindowingHighlightWindow(io.KeyShift ? +1 : -1); - if (!io.KeyCtrl) + if (keyboard_next_window || keyboard_prev_window) + NavUpdateWindowingHighlightWindow(keyboard_next_window ? -1 : +1); + else if ((io.KeyMods & shared_mods) != shared_mods) apply_focus_window = g.NavWindowingTarget; } // Keyboard: Press and Release ALT to toggle menu layer // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer. // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway. - if (nav_keyboard_active && io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0) + if (nav_keyboard_active && IsKeyPressed(ImGuiMod_Alt, ImGuiKeyOwner_None)) { g.NavWindowingToggleLayer = true; g.NavInputSource = ImGuiInputSource_Keyboard; @@ -9966,36 +12157,41 @@ static void ImGui::NavUpdateWindowing() { // We cancel toggling nav layer when any text has been typed (generally while holding Alt). (See #370) // We cancel toggling nav layer when other modifiers are pressed. (See #4439) - if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper) + // We cancel toggling nav layer if an owner has claimed the key. + if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper || TestKeyOwner(ImGuiMod_Alt, ImGuiKeyOwner_None) == false) g.NavWindowingToggleLayer = false; // Apply layer toggle on release - // Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false) // Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss. - if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer) + if (IsKeyReleased(ImGuiMod_Alt) && g.NavWindowingToggleLayer) if (g.ActiveId == 0 || g.ActiveIdAllowOverlap) if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev)) apply_toggle_layer = true; - if (!io.KeyAlt) + if (!IsKeyDown(ImGuiMod_Alt)) g.NavWindowingToggleLayer = false; } // Move window if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove)) { - ImVec2 move_delta; + ImVec2 nav_move_dir; if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift) - move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down); + nav_move_dir = GetKeyMagnitude2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow); if (g.NavInputSource == ImGuiInputSource_Gamepad) - move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down); - if (move_delta.x != 0.0f || move_delta.y != 0.0f) + nav_move_dir = GetKeyMagnitude2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown); + if (nav_move_dir.x != 0.0f || nav_move_dir.y != 0.0f) { const float NAV_MOVE_SPEED = 800.0f; - const float move_speed = ImFloor(NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well - ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindow; - SetWindowPos(moving_window, moving_window->Pos + move_delta * move_speed, ImGuiCond_Always); - MarkIniSettingsDirty(moving_window); + const float move_step = NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); + g.NavWindowingAccumDeltaPos += nav_move_dir * move_step; g.NavDisableMouseHover = true; + ImVec2 accum_floored = ImFloor(g.NavWindowingAccumDeltaPos); + if (accum_floored.x != 0.0f || accum_floored.y != 0.0f) + { + ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindow; + SetWindowPos(moving_window, moving_window->Pos + accum_floored, ImGuiCond_Always); + g.NavWindowingAccumDeltaPos -= accum_floored; + } } } @@ -10003,11 +12199,10 @@ static void ImGui::NavUpdateWindowing() if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow)) { ClearActiveID(); - g.NavDisableHighlight = false; - g.NavDisableMouseHover = true; - apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window); + NavRestoreHighlightAfterMove(); ClosePopupsOverWindow(apply_focus_window, false); - FocusWindow(apply_focus_window); + FocusWindow(apply_focus_window, ImGuiFocusRequestFlags_RestoreFocusedChild); + apply_focus_window = g.NavWindow; if (apply_focus_window->NavLastIds[0] == 0) NavInitWindow(apply_focus_window, false); @@ -10051,6 +12246,7 @@ static void ImGui::NavUpdateWindowing() if (new_nav_layer == ImGuiNavLayer_Menu) g.NavWindow->NavLastIds[new_nav_layer] = 0; NavRestoreLayer(new_nav_layer); + NavRestoreHighlightAfterMove(); } } } @@ -10059,10 +12255,10 @@ static void ImGui::NavUpdateWindowing() static const char* GetFallbackWindowNameForWindowingList(ImGuiWindow* window) { if (window->Flags & ImGuiWindowFlags_Popup) - return "(Popup)"; + return ImGui::LocalizeGetMsg(ImGuiLocKey_WindowingPopup); if ((window->Flags & ImGuiWindowFlags_MenuBar) && strcmp(window->Name, "##MainMenuBar") == 0) - return "(Main menu bar)"; - return "(Untitled)"; + return ImGui::LocalizeGetMsg(ImGuiLocKey_WindowingMainMenuBar); + return ImGui::LocalizeGetMsg(ImGuiLocKey_WindowingUntitled); } // Overlay displayed when using CTRL+TAB. Called by EndFrame(). @@ -10101,6 +12297,12 @@ void ImGui::NavUpdateWindowingOverlay() // [SECTION] DRAG AND DROP //----------------------------------------------------------------------------- +bool ImGui::IsDragDropActive() +{ + ImGuiContext& g = *GImGui; + return g.DragDropActive; +} + void ImGui::ClearDragDrop() { ImGuiContext& g = *GImGui; @@ -10157,20 +12359,21 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) return false; // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: - // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride. + // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag. if (!(flags & ImGuiDragDropFlags_SourceAllowNullID)) { IM_ASSERT(0); return false; } - // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image() + // Magic fallback to handle items with no assigned ID, e.g. Text(), Image() // We build a throwaway ID based on current ID stack + relative AABB of items in window. - // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. + // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING/RESIZINGG OF THE WIDGET, so if your widget moves your dragging operation will be canceled. // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. // Rely on keeping other window->LastItemXXX fields intact. source_id = g.LastItemData.ID = window->GetIDFromRectangle(g.LastItemData.Rect); - bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id); + KeepAliveID(source_id); + bool is_hovered = ItemHoverable(g.LastItemData.Rect, source_id, g.LastItemData.InFlags); if (is_hovered && g.IO.MouseClicked[mouse_button]) { SetActiveID(source_id, window); @@ -10185,7 +12388,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) source_drag_active = IsMouseDragging(mouse_button); // Disable navigation and key inputs while dragging + cancel existing request if any - SetActiveIdUsingNavAndKeys(); + SetActiveIdUsingAllKeyboardKeys(); } else { @@ -10216,13 +12419,12 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) { // Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit) // We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents. - BeginTooltip(); + bool ret = BeginTooltip(); + IM_ASSERT(ret); // FIXME-NEWBEGIN: If this ever becomes false, we need to Begin("##Hidden", NULL, ImGuiWindowFlags_NoSavedSettings) + SetWindowHiddendAndSkipItemsForCurrentFrame(). + IM_UNUSED(ret); + if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip)) - { - ImGuiWindow* tooltip_window = g.CurrentWindow; - tooltip_window->Hidden = tooltip_window->SkipItems = true; - tooltip_window->HiddenFramesCanSkipItems = 1; - } + SetWindowHiddendAndSkipItemsForCurrentFrame(g.CurrentWindow); } if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern)) @@ -10289,6 +12491,7 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s } payload.DataFrameCount = g.FrameCount; + // Return whether the payload has been accepted return (g.DragDropAcceptFrameCount == g.FrameCount) || (g.DragDropAcceptFrameCount == g.FrameCount - 1); } @@ -10316,7 +12519,7 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) } // We don't use BeginDragDropTargetCustom() and duplicate its code because: -// 1) we use LastItemRectHoveredRect which handles items that pushes a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle them. +// 1) we use LastItemRectHoveredRect which handles items that push a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle them. // 2) and it's faster. as this code may be very frequently called, we want to early out as fast as we can. // Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case) bool ImGui::BeginDragDropTarget() @@ -10335,7 +12538,10 @@ bool ImGui::BeginDragDropTarget() const ImRect& display_rect = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? g.LastItemData.DisplayRect : g.LastItemData.Rect; ImGuiID id = g.LastItemData.ID; if (id == 0) + { id = window->GetIDFromRectangle(display_rect); + KeepAliveID(id); + } if (g.DragDropPayload.SourceId == id) return false; @@ -10367,41 +12573,51 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop const bool was_accepted_previously = (g.DragDropAcceptIdPrev == g.DragDropTargetId); ImRect r = g.DragDropTargetRect; float r_surface = r.GetWidth() * r.GetHeight(); - if (r_surface <= g.DragDropAcceptIdCurrRectSurface) - { - g.DragDropAcceptFlags = flags; - g.DragDropAcceptIdCurr = g.DragDropTargetId; - g.DragDropAcceptIdCurrRectSurface = r_surface; - } + if (r_surface > g.DragDropAcceptIdCurrRectSurface) + return NULL; + + g.DragDropAcceptFlags = flags; + g.DragDropAcceptIdCurr = g.DragDropTargetId; + g.DragDropAcceptIdCurrRectSurface = r_surface; + //IMGUI_DEBUG_LOG("AcceptDragDropPayload(): %08X: accept\n", g.DragDropTargetId); // Render default drop visuals - // FIXME-DRAGDROP: Settle on a proper default visuals for drop target. payload.Preview = was_accepted_previously; - flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that lives for 1 frame) + flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that live for 1 frame) if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) window->DrawList->AddRect(r.Min - ImVec2(3.5f,3.5f), r.Max + ImVec2(3.5f, 3.5f), GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); g.DragDropAcceptFrameCount = g.FrameCount; - payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting os window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() + payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting OS window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) return NULL; + //IMGUI_DEBUG_LOG("AcceptDragDropPayload(): %08X: return payload\n", g.DragDropTargetId); return &payload; } +// FIXME-DRAGDROP: Settle on a proper default visuals for drop target. +void ImGui::RenderDragDropTargetRect(const ImRect& bb) +{ + GetWindowDrawList()->AddRect(bb.Min - ImVec2(3.5f, 3.5f), bb.Max + ImVec2(3.5f, 3.5f), GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); +} + const ImGuiPayload* ImGui::GetDragDropPayload() { ImGuiContext& g = *GImGui; - return g.DragDropActive ? &g.DragDropPayload : NULL; + return (g.DragDropActive && g.DragDropPayload.DataFrameCount != -1) ? &g.DragDropPayload : NULL; } -// We don't really use/need this now, but added it for the sake of consistency and because we might need it later. void ImGui::EndDragDropTarget() { ImGuiContext& g = *GImGui; IM_ASSERT(g.DragDropActive); IM_ASSERT(g.DragDropWithinTarget); g.DragDropWithinTarget = false; + + // Clear drag and drop state payload right after delivery + if (g.DragDropPayload.Delivery) + ClearDragDrop(); } //----------------------------------------------------------------------------- @@ -10635,10 +12851,10 @@ void ImGui::LogButtons() #endif const bool log_to_file = Button("Log To File"); SameLine(); const bool log_to_clipboard = Button("Log To Clipboard"); SameLine(); - PushAllowKeyboardFocus(false); + PushTabStop(false); SetNextItemWidth(80.0f); SliderInt("Default Depth", &g.LogDepthToExpandDefault, 0, 9, NULL); - PopAllowKeyboardFocus(); + PopTabStop(); PopID(); // Start logging at the end of the function so that the buttons don't appear in the log @@ -10656,15 +12872,17 @@ void ImGui::LogButtons() //----------------------------------------------------------------------------- // - UpdateSettings() [Internal] // - MarkIniSettingsDirty() [Internal] -// - CreateNewWindowSettings() [Internal] -// - FindWindowSettings() [Internal] -// - FindOrCreateWindowSettings() [Internal] // - FindSettingsHandler() [Internal] // - ClearIniSettings() [Internal] // - LoadIniSettingsFromDisk() // - LoadIniSettingsFromMemory() // - SaveIniSettingsToDisk() // - SaveIniSettingsToMemory() +//----------------------------------------------------------------------------- +// - CreateNewWindowSettings() [Internal] +// - FindWindowSettingsByID() [Internal] +// - FindWindowSettingsByWindow() [Internal] +// - ClearWindowSettings() [Internal] // - WindowSettingsHandler_***() [Internal] //----------------------------------------------------------------------------- @@ -10711,42 +12929,18 @@ void ImGui::MarkIniSettingsDirty(ImGuiWindow* window) g.SettingsDirtyTimer = g.IO.IniSavingRate; } -ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name) +void ImGui::AddSettingsHandler(const ImGuiSettingsHandler* handler) { ImGuiContext& g = *GImGui; - -#if !IMGUI_DEBUG_INI_SETTINGS - // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() - // Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier. - if (const char* p = strstr(name, "###")) - name = p; -#endif - const size_t name_len = strlen(name); - - // Allocate chunk - const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1; - ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size); - IM_PLACEMENT_NEW(settings) ImGuiWindowSettings(); - settings->ID = ImHashStr(name, name_len); - memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator - - return settings; + IM_ASSERT(FindSettingsHandler(handler->TypeName) == NULL); + g.SettingsHandlers.push_back(*handler); } -ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id) +void ImGui::RemoveSettingsHandler(const char* type_name) { ImGuiContext& g = *GImGui; - for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) - if (settings->ID == id) - return settings; - return NULL; -} - -ImGuiWindowSettings* ImGui::FindOrCreateWindowSettings(const char* name) -{ - if (ImGuiWindowSettings* settings = FindWindowSettings(ImHashStr(name))) - return settings; - return CreateNewWindowSettings(name); + if (ImGuiSettingsHandler* handler = FindSettingsHandler(type_name)) + g.SettingsHandlers.erase(handler); } ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name) @@ -10759,6 +12953,7 @@ ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name) return NULL; } +// Clear all settings (windows, tables, docking etc.) void ImGui::ClearIniSettings() { ImGuiContext& g = *GImGui; @@ -10774,11 +12969,13 @@ void ImGui::LoadIniSettingsFromDisk(const char* ini_filename) char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size); if (!file_data) return; - LoadIniSettingsFromMemory(file_data, (size_t)file_data_size); + if (file_data_size > 0) + LoadIniSettingsFromMemory(file_data, (size_t)file_data_size); IM_FREE(file_data); } // Zero-tolerance, no error reporting, cheap .ini parsing +// Set ini_size==0 to let us use strlen(ini_data). Do not call this function with a 0 if your buffer is actually empty! void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size) { ImGuiContext& g = *GImGui; @@ -10882,6 +13079,63 @@ const char* ImGui::SaveIniSettingsToMemory(size_t* out_size) return g.SettingsIniData.c_str(); } +ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name) +{ + ImGuiContext& g = *GImGui; + + if (g.IO.ConfigDebugIniSettings == false) + { + // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() + // Preserve the full string when ConfigDebugVerboseIniSettings is set to make .ini inspection easier. + if (const char* p = strstr(name, "###")) + name = p; + } + const size_t name_len = strlen(name); + + // Allocate chunk + const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1; + ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size); + IM_PLACEMENT_NEW(settings) ImGuiWindowSettings(); + settings->ID = ImHashStr(name, name_len); + memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator + + return settings; +} + +// We don't provide a FindWindowSettingsByName() because Docking system doesn't always hold on names. +// This is called once per window .ini entry + once per newly instantiated window. +ImGuiWindowSettings* ImGui::FindWindowSettingsByID(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) + if (settings->ID == id && !settings->WantDelete) + return settings; + return NULL; +} + +// This is faster if you are holding on a Window already as we don't need to perform a search. +ImGuiWindowSettings* ImGui::FindWindowSettingsByWindow(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (window->SettingsOffset != -1) + return g.SettingsWindows.ptr_from_offset(window->SettingsOffset); + return FindWindowSettingsByID(window->ID); +} + +// This will revert window to its initial state, including enabling the ImGuiCond_FirstUseEver/ImGuiCond_Once conditions once more. +void ImGui::ClearWindowSettings(const char* name) +{ + //IMGUI_DEBUG_LOG("ClearWindowSettings('%s')\n", name); + ImGuiWindow* window = FindWindowByName(name); + if (window != NULL) + { + window->Flags |= ImGuiWindowFlags_NoSavedSettings; + InitOrLoadWindowSettings(window, NULL); + } + if (ImGuiWindowSettings* settings = window ? FindWindowSettingsByWindow(window) : FindWindowSettingsByID(ImHashStr(name))) + settings->WantDelete = true; +} + static void WindowSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*) { ImGuiContext& g = *ctx; @@ -10892,9 +13146,12 @@ static void WindowSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandl static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) { - ImGuiWindowSettings* settings = ImGui::FindOrCreateWindowSettings(name); - ImGuiID id = settings->ID; - *settings = ImGuiWindowSettings(); // Clear existing if recycling previous entry + ImGuiID id = ImHashStr(name); + ImGuiWindowSettings* settings = ImGui::FindWindowSettingsByID(id); + if (settings) + *settings = ImGuiWindowSettings(); // Clear existing if recycling previous entry + else + settings = ImGui::CreateNewWindowSettings(name); settings->ID = id; settings->WantApply = true; return (void*)settings; @@ -10934,7 +13191,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl if (window->Flags & ImGuiWindowFlags_NoSavedSettings) continue; - ImGuiWindowSettings* settings = (window->SettingsOffset != -1) ? g.SettingsWindows.ptr_from_offset(window->SettingsOffset) : ImGui::FindWindowSettings(window->ID); + ImGuiWindowSettings* settings = ImGui::FindWindowSettingsByWindow(window); if (!settings) { settings = ImGui::CreateNewWindowSettings(window->Name); @@ -10945,12 +13202,15 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl settings->Size = ImVec2ih(window->SizeFull); settings->Collapsed = window->Collapsed; + settings->WantDelete = false; } // Write to text buffer buf->reserve(buf->size() + g.SettingsWindows.size() * 6); // ballpark reserve for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) { + if (settings->WantDelete) + continue; const char* settings_name = settings->GetName(); buf->appendf("[%s][%s]\n", handler->TypeName, settings_name); buf->appendf("Pos=%d,%d\n", settings->Pos.x, settings->Pos.y); @@ -10961,10 +13221,23 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl } +//----------------------------------------------------------------------------- +// [SECTION] LOCALIZATION +//----------------------------------------------------------------------------- + +void ImGui::LocalizeRegisterEntries(const ImGuiLocEntry* entries, int count) +{ + ImGuiContext& g = *GImGui; + for (int n = 0; n < count; n++) + g.LocalizationTable[entries[n].Key] = entries[n].Text; +} + + //----------------------------------------------------------------------------- // [SECTION] VIEWPORTS, PLATFORM WINDOWS //----------------------------------------------------------------------------- // - GetMainViewport() +// - SetWindowViewport() [Internal] // - UpdateViewportsNewFrame() [Internal] // (this section is more complete in the 'docking' branch) //----------------------------------------------------------------------------- @@ -10975,6 +13248,11 @@ ImGuiViewport* ImGui::GetMainViewport() return g.Viewports[0]; } +void ImGui::SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport) +{ + window->Viewport = viewport; +} + // Update viewports and monitor infos static void ImGui::UpdateViewportsNewFrame() { @@ -11020,9 +13298,9 @@ static void ImGui::UpdateViewportsNewFrame() // Win32 clipboard implementation // We use g.ClipboardHandlerData for temporary storage to ensure it is freed on Shutdown() -static const char* GetClipboardTextFn_DefaultImpl(void*) +static const char* GetClipboardTextFn_DefaultImpl(void* user_data_ctx) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *(ImGuiContext*)user_data_ctx; g.ClipboardHandlerData.clear(); if (!::OpenClipboard(NULL)) return NULL; @@ -11083,8 +13361,9 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) } } -static const char* GetClipboardTextFn_DefaultImpl(void*) +static const char* GetClipboardTextFn_DefaultImpl(void* user_data_ctx) { + ImGuiContext& g = *(ImGuiContext*)user_data_ctx; if (!main_clipboard) PasteboardCreate(kPasteboardClipboard, &main_clipboard); PasteboardSynchronize(main_clipboard); @@ -11102,7 +13381,6 @@ static const char* GetClipboardTextFn_DefaultImpl(void*) CFDataRef cf_data; if (PasteboardCopyItemFlavorData(main_clipboard, item_id, CFSTR("public.utf8-plain-text"), &cf_data) == noErr) { - ImGuiContext& g = *GImGui; g.ClipboardHandlerData.clear(); int length = (int)CFDataGetLength(cf_data); g.ClipboardHandlerData.resize(length + 1); @@ -11119,15 +13397,15 @@ static const char* GetClipboardTextFn_DefaultImpl(void*) #else // Local Dear ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers. -static const char* GetClipboardTextFn_DefaultImpl(void*) +static const char* GetClipboardTextFn_DefaultImpl(void* user_data_ctx) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *(ImGuiContext*)user_data_ctx; return g.ClipboardHandlerData.empty() ? NULL : g.ClipboardHandlerData.begin(); } -static void SetClipboardTextFn_DefaultImpl(void*, const char* text) +static void SetClipboardTextFn_DefaultImpl(void* user_data_ctx, const char* text) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *(ImGuiContext*)user_data_ctx; g.ClipboardHandlerData.clear(); const char* text_end = text + strlen(text); g.ClipboardHandlerData.resize((int)(text_end - text) + 1); @@ -11145,25 +13423,33 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) #pragma comment(lib, "imm32") #endif -static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y) +static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport, ImGuiPlatformImeData* data) { // Notify OS Input Method Editor of text input position - ImGuiIO& io = ImGui::GetIO(); - if (HWND hwnd = (HWND)io.ImeWindowHandle) - if (HIMC himc = ::ImmGetContext(hwnd)) - { - COMPOSITIONFORM cf; - cf.ptCurrentPos.x = x; - cf.ptCurrentPos.y = y; - cf.dwStyle = CFS_FORCE_POSITION; - ::ImmSetCompositionWindow(himc, &cf); - ::ImmReleaseContext(hwnd, himc); - } + HWND hwnd = (HWND)viewport->PlatformHandleRaw; + if (hwnd == 0) + return; + + //::ImmAssociateContextEx(hwnd, NULL, data->WantVisible ? IACE_DEFAULT : 0); + if (HIMC himc = ::ImmGetContext(hwnd)) + { + COMPOSITIONFORM composition_form = {}; + composition_form.ptCurrentPos.x = (LONG)data->InputPos.x; + composition_form.ptCurrentPos.y = (LONG)data->InputPos.y; + composition_form.dwStyle = CFS_FORCE_POSITION; + ::ImmSetCompositionWindow(himc, &composition_form); + CANDIDATEFORM candidate_form = {}; + candidate_form.dwStyle = CFS_CANDIDATEPOS; + candidate_form.ptCurrentPos.x = (LONG)data->InputPos.x; + candidate_form.ptCurrentPos.y = (LONG)data->InputPos.y; + ::ImmSetCandidateWindow(himc, &candidate_form); + ::ImmReleaseContext(hwnd, himc); + } } #else -static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {} +static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport*, ImGuiPlatformImeData*) {} #endif @@ -11172,20 +13458,25 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {} //----------------------------------------------------------------------------- // - RenderViewportThumbnail() [Internal] // - RenderViewportsThumbnails() [Internal] +// - DebugTextEncoding() // - MetricsHelpMarker() [Internal] +// - ShowFontAtlas() [Internal] // - ShowMetricsWindow() // - DebugNodeColumns() [Internal] // - DebugNodeDrawList() [Internal] // - DebugNodeDrawCmdShowMeshAndBoundingBox() [Internal] +// - DebugNodeFont() [Internal] +// - DebugNodeFontGlyph() [Internal] // - DebugNodeStorage() [Internal] // - DebugNodeTabBar() [Internal] // - DebugNodeViewport() [Internal] // - DebugNodeWindow() [Internal] // - DebugNodeWindowSettings() [Internal] // - DebugNodeWindowsList() [Internal] +// - DebugNodeWindowsListByBeginStackParent() [Internal] //----------------------------------------------------------------------------- -#ifndef IMGUI_DISABLE_METRICS_WINDOW +#ifndef IMGUI_DISABLE_DEBUG_TOOLS void ImGui::DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb) { @@ -11238,13 +13529,97 @@ static void RenderViewportsThumbnails() ImGui::Dummy(bb_full.GetSize() * SCALE); } +// Draw an arbitrary US keyboard layout to visualize translated keys +void ImGui::DebugRenderKeyboardPreview(ImDrawList* draw_list) +{ + const ImVec2 key_size = ImVec2(35.0f, 35.0f); + const float key_rounding = 3.0f; + const ImVec2 key_face_size = ImVec2(25.0f, 25.0f); + const ImVec2 key_face_pos = ImVec2(5.0f, 3.0f); + const float key_face_rounding = 2.0f; + const ImVec2 key_label_pos = ImVec2(7.0f, 4.0f); + const ImVec2 key_step = ImVec2(key_size.x - 1.0f, key_size.y - 1.0f); + const float key_row_offset = 9.0f; + + ImVec2 board_min = GetCursorScreenPos(); + ImVec2 board_max = ImVec2(board_min.x + 3 * key_step.x + 2 * key_row_offset + 10.0f, board_min.y + 3 * key_step.y + 10.0f); + ImVec2 start_pos = ImVec2(board_min.x + 5.0f - key_step.x, board_min.y); + + struct KeyLayoutData { int Row, Col; const char* Label; ImGuiKey Key; }; + const KeyLayoutData keys_to_display[] = + { + { 0, 0, "", ImGuiKey_Tab }, { 0, 1, "Q", ImGuiKey_Q }, { 0, 2, "W", ImGuiKey_W }, { 0, 3, "E", ImGuiKey_E }, { 0, 4, "R", ImGuiKey_R }, + { 1, 0, "", ImGuiKey_CapsLock }, { 1, 1, "A", ImGuiKey_A }, { 1, 2, "S", ImGuiKey_S }, { 1, 3, "D", ImGuiKey_D }, { 1, 4, "F", ImGuiKey_F }, + { 2, 0, "", ImGuiKey_LeftShift },{ 2, 1, "Z", ImGuiKey_Z }, { 2, 2, "X", ImGuiKey_X }, { 2, 3, "C", ImGuiKey_C }, { 2, 4, "V", ImGuiKey_V } + }; + + // Elements rendered manually via ImDrawList API are not clipped automatically. + // While not strictly necessary, here IsItemVisible() is used to avoid rendering these shapes when they are out of view. + Dummy(board_max - board_min); + if (!IsItemVisible()) + return; + draw_list->PushClipRect(board_min, board_max, true); + for (int n = 0; n < IM_ARRAYSIZE(keys_to_display); n++) + { + const KeyLayoutData* key_data = &keys_to_display[n]; + ImVec2 key_min = ImVec2(start_pos.x + key_data->Col * key_step.x + key_data->Row * key_row_offset, start_pos.y + key_data->Row * key_step.y); + ImVec2 key_max = key_min + key_size; + draw_list->AddRectFilled(key_min, key_max, IM_COL32(204, 204, 204, 255), key_rounding); + draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding); + ImVec2 face_min = ImVec2(key_min.x + key_face_pos.x, key_min.y + key_face_pos.y); + ImVec2 face_max = ImVec2(face_min.x + key_face_size.x, face_min.y + key_face_size.y); + draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, ImDrawFlags_None, 2.0f); + draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding); + ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y); + draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label); + if (IsKeyDown(key_data->Key)) + draw_list->AddRectFilled(key_min, key_max, IM_COL32(255, 0, 0, 128), key_rounding); + } + draw_list->PopClipRect(); +} + +// Helper tool to diagnose between text encoding issues and font loading issues. Pass your UTF-8 string and verify that there are correct. +void ImGui::DebugTextEncoding(const char* str) +{ + Text("Text: \"%s\"", str); + if (!BeginTable("##DebugTextEncoding", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable)) + return; + TableSetupColumn("Offset"); + TableSetupColumn("UTF-8"); + TableSetupColumn("Glyph"); + TableSetupColumn("Codepoint"); + TableHeadersRow(); + for (const char* p = str; *p != 0; ) + { + unsigned int c; + const int c_utf8_len = ImTextCharFromUtf8(&c, p, NULL); + TableNextColumn(); + Text("%d", (int)(p - str)); + TableNextColumn(); + for (int byte_index = 0; byte_index < c_utf8_len; byte_index++) + { + if (byte_index > 0) + SameLine(); + Text("0x%02X", (int)(unsigned char)p[byte_index]); + } + TableNextColumn(); + if (GetFont()->FindGlyphNoFallback((ImWchar)c)) + TextUnformatted(p, p + c_utf8_len); + else + TextUnformatted((c == IM_UNICODE_CODEPOINT_INVALID) ? "[invalid]" : "[missing]"); + TableNextColumn(); + Text("U+%04X", (int)c); + p += c_utf8_len; + } + EndTable(); +} + // Avoid naming collision with imgui_demo.cpp's HelpMarker() for unity builds. static void MetricsHelpMarker(const char* desc) { ImGui::TextDisabled("(?)"); - if (ImGui::IsItemHovered()) + if (ImGui::BeginItemTooltip()) { - ImGui::BeginTooltip(); ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); ImGui::TextUnformatted(desc); ImGui::PopTextWrapPos(); @@ -11252,15 +13627,35 @@ static void MetricsHelpMarker(const char* desc) } } -#ifndef IMGUI_DISABLE_DEMO_WINDOWS -namespace ImGui { void ShowFontAtlas(ImFontAtlas* atlas); } -#endif +// [DEBUG] List fonts in a font atlas and display its texture +void ImGui::ShowFontAtlas(ImFontAtlas* atlas) +{ + for (int i = 0; i < atlas->Fonts.Size; i++) + { + ImFont* font = atlas->Fonts[i]; + PushID(font); + DebugNodeFont(font); + PopID(); + } + if (TreeNode("Font Atlas", "Font Atlas (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) + { + ImGuiContext& g = *GImGui; + ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; + Checkbox("Tint with Text Color", &cfg->ShowAtlasTintedWithTextColor); // Using text color ensure visibility of core atlas data, but will alter custom colored icons + ImVec4 tint_col = cfg->ShowAtlasTintedWithTextColor ? GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); + ImVec4 border_col = GetStyleColorVec4(ImGuiCol_Border); + Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), tint_col, border_col); + TreePop(); + } +} void ImGui::ShowMetricsWindow(bool* p_open) { ImGuiContext& g = *GImGui; ImGuiIO& io = g.IO; ImGuiMetricsConfig* cfg = &g.DebugMetricsConfig; + if (cfg->ShowDebugLog) + ShowDebugLogWindow(&cfg->ShowDebugLog); if (cfg->ShowStackTool) ShowStackToolWindow(&cfg->ShowStackTool); @@ -11293,19 +13688,20 @@ void ImGui::ShowMetricsWindow(bool* p_open) { static ImRect GetTableRect(ImGuiTable* table, int rect_type, int n) { + ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); // Always using last submitted instance if (rect_type == TRT_OuterRect) { return table->OuterRect; } else if (rect_type == TRT_InnerRect) { return table->InnerRect; } else if (rect_type == TRT_WorkRect) { return table->WorkRect; } else if (rect_type == TRT_HostClipRect) { return table->HostClipRect; } else if (rect_type == TRT_InnerClipRect) { return table->InnerClipRect; } else if (rect_type == TRT_BackgroundClipRect) { return table->BgClipRect; } - else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table->LastOuterHeight); } + else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table_instance->LastOuterHeight); } else if (rect_type == TRT_ColumnsWorkRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->WorkRect.Min.y, c->WorkMaxX, table->WorkRect.Max.y); } else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; } - else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } // Note: y1/y2 not always accurate - else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } - else if (rect_type == TRT_ColumnsContentFrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXFrozen, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } - else if (rect_type == TRT_ColumnsContentUnfrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y + table->LastFirstRowHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); } + else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); } // Note: y1/y2 not always accurate + else if (rect_type == TRT_ColumnsContentHeadersIdeal){ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersIdeal, table->InnerClipRect.Min.y + table_instance->LastFirstRowHeight); } + else if (rect_type == TRT_ColumnsContentFrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y, c->ContentMaxXFrozen, table->InnerClipRect.Min.y + table_instance->LastFrozenHeight); } + else if (rect_type == TRT_ColumnsContentUnfrozen) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->WorkMinX, table->InnerClipRect.Min.y + table_instance->LastFrozenHeight, c->ContentMaxXUnfrozen, table->InnerClipRect.Max.y); } IM_ASSERT(0); return ImRect(); } @@ -11317,7 +13713,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) else if (rect_type == WRT_InnerRect) { return window->InnerRect; } else if (rect_type == WRT_InnerClipRect) { return window->InnerClipRect; } else if (rect_type == WRT_WorkRect) { return window->WorkRect; } - else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); } + else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); } else if (rect_type == WRT_ContentIdeal) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSizeIdeal); } else if (rect_type == WRT_ContentRegionRect) { return window->ContentRegionRect; } IM_ASSERT(0); @@ -11328,8 +13724,32 @@ void ImGui::ShowMetricsWindow(bool* p_open) // Tools if (TreeNode("Tools")) { + bool show_encoding_viewer = TreeNode("UTF-8 Encoding viewer"); + SameLine(); + MetricsHelpMarker("You can also call ImGui::DebugTextEncoding() from your code with a given string to test that your UTF-8 encoding settings are correct."); + if (show_encoding_viewer) + { + static char buf[100] = ""; + SetNextItemWidth(-FLT_MIN); + InputText("##Text", buf, IM_ARRAYSIZE(buf)); + if (buf[0] != 0) + DebugTextEncoding(buf); + TreePop(); + } + + // The Item Picker tool is super useful to visually select an item and break into the call-stack of where it was submitted. + if (Checkbox("Show Item Picker", &g.DebugItemPickerActive) && g.DebugItemPickerActive) + DebugStartItemPicker(); + SameLine(); + MetricsHelpMarker("Will call the IM_DEBUG_BREAK() macro to break in debugger.\nWarning: If you don't have a debugger attached, this will probably crash."); + // Stack Tool is your best friend! - Checkbox("Show stack tool", &cfg->ShowStackTool); + Checkbox("Show Debug Log", &cfg->ShowDebugLog); + SameLine(); + MetricsHelpMarker("You can also call ImGui::ShowDebugLogWindow() from your code."); + + // Stack Tool is your best friend! + Checkbox("Show Stack Tool", &cfg->ShowStackTool); SameLine(); MetricsHelpMarker("You can also call ImGui::ShowStackToolWindow() from your code."); @@ -11395,18 +13815,35 @@ void ImGui::ShowMetricsWindow(bool* p_open) } } - // The Item Picker tool is super useful to visually select an item and break into the call-stack of where it was submitted. - if (Button("Item Picker..")) - DebugStartItemPicker(); + Checkbox("Debug Begin/BeginChild return value", &io.ConfigDebugBeginReturnValueLoop); SameLine(); - MetricsHelpMarker("Will call the IM_DEBUG_BREAK() macro to break in debugger.\nWarning: If you don't have a debugger attached, this will probably crash."); + MetricsHelpMarker("Some calls to Begin()/BeginChild() will return false.\n\nWill cycle through window depths then repeat. Windows should be flickering while running."); TreePop(); } // Windows - DebugNodeWindowsList(&g.Windows, "Windows"); - //DebugNodeWindowsList(&g.WindowsFocusOrder, "WindowsFocusOrder"); + if (TreeNode("Windows", "Windows (%d)", g.Windows.Size)) + { + //SetNextItemOpen(true, ImGuiCond_Once); + DebugNodeWindowsList(&g.Windows, "By display order"); + DebugNodeWindowsList(&g.WindowsFocusOrder, "By focus order (root windows)"); + if (TreeNode("By submission order (begin stack)")) + { + // Here we display windows in their submitted order/hierarchy, however note that the Begin stack doesn't constitute a Parent<>Child relationship! + ImVector& temp_buffer = g.WindowsTempSortBuffer; + temp_buffer.resize(0); + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i]->LastFrameActive + 1 >= g.FrameCount) + temp_buffer.push_back(g.Windows[i]); + struct Func { static int IMGUI_CDECL WindowComparerByBeginOrder(const void* lhs, const void* rhs) { return ((int)(*(const ImGuiWindow* const *)lhs)->BeginOrderWithinContext - (*(const ImGuiWindow* const*)rhs)->BeginOrderWithinContext); } }; + ImQsort(temp_buffer.Data, (size_t)temp_buffer.Size, sizeof(ImGuiWindow*), Func::WindowComparerByBeginOrder); + DebugNodeWindowsListByBeginStackParent(temp_buffer.Data, temp_buffer.Size, NULL); + TreePop(); + } + + TreePop(); + } // DrawLists int drawlist_count = 0; @@ -11442,8 +13879,12 @@ void ImGui::ShowMetricsWindow(bool* p_open) { for (int i = 0; i < g.OpenPopupStack.Size; i++) { - ImGuiWindow* window = g.OpenPopupStack[i].Window; - BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); + // As it's difficult to interact with tree nodes while popups are open, we display everything inline. + const ImGuiPopupData* popup_data = &g.OpenPopupStack[i]; + ImGuiWindow* window = popup_data->Window; + BulletText("PopupID: %08x, Window: '%s' (%s%s), BackupNavWindow '%s', ParentWindow '%s'", + popup_data->PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? "Child;" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? "Menu;" : "", + popup_data->BackupNavWindow ? popup_data->BackupNavWindow->Name : "NULL", window && window->ParentWindow ? window->ParentWindow->Name : "NULL"); } TreePop(); } @@ -11471,14 +13912,19 @@ void ImGui::ShowMetricsWindow(bool* p_open) } // Details for Fonts -#ifndef IMGUI_DISABLE_DEMO_WINDOWS ImFontAtlas* atlas = g.IO.Fonts; if (TreeNode("Fonts", "Fonts (%d)", atlas->Fonts.Size)) { ShowFontAtlas(atlas); TreePop(); } -#endif + + // Details for InputText + if (TreeNode("InputText")) + { + DebugNodeInputTextState(&g.InputTextState); + TreePop(); + } // Details for Docking #ifdef IMGUI_HAS_DOCK @@ -11504,11 +13950,12 @@ void ImGui::ShowMetricsWindow(bool* p_open) Text("\"%s\"", g.IO.IniFilename); else TextUnformatted(""); + Checkbox("io.ConfigDebugIniSettings", &io.ConfigDebugIniSettings); Text("SettingsDirtyTimer %.2f", g.SettingsDirtyTimer); if (TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size)) { for (int n = 0; n < g.SettingsHandlers.Size; n++) - BulletText("%s", g.SettingsHandlers[n].TypeName); + BulletText("\"%s\"", g.SettingsHandlers[n].TypeName); TreePop(); } if (TreeNode("SettingsWindows", "Settings packed data: Windows: %d bytes", g.SettingsWindows.size())) @@ -11536,11 +13983,102 @@ void ImGui::ShowMetricsWindow(bool* p_open) TreePop(); } - // Misc Details + if (TreeNode("Inputs")) + { + Text("KEYBOARD/GAMEPAD/MOUSE KEYS"); + { + // We iterate both legacy native range and named ImGuiKey ranges, which is a little odd but this allows displaying the data for old/new backends. + // User code should never have to go through such hoops! You can generally iterate between ImGuiKey_NamedKey_BEGIN and ImGuiKey_NamedKey_END. + Indent(); +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } }; +#else + struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array + //Text("Legacy raw:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key++) { if (io.KeysDown[key]) { SameLine(); Text("\"%s\" %d", GetKeyName(key), key); } } +#endif + Text("Keys down:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !IsKeyDown(key)) continue; SameLine(); Text(IsNamedKey(key) ? "\"%s\"" : "\"%s\" %d", GetKeyName(key), key); SameLine(); Text("(%.02f)", GetKeyData(key)->DownDuration); } + Text("Keys pressed:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !IsKeyPressed(key)) continue; SameLine(); Text(IsNamedKey(key) ? "\"%s\"" : "\"%s\" %d", GetKeyName(key), key); } + Text("Keys released:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !IsKeyReleased(key)) continue; SameLine(); Text(IsNamedKey(key) ? "\"%s\"" : "\"%s\" %d", GetKeyName(key), key); } + Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); + Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; SameLine(); Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public. + DebugRenderKeyboardPreview(GetWindowDrawList()); + Unindent(); + } + + Text("MOUSE STATE"); + { + Indent(); + if (IsMousePosValid()) + Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); + else + Text("Mouse pos: "); + Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y); + int count = IM_ARRAYSIZE(io.MouseDown); + Text("Mouse down:"); for (int i = 0; i < count; i++) if (IsMouseDown(i)) { SameLine(); Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } + Text("Mouse clicked:"); for (int i = 0; i < count; i++) if (IsMouseClicked(i)) { SameLine(); Text("b%d (%d)", i, io.MouseClickedCount[i]); } + Text("Mouse released:"); for (int i = 0; i < count; i++) if (IsMouseReleased(i)) { SameLine(); Text("b%d", i); } + Text("Mouse wheel: %.1f", io.MouseWheel); + Text("MouseStationaryTimer: %.2f", g.MouseStationaryTimer); + Text("Mouse source: %s", GetMouseSourceName(io.MouseSource)); + Text("Pen Pressure: %.1f", io.PenPressure); // Note: currently unused + Unindent(); + } + + Text("MOUSE WHEELING"); + { + Indent(); + Text("WheelingWindow: '%s'", g.WheelingWindow ? g.WheelingWindow->Name : "NULL"); + Text("WheelingWindowReleaseTimer: %.2f", g.WheelingWindowReleaseTimer); + Text("WheelingAxisAvg[] = { %.3f, %.3f }, Main Axis: %s", g.WheelingAxisAvg.x, g.WheelingAxisAvg.y, (g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? "X" : (g.WheelingAxisAvg.x < g.WheelingAxisAvg.y) ? "Y" : ""); + Unindent(); + } + + Text("KEY OWNERS"); + { + Indent(); + if (BeginListBox("##owners", ImVec2(-FLT_MIN, GetTextLineHeightWithSpacing() * 6))) + { + for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) + { + ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); + if (owner_data->OwnerCurr == ImGuiKeyOwner_None) + continue; + Text("%s: 0x%08X%s", GetKeyName(key), owner_data->OwnerCurr, + owner_data->LockUntilRelease ? " LockUntilRelease" : owner_data->LockThisFrame ? " LockThisFrame" : ""); + DebugLocateItemOnHover(owner_data->OwnerCurr); + } + EndListBox(); + } + Unindent(); + } + Text("SHORTCUT ROUTING"); + { + Indent(); + if (BeginListBox("##routes", ImVec2(-FLT_MIN, GetTextLineHeightWithSpacing() * 6))) + { + for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) + { + ImGuiKeyRoutingTable* rt = &g.KeysRoutingTable; + for (ImGuiKeyRoutingIndex idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; idx != -1; ) + { + char key_chord_name[64]; + ImGuiKeyRoutingData* routing_data = &rt->Entries[idx]; + GetKeyChordName(key | routing_data->Mods, key_chord_name, IM_ARRAYSIZE(key_chord_name)); + Text("%s: 0x%08X", key_chord_name, routing_data->RoutingCurr); + DebugLocateItemOnHover(routing_data->RoutingCurr); + idx = routing_data->NextEntryIndex; + } + } + EndListBox(); + } + Text("(ActiveIdUsing: AllKeyboardKeys: %d, NavDirMask: 0x%X)", g.ActiveIdUsingAllKeyboardKeys, g.ActiveIdUsingNavDirMask); + Unindent(); + } + TreePop(); + } + if (TreeNode("Internal state")) { - const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Nav", "Clipboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT); - Text("WINDOWING"); Indent(); Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); @@ -11551,20 +14089,24 @@ void ImGui::ShowMetricsWindow(bool* p_open) Text("ITEMS"); Indent(); - Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]); + Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, GetInputSourceName(g.ActiveIdSource)); + DebugLocateItemOnHover(g.ActiveId); Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); - Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %llX", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, g.ActiveIdUsingKeyInputMask); + Text("ActiveIdUsing: AllKeyboardKeys: %d, NavDirMask: %X", g.ActiveIdUsingAllKeyboardKeys, g.ActiveIdUsingNavDirMask); Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame + Text("HoverItemDelayId: 0x%08X, Timer: %.2f, ClearTimer: %.2f", g.HoverItemDelayId, g.HoverItemDelayTimer, g.HoverItemDelayClearTimer); Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize); + DebugLocateItemOnHover(g.DragDropPayload.SourceId); Unindent(); Text("NAV,FOCUS"); Indent(); Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); - Text("NavInputSource: %s", input_source_names[g.NavInputSource]); + DebugLocateItemOnHover(g.NavId); + Text("NavInputSource: %s", GetInputSourceName(g.NavInputSource)); Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); - Text("NavActivateId/DownId/PressedId/InputId: %08X/%08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId, g.NavActivateInputId); + Text("NavActivateId/DownId/PressedId: %08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId); Text("NavActivateFlags: %04X", g.NavActivateFlags); Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId); @@ -11636,25 +14178,6 @@ void ImGui::ShowMetricsWindow(bool* p_open) End(); } -// [DEBUG] List fonts in a font atlas and display its texture -void ImGui::ShowFontAtlas(ImFontAtlas* atlas) -{ - for (int i = 0; i < atlas->Fonts.Size; i++) - { - ImFont* font = atlas->Fonts[i]; - PushID(font); - DebugNodeFont(font); - PopID(); - } - if (TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) - { - ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); - ImVec4 border_col = ImVec4(1.0f, 1.0f, 1.0f, 0.5f); - Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), tint_col, border_col); - TreePop(); - } -} - // [DEBUG] Display contents of Columns void ImGui::DebugNodeColumns(ImGuiOldColumns* columns) { @@ -11685,7 +14208,7 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, const ImDrawList* draw_list, } ImDrawList* fg_draw_list = GetForegroundDrawList(window); // Render additional visuals into the top-most draw list - if (window && IsItemHovered()) + if (window && IsItemHovered() && fg_draw_list) fg_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); if (!node_open) return; @@ -11864,17 +14387,12 @@ void ImGui::DebugNodeFont(ImFont* font) ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size); const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n)); draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50)); - if (glyph) - font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n)); - if (glyph && IsMouseHoveringRect(cell_p1, cell_p2)) + if (!glyph) + continue; + font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n)); + if (IsMouseHoveringRect(cell_p1, cell_p2) && BeginTooltip()) { - BeginTooltip(); - Text("Codepoint: U+%04X", base + n); - Separator(); - Text("Visible: %d", glyph->Visible); - Text("AdvanceX: %.1f", glyph->AdvanceX); - Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); - Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); + DebugNodeFontGlyph(font, glyph); EndTooltip(); } } @@ -11886,6 +14404,16 @@ void ImGui::DebugNodeFont(ImFont* font) TreePop(); } +void ImGui::DebugNodeFontGlyph(ImFont*, const ImFontGlyph* glyph) +{ + Text("Codepoint: U+%04X", glyph->Codepoint); + Separator(); + Text("Visible: %d", glyph->Visible); + Text("AdvanceX: %.1f", glyph->AdvanceX); + Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); + Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); +} + // [DEBUG] Display contents of ImGuiStorage void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label) { @@ -11907,13 +14435,11 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label) char* p = buf; const char* buf_end = buf + IM_ARRAYSIZE(buf); const bool is_active = (tab_bar->PrevFrameVisible >= GetFrameCount() - 2); - p += ImFormatString(p, buf_end - p, "%s 0x%08X (%d tabs)%s", label, tab_bar->ID, tab_bar->Tabs.Size, is_active ? "" : " *Inactive*"); - p += ImFormatString(p, buf_end - p, " { "); + p += ImFormatString(p, buf_end - p, "%s 0x%08X (%d tabs)%s {", label, tab_bar->ID, tab_bar->Tabs.Size, is_active ? "" : " *Inactive*"); for (int tab_n = 0; tab_n < ImMin(tab_bar->Tabs.Size, 3); tab_n++) { ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; - p += ImFormatString(p, buf_end - p, "%s'%s'", - tab_n > 0 ? ", " : "", (tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "???"); + p += ImFormatString(p, buf_end - p, "%s'%s'", tab_n > 0 ? ", " : "", TabBarGetTabName(tab_bar, tab)); } p += ImFormatString(p, buf_end - p, (tab_bar->Tabs.Size > 3) ? " ... }" : " } "); if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } @@ -11930,12 +14456,12 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label) { for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) { - const ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; + ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; PushID(tab); if (SmallButton("<")) { TabBarQueueReorder(tab_bar, tab, -1); } SameLine(0, 2); if (SmallButton(">")) { TabBarQueueReorder(tab_bar, tab, +1); } SameLine(); - Text("%02d%c Tab 0x%08X '%s' Offset: %.1f, Width: %.1f/%.1f", - tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, (tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "???", tab->Offset, tab->Width, tab->ContentWidth); + Text("%02d%c Tab 0x%08X '%s' Offset: %.2f, Width: %.2f/%.2f", + tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, TabBarGetTabName(tab_bar, tab), tab->Offset, tab->Width, tab->ContentWidth); PopID(); } TreePop(); @@ -11998,14 +14524,14 @@ void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label) { ImRect r = window->NavRectRel[layer]; if (r.Min.x >= r.Max.y && r.Min.y >= r.Max.y) - { BulletText("NavLastIds[%d]: 0x%08X", layer, window->NavLastIds[layer]); - continue; - } - BulletText("NavLastIds[%d]: 0x%08X at +(%.1f,%.1f)(%.1f,%.1f)", layer, window->NavLastIds[layer], r.Min.x, r.Min.y, r.Max.x, r.Max.y); - if (IsItemHovered()) - GetForegroundDrawList(window)->AddRect(r.Min + window->Pos, r.Max + window->Pos, IM_COL32(255, 255, 0, 255)); + else + BulletText("NavLastIds[%d]: 0x%08X at +(%.1f,%.1f)(%.1f,%.1f)", layer, window->NavLastIds[layer], r.Min.x, r.Min.y, r.Max.x, r.Max.y); + DebugLocateItemOnHover(window->NavLastIds[layer]); } + const ImVec2* pr = window->NavPreferredScoringPosRel; + for (int layer = 0; layer < ImGuiNavLayer_COUNT; layer++) + BulletText("NavPreferredScoringPosRel[%d] = {%.1f,%.1f)", layer, (pr[layer].x == FLT_MAX ? -99999.0f : pr[layer].x), (pr[layer].y == FLT_MAX ? -99999.0f : pr[layer].y)); // Display as 99999.0f so it looks neater. BulletText("NavLayersActiveMask: %X, NavLastChildNavWindow: %s", window->DC.NavLayersActiveMask, window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); if (window->RootWindow != window) { DebugNodeWindow(window->RootWindow, "RootWindow"); } if (window->ParentWindow != NULL) { DebugNodeWindow(window->ParentWindow, "ParentWindow"); } @@ -12022,15 +14548,18 @@ void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label) void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings* settings) { + if (settings->WantDelete) + BeginDisabled(); Text("0x%08X \"%s\" Pos (%d,%d) Size (%d,%d) Collapsed=%d", settings->ID, settings->GetName(), settings->Pos.x, settings->Pos.y, settings->Size.x, settings->Size.y, settings->Collapsed); + if (settings->WantDelete) + EndDisabled(); } void ImGui::DebugNodeWindowsList(ImVector* windows, const char* label) { if (!TreeNode(label, "%s (%d)", label, windows->Size)) return; - Text("(In front-to-back order:)"); for (int i = windows->Size - 1; i >= 0; i--) // Iterate front to back { PushID((*windows)[i]); @@ -12040,10 +14569,143 @@ void ImGui::DebugNodeWindowsList(ImVector* windows, const char* la TreePop(); } +// FIXME-OPT: This is technically suboptimal, but it is simpler this way. +void ImGui::DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int windows_size, ImGuiWindow* parent_in_begin_stack) +{ + for (int i = 0; i < windows_size; i++) + { + ImGuiWindow* window = windows[i]; + if (window->ParentWindowInBeginStack != parent_in_begin_stack) + continue; + char buf[20]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "[%04d] Window", window->BeginOrderWithinContext); + //BulletText("[%04d] Window '%s'", window->BeginOrderWithinContext, window->Name); + DebugNodeWindow(window, buf); + Indent(); + DebugNodeWindowsListByBeginStackParent(windows + i + 1, windows_size - i - 1, window); + Unindent(); + } +} + +//----------------------------------------------------------------------------- +// [SECTION] DEBUG LOG WINDOW +//----------------------------------------------------------------------------- + +void ImGui::DebugLog(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + DebugLogV(fmt, args); + va_end(args); +} + +void ImGui::DebugLogV(const char* fmt, va_list args) +{ + ImGuiContext& g = *GImGui; + const int old_size = g.DebugLogBuf.size(); + g.DebugLogBuf.appendf("[%05d] ", g.FrameCount); + g.DebugLogBuf.appendfv(fmt, args); + if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTTY) + IMGUI_DEBUG_PRINTF("%s", g.DebugLogBuf.begin() + old_size); + g.DebugLogIndex.append(g.DebugLogBuf.c_str(), old_size, g.DebugLogBuf.size()); +} + +void ImGui::ShowDebugLogWindow(bool* p_open) +{ + ImGuiContext& g = *GImGui; + if (!(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize)) + SetNextWindowSize(ImVec2(0.0f, GetFontSize() * 12.0f), ImGuiCond_FirstUseEver); + if (!Begin("Dear ImGui Debug Log", p_open) || GetCurrentWindow()->BeginCount > 1) + { + End(); + return; + } + + CheckboxFlags("All", &g.DebugLogFlags, ImGuiDebugLogFlags_EventMask_); + SameLine(); CheckboxFlags("ActiveId", &g.DebugLogFlags, ImGuiDebugLogFlags_EventActiveId); + SameLine(); CheckboxFlags("Focus", &g.DebugLogFlags, ImGuiDebugLogFlags_EventFocus); + SameLine(); CheckboxFlags("Popup", &g.DebugLogFlags, ImGuiDebugLogFlags_EventPopup); + SameLine(); CheckboxFlags("Nav", &g.DebugLogFlags, ImGuiDebugLogFlags_EventNav); + SameLine(); if (CheckboxFlags("Clipper", &g.DebugLogFlags, ImGuiDebugLogFlags_EventClipper)) { g.DebugLogClipperAutoDisableFrames = 2; } if (IsItemHovered()) SetTooltip("Clipper log auto-disabled after 2 frames"); + //SameLine(); CheckboxFlags("Selection", &g.DebugLogFlags, ImGuiDebugLogFlags_EventSelection); + SameLine(); CheckboxFlags("IO", &g.DebugLogFlags, ImGuiDebugLogFlags_EventIO); + + if (SmallButton("Clear")) + { + g.DebugLogBuf.clear(); + g.DebugLogIndex.clear(); + } + SameLine(); + if (SmallButton("Copy")) + SetClipboardText(g.DebugLogBuf.c_str()); + BeginChild("##log", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar); + + ImGuiListClipper clipper; + clipper.Begin(g.DebugLogIndex.size()); + while (clipper.Step()) + for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++) + { + const char* line_begin = g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no); + const char* line_end = g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no); + TextUnformatted(line_begin, line_end); + ImRect text_rect = g.LastItemData.Rect; + if (IsItemHovered()) + for (const char* p = line_begin; p <= line_end - 10; p++) + { + ImGuiID id = 0; + if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1) + continue; + ImVec2 p0 = CalcTextSize(line_begin, p); + ImVec2 p1 = CalcTextSize(p, p + 10); + g.LastItemData.Rect = ImRect(text_rect.Min + ImVec2(p0.x, 0.0f), text_rect.Min + ImVec2(p0.x + p1.x, p1.y)); + if (IsMouseHoveringRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, true)) + DebugLocateItemOnHover(id); + p += 10; + } + } + if (GetScrollY() >= GetScrollMaxY()) + SetScrollHereY(1.0f); + EndChild(); + + End(); +} + //----------------------------------------------------------------------------- // [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, STACK TOOL) //----------------------------------------------------------------------------- +static const ImU32 DEBUG_LOCATE_ITEM_COLOR = IM_COL32(0, 255, 0, 255); // Green + +void ImGui::DebugLocateItem(ImGuiID target_id) +{ + ImGuiContext& g = *GImGui; + g.DebugLocateId = target_id; + g.DebugLocateFrames = 2; +} + +void ImGui::DebugLocateItemOnHover(ImGuiID target_id) +{ + if (target_id == 0 || !IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + return; + ImGuiContext& g = *GImGui; + DebugLocateItem(target_id); + GetForegroundDrawList(g.CurrentWindow)->AddRect(g.LastItemData.Rect.Min - ImVec2(3.0f, 3.0f), g.LastItemData.Rect.Max + ImVec2(3.0f, 3.0f), DEBUG_LOCATE_ITEM_COLOR); +} + +void ImGui::DebugLocateItemResolveWithLastItem() +{ + ImGuiContext& g = *GImGui; + ImGuiLastItemData item_data = g.LastItemData; + g.DebugLocateId = 0; + ImDrawList* draw_list = GetForegroundDrawList(g.CurrentWindow); + ImRect r = item_data.Rect; + r.Expand(3.0f); + ImVec2 p1 = g.IO.MousePos; + ImVec2 p2 = ImVec2((p1.x < r.Min.x) ? r.Min.x : (p1.x > r.Max.x) ? r.Max.x : p1.x, (p1.y < r.Min.y) ? r.Min.y : (p1.y > r.Max.y) ? r.Max.y : p1.y); + draw_list->AddRect(r.Min, r.Max, DEBUG_LOCATE_ITEM_COLOR); + draw_list->AddLine(p1, p2, DEBUG_LOCATE_ITEM_COLOR); +} + // [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack. void ImGui::UpdateDebugToolItemPicker() { @@ -12054,18 +14716,27 @@ void ImGui::UpdateDebugToolItemPicker() const ImGuiID hovered_id = g.HoveredIdPreviousFrame; SetMouseCursor(ImGuiMouseCursor_Hand); - if (IsKeyPressedMap(ImGuiKey_Escape)) + if (IsKeyPressed(ImGuiKey_Escape)) g.DebugItemPickerActive = false; - if (IsMouseClicked(0) && hovered_id) + const bool change_mapping = g.IO.KeyMods == (ImGuiMod_Ctrl | ImGuiMod_Shift); + if (!change_mapping && IsMouseClicked(g.DebugItemPickerMouseButton) && hovered_id) { g.DebugItemPickerBreakId = hovered_id; g.DebugItemPickerActive = false; } - SetNextWindowBgAlpha(0.60f); - BeginTooltip(); + for (int mouse_button = 0; mouse_button < 3; mouse_button++) + if (change_mapping && IsMouseClicked(mouse_button)) + g.DebugItemPickerMouseButton = (ImU8)mouse_button; + SetNextWindowBgAlpha(0.70f); + if (!BeginTooltip()) + return; Text("HoveredId: 0x%08X", hovered_id); Text("Press ESC to abort picking."); - TextColored(GetStyleColorVec4(hovered_id ? ImGuiCol_Text : ImGuiCol_TextDisabled), "Click to break in debugger!"); + const char* mouse_button_names[] = { "Left", "Right", "Middle" }; + if (change_mapping) + Text("Remap w/ Ctrl+Shift: click anywhere to select new mouse button."); + else + TextColored(GetStyleColorVec4(hovered_id ? ImGuiCol_Text : ImGuiCol_TextDisabled), "Click %s Button to break in debugger! (remap w/ Ctrl+Shift)", mouse_button_names[g.DebugItemPickerMouseButton]); EndTooltip(); } @@ -12082,7 +14753,7 @@ void ImGui::UpdateDebugToolStackQueries() // Update queries. The steps are: -1: query Stack, >= 0: query each stack item // We can only perform 1 ID Info query every frame. This is designed so the GetID() tests are cheap and constant-time - const ImGuiID query_id = g.ActiveId ? g.ActiveId : g.HoveredIdPreviousFrame; + const ImGuiID query_id = g.HoveredIdPreviousFrame ? g.HoveredIdPreviousFrame : g.ActiveId; if (tool->QueryId != query_id) { tool->QueryId = query_id; @@ -12117,7 +14788,7 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat ImGuiStackTool* tool = &g.DebugStackTool; // Step 0: stack query - // This assume that the ID was computed with the current ID stack, which tends to be the case for our widget. + // This assumes that the ID was computed with the current ID stack, which tends to be the case for our widget. if (tool->StackLevel == -1) { tool->StackLevel++; @@ -12134,32 +14805,52 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat ImGuiStackLevelInfo* info = &tool->Results[tool->StackLevel]; IM_ASSERT(info->ID == id && info->QueryFrameCount > 0); - int data_len; switch (data_type) { case ImGuiDataType_S32: ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id); break; case ImGuiDataType_String: - data_len = data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id); - ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "\"%.*s\"", data_len, (const char*)data_id); + ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id), (const char*)data_id); break; case ImGuiDataType_Pointer: ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id); break; case ImGuiDataType_ID: - if (info->Desc[0] == 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one. - ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id); + if (info->Desc[0] != 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one. + return; + ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id); break; default: IM_ASSERT(0); } info->QuerySuccess = true; + info->DataType = data_type; +} + +static int StackToolFormatLevelInfo(ImGuiStackTool* tool, int n, bool format_for_ui, char* buf, size_t buf_size) +{ + ImGuiStackLevelInfo* info = &tool->Results[n]; + ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? ImGui::FindWindowByID(info->ID) : NULL; + if (window) // Source: window name (because the root ID don't call GetID() and so doesn't get hooked) + return ImFormatString(buf, buf_size, format_for_ui ? "\"%s\" [window]" : "%s", window->Name); + if (info->QuerySuccess) // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id) + return ImFormatString(buf, buf_size, (format_for_ui && info->DataType == ImGuiDataType_String) ? "\"%s\"" : "%s", info->Desc); + if (tool->StackLevel < tool->Results.Size) // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers. + return (*buf = 0); +#ifdef IMGUI_ENABLE_TEST_ENGINE + if (const char* label = ImGuiTestEngine_FindItemDebugLabel(GImGui, info->ID)) // Source: ImGuiTestEngine's ItemInfo() + return ImFormatString(buf, buf_size, format_for_ui ? "??? \"%s\"" : "%s", label); +#endif + return ImFormatString(buf, buf_size, "???"); } // Stack Tool: Display UI void ImGui::ShowStackToolWindow(bool* p_open) { + ImGuiContext& g = *GImGui; + if (!(g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize)) + SetNextWindowSize(ImVec2(0.0f, GetFontSize() * 8.0f), ImGuiCond_FirstUseEver); if (!Begin("Dear ImGui Stack Tool", p_open) || GetCurrentWindow()->BeginCount > 1) { End(); @@ -12167,7 +14858,7 @@ void ImGui::ShowStackToolWindow(bool* p_open) } // Display hovered/active status - ImGuiContext& g = *GImGui; + ImGuiStackTool* tool = &g.DebugStackTool; const ImGuiID hovered_id = g.HoveredIdPreviousFrame; const ImGuiID active_id = g.ActiveId; #ifdef IMGUI_ENABLE_TEST_ENGINE @@ -12178,8 +14869,33 @@ void ImGui::ShowStackToolWindow(bool* p_open) SameLine(); MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details."); + // CTRL+C to copy path + const float time_since_copy = (float)g.Time - tool->CopyToClipboardLastTime; + Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC); + SameLine(); + TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*"); + if (tool->CopyToClipboardOnCtrlC && IsKeyDown(ImGuiMod_Ctrl) && IsKeyPressed(ImGuiKey_C)) + { + tool->CopyToClipboardLastTime = (float)g.Time; + char* p = g.TempBuffer.Data; + char* p_end = p + g.TempBuffer.Size; + for (int stack_n = 0; stack_n < tool->Results.Size && p + 3 < p_end; stack_n++) + { + *p++ = '/'; + char level_desc[256]; + StackToolFormatLevelInfo(tool, stack_n, false, level_desc, IM_ARRAYSIZE(level_desc)); + for (int n = 0; level_desc[n] && p + 2 < p_end; n++) + { + if (level_desc[n] == '/') + *p++ = '\\'; + *p++ = level_desc[n]; + } + } + *p = '\0'; + SetClipboardText(g.TempBuffer.Data); + } + // Display decorated stack - ImGuiStackTool* tool = &g.DebugStackTool; tool->LastActiveFrame = g.FrameCount; if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders)) { @@ -12193,23 +14909,9 @@ void ImGui::ShowStackToolWindow(bool* p_open) ImGuiStackLevelInfo* info = &tool->Results[n]; TableNextColumn(); Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0); - TableNextColumn(); - ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? FindWindowByID(info->ID) : NULL; - if (window) // Source: window name (because the root ID don't call GetID() and so doesn't get hooked) - Text("\"%s\" [window]", window->Name); - else if (info->QuerySuccess) // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id) - TextUnformatted(info->Desc); - else if (tool->StackLevel >= tool->Results.Size) // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers. - { -#ifdef IMGUI_ENABLE_TEST_ENGINE - if (const char* label = ImGuiTestEngine_FindItemDebugLabel(&g, info->ID)) // Source: ImGuiTestEngine's ItemInfo() - Text("??? \"%s\"", label); - else -#endif - TextUnformatted("???"); - } - + StackToolFormatLevelInfo(tool, n, true, g.TempBuffer.Data, g.TempBuffer.Size); + TextUnformatted(g.TempBuffer.Data); TableNextColumn(); Text("0x%08X", info->ID); if (n == tool->Results.Size - 1) @@ -12235,12 +14937,15 @@ void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings*) {} void ImGui::DebugNodeWindowsList(ImVector*, const char*) {} void ImGui::DebugNodeViewport(ImGuiViewportP*) {} +void ImGui::DebugLog(const char*, ...) {} +void ImGui::DebugLogV(const char*, va_list) {} +void ImGui::ShowDebugLogWindow(bool*) {} void ImGui::ShowStackToolWindow(bool*) {} void ImGui::DebugHookIdInfo(ImGuiID, ImGuiDataType, const void*, const void*) {} void ImGui::UpdateDebugToolItemPicker() {} void ImGui::UpdateDebugToolStackQueries() {} -#endif // #ifndef IMGUI_DISABLE_METRICS_WINDOW +#endif // #ifndef IMGUI_DISABLE_DEBUG_TOOLS //----------------------------------------------------------------------------- diff --git a/Externals/imgui/imgui.h b/Externals/imgui/imgui.h index f26063981a..03e503e60e 100644 --- a/Externals/imgui/imgui.h +++ b/Externals/imgui/imgui.h @@ -1,25 +1,33 @@ -// dear imgui, v1.85 +// dear imgui, v1.89.7 // (headers) // Help: -// - Read FAQ at http://dearimgui.org/faq +// - Read FAQ at http://dearimgui.com/faq // - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. // - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that. // Read imgui.cpp for details, links and comments. // Resources: -// - FAQ http://dearimgui.org/faq -// - Homepage & latest https://github.com/ocornut/imgui +// - FAQ http://dearimgui.com/faq +// - Homepage https://github.com/ocornut/imgui // - Releases & changelog https://github.com/ocornut/imgui/releases -// - Gallery https://github.com/ocornut/imgui/issues/4451 (please post your screenshots/video there!) +// - Gallery https://github.com/ocornut/imgui/issues/6478 (please post your screenshots/video there!) // - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there) +// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started // - Glossary https://github.com/ocornut/imgui/wiki/Glossary // - Issues & support https://github.com/ocornut/imgui/issues // Getting Started? -// - For first-time users having issues compiling/linking/running or issues loading fonts: +// - Read https://github.com/ocornut/imgui/wiki/Getting-Started +// - For first-time users having issues compiling/linking/running/loading fonts: // please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. +// Library Version +// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') +#define IMGUI_VERSION "1.89.7" +#define IMGUI_VERSION_NUM 18971 +#define IMGUI_HAS_TABLE + /* Index of this file: @@ -31,23 +39,23 @@ Index of this file: // [SECTION] ImGuiStyle // [SECTION] ImGuiIO // [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs) -// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor) +// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, Math Operators, ImColor) // [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData) // [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont) // [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport) +// [SECTION] Platform Dependent Interfaces (ImGuiPlatformImeData) // [SECTION] Obsolete functions and types */ #pragma once -// Configuration file with compile-time options (edit imconfig.h or '#define IMGUI_USER_CONFIG "myfilename.h" from your build system') +// Configuration file with compile-time options +// (edit imconfig.h or '#define IMGUI_USER_CONFIG "myfilename.h" from your build system') #ifdef IMGUI_USER_CONFIG #include IMGUI_USER_CONFIG #endif -#if !defined(IMGUI_DISABLE_INCLUDE_IMCONFIG_H) || defined(IMGUI_INCLUDE_IMCONFIG_H) #include "imconfig.h" -#endif #ifndef IMGUI_DISABLE @@ -61,13 +69,6 @@ Index of this file: #include // ptrdiff_t, NULL #include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -// Version -// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) -#define IMGUI_VERSION "1.85" -#define IMGUI_VERSION_NUM 18500 -#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) -#define IMGUI_HAS_TABLE - // Define attributes of all API symbols declarations (e.g. for DLL under Windows) // IMGUI_API is used for core imgui functions, IMGUI_IMPL_API is used for the default backends files (imgui_impl_xxx.h) // Using dear imgui via a shared library is not recommended, because we don't guarantee backward nor forward ABI compatibility (also function call overhead, as dear imgui is a call-heavy API) @@ -85,11 +86,8 @@ Index of this file: #endif #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers! #define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds. -#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100) #define IM_OFFSETOF(_TYPE,_MEMBER) offsetof(_TYPE, _MEMBER) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in C++11 -#else -#define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Old style macro. -#endif +#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) // Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions. #if !defined(IMGUI_USE_STB_SPRINTF) && defined(__MINGW32__) && !defined(__clang__) @@ -104,7 +102,7 @@ Index of this file: #endif // Disable some of MSVC most aggressive Debug runtime checks in function header/footer (used in some simple/low-level functions) -#if defined(_MSC_VER) && !defined(__clang__) && !defined(IMGUI_DEBUG_PARANOID) +#if defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(IMGUI_DEBUG_PARANOID) #define IM_MSVC_RUNTIME_CHECKS_OFF __pragma(runtime_checks("",off)) __pragma(check_stack(off)) __pragma(strict_gs_check(push,off)) #define IM_MSVC_RUNTIME_CHECKS_RESTORE __pragma(runtime_checks("",restore)) __pragma(check_stack()) __pragma(strict_gs_check(pop)) #else @@ -151,9 +149,11 @@ struct ImColor; // Helper functions to create a color that c struct ImGuiContext; // Dear ImGui context (opaque structure, unless including imgui_internal.h) struct ImGuiIO; // Main configuration and I/O between your application and ImGui struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use) +struct ImGuiKeyData; // Storage for ImGuiIO and IsKeyDown(), IsKeyPressed() etc functions. struct ImGuiListClipper; // Helper to manually clip large list of items -struct ImGuiOnceUponAFrame; // Helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro +struct ImGuiOnceUponAFrame; // Helper for running a block of code not more than once a frame struct ImGuiPayload; // User data payload for drag and drop operations +struct ImGuiPlatformImeData; // Platform IME data for io.SetPlatformImeDataFn() function. struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use) struct ImGuiStorage; // Helper for key->value storage struct ImGuiStyle; // Runtime data for styling/colors @@ -163,21 +163,27 @@ struct ImGuiTextBuffer; // Helper to hold and append into a text buf struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]") struct ImGuiViewport; // A Platform Window (always only one in 'master' branch), in the future may represent Platform Monitor -// Enums/Flags (declared as int for compatibility with old C++, to allow using as flags without overhead, and to not pollute the top of this file) +// Enumerations +// - We don't use strongly typed enums much because they add constraints (can't extend in private code, can't store typed in bit fields, extra casting on iteration) // - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists! -// In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. // With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. +enum ImGuiKey : int; // -> enum ImGuiKey // Enum: A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value) +enum ImGuiMouseSource : int; // -> enum ImGuiMouseSource // Enum; A mouse input source identifier (Mouse, TouchScreen, Pen) typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for many Set*() functions typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type typedef int ImGuiDir; // -> enum ImGuiDir_ // Enum: A cardinal direction -typedef int ImGuiKey; // -> enum ImGuiKey_ // Enum: A key identifier (ImGui-side enum) -typedef int ImGuiNavInput; // -> enum ImGuiNavInput_ // Enum: An input identifier for navigation typedef int ImGuiMouseButton; // -> enum ImGuiMouseButton_ // Enum: A mouse button identifier (0=left, 1=right, 2=middle) -typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor identifier +typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor shape typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending) typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor() + +// Flags (declared as int for compatibility with old C++, to allow using as flags without overhead, and to not pollute the top of this file) +// - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists! +// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build @@ -190,7 +196,7 @@ typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: f typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused() typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline() -typedef int ImGuiKeyModFlags; // -> enum ImGuiKeyModFlags_ // Flags: for io.KeyMods (Ctrl/Shift/Alt/Super) +typedef int ImGuiKeyChord; // -> ImGuiKey | ImGuiMod_XXX // Flags: for storage only for now: an ImGuiKey optionally OR-ed with one or more ImGuiMod_XXX values. typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable() typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc. @@ -225,17 +231,8 @@ typedef signed short ImS16; // 16-bit signed integer typedef unsigned short ImU16; // 16-bit unsigned integer typedef signed int ImS32; // 32-bit signed integer == int typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) -#if defined(_MSC_VER) && !defined(__clang__) -typedef signed __int64 ImS64; // 64-bit signed integer (pre and post C++11 with Visual Studio) -typedef unsigned __int64 ImU64; // 64-bit unsigned integer (pre and post C++11 with Visual Studio) -#elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100) -#include -typedef int64_t ImS64; // 64-bit signed integer (pre C++11) -typedef uint64_t ImU64; // 64-bit unsigned integer (pre C++11) -#else -typedef signed long long ImS64; // 64-bit signed integer (post C++11) -typedef unsigned long long ImU64; // 64-bit unsigned integer (post C++11) -#endif +typedef signed long long ImS64; // 64-bit signed integer +typedef unsigned long long ImU64; // 64-bit unsigned integer // Character types // (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display) @@ -259,10 +256,10 @@ IM_MSVC_RUNTIME_CHECKS_OFF struct ImVec2 { float x, y; - ImVec2() { x = y = 0.0f; } - ImVec2(float _x, float _y) { x = _x; y = _y; } - float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. - float& operator[] (size_t idx) { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. + constexpr ImVec2() : x(0.0f), y(0.0f) { } + constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { } + float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((float*)(void*)(char*)this)[idx]; } // We very rarely use this [] operator, so the assert overhead is fine. + float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const float*)(const void*)(const char*)this)[idx]; } #ifdef IM_VEC2_CLASS_EXTRA IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2. #endif @@ -271,9 +268,9 @@ struct ImVec2 // ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type] struct ImVec4 { - float x, y, z, w; - ImVec4() { x = y = z = w = 0.0f; } - ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } + float x, y, z, w; + constexpr ImVec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { } + constexpr ImVec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { } #ifdef IM_VEC4_CLASS_EXTRA IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4. #endif @@ -307,12 +304,13 @@ namespace ImGui // Demo, Debug, Information IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window. demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Metrics/Debugger window. display Dear ImGui internals: windows, draw commands, various internal state, etc. + IMGUI_API void ShowDebugLogWindow(bool* p_open = NULL); // create Debug Log window. display a simplified log of important dear imgui events. IMGUI_API void ShowStackToolWindow(bool* p_open = NULL); // create Stack Tool window. hover items with mouse to query information about the source of their unique ID. IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information. IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) IMGUI_API bool ShowStyleSelector(const char* label); // add style selector block (not a window), essentially a combo listing the default styles. IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts. - IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). + IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as an end-user (mouse/keyboard controls). IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.80 WIP" (essentially the value for IMGUI_VERSION from the compiled version of imgui.cpp) // Styles @@ -367,6 +365,7 @@ namespace ImGui IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ scrollable client area, which enforce the range of scrollbars). Not including window decorations (title bar, menu bar, etc.) nor WindowPadding. set an axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / top-most. call before Begin() + IMGUI_API void SetNextWindowScroll(const ImVec2& scroll); // set next window scrolling value (use < 0.0f to not affect a given axis). IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily override the Alpha component of ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground. IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0, 0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. @@ -384,9 +383,11 @@ namespace ImGui IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min for the full window (roughly (0,0)-Scroll), in window coordinates - IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates + IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be overridden with SetNextWindowContentSize(), in window coordinates // Windows Scrolling + // - Any change of Scroll will be applied at the beginning of next frame in the first call to Begin(). + // - You may instead use SetNextWindowScroll() prior to calling Begin() to avoid this delay, as an alternative to using SetScrollX()/SetScrollY(). IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()] IMGUI_API float GetScrollY(); // get scrolling amount [0 .. GetScrollMaxY()] IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0 .. GetScrollMaxX()] @@ -407,8 +408,8 @@ namespace ImGui IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); // modify a style float variable. always use this if you modify the style after NewFrame(). IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); // modify a style ImVec2 variable. always use this if you modify the style after NewFrame(). IMGUI_API void PopStyleVar(int count = 1); - IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // == tab stop enable. Allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets - IMGUI_API void PopAllowKeyboardFocus(); + IMGUI_API void PushTabStop(bool tab_stop); // == tab stop enable. Allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets + IMGUI_API void PopTabStop(); IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. IMGUI_API void PopButtonRepeat(); @@ -421,7 +422,7 @@ namespace ImGui IMGUI_API void PopTextWrapPos(); // Style read access - // - Use the style editor (ShowStyleEditor() function) to interactively see what the colors are) + // - Use the ShowStyleEditor() function to interactively see/edit the colors. IMGUI_API ImFont* GetFont(); // get current font IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API @@ -439,7 +440,7 @@ namespace ImGui // Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions. IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator. IMGUI_API void SameLine(float offset_from_start_x=0.0f, float spacing=-1.0f); // call between widgets or groups to layout them horizontally. X position given in window coordinates. - IMGUI_API void NewLine(); // undo a SameLine() or force a new line when in an horizontal-layout context. + IMGUI_API void NewLine(); // undo a SameLine() or force a new line when in a horizontal-layout context. IMGUI_API void Spacing(); // add vertical spacing. IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size. unlike InvisibleButton(), Dummy() won't take the mouse click or be navigable into. IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by indent_w, or style.IndentSpacing if indent_w <= 0 @@ -462,7 +463,7 @@ namespace ImGui IMGUI_API float GetFrameHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets) // ID stack/scopes - // Read the FAQ (docs/FAQ.md or http://dearimgui.org/faq) for more details about how ID are handled in dear imgui. + // Read the FAQ (docs/FAQ.md or http://dearimgui.com/faq) for more details about how ID are handled in dear imgui. // - Those questions are answered and impacted by understanding of the ID stack system: // - "Q: Why is my widget not reacting when I click on it?" // - "Q: How can I have widgets with an empty label?" @@ -495,6 +496,7 @@ namespace ImGui IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2); IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text() IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1); + IMGUI_API void SeparatorText(const char* label); // currently: formatted text with an horizontal line // Widgets: Main // - Most widgets return true when the value has been changed or when pressed/selected @@ -503,8 +505,6 @@ namespace ImGui IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size, ImGuiButtonFlags flags = 0); // flexible button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape - IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); - IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool Checkbox(const char* label, bool* v); IMGUI_API bool CheckboxFlags(const char* label, int* flags, int flags_value); IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); @@ -513,7 +513,12 @@ namespace ImGui IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-FLT_MIN, 0), const char* overlay = NULL); IMGUI_API void Bullet(); // draw a small circle + keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses - // Widgets: Combo Box + // Widgets: Images + // - Read about ImTextureID here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples + IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0)); + IMGUI_API bool ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); + + // Widgets: Combo Box (Dropdown) // - The BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it, by creating e.g. Selectable() items. // - The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. This is analogous to how ListBox are created. IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); @@ -524,14 +529,15 @@ namespace ImGui // Widgets: Drag Sliders // - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp. - // - For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x + // - For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every function, note that a 'float v[X]' function argument is the same as 'float* v', + // the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x // - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc. // - Format string may also be set to NULL or use the default format ("%f" or "%d"). // - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision). // - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits if ImGuiSliderFlags_AlwaysClamp is not used. // - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum. // - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them. - // - Legacy: Pre-1.78 there are DragXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument. + // - Legacy: Pre-1.78 there are DragXXX() function signatures that take a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument. // If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361 IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", ImGuiSliderFlags flags = 0); // If v_min >= v_max we have no bound IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", ImGuiSliderFlags flags = 0); @@ -550,7 +556,7 @@ namespace ImGui // - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp. // - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc. // - Format string may also be set to NULL or use the default format ("%f" or "%d"). - // - Legacy: Pre-1.78 there are SliderXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument. + // - Legacy: Pre-1.78 there are SliderXXX() function signatures that take a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument. // If you get a warning converting a float to ImGuiSliderFlags, read https://github.com/ocornut/imgui/issues/3361 IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); // adjust format to decorate the value with a prefix or a suffix for in-slider labels or unit display. IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0); @@ -592,7 +598,7 @@ namespace ImGui IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); - IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0, 0)); // display a color square/button, hover for details, return true when pressed. + IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // display a color square/button, hover for details, return true when pressed. IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // initialize current options (generally on application startup) if you want to select a default format, picker type, etc. User will be able to change many settings, unless you pass the _NoOptions flag to your calls. // Widgets: Trees @@ -608,7 +614,7 @@ namespace ImGui IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call TreePush/TreePop yourself if desired. - IMGUI_API void TreePush(const void* ptr_id = NULL); // " + IMGUI_API void TreePush(const void* ptr_id); // " IMGUI_API void TreePop(); // ~ Unindent()+PopId() IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). @@ -661,12 +667,21 @@ namespace ImGui IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL // Tooltips - // - Tooltip are windows following the mouse. They do not take focus away. - IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items). - IMGUI_API void EndTooltip(); - IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). override any previous call to SetTooltip(). + // - Tooltips are windows following the mouse. They do not take focus away. + // - A tooltip window can contain items of any types. SetTooltip() is a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom. + IMGUI_API bool BeginTooltip(); // begin/append a tooltip window. + IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip()/BeginItemTooltip() returns true! + IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip. Often used after a ImGui::IsItemHovered() check. Override any previous call to SetTooltip(). IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); + // Tooltips: helpers for showing a tooltip when hovering an item + // - BeginItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_Tooltip) && BeginTooltip())' idiom. + // - SetItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_Tooltip)) { SetTooltip(...); }' idiom. + // - Where 'ImGuiHoveredFlags_Tooltip' itself is a shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on active input type. For mouse it defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'. + IMGUI_API bool BeginItemTooltip(); // begin/append a tooltip window if preceding item was hovered. + IMGUI_API void SetItemTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip if preceeding item was hovered. override any previous call to SetTooltip(). + IMGUI_API void SetItemTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); + // Popups, Modals // - They block normal mouse hovering detection (and therefore most mouse interactions) behind them. // - If not modal: they can be closed by clicking anywhere outside them, or by pressing ESCAPE. @@ -678,7 +693,7 @@ namespace ImGui // Popups: begin/end functions // - BeginPopup(): query popup state, if open start appending into the window. Call EndPopup() afterwards. ImGuiWindowFlags are forwarded to the window. - // - BeginPopupModal(): block every interactions behind the window, cannot be closed by user, add a dimming background, has a title bar. + // - BeginPopupModal(): block every interaction behind the window, cannot be closed by user, add a dimming background, has a title bar. IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // return true if the modal is open, and you can start outputting to it. IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! @@ -690,6 +705,7 @@ namespace ImGui // - CloseCurrentPopup() is called by default by Selectable()/MenuItem() when activated (FIXME: need some options). // - Use ImGuiPopupFlags_NoOpenOverExistingPopup to avoid opening a popup if there's already one at the same level. This is equivalent to e.g. testing for !IsAnyPopupOpen() prior to OpenPopup(). // - Use IsWindowAppearing() after BeginPopup() to tell if a window just opened. + // - IMPORTANT: Notice that for OpenPopupOnItemClick() we exceptionally default flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter IMGUI_API void OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags = 0); // call to mark popup as open (don't call every frame!). IMGUI_API void OpenPopup(ImGuiID id, ImGuiPopupFlags popup_flags = 0); // id overload to facilitate calling from nested stacks IMGUI_API void OpenPopupOnItemClick(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // helper to open popup when clicked on last item. Default to ImGuiPopupFlags_MouseButtonRight == 1. (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors) @@ -699,7 +715,7 @@ namespace ImGui // - Helpers to do OpenPopup+BeginPopup where the Open action is triggered by e.g. hovering an item and right-clicking. // - They are convenient to easily create context menus, hence the name. // - IMPORTANT: Notice that BeginPopupContextXXX takes ImGuiPopupFlags just like OpenPopup() and unlike BeginPopup(). For full consistency, we may add ImGuiWindowFlags to the BeginPopupContextXXX functions in the future. - // - IMPORTANT: we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight. + // - IMPORTANT: Notice that we exceptionally default their flags to 1 (== ImGuiPopupFlags_MouseButtonRight) for backward compatibility with older API taking 'int mouse_button = 1' parameter, so if you add other flags remember to re-add the ImGuiPopupFlags_MouseButtonRight. IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked on last item. Use str_id==NULL to associate the popup to previous item. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1);// open+begin popup when clicked on current window. IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, ImGuiPopupFlags popup_flags = 1); // open+begin popup when clicked in void (where there are no windows). @@ -711,19 +727,17 @@ namespace ImGui IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open. // Tables - // [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out! // - Full-featured replacement for old Columns API. - // - See Demo->Tables for demo code. - // - See top of imgui_tables.cpp for general commentary. + // - See Demo->Tables for demo code. See top of imgui_tables.cpp for general commentary. // - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags. // The typical call flow is: - // - 1. Call BeginTable(). + // - 1. Call BeginTable(), early out if returning false. // - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults. // - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows. // - 4. Optionally call TableHeadersRow() to submit a header row. Names are pulled from TableSetupColumn() data. // - 5. Populate contents: // - In most situations you can use TableNextRow() + TableSetColumnIndex(N) to start appending into a column. - // - If you are using tables as a sort of grid, where every columns is holding the same type of contents, + // - If you are using tables as a sort of grid, where every column is holding the same type of contents, // you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex(). // TableNextColumn() will automatically wrap-around into the next row if needed. // - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column! @@ -736,10 +750,10 @@ namespace ImGui // -------------------------------------------------------------------------------------------------------- // - 5. Call EndTable() IMGUI_API bool BeginTable(const char* str_id, int column, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f); - IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true! + IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true! IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row. - IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible. - IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible. + IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible. + IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible. // Tables: Headers & Columns declaration // - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc. @@ -750,20 +764,17 @@ namespace ImGui // some advanced use cases (e.g. adding custom widgets in header row). // - Use TableSetupScrollFreeze() to lock columns/rows so they stay visible when scrolled. IMGUI_API void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImGuiID user_id = 0); - IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled. - IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu - IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used) + IMGUI_API void TableSetupScrollFreeze(int cols, int rows); // lock columns/rows so they stay visible when scrolled. + IMGUI_API void TableHeadersRow(); // submit all headers cells based on data provided to TableSetupColumn() + submit context menu + IMGUI_API void TableHeader(const char* label); // submit one header cell manually (rarely used) - // Tables: Sorting - // - Call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting. - // - When 'SpecsDirty == true' you should sort your data. It will be true when sorting specs have changed - // since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, else you may - // wastefully sort your data every frame! - // - Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable(). - IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting). - - // Tables: Miscellaneous functions + // Tables: Sorting & Miscellaneous functions + // - Sorting: call TableGetSortSpecs() to retrieve latest sort specs for the table. NULL when not sorting. + // When 'sort_specs->SpecsDirty == true' you should sort your data. It will be true when sorting specs have + // changed since last call, or the first time. Make sure to set 'SpecsDirty = false' after sorting, + // else you may wastefully sort your data every frame! // - Functions args 'int column_n' treat the default value of -1 as the same as passing the current column index. + IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting). Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable(). IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable) IMGUI_API int TableGetColumnIndex(); // return current column index. IMGUI_API int TableGetRowIndex(); // return current row index. @@ -784,6 +795,7 @@ namespace ImGui IMGUI_API int GetColumnsCount(); // Tab Bars, Tabs + // - Note: Tabs are automatically created by the docking system (when in 'docking' branch). Use this to create tab bars/tabs yourself. IMGUI_API bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags = 0); // create and append into a TabBar IMGUI_API void EndTabBar(); // only call EndTabBar() if BeginTabBar() returns true! IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0); // create a Tab. Returns true if the Tab is selected. @@ -807,7 +819,7 @@ namespace ImGui // - If you stop calling BeginDragDropSource() the payload is preserved however it won't have a preview tooltip (we currently display a fallback "..." tooltip, see #1725) // - An item can be both drag source and drop target. IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call after submitting an item which may be dragged. when this return true, you can call SetDragDropPayload() + EndDragDropSource() - IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. Return true when payload has been accepted. IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive a payload. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. @@ -831,26 +843,29 @@ namespace ImGui IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window. IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. + // Overlapping mode + IMGUI_API void SetNextItemAllowOverlap(); // allow next item to be overlapped by a subsequent item. Useful with invisible buttons, selectable, treenode covering an area where subsequent items may need to be added. Note that both Selectable() and TreeNode() have dedicated flags doing this. + // Item/Widgets Utilities and Query Functions // - Most of the functions are referring to the previous Item that has been submitted. // - See Demo Window under "Widgets->Querying Status" for an interactive visualization of most of those functions. IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options. IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited. This will continuously return true while holding mouse button on an item. Items that don't interact will always return false) IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation? - IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item hovered and mouse clicked on? (**) == IsMouseClicked(mouse_button) && IsItemHovered()Important. (**) this it NOT equivalent to the behavior of e.g. Button(). Read comments in function definition. + IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button = 0); // is the last item hovered and mouse clicked on? (**) == IsMouseClicked(mouse_button) && IsItemHovered()Important. (**) this is NOT equivalent to the behavior of e.g. Button(). Read comments in function definition. IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling) IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets. IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive). - IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing. - IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item). + IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that require continuous editing. + IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that require continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item). IMGUI_API bool IsItemToggledOpen(); // was the last item open state toggled? set by TreeNode(). IMGUI_API bool IsAnyItemHovered(); // is any item hovered? IMGUI_API bool IsAnyItemActive(); // is any item active? IMGUI_API bool IsAnyItemFocused(); // is any item focused? + IMGUI_API ImGuiID GetItemID(); // get ID of last item (~~ often same ImGui::GetID(label) beforehand) IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space) IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space) IMGUI_API ImVec2 GetItemRectSize(); // get size of last item - IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. // Viewports // - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows. @@ -858,18 +873,19 @@ namespace ImGui // - In the future we will extend this concept further to also represent Platform Monitor and support a "no main platform window" operation mode. IMGUI_API ImGuiViewport* GetMainViewport(); // return primary/default viewport. This can never be NULL. + // Background/Foreground Draw Lists + IMGUI_API ImDrawList* GetBackgroundDrawList(); // this draw list will be the first rendered one. Useful to quickly draw shapes/text behind dear imgui contents. + IMGUI_API ImDrawList* GetForegroundDrawList(); // this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents. + // Miscellaneous Utilities IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API double GetTime(); // get global imgui time. incremented by io.DeltaTime every frame. IMGUI_API int GetFrameCount(); // get global imgui frame count. incremented by 1 every frame. - IMGUI_API ImDrawList* GetBackgroundDrawList(); // this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents. - IMGUI_API ImDrawList* GetForegroundDrawList(); // this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents. IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); // you may use this when creating your own ImDrawList instances. IMGUI_API const char* GetStyleColorName(ImGuiCol idx); // get a string corresponding to the enum value (for display, saving, etc.). IMGUI_API void SetStateStorage(ImGuiStorage* storage); // replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API ImGuiStorage* GetStateStorage(); - IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window) @@ -882,35 +898,38 @@ namespace ImGui IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); - // Inputs Utilities: Keyboard - // - For 'int user_key_index' you can use your own indices/enums according to how your backend/engine stored them in io.KeysDown[]. - // - We don't know the meaning of those value. You can use GetKeyIndex() to map a ImGuiKey_ value into the user index. - IMGUI_API int GetKeyIndex(ImGuiKey imgui_key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key] - IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. - IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate - IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down)? - IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate - IMGUI_API void CaptureKeyboardFromApp(bool want_capture_keyboard_value = true); // attention: misleading name! manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application to handle). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard_value"; after the next NewFrame() call. + // Inputs Utilities: Keyboard/Mouse/Gamepad + // - the ImGuiKey enum contains all possible keyboard, mouse and gamepad inputs (e.g. ImGuiKey_A, ImGuiKey_MouseLeft, ImGuiKey_GamepadDpadUp...). + // - before v1.87, we used ImGuiKey to carry native/user indices as defined by each backends. About use of those legacy ImGuiKey values: + // - without IMGUI_DISABLE_OBSOLETE_KEYIO (legacy support): you can still use your legacy native/user indices (< 512) according to how your backend/engine stored them in io.KeysDown[], but need to cast them to ImGuiKey. + // - with IMGUI_DISABLE_OBSOLETE_KEYIO (this is the way forward): any use of ImGuiKey will assert with key < 512. GetKeyIndex() is pass-through and therefore deprecated (gone if IMGUI_DISABLE_OBSOLETE_KEYIO is defined). + IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held. + IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate + IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)? + IMGUI_API int GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate + IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared. + IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call. - // Inputs Utilities: Mouse + // Inputs Utilities: Mouse specific // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. // - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle. // - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold') IMGUI_API bool IsMouseDown(ImGuiMouseButton button); // is mouse button held? - IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down) + IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1. IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down) - IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? (note that a double-click will also report IsMouseClicked() == true) + IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? Same as GetMouseClickedCount() == 2. (note that a double-click will also report IsMouseClicked() == true) + IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0). IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block. IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available - IMGUI_API bool IsAnyMouseDown(); // is any mouse button held? + IMGUI_API bool IsAnyMouseDown(); // [WILL OBSOLETE] is any mouse button held? This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid. IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve mouse position at the time of opening popup we have BeginPopup() into (helper to avoid user backing that value themselves) IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position while the mouse button is pressed or was just released. This is locked and return 0.0f until the mouse moves past a distance threshold at least once (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) IMGUI_API void ResetMouseDragDelta(ImGuiMouseButton button = 0); // - IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you - IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type); // set desired cursor type - IMGUI_API void CaptureMouseFromApp(bool want_capture_mouse_value = true); // attention: misleading name! manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application to handle). This is equivalent to setting "io.WantCaptureMouse = want_capture_mouse_value;" after the next NewFrame() call. + IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired mouse cursor shape. Important: reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you + IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type); // set desired mouse cursor shape + IMGUI_API void SetNextFrameWantCaptureMouse(bool want_capture_mouse); // Override io.WantCaptureMouse flag next frame (said flag is left for your application to handle, typical when true it instucts your app to ignore inputs). This is equivalent to setting "io.WantCaptureMouse = want_capture_mouse;" after the next NewFrame() call. // Clipboard Utilities // - Also see the LogToClipboard() function to capture GUI into clipboard, or easily output text data to the clipboard. @@ -927,7 +946,7 @@ namespace ImGui IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings. // Debug Utilities - // - This is used by the IMGUI_CHECKVERSION() macro. + IMGUI_API void DebugTextEncoding(const char* text); IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // This is called by IMGUI_CHECKVERSION() macro. // Memory Allocators @@ -946,6 +965,7 @@ namespace ImGui //----------------------------------------------------------------------------- // Flags for ImGui::Begin() +// (Those are per-window flags. There are shared flags in ImGuiIO: io.ConfigWindowsResizeFromEdges and io.ConfigWindowsMoveFromTitleBarOnly) enum ImGuiWindowFlags_ { ImGuiWindowFlags_None = 0, @@ -954,7 +974,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programmatically) ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. - ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it + ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it. Also referred to as Window Menu Button (e.g. within a docking node). ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame ImGuiWindowFlags_NoBackground = 1 << 7, // Disable drawing background color (WindowBg, etc.) and outside border. Similar as using SetNextWindowBgAlpha(0.0f). ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file @@ -974,18 +994,16 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, // [Internal] - ImGuiWindowFlags_NavFlattened = 1 << 23, // [BETA] Allow gamepad/keyboard navigation to cross over parent border to this child (only use on child that have no scrolling!) + ImGuiWindowFlags_NavFlattened = 1 << 23, // [BETA] On child window: allow gamepad/keyboard navigation to cross over parent border to this child or between sibling child windows. ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild() ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip() ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup() ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal() - ImGuiWindowFlags_ChildMenu = 1 << 28 // Don't use! For internal use by BeginMenu() - - // [Obsolete] - //ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, // --> Set io.ConfigWindowsResizeFromEdges=true and make sure mouse cursors are supported by backend (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) + ImGuiWindowFlags_ChildMenu = 1 << 28, // Don't use! For internal use by BeginMenu() }; // Flags for ImGui::InputText() +// (Those are per-item flags. There are shared flags in ImGuiIO: io.ConfigInputTextCursorBlink and io.ConfigInputTextEnterKeepActive) enum ImGuiInputTextFlags_ { ImGuiInputTextFlags_None = 0, @@ -1008,12 +1026,11 @@ enum ImGuiInputTextFlags_ ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) - ImGuiInputTextFlags_CallbackEdit = 1 << 19 // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) + ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) + ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) - // Obsolete names (will be removed soon) -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior -#endif + // Obsolete names + //ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior }; // Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*() @@ -1022,7 +1039,7 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_None = 0, ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected ImGuiTreeNodeFlags_Framed = 1 << 1, // Draw frame with background (e.g. for CollapsingHeader) - ImGuiTreeNodeFlags_AllowItemOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one + ImGuiTreeNodeFlags_AllowOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open @@ -1035,7 +1052,11 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (bypass the indented area). ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 13, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop) //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 14, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible - ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog + ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog, + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7 +#endif }; // Flags for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() functions. @@ -1044,7 +1065,7 @@ enum ImGuiTreeNodeFlags_ // It is therefore guaranteed to be legal to pass a mouse button index in ImGuiPopupFlags. // - For the same reason, we exceptionally default the ImGuiPopupFlags argument of BeginPopupContextXXX functions to 1 instead of 0. // IMPORTANT: because the default parameter is 1 (==ImGuiPopupFlags_MouseButtonRight), if you rely on the default parameter -// and want to another another flag, you need to pass in the ImGuiPopupFlags_MouseButtonRight flag. +// and want to use another flag, you need to pass in the ImGuiPopupFlags_MouseButtonRight flag explicitly. // - Multiple buttons currently cannot be combined/or-ed in those functions (we could allow it later). enum ImGuiPopupFlags_ { @@ -1058,18 +1079,22 @@ enum ImGuiPopupFlags_ ImGuiPopupFlags_NoOpenOverItems = 1 << 6, // For BeginPopupContextWindow(): don't return true when hovering items, only when hovering empty space ImGuiPopupFlags_AnyPopupId = 1 << 7, // For IsPopupOpen(): ignore the ImGuiID parameter and test for any popup. ImGuiPopupFlags_AnyPopupLevel = 1 << 8, // For IsPopupOpen(): search/test at any level of the popup stack (default test in the current level) - ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel + ImGuiPopupFlags_AnyPopup = ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel, }; // Flags for ImGui::Selectable() enum ImGuiSelectableFlags_ { ImGuiSelectableFlags_None = 0, - ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window + ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this doesn't close parent popup window ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) ImGuiSelectableFlags_AllowDoubleClick = 1 << 2, // Generate press events on double clicks too ImGuiSelectableFlags_Disabled = 1 << 3, // Cannot be selected, display grayed out text - ImGuiSelectableFlags_AllowItemOverlap = 1 << 4 // (WIP) Hit testing to allow subsequent widgets to overlap this one + ImGuiSelectableFlags_AllowOverlap = 1 << 4, // (WIP) Hit testing to allow subsequent widgets to overlap this one + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGuiSelectableFlags_AllowItemOverlap = ImGuiSelectableFlags_AllowOverlap, // Renamed in 1.89.7 +#endif }; // Flags for ImGui::BeginCombo() @@ -1083,7 +1108,7 @@ enum ImGuiComboFlags_ ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible ImGuiComboFlags_NoArrowButton = 1 << 5, // Display on the preview box without the square arrow button ImGuiComboFlags_NoPreview = 1 << 6, // Display only a square arrow button - ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest, }; // Flags for ImGui::BeginTabBar() @@ -1099,7 +1124,7 @@ enum ImGuiTabBarFlags_ ImGuiTabBarFlags_FittingPolicyResizeDown = 1 << 6, // Resize tabs when they don't fit ImGuiTabBarFlags_FittingPolicyScroll = 1 << 7, // Add scroll buttons when tabs don't fit ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_FittingPolicyResizeDown | ImGuiTabBarFlags_FittingPolicyScroll, - ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyResizeDown + ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyResizeDown, }; // Flags for ImGui::BeginTabItem() @@ -1113,12 +1138,11 @@ enum ImGuiTabItemFlags_ ImGuiTabItemFlags_NoTooltip = 1 << 4, // Disable tooltip for the given tab ImGuiTabItemFlags_NoReorder = 1 << 5, // Disable reordering this tab or having another tab cross over this tab ImGuiTabItemFlags_Leading = 1 << 6, // Enforce the tab position to the left of the tab bar (after the tab list popup button) - ImGuiTabItemFlags_Trailing = 1 << 7 // Enforce the tab position to the right of the tab bar (before the scrolling buttons) + ImGuiTabItemFlags_Trailing = 1 << 7, // Enforce the tab position to the right of the tab bar (before the scrolling buttons) }; // Flags for ImGui::BeginTable() -// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out! -// - Important! Sizing policies have complex and subtle side effects, more so than you would expect. +// - Important! Sizing policies have complex and subtle side effects, much more so than you would expect. // Read comments/demos carefully + experiment with live demos to get acquainted with them. // - The DEFAULT sizing policies are: // - Default to ImGuiTableFlags_SizingFixedFit if ScrollX is on, or if host window has ImGuiWindowFlags_AlwaysAutoResize. @@ -1126,15 +1150,15 @@ enum ImGuiTabItemFlags_ // - When ScrollX is off: // - Table defaults to ImGuiTableFlags_SizingStretchSame -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch with same weight. // - Columns sizing policy allowed: Stretch (default), Fixed/Auto. -// - Fixed Columns will generally obtain their requested width (unless the table cannot fit them all). -// - Stretch Columns will share the remaining width. +// - Fixed Columns (if any) will generally obtain their requested width (unless the table cannot fit them all). +// - Stretch Columns will share the remaining width according to their respective weight. // - Mixed Fixed/Stretch columns is possible but has various side-effects on resizing behaviors. // The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns. // (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing). // - When ScrollX is on: // - Table defaults to ImGuiTableFlags_SizingFixedFit -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed // - Columns sizing policy allowed: Fixed/Auto mostly. -// - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed. +// - Fixed Columns can be enlarged as needed. Table will show a horizontal scrollbar if needed. // - When using auto-resizing (non-resizable) fixed columns, querying the content width to use item right-alignment e.g. SetNextItemWidth(-FLT_MIN) doesn't make sense, would create a feedback loop. // - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable(). // If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again. @@ -1160,8 +1184,8 @@ enum ImGuiTableFlags_ ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders. ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders. ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders. - ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style - ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style + ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appear in Headers). -> May move to style + ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appear in Headers). -> May move to style // Sizing Policy (read above for defaults) ImGuiTableFlags_SizingFixedFit = 1 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching contents width. ImGuiTableFlags_SizingFixedSame = 2 << 13, // Columns default to _WidthFixed or _WidthAuto (if resizable or not resizable), matching the maximum contents width of all columns. Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible. @@ -1175,24 +1199,18 @@ enum ImGuiTableFlags_ // Clipping ImGuiTableFlags_NoClip = 1 << 20, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze(). // Padding - ImGuiTableFlags_PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers. - ImGuiTableFlags_NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outer-most padding. + ImGuiTableFlags_PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outermost padding. Generally desirable if you have headers. + ImGuiTableFlags_NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outermost padding. ImGuiTableFlags_NoPadInnerX = 1 << 23, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off). // Scrolling - ImGuiTableFlags_ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX. + ImGuiTableFlags_ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this creates a child window, ScrollY is currently generally recommended when using ScrollX. ImGuiTableFlags_ScrollY = 1 << 25, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. // Sorting ImGuiTableFlags_SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1). ImGuiTableFlags_SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0). // [Internal] Combinations and masks - ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame - - // Obsolete names (will be removed soon) -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - //, ImGuiTableFlags_ColumnsWidthFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_ColumnsWidthStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2020/12 - //, ImGuiTableFlags_SizingPolicyFixed = ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingPolicyStretch = ImGuiTableFlags_SizingStretchSame // WIP Tables 2021/01 -#endif + ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame, }; // Flags for ImGui::TableSetupColumn() @@ -1229,19 +1247,14 @@ enum ImGuiTableColumnFlags_ ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed, ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable, ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered, - ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge) - - // Obsolete names (will be removed soon) -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - //ImGuiTableColumnFlags_WidthAuto = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize, // Column will not stretch and keep resizing based on submitted contents. -#endif + ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30, // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge) }; // Flags for ImGui::TableNextRow() enum ImGuiTableRowFlags_ { - ImGuiTableRowFlags_None = 0, - ImGuiTableRowFlags_Headers = 1 << 0 // Identify header row (set default background color + width of its contents accounted different for auto column width) + ImGuiTableRowFlags_None = 0, + ImGuiTableRowFlags_Headers = 1 << 0, // Identify header row (set default background color + width of its contents accounted differently for auto column width) }; // Enum for ImGui::TableSetBgColor() @@ -1249,16 +1262,16 @@ enum ImGuiTableRowFlags_ // - Layer 0: draw with RowBg0 color if set, otherwise draw with ColumnBg0 if set. // - Layer 1: draw with RowBg1 color if set, otherwise draw with ColumnBg1 if set. // - Layer 2: draw with CellBg color if set. -// The purpose of the two row/columns layers is to let you decide if a background color changes should override or blend with the existing color. +// The purpose of the two row/columns layers is to let you decide if a background color change should override or blend with the existing color. // When using ImGuiTableFlags_RowBg on the table, each row has the RowBg0 color automatically set for odd/even rows. // If you set the color of RowBg0 target, your color will override the existing RowBg0 color. // If you set the color of RowBg1 or ColumnBg1 target, your color will blend over the RowBg0 color. enum ImGuiTableBgTarget_ { - ImGuiTableBgTarget_None = 0, - ImGuiTableBgTarget_RowBg0 = 1, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used) - ImGuiTableBgTarget_RowBg1 = 2, // Set row background color 1 (generally used for selection marking) - ImGuiTableBgTarget_CellBg = 3 // Set cell background color (top-most color) + ImGuiTableBgTarget_None = 0, + ImGuiTableBgTarget_RowBg0 = 1, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used) + ImGuiTableBgTarget_RowBg1 = 2, // Set row background color 1 (generally used for selection marking) + ImGuiTableBgTarget_CellBg = 3, // Set cell background color (top-most color) }; // Flags for ImGui::IsWindowFocused() @@ -1270,7 +1283,7 @@ enum ImGuiFocusedFlags_ ImGuiFocusedFlags_AnyWindow = 1 << 2, // Return true if any window is focused. Important: If you are trying to tell how to dispatch your low-level inputs, do NOT use this. Use 'io.WantCaptureMouse' instead! Please read the FAQ! ImGuiFocusedFlags_NoPopupHierarchy = 1 << 3, // Do not consider popup hierarchy (do not treat popup emitter as parent of popup) (when used with _ChildWindows or _RootWindow) //ImGuiFocusedFlags_DockHierarchy = 1 << 4, // Consider docking hierarchy (treat dockspace host as parent of docked window) (when used with _ChildWindows or _RootWindow) - ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows + ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows, }; // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() @@ -1287,10 +1300,30 @@ enum ImGuiHoveredFlags_ ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 5, // Return true even if a popup window is normally blocking access to this item/window //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 6, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. - ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window - ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled + ImGuiHoveredFlags_AllowWhenOverlappedByItem = 1 << 8, // IsItemHovered() only: Return true even if the item uses AllowOverlap mode and is overlapped by another hoverable item. + ImGuiHoveredFlags_AllowWhenOverlappedByWindow = 1 << 9, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window. + ImGuiHoveredFlags_AllowWhenDisabled = 1 << 10, // IsItemHovered() only: Return true even if the item is disabled + ImGuiHoveredFlags_NoNavOverride = 1 << 11, // IsItemHovered() only: Disable using gamepad/keyboard navigation state when active, always query mouse + ImGuiHoveredFlags_AllowWhenOverlapped = ImGuiHoveredFlags_AllowWhenOverlappedByItem | ImGuiHoveredFlags_AllowWhenOverlappedByWindow, ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, - ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows + ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows, + + // Tooltips mode + // - typically used in IsItemHovered() + SetTooltip() sequence. + // - this is a shortcut to pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' where you can reconfigure desired behavior. + // e.g. 'TooltipHoveredFlagsForMouse' defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'. + // - for frequently actioned or hovered items providing a tooltip, you want may to use ImGuiHoveredFlags_ForTooltip (stationary + delay) so the tooltip doesn't show too often. + // - for items which main purpose is to be hovered, or items with low affordance, or in less consistent apps, prefer no delay or shorter delay. + ImGuiHoveredFlags_ForTooltip = 1 << 11, // Shortcut for standard flags when using IsItemHovered() + SetTooltip() sequence. + + // (Advanced) Mouse Hovering delays. + // - generally you can use ImGuiHoveredFlags_ForTooltip to use application-standardized flags. + // - use those if you need specific overrides. + ImGuiHoveredFlags_Stationary = 1 << 12, // Require mouse to be stationary for style.HoverStationaryDelay (~0.15 sec) _at least one time_. After this, can move on same item/window. Using the stationary test tends to reduces the need for a long delay. + ImGuiHoveredFlags_DelayNone = 1 << 13, // IsItemHovered() only: Return true immediately (default). As this is the default you generally ignore this. + ImGuiHoveredFlags_DelayShort = 1 << 14, // IsItemHovered() only: Return true after style.HoverDelayShort elapsed (~0.15 sec) (shared between items) + requires mouse to be stationary for style.HoverStationaryDelay (once per item). + ImGuiHoveredFlags_DelayNormal = 1 << 15, // IsItemHovered() only: Return true after style.HoverDelayNormal elapsed (~0.40 sec) (shared between items) + requires mouse to be stationary for style.HoverStationaryDelay (once per item). + ImGuiHoveredFlags_NoSharedDelay = 1 << 16, // IsItemHovered() only: Disable shared delay system where moving from one item to the next keeps the previous timer for a short time (standard for tooltips with long delays) }; // Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() @@ -1298,8 +1331,8 @@ enum ImGuiDragDropFlags_ { ImGuiDragDropFlags_None = 0, // BeginDragDropSource() flags - ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disable this behavior. - ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return false, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. + ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // Disable preview tooltip. By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disables this behavior. + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return false, to avoid subsequent user code submitting tooltips. This flag disables this behavior so you can still call IsItemHovered() on the source item. ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of dear imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously. @@ -1308,7 +1341,7 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. ImGuiDragDropFlags_AcceptNoPreviewTooltip = 1 << 12, // Request hiding the BeginDragDropSource tooltip from the BeginDragDropTarget site. - ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect, // For peeking ahead and inspecting the payload before delivery. }; // Standard Drag and Drop payload types. You can define you own payload types using short strings. Types starting with '_' are defined by Dear ImGui. @@ -1350,10 +1383,16 @@ enum ImGuiSortDirection_ ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc. }; -// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array -enum ImGuiKey_ +// A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value): can represent Keyboard, Mouse and Gamepad values. +// All our named keys are >= 512. Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87). +// Since >= 1.89 we increased typing (went from int to enum), some legacy code may need a cast to ImGuiKey. +// Read details about the 1.87 and 1.89 transition : https://github.com/ocornut/imgui/issues/4921 +// Note that "Keys" related to physical keys and are not the same concept as input "Characters", the later are submitted via io.AddInputCharacter(). +enum ImGuiKey : int { - ImGuiKey_Tab, + // Keyboard + ImGuiKey_None = 0, + ImGuiKey_Tab = 512, // == ImGuiKey_NamedKey_BEGIN ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, @@ -1368,74 +1407,138 @@ enum ImGuiKey_ ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, - ImGuiKey_KeyPadEnter, - ImGuiKey_A, // for text edit CTRL+A: select all - ImGuiKey_C, // for text edit CTRL+C: copy - ImGuiKey_V, // for text edit CTRL+V: paste - ImGuiKey_X, // for text edit CTRL+X: cut - ImGuiKey_Y, // for text edit CTRL+Y: redo - ImGuiKey_Z, // for text edit CTRL+Z: undo - ImGuiKey_COUNT + ImGuiKey_LeftCtrl, ImGuiKey_LeftShift, ImGuiKey_LeftAlt, ImGuiKey_LeftSuper, + ImGuiKey_RightCtrl, ImGuiKey_RightShift, ImGuiKey_RightAlt, ImGuiKey_RightSuper, + ImGuiKey_Menu, + ImGuiKey_0, ImGuiKey_1, ImGuiKey_2, ImGuiKey_3, ImGuiKey_4, ImGuiKey_5, ImGuiKey_6, ImGuiKey_7, ImGuiKey_8, ImGuiKey_9, + ImGuiKey_A, ImGuiKey_B, ImGuiKey_C, ImGuiKey_D, ImGuiKey_E, ImGuiKey_F, ImGuiKey_G, ImGuiKey_H, ImGuiKey_I, ImGuiKey_J, + ImGuiKey_K, ImGuiKey_L, ImGuiKey_M, ImGuiKey_N, ImGuiKey_O, ImGuiKey_P, ImGuiKey_Q, ImGuiKey_R, ImGuiKey_S, ImGuiKey_T, + ImGuiKey_U, ImGuiKey_V, ImGuiKey_W, ImGuiKey_X, ImGuiKey_Y, ImGuiKey_Z, + ImGuiKey_F1, ImGuiKey_F2, ImGuiKey_F3, ImGuiKey_F4, ImGuiKey_F5, ImGuiKey_F6, + ImGuiKey_F7, ImGuiKey_F8, ImGuiKey_F9, ImGuiKey_F10, ImGuiKey_F11, ImGuiKey_F12, + ImGuiKey_Apostrophe, // ' + ImGuiKey_Comma, // , + ImGuiKey_Minus, // - + ImGuiKey_Period, // . + ImGuiKey_Slash, // / + ImGuiKey_Semicolon, // ; + ImGuiKey_Equal, // = + ImGuiKey_LeftBracket, // [ + ImGuiKey_Backslash, // \ (this text inhibit multiline comment caused by backslash) + ImGuiKey_RightBracket, // ] + ImGuiKey_GraveAccent, // ` + ImGuiKey_CapsLock, + ImGuiKey_ScrollLock, + ImGuiKey_NumLock, + ImGuiKey_PrintScreen, + ImGuiKey_Pause, + ImGuiKey_Keypad0, ImGuiKey_Keypad1, ImGuiKey_Keypad2, ImGuiKey_Keypad3, ImGuiKey_Keypad4, + ImGuiKey_Keypad5, ImGuiKey_Keypad6, ImGuiKey_Keypad7, ImGuiKey_Keypad8, ImGuiKey_Keypad9, + ImGuiKey_KeypadDecimal, + ImGuiKey_KeypadDivide, + ImGuiKey_KeypadMultiply, + ImGuiKey_KeypadSubtract, + ImGuiKey_KeypadAdd, + ImGuiKey_KeypadEnter, + ImGuiKey_KeypadEqual, + + // Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION ACTION + // (download controller mapping PNG/PSD at http://dearimgui.com/controls_sheets) + ImGuiKey_GamepadStart, // Menu (Xbox) + (Switch) Start/Options (PS) + ImGuiKey_GamepadBack, // View (Xbox) - (Switch) Share (PS) + ImGuiKey_GamepadFaceLeft, // X (Xbox) Y (Switch) Square (PS) // Tap: Toggle Menu. Hold: Windowing mode (Focus/Move/Resize windows) + ImGuiKey_GamepadFaceRight, // B (Xbox) A (Switch) Circle (PS) // Cancel / Close / Exit + ImGuiKey_GamepadFaceUp, // Y (Xbox) X (Switch) Triangle (PS) // Text Input / On-screen Keyboard + ImGuiKey_GamepadFaceDown, // A (Xbox) B (Switch) Cross (PS) // Activate / Open / Toggle / Tweak + ImGuiKey_GamepadDpadLeft, // D-pad Left // Move / Tweak / Resize Window (in Windowing mode) + ImGuiKey_GamepadDpadRight, // D-pad Right // Move / Tweak / Resize Window (in Windowing mode) + ImGuiKey_GamepadDpadUp, // D-pad Up // Move / Tweak / Resize Window (in Windowing mode) + ImGuiKey_GamepadDpadDown, // D-pad Down // Move / Tweak / Resize Window (in Windowing mode) + ImGuiKey_GamepadL1, // L Bumper (Xbox) L (Switch) L1 (PS) // Tweak Slower / Focus Previous (in Windowing mode) + ImGuiKey_GamepadR1, // R Bumper (Xbox) R (Switch) R1 (PS) // Tweak Faster / Focus Next (in Windowing mode) + ImGuiKey_GamepadL2, // L Trig. (Xbox) ZL (Switch) L2 (PS) [Analog] + ImGuiKey_GamepadR2, // R Trig. (Xbox) ZR (Switch) R2 (PS) [Analog] + ImGuiKey_GamepadL3, // L Stick (Xbox) L3 (Switch) L3 (PS) + ImGuiKey_GamepadR3, // R Stick (Xbox) R3 (Switch) R3 (PS) + ImGuiKey_GamepadLStickLeft, // [Analog] // Move Window (in Windowing mode) + ImGuiKey_GamepadLStickRight, // [Analog] // Move Window (in Windowing mode) + ImGuiKey_GamepadLStickUp, // [Analog] // Move Window (in Windowing mode) + ImGuiKey_GamepadLStickDown, // [Analog] // Move Window (in Windowing mode) + ImGuiKey_GamepadRStickLeft, // [Analog] + ImGuiKey_GamepadRStickRight, // [Analog] + ImGuiKey_GamepadRStickUp, // [Analog] + ImGuiKey_GamepadRStickDown, // [Analog] + + // Aliases: Mouse Buttons (auto-submitted from AddMouseButtonEvent() calls) + // - This is mirroring the data also written to io.MouseDown[], io.MouseWheel, in a format allowing them to be accessed via standard key API. + ImGuiKey_MouseLeft, ImGuiKey_MouseRight, ImGuiKey_MouseMiddle, ImGuiKey_MouseX1, ImGuiKey_MouseX2, ImGuiKey_MouseWheelX, ImGuiKey_MouseWheelY, + + // [Internal] Reserved for mod storage + ImGuiKey_ReservedForModCtrl, ImGuiKey_ReservedForModShift, ImGuiKey_ReservedForModAlt, ImGuiKey_ReservedForModSuper, + ImGuiKey_COUNT, + + // Keyboard Modifiers (explicitly submitted by backend via AddKeyEvent() calls) + // - This is mirroring the data also written to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper, in a format allowing + // them to be accessed via standard key API, allowing calls such as IsKeyPressed(), IsKeyReleased(), querying duration etc. + // - Code polling every key (e.g. an interface to detect a key press for input mapping) might want to ignore those + // and prefer using the real keys (e.g. ImGuiKey_LeftCtrl, ImGuiKey_RightCtrl instead of ImGuiMod_Ctrl). + // - In theory the value of keyboard modifiers should be roughly equivalent to a logical or of the equivalent left/right keys. + // In practice: it's complicated; mods are often provided from different sources. Keyboard layout, IME, sticky keys and + // backends tend to interfere and break that equivalence. The safer decision is to relay that ambiguity down to the end-user... + ImGuiMod_None = 0, + ImGuiMod_Ctrl = 1 << 12, // Ctrl + ImGuiMod_Shift = 1 << 13, // Shift + ImGuiMod_Alt = 1 << 14, // Option/Menu + ImGuiMod_Super = 1 << 15, // Cmd/Super/Windows + ImGuiMod_Shortcut = 1 << 11, // Alias for Ctrl (non-macOS) _or_ Super (macOS). + ImGuiMod_Mask_ = 0xF800, // 5-bits + + // [Internal] Prior to 1.87 we required user to fill io.KeysDown[512] using their own native index + the io.KeyMap[] array. + // We are ditching this method but keeping a legacy path for user code doing e.g. IsKeyPressed(MY_NATIVE_KEY_CODE) + // If you need to iterate all keys (for e.g. an input mapper) you may use ImGuiKey_NamedKey_BEGIN..ImGuiKey_NamedKey_END. + ImGuiKey_NamedKey_BEGIN = 512, + ImGuiKey_NamedKey_END = ImGuiKey_COUNT, + ImGuiKey_NamedKey_COUNT = ImGuiKey_NamedKey_END - ImGuiKey_NamedKey_BEGIN, +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + ImGuiKey_KeysData_SIZE = ImGuiKey_NamedKey_COUNT, // Size of KeysData[]: only hold named keys + ImGuiKey_KeysData_OFFSET = ImGuiKey_NamedKey_BEGIN, // Accesses to io.KeysData[] must use (key - ImGuiKey_KeysData_OFFSET) index. +#else + ImGuiKey_KeysData_SIZE = ImGuiKey_COUNT, // Size of KeysData[]: hold legacy 0..512 keycodes + named keys + ImGuiKey_KeysData_OFFSET = 0, // Accesses to io.KeysData[] must use (key - ImGuiKey_KeysData_OFFSET) index. +#endif + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGuiKey_ModCtrl = ImGuiMod_Ctrl, ImGuiKey_ModShift = ImGuiMod_Shift, ImGuiKey_ModAlt = ImGuiMod_Alt, ImGuiKey_ModSuper = ImGuiMod_Super, // Renamed in 1.89 + ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter, // Renamed in 1.87 +#endif }; -// To test io.KeyMods (which is a combination of individual fields io.KeyCtrl, io.KeyShift, io.KeyAlt set by user/backend) -enum ImGuiKeyModFlags_ +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO +// OBSOLETED in 1.88 (from July 2022): ImGuiNavInput and io.NavInputs[]. +// Official backends between 1.60 and 1.86: will keep working and feed gamepad inputs as long as IMGUI_DISABLE_OBSOLETE_KEYIO is not set. +// Custom backends: feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums. +enum ImGuiNavInput { - ImGuiKeyModFlags_None = 0, - ImGuiKeyModFlags_Ctrl = 1 << 0, - ImGuiKeyModFlags_Shift = 1 << 1, - ImGuiKeyModFlags_Alt = 1 << 2, - ImGuiKeyModFlags_Super = 1 << 3 -}; - -// Gamepad/Keyboard navigation -// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays. -// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Backend: set ImGuiBackendFlags_HasGamepad and fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). -// Read instructions in imgui.cpp for more details. Download PNG/PSD at http://dearimgui.org/controls_sheets. -enum ImGuiNavInput_ -{ - // Gamepad Mapping - ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Cross (PS4), A (Xbox), A (Switch), Space (Keyboard) - ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Circle (PS4), B (Xbox), B (Switch), Escape (Keyboard) - ImGuiNavInput_Input, // text input / on-screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard) - ImGuiNavInput_Menu, // tap: toggle menu / hold: focus, move, resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard) - ImGuiNavInput_DpadLeft, // move / tweak / resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard) - ImGuiNavInput_DpadRight, // - ImGuiNavInput_DpadUp, // - ImGuiNavInput_DpadDown, // - ImGuiNavInput_LStickLeft, // scroll / move window (w/ PadMenu) // e.g. Left Analog Stick Left/Right/Up/Down - ImGuiNavInput_LStickRight, // - ImGuiNavInput_LStickUp, // - ImGuiNavInput_LStickDown, // - ImGuiNavInput_FocusPrev, // next window (w/ PadMenu) // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) - ImGuiNavInput_FocusNext, // prev window (w/ PadMenu) // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) - ImGuiNavInput_TweakSlow, // slower tweaks // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) - ImGuiNavInput_TweakFast, // faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) - - // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them. - // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeysDown[] instead of io.NavInputs[]. - ImGuiNavInput_KeyLeft_, // move left // = Arrow keys - ImGuiNavInput_KeyRight_, // move right - ImGuiNavInput_KeyUp_, // move up - ImGuiNavInput_KeyDown_, // move down + ImGuiNavInput_Activate, ImGuiNavInput_Cancel, ImGuiNavInput_Input, ImGuiNavInput_Menu, ImGuiNavInput_DpadLeft, ImGuiNavInput_DpadRight, ImGuiNavInput_DpadUp, ImGuiNavInput_DpadDown, + ImGuiNavInput_LStickLeft, ImGuiNavInput_LStickRight, ImGuiNavInput_LStickUp, ImGuiNavInput_LStickDown, ImGuiNavInput_FocusPrev, ImGuiNavInput_FocusNext, ImGuiNavInput_TweakSlow, ImGuiNavInput_TweakFast, ImGuiNavInput_COUNT, - ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyLeft_ }; +#endif // Configuration flags stored in io.ConfigFlags. Set by user/application. enum ImGuiConfigFlags_ { ImGuiConfigFlags_None = 0, - ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeysDown[]. - ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui backend to fill io.NavInputs[]. Backend also needs to set ImGuiBackendFlags_HasGamepad. + ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + space/enter to activate. + ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad. ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth. ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set. ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct imgui to clear mouse position/buttons in NewFrame(). This allows ignoring the mouse information set by the backend. ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead. - // User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are not used by core Dear ImGui) + // User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are NOT used by core Dear ImGui) ImGuiConfigFlags_IsSRGB = 1 << 20, // Application is SRGB-aware. - ImGuiConfigFlags_IsTouchScreen = 1 << 21 // Application is using a touch screen instead of a mouse. + ImGuiConfigFlags_IsTouchScreen = 1 << 21, // Application is using a touch screen instead of a mouse. }; // Backend capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom backend. @@ -1445,7 +1548,7 @@ enum ImGuiBackendFlags_ ImGuiBackendFlags_HasGamepad = 1 << 0, // Backend Platform supports gamepad and currently has one connected. ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Backend Platform supports honoring GetMouseCursor() value to change the OS cursor shape. ImGuiBackendFlags_HasSetMousePos = 1 << 2, // Backend Platform supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set). - ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3 // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices. + ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices. }; // Enumeration for PushStyleColor() / PopStyleColor() @@ -1481,10 +1584,10 @@ enum ImGuiCol_ ImGuiCol_Separator, ImGuiCol_SeparatorHovered, ImGuiCol_SeparatorActive, - ImGuiCol_ResizeGrip, + ImGuiCol_ResizeGrip, // Resize grip in lower-right and lower-left corners of windows. ImGuiCol_ResizeGripHovered, ImGuiCol_ResizeGripActive, - ImGuiCol_Tab, + ImGuiCol_Tab, // TabItem in a TabBar ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, @@ -1499,7 +1602,7 @@ enum ImGuiCol_ ImGuiCol_TableRowBg, // Table row background (even rows) ImGuiCol_TableRowBgAlt, // Table row background (odd rows) ImGuiCol_TextSelectedBg, - ImGuiCol_DragDropTarget, + ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active @@ -1511,7 +1614,7 @@ enum ImGuiCol_ // - The enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code. // During initialization or between frames, feel free to just poke into ImGuiStyle directly. // - Tip: Use your programming IDE navigation facilities on the names in the _second column_ below to find the actual members and their description. -// In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. // With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. // - When changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. enum ImGuiStyleVar_ @@ -1542,6 +1645,9 @@ enum ImGuiStyleVar_ ImGuiStyleVar_TabRounding, // float TabRounding ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign + ImGuiStyleVar_SeparatorTextBorderSize,// float SeparatorTextBorderSize + ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign + ImGuiStyleVar_SeparatorTextPadding,// ImVec2 SeparatorTextPadding ImGuiStyleVar_COUNT }; @@ -1555,7 +1661,7 @@ enum ImGuiButtonFlags_ // [Internal] ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, - ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft + ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, }; // Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() @@ -1596,16 +1702,15 @@ enum ImGuiColorEditFlags_ ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex, ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float, ImGuiColorEditFlags_PickerMask_ = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar, - ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV + ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV, - // Obsolete names (will be removed) -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69] -#endif + // Obsolete names + //ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69] }; // Flags for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc. // We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them. +// (Those are per-item flags. There are shared flags in ImGuiIO: io.ConfigDragClickToInputText) enum ImGuiSliderFlags_ { ImGuiSliderFlags_None = 0, @@ -1613,12 +1718,10 @@ enum ImGuiSliderFlags_ ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits. ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits) ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget - ImGuiSliderFlags_InvalidMask_ = 0x7000000F // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. + ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed. - // Obsolete names (will be removed) -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiSliderFlags_ClampOnInput = ImGuiSliderFlags_AlwaysClamp // [renamed in 1.79] -#endif + // Obsolete names + //ImGuiSliderFlags_ClampOnInput = ImGuiSliderFlags_AlwaysClamp, // [renamed in 1.79] }; // Identify a mouse button. @@ -1639,7 +1742,7 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_Arrow = 0, ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. ImGuiMouseCursor_ResizeAll, // (Unused by Dear ImGui functions) - ImGuiMouseCursor_ResizeNS, // When hovering over an horizontal border + ImGuiMouseCursor_ResizeNS, // When hovering over a horizontal border ImGuiMouseCursor_ResizeEW, // When hovering over a vertical border or a column ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window @@ -1648,16 +1751,28 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_COUNT }; +// Enumeration for AddMouseSourceEvent() actual source of Mouse Input data. +// Historically we use "Mouse" terminology everywhere to indicate pointer data, e.g. MousePos, IsMousePressed(), io.AddMousePosEvent() +// But that "Mouse" data can come from different source which occasionally may be useful for application to know about. +// You can submit a change of pointer type using io.AddMouseSourceEvent(). +enum ImGuiMouseSource : int +{ + ImGuiMouseSource_Mouse = 0, // Input is coming from an actual mouse. + ImGuiMouseSource_TouchScreen, // Input is coming from a touch screen (no hovering prior to initial press, less precise initial press aiming, dual-axis wheeling possible). + ImGuiMouseSource_Pen, // Input is coming from a pressure/magnetic pen (often used in conjunction with high-sampling rates). + ImGuiMouseSource_COUNT +}; + // Enumeration for ImGui::SetWindow***(), SetNextWindow***(), SetNextItem***() functions // Represent a condition. // Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always. enum ImGuiCond_ { ImGuiCond_None = 0, // No condition (always set the variable), same as _Always - ImGuiCond_Always = 1 << 0, // No condition (always set the variable) + ImGuiCond_Always = 1 << 0, // No condition (always set the variable), same as _None ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call will succeed) ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file) - ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time) + ImGuiCond_Appearing = 1 << 3, // Set the variable if the object/window is appearing after being hidden/inactive (or the first time) }; //----------------------------------------------------------------------------- @@ -1706,7 +1821,7 @@ struct ImVector // Constructors, destructor inline ImVector() { Size = Capacity = 0; Data = NULL; } inline ImVector(const ImVector& src) { Size = Capacity = 0; Data = NULL; operator=(src); } - inline ImVector& operator=(const ImVector& src) { clear(); resize(src.Size); memcpy(Data, src.Data, (size_t)Size * sizeof(T)); return *this; } + inline ImVector& operator=(const ImVector& src) { clear(); resize(src.Size); if (src.Data) memcpy(Data, src.Data, (size_t)Size * sizeof(T)); return *this; } inline ~ImVector() { if (Data) IM_FREE(Data); } // Important: does not destruct anything inline void clear() { if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } } // Important: does not destruct anything @@ -1736,13 +1851,14 @@ struct ImVector inline void resize(int new_size, const T& v) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) memcpy(&Data[n], &v, sizeof(v)); Size = new_size; } inline void shrink(int new_size) { IM_ASSERT(new_size <= Size); Size = new_size; } // Resize a vector to a smaller size, guaranteed not to cause a reallocation inline void reserve(int new_capacity) { if (new_capacity <= Capacity) return; T* new_data = (T*)IM_ALLOC((size_t)new_capacity * sizeof(T)); if (Data) { memcpy(new_data, Data, (size_t)Size * sizeof(T)); IM_FREE(Data); } Data = new_data; Capacity = new_capacity; } + inline void reserve_discard(int new_capacity) { if (new_capacity <= Capacity) return; if (Data) IM_FREE(Data); Data = (T*)IM_ALLOC((size_t)new_capacity * sizeof(T)); Capacity = new_capacity; } // NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the ImVector data itself! e.g. v.push_back(v[10]) is forbidden. inline void push_back(const T& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); memcpy(&Data[Size], &v, sizeof(v)); Size++; } inline void pop_back() { IM_ASSERT(Size > 0); Size--; } inline void push_front(const T& v) { if (Size == 0) push_back(v); else insert(Data, v); } inline T* erase(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(T)); Size--; return Data + off; } - inline T* erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last > it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - count) * sizeof(T)); Size -= (int)count; return Data + off; } + inline T* erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last >= it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; } inline T* erase_unsorted(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; if (it < Data + Size - 1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; } inline T* insert(const T* it, const T& v) { IM_ASSERT(it >= Data && it <= Data + Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; } inline bool contains(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } @@ -1769,7 +1885,7 @@ struct ImGuiStyle ImVec2 WindowPadding; // Padding within a window. float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended. float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). - ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constraint individual windows, use SetNextWindowSizeConstraints(). + ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constrain individual windows, use SetNextWindowSizeConstraints(). ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. ImGuiDir WindowMenuButtonPosition; // Side of the collapsing/docking button in the title bar (None/Left/Right). Defaults to ImGuiDir_Left. float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. @@ -1792,20 +1908,31 @@ struct ImGuiStyle float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. float TabBorderSize; // Thickness of border around tabs. - float TabMinWidthForCloseButton; // Minimum width for close button to appears on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + float TabMinWidthForCloseButton; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. + float SeparatorTextBorderSize; // Thickkness of border in SeparatorText() + ImVec2 SeparatorTextAlign; // Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center). + ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y. ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly! float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). - bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering. Latched at the beginning of the frame (copied to ImDrawList). + bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. float CircleTessellationMaxError; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. ImVec4 Colors[ImGuiCol_COUNT]; + // Behaviors + // (It is possible to modify those fields mid-frame if specific behavior need it, unlike e.g. configuration fields in ImGuiIO) + float HoverStationaryDelay; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary. + float HoverDelayShort; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayShort). Usually used along with HoverStationaryDelay. + float HoverDelayNormal; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayNormal). " + ImGuiHoveredFlags HoverFlagsForTooltipMouse;// Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse. + ImGuiHoveredFlags HoverFlagsForTooltipNav; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad. + IMGUI_API ImGuiStyle(); IMGUI_API void ScaleAllSizes(float scale_factor); }; @@ -1817,26 +1944,30 @@ struct ImGuiStyle // Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage. //----------------------------------------------------------------------------- +// [Internal] Storage used by IsKeyDown(), IsKeyPressed() etc functions. +// If prior to 1.87 you used io.KeysDownDuration[] (which was marked as internal), you should use GetKeyData(key)->DownDuration and *NOT* io.KeysData[key]->DownDuration. +struct ImGuiKeyData +{ + bool Down; // True for if key is down + float DownDuration; // Duration the key has been down (<0.0f: not pressed, 0.0f: just pressed, >0.0f: time held) + float DownDurationPrev; // Last frame duration the key has been down + float AnalogValue; // 0.0f..1.0f for gamepad values +}; + struct ImGuiIO { //------------------------------------------------------------------ - // Configuration (fill once) // Default value + // Configuration // Default value //------------------------------------------------------------------ ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc. ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend. - ImVec2 DisplaySize; // // Main display size, in pixels (generally == GetMainViewport()->Size) - float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. + ImVec2 DisplaySize; // // Main display size, in pixels (generally == GetMainViewport()->Size). May change every frame. + float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. May change every frame. float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds. const char* IniFilename; // = "imgui.ini" // Path to .ini file (important: default "imgui.ini" is relative to current working dir!). Set NULL to disable automatic .ini loading/saving or if you want to manually call LoadIniSettingsXXX() / SaveIniSettingsXXX() functions. const char* LogFilename; // = "imgui_log.txt"// Path to .log file (default parameter to ImGui::LogToFile when no file is specified). - float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. - float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. - float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging. - int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. - float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). - float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. - void* UserData; // = NULL // Store your own data for retrieval by callbacks. + void* UserData; // = NULL // Store your own data. ImFontAtlas*Fonts; // // Font atlas: load, rasterize and pack one or more fonts into a single texture. float FontGlobalScale; // = 1.0f // Global scale all fonts @@ -1847,12 +1978,41 @@ struct ImGuiIO // Miscellaneous options bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. + bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). + bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar. float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. + // Inputs Behaviors + // (other variables, ones which are expected to be tweaked within UI code, are exposed in ImGuiStyle) + float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. + float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. + float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging. + float KeyRepeatDelay; // = 0.275f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). + float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. + + //------------------------------------------------------------------ + // Debug options + //------------------------------------------------------------------ + + // Tools to test correct Begin/End and BeginChild/EndChild behaviors. + // Presently Begin()/End() and BeginChild()/EndChild() needs to ALWAYS be called in tandem, regardless of return value of BeginXXX() + // This is inconsistent with other BeginXXX functions and create confusion for many users. + // We expect to update the API eventually. In the meanwhile we provide tools to facilitate checking user-code behavior. + bool ConfigDebugBeginReturnValueOnce;// = false // First-time calls to Begin()/BeginChild() will return false. NEEDS TO BE SET AT APPLICATION BOOT TIME if you don't want to miss windows. + bool ConfigDebugBeginReturnValueLoop;// = false // Some calls to Begin()/BeginChild() will return false. Will cycle through window depths then repeat. Suggested use: add "io.ConfigDebugBeginReturnValue = io.KeyShift" in your main loop then occasionally press SHIFT. Windows should be flickering while running. + + // Option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data. + // Backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them. + // Consider using e.g. Win32's IsDebuggerPresent() as an additional filter (or see ImOsIsDebuggerPresent() in imgui_test_engine/imgui_te_utils.cpp for a Unix compatible version). + bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys() in input processing. + + // Options to audit .ini data + bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower) + //------------------------------------------------------------------ // Platform Functions // (the imgui_impl_xxxx backend files are setting those up for you) @@ -1873,31 +2033,33 @@ struct ImGuiIO // Optional: Notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME on Windows) // (default to use native imm32 api on Windows) - void (*ImeSetInputScreenPosFn)(int x, int y); - void* ImeWindowHandle; // = NULL // (Windows) Set this to your HWND to get automatic IME cursor positioning. + void (*SetPlatformImeDataFn)(ImGuiViewport* viewport, ImGuiPlatformImeData* data); +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + void* ImeWindowHandle; // = NULL // [Obsolete] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. +#else + void* _UnusedPadding; // Unused field to keep data structure the same size. +#endif //------------------------------------------------------------------ - // Input - Fill before calling NewFrame() + // Input - Call before calling NewFrame() //------------------------------------------------------------------ - ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) - bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. - float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all backends. - bool KeyCtrl; // Keyboard modifier pressed: Control - bool KeyShift; // Keyboard modifier pressed: Shift - bool KeyAlt; // Keyboard modifier pressed: Alt - bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows - bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). - float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). + // Input Functions + IMGUI_API void AddKeyEvent(ImGuiKey key, bool down); // Queue a new key down/up event. Key should be "translated" (as in, generally ImGuiKey_A matches the key end-user would use to emit an 'A' character) + IMGUI_API void AddKeyAnalogEvent(ImGuiKey key, bool down, float v); // Queue a new key down/up event for analog values (e.g. ImGuiKey_Gamepad_ values). Dead-zones should be handled by the backend. + IMGUI_API void AddMousePosEvent(float x, float y); // Queue a mouse position update. Use -FLT_MAX,-FLT_MAX to signify no mouse (e.g. app not focused and not hovered) + IMGUI_API void AddMouseButtonEvent(int button, bool down); // Queue a mouse button change + IMGUI_API void AddMouseWheelEvent(float wheel_x, float wheel_y); // Queue a mouse wheel update. wheel_y<0: scroll down, wheel_y>0: scroll up, wheel_x<0: scroll right, wheel_x>0: scroll left. + IMGUI_API void AddMouseSourceEvent(ImGuiMouseSource source); // Queue a mouse source change (Mouse/TouchScreen/Pen) + IMGUI_API void AddFocusEvent(bool focused); // Queue a gain/loss of focus for the application (generally based on OS/platform focus of your window) + IMGUI_API void AddInputCharacter(unsigned int c); // Queue a new character input + IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue a new character input from a UTF-16 character, it can be a surrogate + IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue a new characters input from a UTF-8 string - // Functions - IMGUI_API void AddInputCharacter(unsigned int c); // Queue new character input - IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue new character input from an UTF-16 character, it can be a surrogate - IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue new characters input from an UTF-8 string - IMGUI_API void AddFocusEvent(bool focused); // Notifies Dear ImGui when hosting platform windows lose or gain input focus - IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually - IMGUI_API void ClearInputKeys(); // [Internal] Release all keys + IMGUI_API void SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native_scancode, int native_legacy_index = -1); // [Optional] Specify index for legacy <1.87 IsKeyXXX() functions with native indices + specify native keycode, scancode. + IMGUI_API void SetAppAcceptingEvents(bool accepting_events); // Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen. + IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually + IMGUI_API void ClearInputKeys(); // [Internal] Release all keys //------------------------------------------------------------------ // Output - Updated by NewFrame() or EndFrame()/Render() @@ -1905,49 +2067,74 @@ struct ImGuiIO // generally easier and more correct to use their state BEFORE calling NewFrame(). See FAQ for details!) //------------------------------------------------------------------ - bool WantCaptureMouse; // Set when Dear ImGui will use mouse inputs, in this case do not dispatch them to your main game/application (either way, always pass on mouse inputs to imgui). (e.g. unclicked mouse is hovering over an imgui window, widget is active, mouse was clicked over an imgui window, etc.). - bool WantCaptureKeyboard; // Set when Dear ImGui will use keyboard inputs, in this case do not dispatch them to your main game/application (either way, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). - bool WantTextInput; // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). - bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. - bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! - bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. - bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events). - float Framerate; // Rough estimate of application framerate, in frame per second. Solely for convenience. Rolling average estimation based on io.DeltaTime over 120 frames. - int MetricsRenderVertices; // Vertices output during last call to Render() - int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 - int MetricsRenderWindows; // Number of visible windows - int MetricsActiveWindows; // Number of active windows - int MetricsActiveAllocations; // Number of active allocations, updated by MemAlloc/MemFree based on current context. May be off if you have multiple imgui contexts. - ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. + bool WantCaptureMouse; // Set when Dear ImGui will use mouse inputs, in this case do not dispatch them to your main game/application (either way, always pass on mouse inputs to imgui). (e.g. unclicked mouse is hovering over an imgui window, widget is active, mouse was clicked over an imgui window, etc.). + bool WantCaptureKeyboard; // Set when Dear ImGui will use keyboard inputs, in this case do not dispatch them to your main game/application (either way, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). + bool WantTextInput; // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). + bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. + bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! + bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. + bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events). + float Framerate; // Estimate of application framerate (rolling average over 60 frames, based on io.DeltaTime), in frame per second. Solely for convenience. Slow applications may not want to use a moving average or may want to reset underlying buffers occasionally. + int MetricsRenderVertices; // Vertices output during last call to Render() + int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 + int MetricsRenderWindows; // Number of visible windows + int MetricsActiveWindows; // Number of active windows + int MetricsActiveAllocations; // Number of active allocations, updated by MemAlloc/MemFree based on current context. May be off if you have multiple imgui contexts. + ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. + + // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. + // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). + // Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space) +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512. + bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow. + float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums. +#endif //------------------------------------------------------------------ // [Internal] Dear ImGui will maintain those fields. Forward compatibility not guaranteed! //------------------------------------------------------------------ - bool WantCaptureMouseUnlessPopupClose;// Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. - ImGuiKeyModFlags KeyMods; // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame() - ImGuiKeyModFlags KeyModsPrev; // Previous key mods - ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) - ImVec2 MouseClickedPos[5]; // Position at time of clicking - double MouseClickedTime[5]; // Time of last click (used to figure out double-click) - bool MouseClicked[5]; // Mouse button went from !Down to Down - bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? - bool MouseReleased[5]; // Mouse button went from Down to !Down - bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds. - bool MouseDownOwnedUnlessPopupClose[5];//Track if button was clicked inside a dear imgui window. - bool MouseDownWasDoubleClick[5]; // Track if button down was a double-click - float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) - float MouseDownDurationPrev[5]; // Previous time the mouse button has been down - ImVec2 MouseDragMaxDistanceAbs[5]; // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point - float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point - float KeysDownDuration[512]; // Duration the keyboard key has been down (0.0f == just pressed) - float KeysDownDurationPrev[512]; // Previous duration the key has been down - float NavInputsDownDuration[ImGuiNavInput_COUNT]; - float NavInputsDownDurationPrev[ImGuiNavInput_COUNT]; - float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui. - bool AppFocusLost; - ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16 - ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper. + ImGuiContext* Ctx; // Parent UI context (needs to be set explicitly by parent). + + // Main Input State + // (this block used to be written by backend, since 1.87 it is best to NOT write to those directly, call the AddXXX functions above instead) + // (reading from those variables is fair game, as they are extremely unlikely to be moving anywhere) + ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) + bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Other buttons allow us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. >0 scrolls Up, <0 scrolls Down. Hold SHIFT to turn vertical scroll into horizontal scroll. + float MouseWheelH; // Mouse wheel Horizontal. >0 scrolls Left, <0 scrolls Right. Most users don't have a mouse with a horizontal wheel, may not be filled by all backends. + ImGuiMouseSource MouseSource; // Mouse actual input peripheral (Mouse/TouchScreen/Pen). + bool KeyCtrl; // Keyboard modifier down: Control + bool KeyShift; // Keyboard modifier down: Shift + bool KeyAlt; // Keyboard modifier down: Alt + bool KeySuper; // Keyboard modifier down: Cmd/Super/Windows + + // Other state maintained from data above + IO function calls + ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. DOES NOT CONTAINS ImGuiMod_Shortcut which is pretranslated). Read-only, updated by NewFrame() + ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE]; // Key state for all known keys. Use IsKeyXXX() functions to access this. + bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. + ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) + ImVec2 MouseClickedPos[5]; // Position at time of clicking + double MouseClickedTime[5]; // Time of last click (used to figure out double-click) + bool MouseClicked[5]; // Mouse button went from !Down to Down (same as MouseClickedCount[x] != 0) + bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? (same as MouseClickedCount[x] == 2) + ImU16 MouseClickedCount[5]; // == 0 (not clicked), == 1 (same as MouseClicked[]), == 2 (double-clicked), == 3 (triple-clicked) etc. when going from !Down to Down + ImU16 MouseClickedLastCount[5]; // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done. + bool MouseReleased[5]; // Mouse button went from Down to !Down + bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds. + bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window. + bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system. + float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) + float MouseDownDurationPrev[5]; // Previous time the mouse button has been down + float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point (used for moving thresholds) + float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui. + bool AppFocusLost; // Only modify via AddFocusEvent() + bool AppAcceptingEvents; // Only modify via SetAppAcceptingEvents() + ImS8 BackendUsingLegacyKeyArrays; // -1: unknown, 0: using AddKeyEvent(), 1: using legacy io.KeysDown[] + bool BackendUsingLegacyNavInputArray; // 0: using AddKeyAnalogEvent(), 1: writing to legacy io.NavInputs[] directly + ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16() + ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper. IMGUI_API ImGuiIO(); }; @@ -1967,6 +2154,7 @@ struct ImGuiIO // - ImGuiInputTextFlags_CallbackResize: Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. struct ImGuiInputTextCallbackData { + ImGuiContext* Ctx; // Parent UI context ImGuiInputTextFlags EventFlag; // One ImGuiInputTextFlags_Callback* // Read-only ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only void* UserData; // What user passed to InputText() // Read-only @@ -1998,7 +2186,7 @@ struct ImGuiInputTextCallbackData // NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough. struct ImGuiSizeCallbackData { - void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() + void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints(). Generally store an integer or float in here (need reinterpret_cast<>). ImVec2 Pos; // Read-only. Window position, for reference. ImVec2 CurrentSize; // Read-only. Current window size. ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. @@ -2051,7 +2239,7 @@ struct ImGuiTableSortSpecs }; //----------------------------------------------------------------------------- -// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor) +// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, Math Operators, ImColor) //----------------------------------------------------------------------------- // Helper: Unicode defines @@ -2062,7 +2250,7 @@ struct ImGuiTableSortSpecs #define IM_UNICODE_CODEPOINT_MAX 0xFFFF // Maximum Unicode code point supported by this build. #endif -// Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. +// Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create a UI within deep-nested code that runs multiple times every frame. // Usage: static ImGuiOnceUponAFrame oaf; if (oaf) ImGui::Text("This will be called only once per frame"); struct ImGuiOnceUponAFrame { @@ -2170,10 +2358,12 @@ struct ImGuiStorage }; // Helper: Manually clip large list of items. -// If you are submitting lots of evenly spaced items and you have a random access to the list, you can perform coarse -// clipping based on visibility to save yourself from processing those items at all. +// If you have lots evenly spaced items and you have random access to the list, you can perform coarse +// clipping based on visibility to only submit items that are in view. // The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped. -// (Dear ImGui already clip items based on their bounds but it needs to measure text size to do so, whereas manual coarse clipping before submission makes this cost and your own data fetching/submission cost almost null) +// (Dear ImGui already clip items based on their bounds but: it needs to first layout the item to do so, and generally +// fetching/submitting your own data incurs additional cost. Coarse clipping using ImGuiListClipper allows you to easily +// scale using lists with tens of thousands of items without a problem) // Usage: // ImGuiListClipper clipper; // clipper.Begin(1000); // We have 1000 elements, evenly spaced. @@ -2182,37 +2372,68 @@ struct ImGuiStorage // ImGui::Text("line number %d", i); // Generally what happens is: // - Clipper lets you process the first element (DisplayStart = 0, DisplayEnd = 1) regardless of it being visible or not. -// - User code submit one element. +// - User code submit that one element. // - Clipper can measure the height of the first element // - Clipper calculate the actual range of elements to display based on the current clipping rectangle, position the cursor before the first visible element. // - User code submit visible elements. +// - The clipper also handles various subtleties related to keyboard/gamepad navigation, wrapping etc. struct ImGuiListClipper { - int DisplayStart; - int DisplayEnd; - - // [Internal] - int ItemsCount; - int StepNo; - int ItemsFrozen; - float ItemsHeight; - float StartPosY; - - IMGUI_API ImGuiListClipper(); - IMGUI_API ~ImGuiListClipper(); + ImGuiContext* Ctx; // Parent UI context + int DisplayStart; // First item to display, updated by each call to Step() + int DisplayEnd; // End of items to display (exclusive) + int ItemsCount; // [Internal] Number of items + float ItemsHeight; // [Internal] Height of item after a first step and item submission can calculate it + float StartPosY; // [Internal] Cursor position at the time of Begin() or after table frozen rows are all processed + void* TempData; // [Internal] Internal data // items_count: Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step) // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing(). - IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1. - IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. - IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. + IMGUI_API ImGuiListClipper(); + IMGUI_API ~ImGuiListClipper(); + IMGUI_API void Begin(int items_count, float items_height = -1.0f); + IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. + IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. + + // Call IncludeRangeByIndices() *BEFORE* first call to Step() if you need a range of items to not be clipped, regardless of their visibility. + // (Due to alignment / padding of certain items it is possible that an extra item may be included on either end of the display range). + IMGUI_API void IncludeRangeByIndices(int item_begin, int item_end); // item_end is exclusive e.g. use (42, 42+1) to make item 42 never clipped. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79] + inline void ForceDisplayRangeByIndices(int item_begin, int item_end) { IncludeRangeByIndices(item_begin, item_end); } // [renamed in 1.89.6] + //inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79] #endif }; +// Helpers: ImVec2/ImVec4 operators +// - It is important that we are keeping those disabled by default so they don't leak in user space. +// - This is in order to allow user enabling implicit cast operators between ImVec2/ImVec4 and their own types (using IM_VEC2_CLASS_EXTRA in imconfig.h) +// - You can use '#define IMGUI_DEFINE_MATH_OPERATORS' to import our operators, provided as a courtesy. +#ifdef IMGUI_DEFINE_MATH_OPERATORS +#define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED +IM_MSVC_RUNTIME_CHECKS_OFF +static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); } +static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } +static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } +static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } +static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); } +static inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); } +static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } +static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } +static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } +static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } +static inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; } +static inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; } +static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } +static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } +static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } +IM_MSVC_RUNTIME_CHECKS_RESTORE +#endif + // Helpers macros to generate 32-bit encoded colors +// User can declare their own format by #defining the 5 _SHIFT/_MASK macros in their imconfig file. +#ifndef IM_COL32_R_SHIFT #ifdef IMGUI_USE_BGRA_PACKED_COLOR #define IM_COL32_R_SHIFT 16 #define IM_COL32_G_SHIFT 8 @@ -2226,6 +2447,7 @@ struct ImGuiListClipper #define IM_COL32_A_SHIFT 24 #define IM_COL32_A_MASK 0xFF000000 #endif +#endif #define IM_COL32(R,G,B,A) (((ImU32)(A)<> IM_COL32_R_SHIFT) & 0xFF) * sc; Value.y = (float)((rgba >> IM_COL32_G_SHIFT) & 0xFF) * sc; Value.z = (float)((rgba >> IM_COL32_B_SHIFT) & 0xFF) * sc; Value.w = (float)((rgba >> IM_COL32_A_SHIFT) & 0xFF) * sc; } - ImColor(float r, float g, float b, float a = 1.0f) { Value.x = r; Value.y = g; Value.z = b; Value.w = a; } - ImColor(const ImVec4& col) { Value = col; } inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } inline operator ImVec4() const { return Value; } @@ -2280,16 +2502,16 @@ typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* c #define ImDrawCallback_ResetRenderState (ImDrawCallback)(-1) // Typically, 1 command = 1 GPU draw call (unless command is a callback) -// - VtxOffset/IdxOffset: When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset' is enabled, -// those fields allow us to render meshes larger than 64K vertices while keeping 16-bit indices. -// Pre-1.71 backends will typically ignore the VtxOffset/IdxOffset fields. +// - VtxOffset: When 'io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset' is enabled, +// this fields allow us to render meshes larger than 64K vertices while keeping 16-bit indices. +// Backends made for <1.71. will typically ignore the VtxOffset fields. // - The ClipRect/TextureId/VtxOffset fields must be contiguous as we memcmp() them together (this is asserted for). struct ImDrawCmd { ImVec4 ClipRect; // 4*4 // Clipping rectangle (x1, y1, x2, y2). Subtract ImDrawData->DisplayPos to get clipping rectangle in "viewport" coordinates ImTextureID TextureId; // 4-8 // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. unsigned int VtxOffset; // 4 // Start offset in vertex buffer. ImGuiBackendFlags_RendererHasVtxOffset: always 0, otherwise may be >0 to support meshes larger than 64K vertices with 16-bit indices. - unsigned int IdxOffset; // 4 // Start offset in index buffer. Always equal to sum of ElemCount drawn so far. + unsigned int IdxOffset; // 4 // Start offset in index buffer. unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. void* UserCallbackData; // 4-8 // The draw callback code can access this. @@ -2311,7 +2533,7 @@ struct ImDrawVert #else // You can override the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h // The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. -// The type has to be described within the macro (you can either declare the struct or use a typedef). This is because ImVec2/ImU32 are likely not declared a the time you'd want to set your type up. +// The type has to be described within the macro (you can either declare the struct or use a typedef). This is because ImVec2/ImU32 are likely not declared at the time you'd want to set your type up. // NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR SO ANY CUSTOM FIELD WILL BE UNINITIALIZED. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THEM DURING RENDER OR TO IGNORE THEM. IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; #endif @@ -2366,7 +2588,7 @@ enum ImDrawFlags_ ImDrawFlags_RoundCornersRight = ImDrawFlags_RoundCornersBottomRight | ImDrawFlags_RoundCornersTopRight, ImDrawFlags_RoundCornersAll = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight | ImDrawFlags_RoundCornersBottomLeft | ImDrawFlags_RoundCornersBottomRight, ImDrawFlags_RoundCornersDefault_ = ImDrawFlags_RoundCornersAll, // Default to ALL corners if none of the _RoundCornersXX flags are specified. - ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone + ImDrawFlags_RoundCornersMask_ = ImDrawFlags_RoundCornersAll | ImDrawFlags_RoundCornersNone, }; // Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly. @@ -2375,9 +2597,9 @@ enum ImDrawListFlags_ { ImDrawListFlags_None = 0, ImDrawListFlags_AntiAliasedLines = 1 << 0, // Enable anti-aliased lines/borders (*2 the number of triangles for 1.0f wide line or lines thin enough to be drawn using textures, otherwise *3 the number of triangles) - ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering. + ImDrawListFlags_AntiAliasedLinesUseTex = 1 << 1, // Enable anti-aliased lines/borders using textures when possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). ImDrawListFlags_AntiAliasedFill = 1 << 2, // Enable anti-aliased edge around filled shapes (rounded rectangles, circles). - ImDrawListFlags_AllowVtxOffset = 1 << 3 // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled. + ImDrawListFlags_AllowVtxOffset = 1 << 3, // Can emit 'VtxOffset > 0' to allow large meshes. Set when 'ImGuiBackendFlags_RendererHasVtxOffset' is enabled. }; // Draw command list @@ -2399,7 +2621,7 @@ struct ImDrawList // [Internal, used while building lists] unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0. - const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) + ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) const char* _OwnerName; // Pointer to owner window's name for debugging ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) @@ -2411,10 +2633,10 @@ struct ImDrawList float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) - ImDrawList(const ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; } + ImDrawList(ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; } ~ImDrawList() { _ClearFreeMemory(); } - IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) + IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) IMGUI_API void PushClipRectFullScreen(); IMGUI_API void PopClipRect(); IMGUI_API void PushTextureID(ImTextureID texture_id); @@ -2423,11 +2645,12 @@ struct ImDrawList inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); } // Primitives + // - Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing. // - For rectangular primitives, "p_min" and "p_max" represent the upper-left and lower-right corners. // - For circle primitives, use "num_segments == 0" to automatically calculate tessellation (preferred). // In older versions (until Dear ImGui 1.77) the AddCircle functions defaulted to num_segments == 12. // In future versions we will use textures to provide cheaper and higher-quality circles. - // Use AddNgon() and AddNgonFilled() functions if you need to guaranteed a specific number of sides. + // Use AddNgon() and AddNgonFilled() functions if you need to guarantee a specific number of sides. IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f); IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size) IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size) @@ -2443,7 +2666,7 @@ struct ImDrawList IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); - IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order. + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points) IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points) @@ -2456,10 +2679,11 @@ struct ImDrawList IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col, float rounding, ImDrawFlags flags = 0); // Stateful path API, add points then finish with PathFillConvex() or PathStroke() + // - Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing. inline void PathClear() { _Path.Size = 0; } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); } - inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } // Note: Anti-aliased filling requires points to be in clockwise order. + inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; } IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0); IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle @@ -2494,10 +2718,9 @@ struct ImDrawList inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; } inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } // Write vertex with unique index -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); } - inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); } -#endif + // Obsolete names + //inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); } // OBSOLETED in 1.80 (Jan 2021) + //inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); } // OBSOLETED in 1.80 (Jan 2021) // [Internal helpers] IMGUI_API void _ResetForNewFrame(); @@ -2549,7 +2772,7 @@ struct ImFontConfig bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. - const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. + const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. @@ -2611,7 +2834,7 @@ enum ImFontAtlasFlags_ ImFontAtlasFlags_None = 0, ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two ImFontAtlasFlags_NoMouseCursors = 1 << 1, // Don't build software mouse cursors into the atlas (save a little texture memory) - ImFontAtlasFlags_NoBakedLines = 1 << 2 // Don't build thick line textures into the atlas (save a little texture memory). The AntiAliasedLinesUseTex features uses them, otherwise they will be rendered using polygons (more expensive for CPU/GPU). + ImFontAtlasFlags_NoBakedLines = 1 << 2, // Don't build thick line textures into the atlas (save a little texture memory, allow support for point/nearest filtering). The AntiAliasedLinesUseTex features uses them, otherwise they will be rendered using polygons (more expensive for CPU/GPU). }; // Load and rasterize multiple TTF/OTF fonts into a same texture. The font atlas will build a single texture holding: @@ -2630,7 +2853,7 @@ enum ImFontAtlasFlags_ // - Important: By default, AddFontFromMemoryTTF() takes ownership of the data. Even though we are not writing to it, we will free the pointer on destruction. // You can set font_cfg->FontDataOwnedByAtlas=false to keep ownership of your data and it won't be freed, // - Even though many functions are suffixed with "TTF", OTF data is supported just as well. -// - This is an old API and it is currently awkward for those and and various other reasons! We will address them in the future! +// - This is an old API and it is currently awkward for those and various other reasons! We will address them in the future! struct ImFontAtlas { IMGUI_API ImFontAtlas(); @@ -2654,7 +2877,7 @@ struct ImFontAtlas IMGUI_API bool Build(); // Build pixels data. This is called automatically for you by the GetTexData*** functions. IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel - bool IsBuilt() const { return Fonts.Size > 0 && TexReady; } // Bit ambiguous: used to detect when user didn't built texture but effectively we should check TexID != 0 except that would be backend dependent... + bool IsBuilt() const { return Fonts.Size > 0 && TexReady; } // Bit ambiguous: used to detect when user didn't build texture but effectively we should check TexID != 0 except that would be backend dependent... void SetTexID(ImTextureID id) { TexID = id; } //------------------------------------------- @@ -2662,9 +2885,11 @@ struct ImFontAtlas //------------------------------------------- // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) - // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8"Hello world" syntax. See FAQ for details. + // NB: Make sure that your string are UTF-8 and NOT in your local code page. + // Read https://github.com/ocornut/imgui/blob/master/docs/FONTS.md/#about-utf-8-encoding for details. // NB: Consider using ImFontGlyphRangesBuilder to build glyph ranges from textual data. IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin + IMGUI_API const ImWchar* GetGlyphRangesGreek(); // Default + Greek and Coptic IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 2999 Ideographs IMGUI_API const ImWchar* GetGlyphRangesChineseFull(); // Default + Half-Width + Japanese Hiragana/Katakana + full set of about 21000 CJK Unified Ideographs @@ -2699,8 +2924,9 @@ struct ImFontAtlas ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_) ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. - int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0. + int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false). bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert. + void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas). // [Internal] // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. @@ -2725,10 +2951,9 @@ struct ImFontAtlas int PackIdMouseCursors; // Custom texture rectangle ID for white pixel and mouse cursors int PackIdLines; // Custom texture rectangle ID for baked anti-aliased lines -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+ + // [Obsolete] + //typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+ //typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+ -#endif }; // Font runtime data and rendering @@ -2750,8 +2975,10 @@ struct ImFont const ImFontConfig* ConfigData; // 4-8 // in // // Pointer within ContainerAtlas->ConfigData short ConfigDataCount; // 2 // in // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont. ImWchar FallbackChar; // 2 // out // = FFFD/'?' // Character used if a glyph isn't found. - ImWchar EllipsisChar; // 2 // out // = '...' // Character used for ellipsis rendering. - ImWchar DotChar; // 2 // out // = '.' // Character used for ellipsis rendering (if a single '...' character isn't found) + ImWchar EllipsisChar; // 2 // out // = '...'/'.'// Character used for ellipsis rendering. + short EllipsisCharCount; // 1 // out // 1 or 3 + float EllipsisWidth; // 4 // out // Width + float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0 bool DirtyLookupTables; // 1 // out // float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale() float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] @@ -2771,8 +2998,8 @@ struct ImFont // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; - IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const; - IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; + IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) const; + IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; // [Internal] Don't use! IMGUI_API void BuildLookupTable(); @@ -2794,7 +3021,7 @@ enum ImGuiViewportFlags_ ImGuiViewportFlags_None = 0, ImGuiViewportFlags_IsPlatformWindow = 1 << 0, // Represent a Platform Window ImGuiViewportFlags_IsPlatformMonitor = 1 << 1, // Represent a Platform Monitor (unused yet) - ImGuiViewportFlags_OwnedByApp = 1 << 2 // Platform Window: is created/managed by the application (rather than a dear imgui backend) + ImGuiViewportFlags_OwnedByApp = 1 << 2, // Platform Window: is created/managed by the application (rather than a dear imgui backend) }; // - Currently represents the Platform Window created by the application which is hosting our Dear ImGui windows. @@ -2812,6 +3039,9 @@ struct ImGuiViewport ImVec2 WorkPos; // Work Area: Position of the viewport minus task bars, menus bars, status bars (>= Pos) ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size) + // Platform/Backend Dependent Data + void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms) + ImGuiViewport() { memset(this, 0, sizeof(*this)); } // Helpers @@ -2819,58 +3049,102 @@ struct ImGuiViewport ImVec2 GetWorkCenter() const { return ImVec2(WorkPos.x + WorkSize.x * 0.5f, WorkPos.y + WorkSize.y * 0.5f); } }; +//----------------------------------------------------------------------------- +// [SECTION] Platform Dependent Interfaces +//----------------------------------------------------------------------------- + +// (Optional) Support for IME (Input Method Editor) via the io.SetPlatformImeDataFn() function. +struct ImGuiPlatformImeData +{ + bool WantVisible; // A widget wants the IME to be visible + ImVec2 InputPos; // Position of the input cursor + float InputLineHeight; // Line height + + ImGuiPlatformImeData() { memset(this, 0, sizeof(*this)); } +}; + //----------------------------------------------------------------------------- // [SECTION] Obsolete functions and types // (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details) // Please keep your copy of dear imgui up to date! Occasionally set '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in imconfig.h to stay ahead. //----------------------------------------------------------------------------- +namespace ImGui +{ +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // map ImGuiKey_* values into legacy native key index. == io.KeyMap[key] +#else + static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END && "ImGuiKey and native_index was merged together and native_index is disabled by IMGUI_DISABLE_OBSOLETE_KEYIO. Please switch to ImGuiKey."); return key; } +#endif +} + #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + // OBSOLETED in 1.89.7 (from June 2023) + IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() before item. + // OBSOLETED in 1.89.4 (from March 2023) + static inline void PushAllowKeyboardFocus(bool tab_stop) { PushTabStop(tab_stop); } + static inline void PopAllowKeyboardFocus() { PopTabStop(); } + // OBSOLETED in 1.89 (from August 2022) + IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // Use new ImageButton() signature (explicit item id, regular FramePadding) + // OBSOLETED in 1.88 (from May 2022) + static inline void CaptureKeyboardFromApp(bool want_capture_keyboard = true) { SetNextFrameWantCaptureKeyboard(want_capture_keyboard); } // Renamed as name was misleading + removed default value. + static inline void CaptureMouseFromApp(bool want_capture_mouse = true) { SetNextFrameWantCaptureMouse(want_capture_mouse); } // Renamed as name was misleading + removed default value. + // OBSOLETED in 1.86 (from November 2021) + IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Calculate coarse clipping for large list of evenly sized items. Prefer using ImGuiListClipper. // OBSOLETED in 1.85 (from August 2021) - static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; } - // OBSOLETED in 1.81 (from February 2021) - IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items - static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); } - static inline void ListBoxFooter() { EndListBox(); } - // OBSOLETED in 1.79 (from August 2020) - static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry! - // OBSOLETED in 1.78 (from June 2020) - // Old drag/sliders functions that took a 'float power = 1.0' argument instead of flags. - // For shared code, you can version check at compile-time with `#if IMGUI_VERSION_NUM >= 17704`. - IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, float power); - IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, float power); - static inline bool DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, format, power); } - static inline bool DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 2, v_speed, &v_min, &v_max, format, power); } - static inline bool DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 3, v_speed, &v_min, &v_max, format, power); } - static inline bool DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, float power) { return DragScalarN(label, ImGuiDataType_Float, v, 4, v_speed, &v_min, &v_max, format, power); } - IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power); - IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, float power); - static inline bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, float power) { return SliderScalar(label, ImGuiDataType_Float, v, &v_min, &v_max, format, power); } - static inline bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 2, &v_min, &v_max, format, power); } - static inline bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 3, &v_min, &v_max, format, power); } - static inline bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, float power) { return SliderScalarN(label, ImGuiDataType_Float, v, 4, &v_min, &v_max, format, power); } - // OBSOLETED in 1.77 (from June 2020) - static inline bool BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mb, bool over_items) { return BeginPopupContextWindow(str_id, mb | (over_items ? 0 : ImGuiPopupFlags_NoOpenOverItems)); } - // OBSOLETED in 1.72 (from April 2019) - static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); } - // OBSOLETED in 1.71 (from June 2019) - static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); } - // OBSOLETED in 1.70 (from May 2019) - static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; } + static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; } // Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE) - //static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); } // OBSOLETED in 1.69 (from Mar 2019) - //static inline void SetScrollHere(float ratio = 0.5f) { SetScrollHereY(ratio); } // OBSOLETED in 1.66 (from Nov 2018) - //static inline bool IsItemDeactivatedAfterChange() { return IsItemDeactivatedAfterEdit(); } // OBSOLETED in 1.63 (from Aug 2018) - //static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } // OBSOLETED in 1.60 (from Apr 2018) - //static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } // OBSOLETED in 1.60 (between Dec 2017 and Apr 2018) - //static inline void ShowTestWindow() { return ShowDemoWindow(); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) - //static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) - //static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) - //static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) - //static inline float GetItemsLineHeightWithSpacing() { return GetFrameHeightWithSpacing(); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //-- OBSOLETED in 1.81 (from February 2021) + //static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); } + //static inline bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1) { float height = GetTextLineHeightWithSpacing() * ((height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f) + GetStyle().FramePadding.y * 2.0f; return BeginListBox(label, ImVec2(0.0f, height)); } // Helper to calculate size from items_count and height_in_items + //static inline void ListBoxFooter() { EndListBox(); } + //-- OBSOLETED in 1.79 (from August 2020) + //static inline void OpenPopupContextItem(const char* str_id = NULL, ImGuiMouseButton mb = 1) { OpenPopupOnItemClick(str_id, mb); } // Bool return value removed. Use IsWindowAppearing() in BeginPopup() instead. Renamed in 1.77, renamed back in 1.79. Sorry! + //-- OBSOLETED in 1.78 (from June 2020): Old drag/sliders functions that took a 'float power > 1.0f' argument instead of ImGuiSliderFlags_Logarithmic. See github.com/ocornut/imgui/issues/3361 for details. + //IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, float power = 1.0f) // OBSOLETED in 1.78 (from June 2020) + //IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, float power = 1.0f); // OBSOLETED in 1.78 (from June 2020) + //IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power = 1.0f); // OBSOLETED in 1.78 (from June 2020) + //IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, const void* p_min, const void* p_max, const char* format, float power = 1.0f); // OBSOLETED in 1.78 (from June 2020) + //static inline bool DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, float power = 1.0f) { return DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //static inline bool DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, float power = 1.0f) { return DragScalarN(label, ImGuiDataType_Float, v, 2, v_speed, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //static inline bool DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, float power = 1.0f) { return DragScalarN(label, ImGuiDataType_Float, v, 3, v_speed, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //static inline bool DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, float power = 1.0f) { return DragScalarN(label, ImGuiDataType_Float, v, 4, v_speed, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //static inline bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, float power = 1.0f) { return SliderScalar(label, ImGuiDataType_Float, v, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //static inline bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, float power = 1.0f) { return SliderScalarN(label, ImGuiDataType_Float, v, 2, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //static inline bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, float power = 1.0f) { return SliderScalarN(label, ImGuiDataType_Float, v, 3, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //static inline bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, float power = 1.0f) { return SliderScalarN(label, ImGuiDataType_Float, v, 4, &v_min, &v_max, format, power); } // OBSOLETED in 1.78 (from June 2020) + //-- OBSOLETED in 1.77 and before + //static inline bool BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mb, bool over_items) { return BeginPopupContextWindow(str_id, mb | (over_items ? 0 : ImGuiPopupFlags_NoOpenOverItems)); } // OBSOLETED in 1.77 (from June 2020) + //static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); } // OBSOLETED in 1.72 (from July 2019) + //static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); } // OBSOLETED in 1.71 (from June 2019) + //static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; } // OBSOLETED in 1.70 (from May 2019) + //static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); } // OBSOLETED in 1.69 (from Mar 2019) + //static inline void SetScrollHere(float ratio = 0.5f) { SetScrollHereY(ratio); } // OBSOLETED in 1.66 (from Nov 2018) + //static inline bool IsItemDeactivatedAfterChange() { return IsItemDeactivatedAfterEdit(); } // OBSOLETED in 1.63 (from Aug 2018) + //-- OBSOLETED in 1.60 and before + //static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } // OBSOLETED in 1.60 (from Apr 2018) + //static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } // OBSOLETED in 1.60 (between Dec 2017 and Apr 2018) + //static inline void ShowTestWindow() { return ShowDemoWindow(); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //static inline float GetItemsLineHeightWithSpacing() { return GetFrameHeightWithSpacing(); } // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) + //IMGUI_API bool Begin(char* name, bool* p_open, ImVec2 size_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags=0); // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017): Equivalent of using SetNextWindowSize(size, ImGuiCond_FirstUseEver) and SetNextWindowBgAlpha(). + //static inline bool IsRootWindowOrAnyChildHovered() { return IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows); } // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) + //static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) + //static inline void SetNextWindowPosCenter(ImGuiCond c=0) { SetNextWindowPos(GetMainViewport()->GetCenter(), c, ImVec2(0.5f,0.5f)); } // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) + //static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } // OBSOLETED in 1.51 (between Jun 2017 and Aug 2017) + //static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETED in 1.51 (between Jun 2017 and Aug 2017): This was misleading and partly broken. You probably want to use the io.WantCaptureMouse flag instead. + //static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } // OBSOLETED in 1.51 (between Jun 2017 and Aug 2017) + //static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } // OBSOLETED in 1.51 (between Jun 2017 and Aug 2017) + //-- OBSOLETED in 1.50 and before + //static inline bool CollapsingHeader(char* label, const char* str_id, bool framed = true, bool default_open = false) { return CollapsingHeader(label, (default_open ? (1 << 5) : 0)); } // OBSOLETED in 1.49 + //static inline ImFont*GetWindowFont() { return GetFont(); } // OBSOLETED in 1.48 + //static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETED in 1.48 + //static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETED in 1.42 } // OBSOLETED in 1.82 (from Mars 2021): flags for AddRect(), AddRectFilled(), AddImageRounded(), PathRect() @@ -2886,11 +3160,26 @@ enum ImDrawCornerFlags_ ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, - ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight + ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight, }; +// RENAMED and MERGED both ImGuiKey_ModXXX and ImGuiModFlags_XXX into ImGuiMod_XXX (from September 2022) +// RENAMED ImGuiKeyModFlags -> ImGuiModFlags in 1.88 (from April 2022). Exceptionally commented out ahead of obscolescence schedule to reduce confusion and because they were not meant to be used in the first place. +typedef ImGuiKeyChord ImGuiModFlags; // == int. We generally use ImGuiKeyChord to mean "a ImGuiKey or-ed with any number of ImGuiMod_XXX value", but you may store only mods in there. +enum ImGuiModFlags_ { ImGuiModFlags_None = 0, ImGuiModFlags_Ctrl = ImGuiMod_Ctrl, ImGuiModFlags_Shift = ImGuiMod_Shift, ImGuiModFlags_Alt = ImGuiMod_Alt, ImGuiModFlags_Super = ImGuiMod_Super }; +//typedef ImGuiKeyChord ImGuiKeyModFlags; // == int +//enum ImGuiKeyModFlags_ { ImGuiKeyModFlags_None = 0, ImGuiKeyModFlags_Ctrl = ImGuiMod_Ctrl, ImGuiKeyModFlags_Shift = ImGuiMod_Shift, ImGuiKeyModFlags_Alt = ImGuiMod_Alt, ImGuiKeyModFlags_Super = ImGuiMod_Super }; + #endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +// RENAMED IMGUI_DISABLE_METRICS_WINDOW > IMGUI_DISABLE_DEBUG_TOOLS in 1.88 (from June 2022) +#if defined(IMGUI_DISABLE_METRICS_WINDOW) && !defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && !defined(IMGUI_DISABLE_DEBUG_TOOLS) +#define IMGUI_DISABLE_DEBUG_TOOLS +#endif +#if defined(IMGUI_DISABLE_METRICS_WINDOW) && defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) +#error IMGUI_DISABLE_METRICS_WINDOW was renamed to IMGUI_DISABLE_DEBUG_TOOLS, please use new name. +#endif + //----------------------------------------------------------------------------- #if defined(__clang__) diff --git a/Externals/imgui/imgui.vcxproj b/Externals/imgui/imgui.vcxproj index bcbd4d0766..daeb44865d 100644 --- a/Externals/imgui/imgui.vcxproj +++ b/Externals/imgui/imgui.vcxproj @@ -23,6 +23,7 @@ + diff --git a/Externals/imgui/imgui_demo.cpp b/Externals/imgui/imgui_demo.cpp new file mode 100644 index 0000000000..431cd4c788 --- /dev/null +++ b/Externals/imgui/imgui_demo.cpp @@ -0,0 +1,8130 @@ +// dear imgui, v1.89.7 +// (demo code) + +// Help: +// - Read FAQ at http://dearimgui.com/faq +// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that. +// - Need help integrating Dear ImGui in your codebase? +// - Read Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started +// - Read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. +// Read imgui.cpp for more details, documentation and comments. +// Get the latest version at https://github.com/ocornut/imgui + +// ------------------------------------------------- +// PLEASE DO NOT REMOVE THIS FILE FROM YOUR PROJECT! +// ------------------------------------------------- +// Message to the person tempted to delete this file when integrating Dear ImGui into their codebase: +// Think again! It is the most useful reference code that you and other coders will want to refer to and call. +// Have the ImGui::ShowDemoWindow() function wired in an always-available debug menu of your game/app! +// Also include Metrics! ItemPicker! DebugLog! and other debug features. +// Removing this file from your project is hindering access to documentation for everyone in your team, +// likely leading you to poorer usage of the library. +// Everything in this file will be stripped out by the linker if you don't call ImGui::ShowDemoWindow(). +// If you want to link core Dear ImGui in your shipped builds but want a thorough guarantee that the demo will not be +// linked, you can setup your imconfig.h with #define IMGUI_DISABLE_DEMO_WINDOWS and those functions will be empty. +// In another situation, whenever you have Dear ImGui available you probably want this to be available for reference. +// Thank you, +// -Your beloved friend, imgui_demo.cpp (which you won't delete) + +// Message to beginner C/C++ programmers about the meaning of the 'static' keyword: +// In this demo code, we frequently use 'static' variables inside functions. A static variable persists across calls, +// so it is essentially like a global variable but declared inside the scope of the function. We do this as a way to +// gather code and data in the same place, to make the demo source code faster to read, faster to write, and smaller +// in size. It also happens to be a convenient way of storing simple UI related information as long as your function +// doesn't need to be reentrant or used in multiple threads. This might be a pattern you will want to use in your code, +// but most of the real data you would be editing is likely going to be stored outside your functions. + +// The Demo code in this file is designed to be easy to copy-and-paste into your application! +// Because of this: +// - We never omit the ImGui:: prefix when calling functions, even though most code here is in the same namespace. +// - We try to declare static variables in the local scope, as close as possible to the code using them. +// - We never use any of the helpers/facilities used internally by Dear ImGui, unless available in the public API. +// - We never use maths operators on ImVec2/ImVec4. For our other sources files we use them, and they are provided +// by imgui.h using the IMGUI_DEFINE_MATH_OPERATORS define. For your own sources file they are optional +// and require you either enable those, either provide your own via IM_VEC2_CLASS_EXTRA in imconfig.h. +// Because we can't assume anything about your support of maths operators, we cannot use them in imgui_demo.cpp. + +// Navigating this file: +// - In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. + +/* + +Index of this file: + +// [SECTION] Forward Declarations +// [SECTION] Helpers +// [SECTION] Demo Window / ShowDemoWindow() +// - ShowDemoWindow() +// - sub section: ShowDemoWindowWidgets() +// - sub section: ShowDemoWindowLayout() +// - sub section: ShowDemoWindowPopups() +// - sub section: ShowDemoWindowTables() +// - sub section: ShowDemoWindowInputs() +// [SECTION] About Window / ShowAboutWindow() +// [SECTION] Style Editor / ShowStyleEditor() +// [SECTION] User Guide / ShowUserGuide() +// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar() +// [SECTION] Example App: Debug Console / ShowExampleAppConsole() +// [SECTION] Example App: Debug Log / ShowExampleAppLog() +// [SECTION] Example App: Simple Layout / ShowExampleAppLayout() +// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor() +// [SECTION] Example App: Long Text / ShowExampleAppLongText() +// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize() +// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize() +// [SECTION] Example App: Simple overlay / ShowExampleAppSimpleOverlay() +// [SECTION] Example App: Fullscreen window / ShowExampleAppFullscreen() +// [SECTION] Example App: Manipulating window titles / ShowExampleAppWindowTitles() +// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering() +// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments() + +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE + +// System includes +#include // toupper +#include // INT_MIN, INT_MAX +#include // sqrtf, powf, cosf, sinf, floorf, ceilf +#include // vsnprintf, sscanf, printf +#include // NULL, malloc, free, atoi +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t +#else +#include // intptr_t +#endif + +// Visual Studio warnings +#ifdef _MSC_VER +#pragma warning (disable: 4127) // condition expression is constant +#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to an 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#if __has_warning("-Wunknown-warning-option") +#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! +#endif +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' +#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning: 'xx' is deprecated: The POSIX name for this.. // for strdup used in demo code (so user can copy & paste the code) +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type +#pragma clang diagnostic ignored "-Wformat-security" // warning: format string is not a string literal +#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. +#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used. +#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. +#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier +#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#elif defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size +#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure) +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub. +#endif + +// Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!) +#ifdef _WIN32 +#define IM_NEWLINE "\r\n" +#else +#define IM_NEWLINE "\n" +#endif + +// Helpers +#if defined(_MSC_VER) && !defined(snprintf) +#define snprintf _snprintf +#endif +#if defined(_MSC_VER) && !defined(vsnprintf) +#define vsnprintf _vsnprintf +#endif + +// Format specifiers, printing 64-bit hasn't been decently standardized... +// In a real application you should be using PRId64 and PRIu64 from (non-windows) and on Windows define them yourself. +#ifdef _MSC_VER +#define IM_PRId64 "I64d" +#define IM_PRIu64 "I64u" +#else +#define IM_PRId64 "lld" +#define IM_PRIu64 "llu" +#endif + +// Helpers macros +// We normally try to not use many helpers in imgui_demo.cpp in order to make code easier to copy and paste, +// but making an exception here as those are largely simplifying code... +// In other imgui sources we can use nicer internal functions from imgui_internal.h (ImMin/ImMax) but not in the demo. +#define IM_MIN(A, B) (((A) < (B)) ? (A) : (B)) +#define IM_MAX(A, B) (((A) >= (B)) ? (A) : (B)) +#define IM_CLAMP(V, MN, MX) ((V) < (MN) ? (MN) : (V) > (MX) ? (MX) : (V)) + +// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall +#ifndef IMGUI_CDECL +#ifdef _MSC_VER +#define IMGUI_CDECL __cdecl +#else +#define IMGUI_CDECL +#endif +#endif + +//----------------------------------------------------------------------------- +// [SECTION] Forward Declarations, Helpers +//----------------------------------------------------------------------------- + +#if !defined(IMGUI_DISABLE_DEMO_WINDOWS) + +// Forward Declarations +static void ShowExampleAppDocuments(bool* p_open); +static void ShowExampleAppMainMenuBar(); +static void ShowExampleAppConsole(bool* p_open); +static void ShowExampleAppLog(bool* p_open); +static void ShowExampleAppLayout(bool* p_open); +static void ShowExampleAppPropertyEditor(bool* p_open); +static void ShowExampleAppLongText(bool* p_open); +static void ShowExampleAppAutoResize(bool* p_open); +static void ShowExampleAppConstrainedResize(bool* p_open); +static void ShowExampleAppSimpleOverlay(bool* p_open); +static void ShowExampleAppFullscreen(bool* p_open); +static void ShowExampleAppWindowTitles(bool* p_open); +static void ShowExampleAppCustomRendering(bool* p_open); +static void ShowExampleMenuFile(); + +// We split the contents of the big ShowDemoWindow() function into smaller functions +// (because the link time of very large functions grow non-linearly) +static void ShowDemoWindowWidgets(); +static void ShowDemoWindowLayout(); +static void ShowDemoWindowPopups(); +static void ShowDemoWindowTables(); +static void ShowDemoWindowColumns(); +static void ShowDemoWindowInputs(); + +//----------------------------------------------------------------------------- +// [SECTION] Helpers +//----------------------------------------------------------------------------- + +// Helper to display a little (?) mark which shows a tooltip when hovered. +// In your own code you may want to display an actual icon if you are using a merged icon fonts (see docs/FONTS.md) +static void HelpMarker(const char* desc) +{ + ImGui::TextDisabled("(?)"); + if (ImGui::BeginItemTooltip()) + { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted(desc); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } +} + +// Helper to wire demo markers located in code to an interactive browser +typedef void (*ImGuiDemoMarkerCallback)(const char* file, int line, const char* section, void* user_data); +extern ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback; +extern void* GImGuiDemoMarkerCallbackUserData; +ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback = NULL; +void* GImGuiDemoMarkerCallbackUserData = NULL; +#define IMGUI_DEMO_MARKER(section) do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback(__FILE__, __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0) + +//----------------------------------------------------------------------------- +// [SECTION] Demo Window / ShowDemoWindow() +//----------------------------------------------------------------------------- +// - ShowDemoWindow() +// - ShowDemoWindowWidgets() +// - ShowDemoWindowLayout() +// - ShowDemoWindowPopups() +// - ShowDemoWindowTables() +// - ShowDemoWindowColumns() +// - ShowDemoWindowInputs() +//----------------------------------------------------------------------------- + +// Demonstrate most Dear ImGui features (this is big function!) +// You may execute this function to experiment with the UI and understand what it does. +// You may then search for keywords in the code when you are interested by a specific feature. +void ImGui::ShowDemoWindow(bool* p_open) +{ + // Exceptionally add an extra assert here for people confused about initial Dear ImGui setup + // Most functions would normally just crash if the context is missing. + IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing dear imgui context. Refer to examples app!"); + + // Examples Apps (accessible from the "Examples" menu) + static bool show_app_main_menu_bar = false; + static bool show_app_documents = false; + static bool show_app_console = false; + static bool show_app_log = false; + static bool show_app_layout = false; + static bool show_app_property_editor = false; + static bool show_app_long_text = false; + static bool show_app_auto_resize = false; + static bool show_app_constrained_resize = false; + static bool show_app_simple_overlay = false; + static bool show_app_fullscreen = false; + static bool show_app_window_titles = false; + static bool show_app_custom_rendering = false; + + if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); + if (show_app_documents) ShowExampleAppDocuments(&show_app_documents); + if (show_app_console) ShowExampleAppConsole(&show_app_console); + if (show_app_log) ShowExampleAppLog(&show_app_log); + if (show_app_layout) ShowExampleAppLayout(&show_app_layout); + if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); + if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); + if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); + if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize); + if (show_app_simple_overlay) ShowExampleAppSimpleOverlay(&show_app_simple_overlay); + if (show_app_fullscreen) ShowExampleAppFullscreen(&show_app_fullscreen); + if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles); + if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); + + // Dear ImGui Tools/Apps (accessible from the "Tools" menu) + static bool show_app_metrics = false; + static bool show_app_debug_log = false; + static bool show_app_stack_tool = false; + static bool show_app_about = false; + static bool show_app_style_editor = false; + + if (show_app_metrics) + ImGui::ShowMetricsWindow(&show_app_metrics); + if (show_app_debug_log) + ImGui::ShowDebugLogWindow(&show_app_debug_log); + if (show_app_stack_tool) + ImGui::ShowStackToolWindow(&show_app_stack_tool); + if (show_app_about) + ImGui::ShowAboutWindow(&show_app_about); + if (show_app_style_editor) + { + ImGui::Begin("Dear ImGui Style Editor", &show_app_style_editor); + ImGui::ShowStyleEditor(); + ImGui::End(); + } + + // Demonstrate the various window flags. Typically you would just use the default! + static bool no_titlebar = false; + static bool no_scrollbar = false; + static bool no_menu = false; + static bool no_move = false; + static bool no_resize = false; + static bool no_collapse = false; + static bool no_close = false; + static bool no_nav = false; + static bool no_background = false; + static bool no_bring_to_front = false; + static bool unsaved_document = false; + + ImGuiWindowFlags window_flags = 0; + if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; + if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; + if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; + if (no_move) window_flags |= ImGuiWindowFlags_NoMove; + if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; + if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; + if (no_nav) window_flags |= ImGuiWindowFlags_NoNav; + if (no_background) window_flags |= ImGuiWindowFlags_NoBackground; + if (no_bring_to_front) window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus; + if (unsaved_document) window_flags |= ImGuiWindowFlags_UnsavedDocument; + if (no_close) p_open = NULL; // Don't pass our bool* to Begin + + // We specify a default position/size in case there's no data in the .ini file. + // We only do it to make the demo applications a little more welcoming, but typically this isn't required. + const ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20), ImGuiCond_FirstUseEver); + ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver); + + // Main body of the Demo window starts here. + if (!ImGui::Begin("Dear ImGui Demo", p_open, window_flags)) + { + // Early out if the window is collapsed, as an optimization. + ImGui::End(); + return; + } + + // Most "big" widgets share a common width settings by default. See 'Demo->Layout->Widgets Width' for details. + // e.g. Use 2/3 of the space for widgets and 1/3 for labels (right align) + //ImGui::PushItemWidth(-ImGui::GetWindowWidth() * 0.35f); + // e.g. Leave a fixed amount of width for labels (by passing a negative value), the rest goes to widgets. + ImGui::PushItemWidth(ImGui::GetFontSize() * -12); + + // Menu Bar + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + IMGUI_DEMO_MARKER("Menu/File"); + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Examples")) + { + IMGUI_DEMO_MARKER("Menu/Examples"); + ImGui::MenuItem("Main menu bar", NULL, &show_app_main_menu_bar); + ImGui::MenuItem("Console", NULL, &show_app_console); + ImGui::MenuItem("Log", NULL, &show_app_log); + ImGui::MenuItem("Simple layout", NULL, &show_app_layout); + ImGui::MenuItem("Property editor", NULL, &show_app_property_editor); + ImGui::MenuItem("Long text display", NULL, &show_app_long_text); + ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize); + ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize); + ImGui::MenuItem("Simple overlay", NULL, &show_app_simple_overlay); + ImGui::MenuItem("Fullscreen window", NULL, &show_app_fullscreen); + ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles); + ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); + ImGui::MenuItem("Documents", NULL, &show_app_documents); + ImGui::EndMenu(); + } + //if (ImGui::MenuItem("MenuItem")) {} // You can also use MenuItem() inside a menu bar! + if (ImGui::BeginMenu("Tools")) + { + IMGUI_DEMO_MARKER("Menu/Tools"); +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + const bool has_debug_tools = true; +#else + const bool has_debug_tools = false; +#endif + ImGui::MenuItem("Metrics/Debugger", NULL, &show_app_metrics, has_debug_tools); + ImGui::MenuItem("Debug Log", NULL, &show_app_debug_log, has_debug_tools); + ImGui::MenuItem("Stack Tool", NULL, &show_app_stack_tool, has_debug_tools); + ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor); + ImGui::MenuItem("About Dear ImGui", NULL, &show_app_about); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + ImGui::Text("dear imgui says hello! (%s) (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM); + ImGui::Spacing(); + + IMGUI_DEMO_MARKER("Help"); + if (ImGui::CollapsingHeader("Help")) + { + ImGui::SeparatorText("ABOUT THIS DEMO:"); + ImGui::BulletText("Sections below are demonstrating many aspects of the library."); + ImGui::BulletText("The \"Examples\" menu above leads to more demo contents."); + ImGui::BulletText("The \"Tools\" menu above gives access to: About Box, Style Editor,\n" + "and Metrics/Debugger (general purpose Dear ImGui debugging tool)."); + + ImGui::SeparatorText("PROGRAMMER GUIDE:"); + ImGui::BulletText("See the ShowDemoWindow() code in imgui_demo.cpp. <- you are here!"); + ImGui::BulletText("See comments in imgui.cpp."); + ImGui::BulletText("See example applications in the examples/ folder."); + ImGui::BulletText("Read the FAQ at http://www.dearimgui.com/faq/"); + ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableKeyboard' for keyboard controls."); + ImGui::BulletText("Set 'io.ConfigFlags |= NavEnableGamepad' for gamepad controls."); + + ImGui::SeparatorText("USER GUIDE:"); + ImGui::ShowUserGuide(); + } + + IMGUI_DEMO_MARKER("Configuration"); + if (ImGui::CollapsingHeader("Configuration")) + { + ImGuiIO& io = ImGui::GetIO(); + + if (ImGui::TreeNode("Configuration##2")) + { + ImGui::SeparatorText("General"); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", &io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); + ImGui::SameLine(); HelpMarker("Enable keyboard controls."); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); + ImGui::SameLine(); HelpMarker("Enable gamepad controls. Require backend to set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details."); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos); + ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); + ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) + { + // The "NoMouse" option can get us stuck with a disabled mouse! Let's provide an alternative way to fix it: + if (fmodf((float)ImGui::GetTime(), 0.40f) < 0.20f) + { + ImGui::SameLine(); + ImGui::Text("<>"); + } + if (ImGui::IsKeyPressed(ImGuiKey_Space)) + io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; + } + ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", &io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); + ImGui::SameLine(); HelpMarker("Instruct backend to not alter mouse cursor shape and visibility."); + ImGui::Checkbox("io.ConfigInputTrickleEventQueue", &io.ConfigInputTrickleEventQueue); + ImGui::SameLine(); HelpMarker("Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates."); + ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); + ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); + + ImGui::SeparatorText("Widgets"); + ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); + ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting)."); + ImGui::Checkbox("io.ConfigInputTextEnterKeepActive", &io.ConfigInputTextEnterKeepActive); + ImGui::SameLine(); HelpMarker("Pressing Enter will keep item active and select contents (single-line only)."); + ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText); + ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving)."); + ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges); + ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback."); + ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly); + ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors); + ImGui::Text("Also see Style->Rendering for rendering options."); + + ImGui::SeparatorText("Debug"); + ImGui::BeginDisabled(); + ImGui::Checkbox("io.ConfigDebugBeginReturnValueOnce", &io.ConfigDebugBeginReturnValueOnce); // . + ImGui::EndDisabled(); + ImGui::SameLine(); HelpMarker("First calls to Begin()/BeginChild() will return false.\n\nTHIS OPTION IS DISABLED because it needs to be set at application boot-time to make sense. Showing the disabled option is a way to make this feature easier to discover"); + ImGui::Checkbox("io.ConfigDebugBeginReturnValueLoop", &io.ConfigDebugBeginReturnValueLoop); + ImGui::SameLine(); HelpMarker("Some calls to Begin()/BeginChild() will return false.\n\nWill cycle through window depths then repeat. Windows should be flickering while running."); + ImGui::Checkbox("io.ConfigDebugIgnoreFocusLoss", &io.ConfigDebugIgnoreFocusLoss); + ImGui::SameLine(); HelpMarker("Option to deactivate io.AddFocusEvent(false) handling. May facilitate interactions with a debugger when focus loss leads to clearing inputs data."); + ImGui::Checkbox("io.ConfigDebugIniSettings", &io.ConfigDebugIniSettings); + ImGui::SameLine(); HelpMarker("Option to save .ini data with extra comments (particularly helpful for Docking, but makes saving slower)."); + + ImGui::TreePop(); + ImGui::Spacing(); + } + + IMGUI_DEMO_MARKER("Configuration/Backend Flags"); + if (ImGui::TreeNode("Backend Flags")) + { + HelpMarker( + "Those flags are set by the backends (imgui_impl_xxx files) to specify their capabilities.\n" + "Here we expose them as read-only fields to avoid breaking interactions with your backend."); + + // FIXME: Maybe we need a BeginReadonly() equivalent to keep label bright? + ImGui::BeginDisabled(); + ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", &io.BackendFlags, ImGuiBackendFlags_HasGamepad); + ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors); + ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos); + ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset); + ImGui::EndDisabled(); + ImGui::TreePop(); + ImGui::Spacing(); + } + + IMGUI_DEMO_MARKER("Configuration/Style"); + if (ImGui::TreeNode("Style")) + { + HelpMarker("The same contents can be accessed in 'Tools->Style Editor' or by calling the ShowStyleEditor() function."); + ImGui::ShowStyleEditor(); + ImGui::TreePop(); + ImGui::Spacing(); + } + + IMGUI_DEMO_MARKER("Configuration/Capture, Logging"); + if (ImGui::TreeNode("Capture/Logging")) + { + HelpMarker( + "The logging API redirects all text output so you can easily capture the content of " + "a window or a block. Tree nodes can be automatically expanded.\n" + "Try opening any of the contents below in this window and then click one of the \"Log To\" button."); + ImGui::LogButtons(); + + HelpMarker("You can also call ImGui::LogText() to output directly to the log without a visual output."); + if (ImGui::Button("Copy \"Hello, world!\" to clipboard")) + { + ImGui::LogToClipboard(); + ImGui::LogText("Hello, world!"); + ImGui::LogFinish(); + } + ImGui::TreePop(); + } + } + + IMGUI_DEMO_MARKER("Window options"); + if (ImGui::CollapsingHeader("Window options")) + { + if (ImGui::BeginTable("split", 3)) + { + ImGui::TableNextColumn(); ImGui::Checkbox("No titlebar", &no_titlebar); + ImGui::TableNextColumn(); ImGui::Checkbox("No scrollbar", &no_scrollbar); + ImGui::TableNextColumn(); ImGui::Checkbox("No menu", &no_menu); + ImGui::TableNextColumn(); ImGui::Checkbox("No move", &no_move); + ImGui::TableNextColumn(); ImGui::Checkbox("No resize", &no_resize); + ImGui::TableNextColumn(); ImGui::Checkbox("No collapse", &no_collapse); + ImGui::TableNextColumn(); ImGui::Checkbox("No close", &no_close); + ImGui::TableNextColumn(); ImGui::Checkbox("No nav", &no_nav); + ImGui::TableNextColumn(); ImGui::Checkbox("No background", &no_background); + ImGui::TableNextColumn(); ImGui::Checkbox("No bring to front", &no_bring_to_front); + ImGui::TableNextColumn(); ImGui::Checkbox("Unsaved document", &unsaved_document); + ImGui::EndTable(); + } + } + + // All demo contents + ShowDemoWindowWidgets(); + ShowDemoWindowLayout(); + ShowDemoWindowPopups(); + ShowDemoWindowTables(); + ShowDemoWindowInputs(); + + // End of ShowDemoWindow() + ImGui::PopItemWidth(); + ImGui::End(); +} + +static void ShowDemoWindowWidgets() +{ + IMGUI_DEMO_MARKER("Widgets"); + if (!ImGui::CollapsingHeader("Widgets")) + return; + + static bool disable_all = false; // The Checkbox for that is inside the "Disabled" section at the bottom + if (disable_all) + ImGui::BeginDisabled(); + + IMGUI_DEMO_MARKER("Widgets/Basic"); + if (ImGui::TreeNode("Basic")) + { + ImGui::SeparatorText("General"); + + IMGUI_DEMO_MARKER("Widgets/Basic/Button"); + static int clicked = 0; + if (ImGui::Button("Button")) + clicked++; + if (clicked & 1) + { + ImGui::SameLine(); + ImGui::Text("Thanks for clicking me!"); + } + + IMGUI_DEMO_MARKER("Widgets/Basic/Checkbox"); + static bool check = true; + ImGui::Checkbox("checkbox", &check); + + IMGUI_DEMO_MARKER("Widgets/Basic/RadioButton"); + static int e = 0; + ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine(); + ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); + ImGui::RadioButton("radio c", &e, 2); + + // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. + IMGUI_DEMO_MARKER("Widgets/Basic/Buttons (Colored)"); + for (int i = 0; i < 7; i++) + { + if (i > 0) + ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.8f, 0.8f)); + ImGui::Button("Click"); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + + // Use AlignTextToFramePadding() to align text baseline to the baseline of framed widgets elements + // (otherwise a Text+SameLine+Button sequence will have the text a little too high by default!) + // See 'Demo->Layout->Text Baseline Alignment' for details. + ImGui::AlignTextToFramePadding(); + ImGui::Text("Hold to repeat:"); + ImGui::SameLine(); + + // Arrow buttons with Repeater + IMGUI_DEMO_MARKER("Widgets/Basic/Buttons (Repeating)"); + static int counter = 0; + float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + ImGui::PushButtonRepeat(true); + if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { counter--; } + ImGui::SameLine(0.0f, spacing); + if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { counter++; } + ImGui::PopButtonRepeat(); + ImGui::SameLine(); + ImGui::Text("%d", counter); + + ImGui::Button("Tooltip"); + ImGui::SetItemTooltip("I am a tooltip"); + + ImGui::LabelText("label", "Value"); + + ImGui::SeparatorText("Inputs"); + + { + // To wire InputText() with std::string or any other custom string type, + // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file. + IMGUI_DEMO_MARKER("Widgets/Basic/InputText"); + static char str0[128] = "Hello, world!"; + ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); + ImGui::SameLine(); HelpMarker( + "USER:\n" + "Hold SHIFT or use mouse to select text.\n" + "CTRL+Left/Right to word jump.\n" + "CTRL+A or Double-Click to select all.\n" + "CTRL+X,CTRL+C,CTRL+V clipboard.\n" + "CTRL+Z,CTRL+Y undo/redo.\n" + "ESCAPE to revert.\n\n" + "PROGRAMMER:\n" + "You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() " + "to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated " + "in imgui_demo.cpp)."); + + static char str1[128] = ""; + ImGui::InputTextWithHint("input text (w/ hint)", "enter text here", str1, IM_ARRAYSIZE(str1)); + + IMGUI_DEMO_MARKER("Widgets/Basic/InputInt, InputFloat"); + static int i0 = 123; + ImGui::InputInt("input int", &i0); + + static float f0 = 0.001f; + ImGui::InputFloat("input float", &f0, 0.01f, 1.0f, "%.3f"); + + static double d0 = 999999.00000001; + ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.8f"); + + static float f1 = 1.e10f; + ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e"); + ImGui::SameLine(); HelpMarker( + "You can input value using the scientific notation,\n" + " e.g. \"1e+8\" becomes \"100000000\"."); + + static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + ImGui::InputFloat3("input float3", vec4a); + } + + ImGui::SeparatorText("Drags"); + + { + IMGUI_DEMO_MARKER("Widgets/Basic/DragInt, DragFloat"); + static int i1 = 50, i2 = 42; + ImGui::DragInt("drag int", &i1, 1); + ImGui::SameLine(); HelpMarker( + "Click and drag to edit value.\n" + "Hold SHIFT/ALT for faster/slower edit.\n" + "Double-click or CTRL+click to input value."); + + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp); + + static float f1 = 1.00f, f2 = 0.0067f; + ImGui::DragFloat("drag float", &f1, 0.005f); + ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); + } + + ImGui::SeparatorText("Sliders"); + + { + IMGUI_DEMO_MARKER("Widgets/Basic/SliderInt, SliderFloat"); + static int i1 = 0; + ImGui::SliderInt("slider int", &i1, -1, 3); + ImGui::SameLine(); HelpMarker("CTRL+click to input value."); + + static float f1 = 0.123f, f2 = 0.0f; + ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); + ImGui::SliderFloat("slider float (log)", &f2, -10.0f, 10.0f, "%.4f", ImGuiSliderFlags_Logarithmic); + + IMGUI_DEMO_MARKER("Widgets/Basic/SliderAngle"); + static float angle = 0.0f; + ImGui::SliderAngle("slider angle", &angle); + + // Using the format string to display a name instead of an integer. + // Here we completely omit '%d' from the format string, so it'll only display a name. + // This technique can also be used with DragInt(). + IMGUI_DEMO_MARKER("Widgets/Basic/Slider (enum)"); + enum Element { Element_Fire, Element_Earth, Element_Air, Element_Water, Element_COUNT }; + static int elem = Element_Fire; + const char* elems_names[Element_COUNT] = { "Fire", "Earth", "Air", "Water" }; + const char* elem_name = (elem >= 0 && elem < Element_COUNT) ? elems_names[elem] : "Unknown"; + ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); // Use ImGuiSliderFlags_NoInput flag to disable CTRL+Click here. + ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer."); + } + + ImGui::SeparatorText("Selectors/Pickers"); + + { + IMGUI_DEMO_MARKER("Widgets/Basic/ColorEdit3, ColorEdit4"); + static float col1[3] = { 1.0f, 0.0f, 0.2f }; + static float col2[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; + ImGui::ColorEdit3("color 1", col1); + ImGui::SameLine(); HelpMarker( + "Click on the color square to open a color picker.\n" + "Click and hold to use drag and drop.\n" + "Right-click on the color square to show options.\n" + "CTRL+click on individual component to input value.\n"); + + ImGui::ColorEdit4("color 2", col2); + } + + { + // Using the _simplified_ one-liner Combo() api here + // See "Combo" section for examples of how to use the more flexible BeginCombo()/EndCombo() api. + IMGUI_DEMO_MARKER("Widgets/Basic/Combo"); + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIIIIII", "JJJJ", "KKKKKKK" }; + static int item_current = 0; + ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items)); + ImGui::SameLine(); HelpMarker( + "Using the simplified one-liner Combo API here.\nRefer to the \"Combo\" section below for an explanation of how to use the more flexible and general BeginCombo/EndCombo API."); + } + + { + // Using the _simplified_ one-liner ListBox() api here + // See "List boxes" section for examples of how to use the more flexible BeginListBox()/EndListBox() api. + IMGUI_DEMO_MARKER("Widgets/Basic/ListBox"); + const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; + static int item_current = 1; + ImGui::ListBox("listbox", &item_current, items, IM_ARRAYSIZE(items), 4); + ImGui::SameLine(); HelpMarker( + "Using the simplified one-liner ListBox API here.\nRefer to the \"List boxes\" section below for an explanation of how to use the more flexible and general BeginListBox/EndListBox API."); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tooltips"); + if (ImGui::TreeNode("Tooltips")) + { + // Tooltips are windows following the mouse. They do not take focus away. + ImGui::SeparatorText("General"); + + // Typical use cases: + // - Short-form (text only): SetItemTooltip("Hello"); + // - Short-form (any contents): if (BeginItemTooltip()) { Text("Hello"); EndTooltip(); } + + // - Full-form (text only): if (IsItemHovered(...)) { SetTooltip("Hello"); } + // - Full-form (any contents): if (IsItemHovered(...) && BeginTooltip()) { Text("Hello"); EndTooltip(); } + + HelpMarker( + "Tooltip are typically created by using a IsItemHovered() + SetTooltip() sequence.\n\n" + "We provide a helper SetItemTooltip() function to perform the two with standards flags."); + + ImVec2 sz = ImVec2(-FLT_MIN, 0.0f); + + ImGui::Button("Basic", sz); + ImGui::SetItemTooltip("I am a tooltip"); + + ImGui::Button("Fancy", sz); + if (ImGui::BeginItemTooltip()) + { + ImGui::Text("I am a fancy tooltip"); + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); + ImGui::Text("Sin(time) = %f", sinf((float)ImGui::GetTime())); + ImGui::EndTooltip(); + } + + ImGui::SeparatorText("Always On"); + + // Showcase NOT relying on a IsItemHovered() to emit a tooltip. + // Here the tooltip is always emitted when 'always_on == true'. + static int always_on = 0; + ImGui::RadioButton("Off", &always_on, 0); + ImGui::SameLine(); + ImGui::RadioButton("Always On (Simple)", &always_on, 1); + ImGui::SameLine(); + ImGui::RadioButton("Always On (Advanced)", &always_on, 2); + if (always_on == 1) + ImGui::SetTooltip("I am following you around."); + else if (always_on == 2 && ImGui::BeginTooltip()) + { + ImGui::ProgressBar(sinf((float)ImGui::GetTime()) * 0.5f + 0.5f, ImVec2(ImGui::GetFontSize() * 25, 0.0f)); + ImGui::EndTooltip(); + } + + ImGui::SeparatorText("Custom"); + + // The following examples are passed for documentation purpose but may not be useful to most users. + // Passing ImGuiHoveredFlags_Tooltip to IsItemHovered() will pull ImGuiHoveredFlags flags values from + // 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on whether mouse or gamepad/keyboard is being used. + // With default settings, ImGuiHoveredFlags_Tooltip is equivalent to ImGuiHoveredFlags_DelayShort + ImGuiHoveredFlags_Stationary. + ImGui::Button("Manual", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip)) + ImGui::SetTooltip("I am a manually emitted tooltip"); + + ImGui::Button("DelayNone", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNone)) + ImGui::SetTooltip("I am a tooltip with no delay."); + + ImGui::Button("DelayShort", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_NoSharedDelay)) + ImGui::SetTooltip("I am a tooltip with a short delay (%0.2f sec).", ImGui::GetStyle().HoverDelayShort); + + ImGui::Button("DelayLong", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay)) + ImGui::SetTooltip("I am a tooltip with a long delay (%0.2f sec)", ImGui::GetStyle().HoverDelayNormal); + + ImGui::Button("Stationary", sz); + if (ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary)) + ImGui::SetTooltip("I am a tooltip requiring mouse to be stationary before activating."); + + ImGui::TreePop(); + } + + // Testing ImGuiOnceUponAFrame helper. + //static ImGuiOnceUponAFrame once; + //for (int i = 0; i < 5; i++) + // if (once) + // ImGui::Text("This will be displayed only once."); + + IMGUI_DEMO_MARKER("Widgets/Trees"); + if (ImGui::TreeNode("Trees")) + { + IMGUI_DEMO_MARKER("Widgets/Trees/Basic trees"); + if (ImGui::TreeNode("Basic trees")) + { + for (int i = 0; i < 5; i++) + { + // Use SetNextItemOpen() so set the default state of a node to be open. We could + // also use TreeNodeEx() with the ImGuiTreeNodeFlags_DefaultOpen flag to achieve the same thing! + if (i == 0) + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + + if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) + { + ImGui::Text("blah blah"); + ImGui::SameLine(); + if (ImGui::SmallButton("button")) {} + ImGui::TreePop(); + } + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Trees/Advanced, with Selectable nodes"); + if (ImGui::TreeNode("Advanced, with Selectable nodes")) + { + HelpMarker( + "This is a more typical looking tree with selectable nodes.\n" + "Click to select, CTRL+Click to toggle, click on arrows or double-click to open."); + static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; + static bool align_label_with_current_x_position = false; + static bool test_drag_and_drop = false; + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", &base_flags, ImGuiTreeNodeFlags_OpenOnArrow); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); + ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop); + ImGui::Text("Hello!"); + if (align_label_with_current_x_position) + ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); + + // 'selection_mask' is dumb representation of what may be user-side selection state. + // You may retain selection state inside or outside your objects in whatever format you see fit. + // 'node_clicked' is temporary storage of what node we have clicked to process selection at the end + /// of the loop. May be a pointer to your own node type, etc. + static int selection_mask = (1 << 2); + int node_clicked = -1; + for (int i = 0; i < 6; i++) + { + // Disable the default "open on single-click behavior" + set Selected flag according to our selection. + // To alter selection we use IsItemClicked() && !IsItemToggledOpen(), so clicking on an arrow doesn't alter selection. + ImGuiTreeNodeFlags node_flags = base_flags; + const bool is_selected = (selection_mask & (1 << i)) != 0; + if (is_selected) + node_flags |= ImGuiTreeNodeFlags_Selected; + if (i < 3) + { + // Items 0..2 are Tree Node + bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + node_clicked = i; + if (test_drag_and_drop && ImGui::BeginDragDropSource()) + { + ImGui::SetDragDropPayload("_TREENODE", NULL, 0); + ImGui::Text("This is a drag and drop source"); + ImGui::EndDragDropSource(); + } + if (node_open) + { + ImGui::BulletText("Blah blah\nBlah Blah"); + ImGui::TreePop(); + } + } + else + { + // Items 3..5 are Tree Leaves + // The only reason we use TreeNode at all is to allow selection of the leaf. Otherwise we can + // use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text(). + node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet + ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); + if (ImGui::IsItemClicked() && !ImGui::IsItemToggledOpen()) + node_clicked = i; + if (test_drag_and_drop && ImGui::BeginDragDropSource()) + { + ImGui::SetDragDropPayload("_TREENODE", NULL, 0); + ImGui::Text("This is a drag and drop source"); + ImGui::EndDragDropSource(); + } + } + } + if (node_clicked != -1) + { + // Update selection state + // (process outside of tree loop to avoid visual inconsistencies during the clicking frame) + if (ImGui::GetIO().KeyCtrl) + selection_mask ^= (1 << node_clicked); // CTRL+click to toggle + else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection + selection_mask = (1 << node_clicked); // Click to single-select + } + if (align_label_with_current_x_position) + ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Collapsing Headers"); + if (ImGui::TreeNode("Collapsing Headers")) + { + static bool closable_group = true; + ImGui::Checkbox("Show 2nd header", &closable_group); + if (ImGui::CollapsingHeader("Header", ImGuiTreeNodeFlags_None)) + { + ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered()); + for (int i = 0; i < 5; i++) + ImGui::Text("Some content %d", i); + } + if (ImGui::CollapsingHeader("Header with a close button", &closable_group)) + { + ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered()); + for (int i = 0; i < 5; i++) + ImGui::Text("More content %d", i); + } + /* + if (ImGui::CollapsingHeader("Header with a bullet", ImGuiTreeNodeFlags_Bullet)) + ImGui::Text("IsItemHovered: %d", ImGui::IsItemHovered()); + */ + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Bullets"); + if (ImGui::TreeNode("Bullets")) + { + ImGui::BulletText("Bullet point 1"); + ImGui::BulletText("Bullet point 2\nOn multiple lines"); + if (ImGui::TreeNode("Tree node")) + { + ImGui::BulletText("Another bullet point"); + ImGui::TreePop(); + } + ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); + ImGui::Bullet(); ImGui::SmallButton("Button"); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text"); + if (ImGui::TreeNode("Text")) + { + IMGUI_DEMO_MARKER("Widgets/Text/Colored Text"); + if (ImGui::TreeNode("Colorful Text")) + { + // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. + ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Pink"); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Yellow"); + ImGui::TextDisabled("Disabled"); + ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle."); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text/Word Wrapping"); + if (ImGui::TreeNode("Word Wrapping")) + { + // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. + ImGui::TextWrapped( + "This text should automatically wrap on the edge of the window. The current implementation " + "for text wrapping follows simple rules suitable for English and possibly other languages."); + ImGui::Spacing(); + + static float wrap_width = 200.0f; + ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); + + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + for (int n = 0; n < 2; n++) + { + ImGui::Text("Test paragraph %d:", n); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec2 marker_min = ImVec2(pos.x + wrap_width, pos.y); + ImVec2 marker_max = ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + if (n == 0) + ImGui::Text("The lazy dog is a good dog. This paragraph should fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); + else + ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); + + // Draw actual text bounding box, following by marker of our expected limit (should not overlap!) + draw_list->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255)); + draw_list->AddRectFilled(marker_min, marker_max, IM_COL32(255, 0, 255, 255)); + ImGui::PopTextWrapPos(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text/UTF-8 Text"); + if (ImGui::TreeNode("UTF-8 Text")) + { + // UTF-8 test with Japanese characters + // (Needs a suitable font? Try "Google Noto" or "Arial Unicode". See docs/FONTS.md for details.) + // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 + // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. in Visual Studio, you + // can save your source files as 'UTF-8 without signature'). + // - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8 + // CHARACTERS IN THIS SOURCE FILE. Instead we are encoding a few strings with hexadecimal constants. + // Don't do this in your application! Please use u8"text in any language" in your application! + // Note that characters values are preserved even by InputText() if the font cannot be displayed, + // so you can safely copy & paste garbled characters into another application. + ImGui::TextWrapped( + "CJK text will only appear if the font was loaded with the appropriate CJK character ranges. " + "Call io.Fonts->AddFontFromFileTTF() manually to load extra character ranges. " + "Read docs/FONTS.md for details."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string. + ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); + static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; + //static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis + ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Images"); + if (ImGui::TreeNode("Images")) + { + ImGuiIO& io = ImGui::GetIO(); + ImGui::TextWrapped( + "Below we are displaying the font texture (which is the only texture we have access to in this demo). " + "Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. " + "Hover the texture for a zoomed view!"); + + // Below we are displaying the font texture because it is the only texture we have access to inside the demo! + // Remember that ImTextureID is just storage for whatever you want it to be. It is essentially a value that + // will be passed to the rendering backend via the ImDrawCmd structure. + // If you use one of the default imgui_impl_XXXX.cpp rendering backend, they all have comments at the top + // of their respective source file to specify what they expect to be stored in ImTextureID, for example: + // - The imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer + // - The imgui_impl_opengl3.cpp renderer expect a GLuint OpenGL texture identifier, etc. + // More: + // - If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers + // to ImGui::Image(), and gather width/height through your own functions, etc. + // - You can use ShowMetricsWindow() to inspect the draw data that are being passed to your renderer, + // it will help you debug issues if you are confused about it. + // - Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). + // - Read https://github.com/ocornut/imgui/blob/master/docs/FAQ.md + // - Read https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples + ImTextureID my_tex_id = io.Fonts->TexID; + float my_tex_w = (float)io.Fonts->TexWidth; + float my_tex_h = (float)io.Fonts->TexHeight; + { + static bool use_text_color_for_tint = false; + ImGui::Checkbox("Use Text Color for Tint", &use_text_color_for_tint); + ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec2 uv_min = ImVec2(0.0f, 0.0f); // Top-left + ImVec2 uv_max = ImVec2(1.0f, 1.0f); // Lower-right + ImVec4 tint_col = use_text_color_for_tint ? ImGui::GetStyleColorVec4(ImGuiCol_Text) : ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + ImVec4 border_col = ImGui::GetStyleColorVec4(ImGuiCol_Border); + ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), uv_min, uv_max, tint_col, border_col); + if (ImGui::BeginItemTooltip()) + { + float region_sz = 32.0f; + float region_x = io.MousePos.x - pos.x - region_sz * 0.5f; + float region_y = io.MousePos.y - pos.y - region_sz * 0.5f; + float zoom = 4.0f; + if (region_x < 0.0f) { region_x = 0.0f; } + else if (region_x > my_tex_w - region_sz) { region_x = my_tex_w - region_sz; } + if (region_y < 0.0f) { region_y = 0.0f; } + else if (region_y > my_tex_h - region_sz) { region_y = my_tex_h - region_sz; } + ImGui::Text("Min: (%.2f, %.2f)", region_x, region_y); + ImGui::Text("Max: (%.2f, %.2f)", region_x + region_sz, region_y + region_sz); + ImVec2 uv0 = ImVec2((region_x) / my_tex_w, (region_y) / my_tex_h); + ImVec2 uv1 = ImVec2((region_x + region_sz) / my_tex_w, (region_y + region_sz) / my_tex_h); + ImGui::Image(my_tex_id, ImVec2(region_sz * zoom, region_sz * zoom), uv0, uv1, tint_col, border_col); + ImGui::EndTooltip(); + } + } + + IMGUI_DEMO_MARKER("Widgets/Images/Textured buttons"); + ImGui::TextWrapped("And now some textured buttons.."); + static int pressed_count = 0; + for (int i = 0; i < 8; i++) + { + // UV coordinates are often (0.0f, 0.0f) and (1.0f, 1.0f) to display an entire textures. + // Here are trying to display only a 32x32 pixels area of the texture, hence the UV computation. + // Read about UV coordinates here: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples + ImGui::PushID(i); + if (i > 0) + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(i - 1.0f, i - 1.0f)); + ImVec2 size = ImVec2(32.0f, 32.0f); // Size of the image we want to make visible + ImVec2 uv0 = ImVec2(0.0f, 0.0f); // UV coordinates for lower-left + ImVec2 uv1 = ImVec2(32.0f / my_tex_w, 32.0f / my_tex_h); // UV coordinates for (32,32) in our texture + ImVec4 bg_col = ImVec4(0.0f, 0.0f, 0.0f, 1.0f); // Black background + ImVec4 tint_col = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // No tint + if (ImGui::ImageButton("", my_tex_id, size, uv0, uv1, bg_col, tint_col)) + pressed_count += 1; + if (i > 0) + ImGui::PopStyleVar(); + ImGui::PopID(); + ImGui::SameLine(); + } + ImGui::NewLine(); + ImGui::Text("Pressed %d times.", pressed_count); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Combo"); + if (ImGui::TreeNode("Combo")) + { + // Combo Boxes are also called "Dropdown" in other systems + // Expose flags as checkbox for the demo + static ImGuiComboFlags flags = 0; + ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", &flags, ImGuiComboFlags_PopupAlignLeft); + ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo"); + if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", &flags, ImGuiComboFlags_NoArrowButton)) + flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both + if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", &flags, ImGuiComboFlags_NoPreview)) + flags &= ~ImGuiComboFlags_NoArrowButton; // Clear the other flag, as we cannot combine both + + // Using the generic BeginCombo() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; + static int item_current_idx = 0; // Here we store our selection data as an index. + const char* combo_preview_value = items[item_current_idx]; // Pass in the preview value visible before opening the combo (it could be anything) + if (ImGui::BeginCombo("combo 1", combo_preview_value, flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_current_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + // Simplified one-liner Combo() API, using values packed in a single constant string + // This is a convenience for when the selection set is small and known at compile-time. + static int item_current_2 = 0; + ImGui::Combo("combo 2 (one-liner)", &item_current_2, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + + // Simplified one-liner Combo() using an array of const char* + // This is not very useful (may obsolete): prefer using BeginCombo()/EndCombo() for full control. + static int item_current_3 = -1; // If the selection isn't within 0..count, Combo won't display a preview + ImGui::Combo("combo 3 (array)", &item_current_3, items, IM_ARRAYSIZE(items)); + + // Simplified one-liner Combo() using an accessor function + struct Funcs { static bool ItemGetter(void* data, int n, const char** out_str) { *out_str = ((const char**)data)[n]; return true; } }; + static int item_current_4 = 0; + ImGui::Combo("combo 4 (function)", &item_current_4, &Funcs::ItemGetter, items, IM_ARRAYSIZE(items)); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/List Boxes"); + if (ImGui::TreeNode("List boxes")) + { + // Using the generic BeginListBox() API, you have full control over how to display the combo contents. + // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively + // stored in the object itself, etc.) + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; + static int item_current_idx = 0; // Here we store our selection data as an index. + if (ImGui::BeginListBox("listbox 1")) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_current_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + // Custom size: use all width, 5 items tall + ImGui::Text("Full-width:"); + if (ImGui::BeginListBox("##listbox 2", ImVec2(-FLT_MIN, 5 * ImGui::GetTextLineHeightWithSpacing()))) + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + const bool is_selected = (item_current_idx == n); + if (ImGui::Selectable(items[n], is_selected)) + item_current_idx = n; + + // Set the initial focus when opening the combo (scrolling + keyboard navigation focus) + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndListBox(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Selectables"); + if (ImGui::TreeNode("Selectables")) + { + // Selectable() has 2 overloads: + // - The one taking "bool selected" as a read-only selection information. + // When Selectable() has been clicked it returns true and you can alter selection state accordingly. + // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases) + // The earlier is more flexible, as in real application your selection may be stored in many different ways + // and not necessarily inside a bool value (e.g. in flags within objects, as an external list, etc). + IMGUI_DEMO_MARKER("Widgets/Selectables/Basic"); + if (ImGui::TreeNode("Basic")) + { + static bool selection[5] = { false, true, false, false, false }; + ImGui::Selectable("1. I am selectable", &selection[0]); + ImGui::Selectable("2. I am selectable", &selection[1]); + ImGui::Text("(I am not selectable)"); + ImGui::Selectable("4. I am selectable", &selection[3]); + if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick)) + if (ImGui::IsMouseDoubleClicked(0)) + selection[4] = !selection[4]; + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Single Selection"); + if (ImGui::TreeNode("Selection State: Single Selection")) + { + static int selected = -1; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selected == n)) + selected = n; + } + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Multiple Selection"); + if (ImGui::TreeNode("Selection State: Multiple Selection")) + { + HelpMarker("Hold CTRL and click to select multiple items."); + static bool selection[5] = { false, false, false, false, false }; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selection[n])) + { + if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held + memset(selection, 0, sizeof(selection)); + selection[n] ^= 1; + } + } + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Rendering more text into the same line"); + if (ImGui::TreeNode("Rendering more text into the same line")) + { + // Using the Selectable() override that takes "bool* p_selected" parameter, + // this function toggle your bool value automatically. + static bool selected[3] = { false, false, false }; + ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes"); + ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/In columns"); + if (ImGui::TreeNode("In columns")) + { + static bool selected[10] = {}; + + if (ImGui::BeginTable("split1", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) + { + for (int i = 0; i < 10; i++) + { + char label[32]; + sprintf(label, "Item %d", i); + ImGui::TableNextColumn(); + ImGui::Selectable(label, &selected[i]); // FIXME-TABLE: Selection overlap + } + ImGui::EndTable(); + } + ImGui::Spacing(); + if (ImGui::BeginTable("split2", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders)) + { + for (int i = 0; i < 10; i++) + { + char label[32]; + sprintf(label, "Item %d", i); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Selectable(label, &selected[i], ImGuiSelectableFlags_SpanAllColumns); + ImGui::TableNextColumn(); + ImGui::Text("Some other contents"); + ImGui::TableNextColumn(); + ImGui::Text("123456"); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Grid"); + if (ImGui::TreeNode("Grid")) + { + static char selected[4][4] = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } }; + + // Add in a bit of silly fun... + const float time = (float)ImGui::GetTime(); + const bool winning_state = memchr(selected, 0, sizeof(selected)) == NULL; // If all cells are selected... + if (winning_state) + ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f + 0.5f * cosf(time * 2.0f), 0.5f + 0.5f * sinf(time * 3.0f))); + + for (int y = 0; y < 4; y++) + for (int x = 0; x < 4; x++) + { + if (x > 0) + ImGui::SameLine(); + ImGui::PushID(y * 4 + x); + if (ImGui::Selectable("Sailor", selected[y][x] != 0, 0, ImVec2(50, 50))) + { + // Toggle clicked cell + toggle neighbors + selected[y][x] ^= 1; + if (x > 0) { selected[y][x - 1] ^= 1; } + if (x < 3) { selected[y][x + 1] ^= 1; } + if (y > 0) { selected[y - 1][x] ^= 1; } + if (y < 3) { selected[y + 1][x] ^= 1; } + } + ImGui::PopID(); + } + + if (winning_state) + ImGui::PopStyleVar(); + ImGui::TreePop(); + } + IMGUI_DEMO_MARKER("Widgets/Selectables/Alignment"); + if (ImGui::TreeNode("Alignment")) + { + HelpMarker( + "By default, Selectables uses style.SelectableTextAlign but it can be overridden on a per-item " + "basis using PushStyleVar(). You'll probably want to always keep your default situation to " + "left-align otherwise it becomes difficult to layout multiple items on a same line"); + static bool selected[3 * 3] = { true, false, true, false, true, false, true, false, true }; + for (int y = 0; y < 3; y++) + { + for (int x = 0; x < 3; x++) + { + ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f); + char name[32]; + sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y); + if (x > 0) ImGui::SameLine(); + ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment); + ImGui::Selectable(name, &selected[3 * y + x], ImGuiSelectableFlags_None, ImVec2(80, 80)); + ImGui::PopStyleVar(); + } + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + // To wire InputText() with std::string or any other custom string type, + // see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file. + IMGUI_DEMO_MARKER("Widgets/Text Input"); + if (ImGui::TreeNode("Text Input")) + { + IMGUI_DEMO_MARKER("Widgets/Text Input/Multi-line Text Input"); + if (ImGui::TreeNode("Multi-line Text Input")) + { + // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize + // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings. + static char text[1024 * 16] = + "/*\n" + " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" + " the hexadecimal encoding of one offending instruction,\n" + " more formally, the invalid operand with locked CMPXCHG8B\n" + " instruction bug, is a design flaw in the majority of\n" + " Intel Pentium, Pentium MMX, and Pentium OverDrive\n" + " processors (all in the P5 microarchitecture).\n" + "*/\n\n" + "label:\n" + "\tlock cmpxchg8b eax\n"; + + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput; + HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include in here)"); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); + ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput); + ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine); + ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Filtered Text Input"); + if (ImGui::TreeNode("Filtered Text Input")) + { + struct TextFilters + { + // Modify character input by altering 'data->Eventchar' (ImGuiInputTextFlags_CallbackCharFilter callback) + static int FilterCasingSwap(ImGuiInputTextCallbackData* data) + { + if (data->EventChar >= 'a' && data->EventChar <= 'z') { data->EventChar -= 'a' - 'A'; } // Lowercase becomes uppercase + else if (data->EventChar >= 'A' && data->EventChar <= 'Z') { data->EventChar += 'a' - 'A'; } // Uppercase becomes lowercase + return 0; + } + + // Return 0 (pass) if the character is 'i' or 'm' or 'g' or 'u' or 'i', otherwise return 1 (filter out) + static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) + { + if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) + return 0; + return 1; + } + }; + + static char buf1[32] = ""; ImGui::InputText("default", buf1, 32); + static char buf2[32] = ""; ImGui::InputText("decimal", buf2, 32, ImGuiInputTextFlags_CharsDecimal); + static char buf3[32] = ""; ImGui::InputText("hexadecimal", buf3, 32, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); + static char buf4[32] = ""; ImGui::InputText("uppercase", buf4, 32, ImGuiInputTextFlags_CharsUppercase); + static char buf5[32] = ""; ImGui::InputText("no blank", buf5, 32, ImGuiInputTextFlags_CharsNoBlank); + static char buf6[32] = ""; ImGui::InputText("casing swap", buf6, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterCasingSwap); // Use CharFilter callback to replace characters. + static char buf7[32] = ""; ImGui::InputText("\"imgui\"", buf7, 32, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); // Use CharFilter callback to disable some characters. + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Password input"); + if (ImGui::TreeNode("Password Input")) + { + static char password[64] = "password123"; + ImGui::InputText("password", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); + ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); + ImGui::InputTextWithHint("password (w/ hint)", "", password, IM_ARRAYSIZE(password), ImGuiInputTextFlags_Password); + ImGui::InputText("password (clear)", password, IM_ARRAYSIZE(password)); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Completion, History, Edit Callbacks")) + { + struct Funcs + { + static int MyCallback(ImGuiInputTextCallbackData* data) + { + if (data->EventFlag == ImGuiInputTextFlags_CallbackCompletion) + { + data->InsertChars(data->CursorPos, ".."); + } + else if (data->EventFlag == ImGuiInputTextFlags_CallbackHistory) + { + if (data->EventKey == ImGuiKey_UpArrow) + { + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, "Pressed Up!"); + data->SelectAll(); + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, "Pressed Down!"); + data->SelectAll(); + } + } + else if (data->EventFlag == ImGuiInputTextFlags_CallbackEdit) + { + // Toggle casing of first character + char c = data->Buf[0]; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) data->Buf[0] ^= 32; + data->BufDirty = true; + + // Increment a counter + int* p_int = (int*)data->UserData; + *p_int = *p_int + 1; + } + return 0; + } + }; + static char buf1[64]; + ImGui::InputText("Completion", buf1, 64, ImGuiInputTextFlags_CallbackCompletion, Funcs::MyCallback); + ImGui::SameLine(); HelpMarker("Here we append \"..\" each time Tab is pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback."); + + static char buf2[64]; + ImGui::InputText("History", buf2, 64, ImGuiInputTextFlags_CallbackHistory, Funcs::MyCallback); + ImGui::SameLine(); HelpMarker("Here we replace and select text each time Up/Down are pressed. See 'Examples>Console' for a more meaningful demonstration of using this callback."); + + static char buf3[64]; + static int edit_count = 0; + ImGui::InputText("Edit", buf3, 64, ImGuiInputTextFlags_CallbackEdit, Funcs::MyCallback, (void*)&edit_count); + ImGui::SameLine(); HelpMarker("Here we toggle the casing of the first character on every edit + count edits."); + ImGui::SameLine(); ImGui::Text("(%d)", edit_count); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Input/Resize Callback"); + if (ImGui::TreeNode("Resize Callback")) + { + // To wire InputText() with std::string or any other custom string type, + // you can use the ImGuiInputTextFlags_CallbackResize flag + create a custom ImGui::InputText() wrapper + // using your preferred type. See misc/cpp/imgui_stdlib.h for an implementation of this using std::string. + HelpMarker( + "Using ImGuiInputTextFlags_CallbackResize to wire your custom string type to InputText().\n\n" + "See misc/cpp/imgui_stdlib.h for an implementation of this for std::string."); + struct Funcs + { + static int MyResizeCallback(ImGuiInputTextCallbackData* data) + { + if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) + { + ImVector* my_str = (ImVector*)data->UserData; + IM_ASSERT(my_str->begin() == data->Buf); + my_str->resize(data->BufSize); // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1 + data->Buf = my_str->begin(); + } + return 0; + } + + // Note: Because ImGui:: is a namespace you would typically add your own function into the namespace. + // For example, you code may declare a function 'ImGui::InputText(const char* label, MyString* my_str)' + static bool MyInputTextMultiline(const char* label, ImVector* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0) + { + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str); + } + }; + + // For this demo we are using ImVector as a string container. + // Note that because we need to store a terminating zero character, our size/capacity are 1 more + // than usually reported by a typical string class. + static ImVector my_str; + if (my_str.empty()) + my_str.push_back(0); + Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16)); + ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity()); + ImGui::TreePop(); + } + + ImGui::TreePop(); + } + + // Tabs + IMGUI_DEMO_MARKER("Widgets/Tabs"); + if (ImGui::TreeNode("Tabs")) + { + IMGUI_DEMO_MARKER("Widgets/Tabs/Basic"); + if (ImGui::TreeNode("Basic")) + { + ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None; + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + if (ImGui::BeginTabItem("Avocado")) + { + ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Broccoli")) + { + ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Cucumber")) + { + ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tabs/Advanced & Close Button"); + if (ImGui::TreeNode("Advanced & Close Button")) + { + // Expose a couple of the available flags. In most cases you may just call BeginTabBar() with no flags (0). + static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable; + ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", &tab_bar_flags, ImGuiTabBarFlags_Reorderable); + ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", &tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs); + ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); + ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton); + if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0) + tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_; + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); + + // Tab Bar + const char* names[4] = { "Artichoke", "Beetroot", "Celery", "Daikon" }; + static bool opened[4] = { true, true, true, true }; // Persistent user state + for (int n = 0; n < IM_ARRAYSIZE(opened); n++) + { + if (n > 0) { ImGui::SameLine(); } + ImGui::Checkbox(names[n], &opened[n]); + } + + // Passing a bool* to BeginTabItem() is similar to passing one to Begin(): + // the underlying bool will be set to false when the tab is closed. + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + for (int n = 0; n < IM_ARRAYSIZE(opened); n++) + if (opened[n] && ImGui::BeginTabItem(names[n], &opened[n], ImGuiTabItemFlags_None)) + { + ImGui::Text("This is the %s tab!", names[n]); + if (n & 1) + ImGui::Text("I am an odd tab."); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Tabs/TabItemButton & Leading-Trailing flags"); + if (ImGui::TreeNode("TabItemButton & Leading/Trailing flags")) + { + static ImVector active_tabs; + static int next_tab_id = 0; + if (next_tab_id == 0) // Initialize with some default tabs + for (int i = 0; i < 3; i++) + active_tabs.push_back(next_tab_id++); + + // TabItemButton() and Leading/Trailing flags are distinct features which we will demo together. + // (It is possible to submit regular tabs with Leading/Trailing flags, or TabItemButton tabs without Leading/Trailing flags... + // but they tend to make more sense together) + static bool show_leading_button = true; + static bool show_trailing_button = true; + ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button); + ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button); + + // Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs + static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown; + ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown); + if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll)) + tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll); + + if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) + { + // Demo a Leading TabItemButton(): click the "?" button to open a menu + if (show_leading_button) + if (ImGui::TabItemButton("?", ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_NoTooltip)) + ImGui::OpenPopup("MyHelpMenu"); + if (ImGui::BeginPopup("MyHelpMenu")) + { + ImGui::Selectable("Hello!"); + ImGui::EndPopup(); + } + + // Demo Trailing Tabs: click the "+" button to add a new tab (in your app you may want to use a font icon instead of the "+") + // Note that we submit it before the regular tabs, but because of the ImGuiTabItemFlags_Trailing flag it will always appear at the end. + if (show_trailing_button) + if (ImGui::TabItemButton("+", ImGuiTabItemFlags_Trailing | ImGuiTabItemFlags_NoTooltip)) + active_tabs.push_back(next_tab_id++); // Add new tab + + // Submit our regular tabs + for (int n = 0; n < active_tabs.Size; ) + { + bool open = true; + char name[16]; + snprintf(name, IM_ARRAYSIZE(name), "%04d", active_tabs[n]); + if (ImGui::BeginTabItem(name, &open, ImGuiTabItemFlags_None)) + { + ImGui::Text("This is the %s tab!", name); + ImGui::EndTabItem(); + } + + if (!open) + active_tabs.erase(active_tabs.Data + n); + else + n++; + } + + ImGui::EndTabBar(); + } + ImGui::Separator(); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + // Plot/Graph widgets are not very good. + // Consider using a third-party library such as ImPlot: https://github.com/epezent/implot + // (see others https://github.com/ocornut/imgui/wiki/Useful-Extensions) + IMGUI_DEMO_MARKER("Widgets/Plotting"); + if (ImGui::TreeNode("Plotting")) + { + static bool animate = true; + ImGui::Checkbox("Animate", &animate); + + // Plot as lines and plot as histogram + IMGUI_DEMO_MARKER("Widgets/Plotting/PlotLines, PlotHistogram"); + static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; + ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f)); + + // Fill an array of contiguous float values to plot + // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float + // and the sizeof() of your structure in the "stride" parameter. + static float values[90] = {}; + static int values_offset = 0; + static double refresh_time = 0.0; + if (!animate || refresh_time == 0.0) + refresh_time = ImGui::GetTime(); + while (refresh_time < ImGui::GetTime()) // Create data at fixed 60 Hz rate for the demo + { + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset + 1) % IM_ARRAYSIZE(values); + phase += 0.10f * values_offset; + refresh_time += 1.0f / 60.0f; + } + + // Plots can display overlay texts + // (in this example, we will display an average value) + { + float average = 0.0f; + for (int n = 0; n < IM_ARRAYSIZE(values); n++) + average += values[n]; + average /= (float)IM_ARRAYSIZE(values); + char overlay[32]; + sprintf(overlay, "avg %f", average); + ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0, 80.0f)); + } + + // Use functions to generate output + // FIXME: This is actually VERY awkward because current plot API only pass in indices. + // We probably want an API passing floats and user provide sample rate/count. + struct Funcs + { + static float Sin(void*, int i) { return sinf(i * 0.1f); } + static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } + }; + static int func_type = 0, display_count = 70; + ImGui::SeparatorText("Functions"); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::Combo("func", &func_type, "Sin\0Saw\0"); + ImGui::SameLine(); + ImGui::SliderInt("Sample count", &display_count, 1, 400); + float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; + ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::Separator(); + + // Animate a simple progress bar + IMGUI_DEMO_MARKER("Widgets/Plotting/ProgressBar"); + static float progress = 0.0f, progress_dir = 1.0f; + if (animate) + { + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } + if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } + } + + // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width, + // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. + ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f)); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Progress Bar"); + + float progress_saturated = IM_CLAMP(progress, 0.0f, 1.0f); + char buf[32]; + sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); + ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Color"); + if (ImGui::TreeNode("Color/Picker Widgets")) + { + static ImVec4 color = ImVec4(114.0f / 255.0f, 144.0f / 255.0f, 154.0f / 255.0f, 200.0f / 255.0f); + + static bool alpha_preview = true; + static bool alpha_half_preview = false; + static bool drag_and_drop = true; + static bool options_menu = true; + static bool hdr = false; + ImGui::SeparatorText("Options"); + ImGui::Checkbox("With Alpha Preview", &alpha_preview); + ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); + ImGui::Checkbox("With Drag and Drop", &drag_and_drop); + ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options."); + ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); + ImGuiColorEditFlags misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit"); + ImGui::SeparatorText("Inline color editor"); + ImGui::Text("Color widget:"); + ImGui::SameLine(); HelpMarker( + "Click on the color square to open a color picker.\n" + "CTRL+click on individual component to input value.\n"); + ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)"); + ImGui::Text("Color widget HSV with Alpha:"); + ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (float display)"); + ImGui::Text("Color widget with Float Display:"); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with Picker)"); + ImGui::Text("Color button with Picker:"); + ImGui::SameLine(); HelpMarker( + "With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\n" + "With the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only " + "be used for the tooltip and picker popup."); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with custom Picker popup)"); + ImGui::Text("Color button with Custom Picker Popup:"); + + // Generate a default palette. The palette will persist and can be edited. + static bool saved_palette_init = true; + static ImVec4 saved_palette[32] = {}; + if (saved_palette_init) + { + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + { + ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, + saved_palette[n].x, saved_palette[n].y, saved_palette[n].z); + saved_palette[n].w = 1.0f; // Alpha + } + saved_palette_init = false; + } + + static ImVec4 backup_color; + bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags); + ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x); + open_popup |= ImGui::Button("Palette"); + if (open_popup) + { + ImGui::OpenPopup("mypicker"); + backup_color = color; + } + if (ImGui::BeginPopup("mypicker")) + { + ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!"); + ImGui::Separator(); + ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); + ImGui::SameLine(); + + ImGui::BeginGroup(); // Lock X position + ImGui::Text("Current"); + ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40)); + ImGui::Text("Previous"); + if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40))) + color = backup_color; + ImGui::Separator(); + ImGui::Text("Palette"); + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + { + ImGui::PushID(n); + if ((n % 8) != 0) + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); + + ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip; + if (ImGui::ColorButton("##palette", saved_palette[n], palette_button_flags, ImVec2(20, 20))) + color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha! + + // Allow user to drop colors into each palette entry. Note that ColorButton() is already a + // drag source by default, unless specifying the ImGuiColorEditFlags_NoDragDrop flag. + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3); + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4); + ImGui::EndDragDropTarget(); + } + + ImGui::PopID(); + } + ImGui::EndGroup(); + ImGui::EndPopup(); + } + + IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (simple)"); + ImGui::Text("Color button only:"); + static bool no_border = false; + ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border); + ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80)); + + IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker"); + ImGui::SeparatorText("Color picker"); + static bool alpha = true; + static bool alpha_bar = true; + static bool side_preview = true; + static bool ref_color = false; + static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f); + static int display_mode = 0; + static int picker_mode = 0; + ImGui::Checkbox("With Alpha", &alpha); + ImGui::Checkbox("With Alpha Bar", &alpha_bar); + ImGui::Checkbox("With Side Preview", &side_preview); + if (side_preview) + { + ImGui::SameLine(); + ImGui::Checkbox("With Ref Color", &ref_color); + if (ref_color) + { + ImGui::SameLine(); + ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags); + } + } + ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0"); + ImGui::SameLine(); HelpMarker( + "ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, " + "but the user can change it with a right-click on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex " + "if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions()."); + ImGui::SameLine(); HelpMarker("When not specified explicitly (Auto/Current mode), user can right-click the picker to change mode."); + ImGuiColorEditFlags flags = misc_flags; + if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() + if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; + if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; + if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel; + if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays + if (display_mode == 2) flags |= ImGuiColorEditFlags_DisplayRGB; // Override display mode + if (display_mode == 3) flags |= ImGuiColorEditFlags_DisplayHSV; + if (display_mode == 4) flags |= ImGuiColorEditFlags_DisplayHex; + ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); + + ImGui::Text("Set defaults in code:"); + ImGui::SameLine(); HelpMarker( + "SetColorEditOptions() is designed to allow you to set boot-time default.\n" + "We don't have Push/Pop functions because you can force options on a per-widget basis if needed," + "and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid" + "encouraging you to persistently save values that aren't forward-compatible."); + if (ImGui::Button("Default: Uint8 + HSV + Hue Bar")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_PickerHueBar); + if (ImGui::Button("Default: Float + HDR + Hue Wheel")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel); + + // Always both a small version of both types of pickers (to make it more visible in the demo to people who are skimming quickly through it) + ImGui::Text("Both types:"); + float w = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.y) * 0.40f; + ImGui::SetNextItemWidth(w); + ImGui::ColorPicker3("##MyColor##5", (float*)&color, ImGuiColorEditFlags_PickerHueBar | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha); + ImGui::SameLine(); + ImGui::SetNextItemWidth(w); + ImGui::ColorPicker3("##MyColor##6", (float*)&color, ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha); + + // HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0) + static ImVec4 color_hsv(0.23f, 1.0f, 1.0f, 1.0f); // Stored as HSV! + ImGui::Spacing(); + ImGui::Text("HSV encoded colors"); + ImGui::SameLine(); HelpMarker( + "By default, colors are given to ColorEdit and ColorPicker in RGB, but ImGuiColorEditFlags_InputHSV" + "allows you to store colors as HSV and pass them to ColorEdit and ColorPicker as HSV. This comes with the" + "added benefit that you can manipulate hue values with the picker even when saturation or value are zero."); + ImGui::Text("Color widget with InputHSV:"); + ImGui::ColorEdit4("HSV shown as RGB##1", (float*)&color_hsv, ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float); + ImGui::ColorEdit4("HSV shown as HSV##1", (float*)&color_hsv, ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float); + ImGui::DragFloat4("Raw HSV values", (float*)&color_hsv, 0.01f, 0.0f, 1.0f); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and Slider Flags"); + if (ImGui::TreeNode("Drag/Slider Flags")) + { + // Demonstrate using advanced flags for DragXXX and SliderXXX functions. Note that the flags are the same! + static ImGuiSliderFlags flags = ImGuiSliderFlags_None; + ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp); + ImGui::SameLine(); HelpMarker("Always clamp value to min/max bounds (if any) when input manually with CTRL+Click."); + ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic); + ImGui::SameLine(); HelpMarker("Enable logarithmic editing (more precision for small values)."); + ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat); + ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits)."); + ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput); + ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget."); + + // Drags + static float drag_f = 0.5f; + static int drag_i = 50; + ImGui::Text("Underlying float value: %f", drag_f); + ImGui::DragFloat("DragFloat (0 -> 1)", &drag_f, 0.005f, 0.0f, 1.0f, "%.3f", flags); + ImGui::DragFloat("DragFloat (0 -> +inf)", &drag_f, 0.005f, 0.0f, FLT_MAX, "%.3f", flags); + ImGui::DragFloat("DragFloat (-inf -> 1)", &drag_f, 0.005f, -FLT_MAX, 1.0f, "%.3f", flags); + ImGui::DragFloat("DragFloat (-inf -> +inf)", &drag_f, 0.005f, -FLT_MAX, +FLT_MAX, "%.3f", flags); + ImGui::DragInt("DragInt (0 -> 100)", &drag_i, 0.5f, 0, 100, "%d", flags); + + // Sliders + static float slider_f = 0.5f; + static int slider_i = 50; + ImGui::Text("Underlying float value: %f", slider_f); + ImGui::SliderFloat("SliderFloat (0 -> 1)", &slider_f, 0.0f, 1.0f, "%.3f", flags); + ImGui::SliderInt("SliderInt (0 -> 100)", &slider_i, 0, 100, "%d", flags); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Range Widgets"); + if (ImGui::TreeNode("Range Widgets")) + { + static float begin = 10, end = 90; + static int begin_i = 100, end_i = 1000; + ImGui::DragFloatRange2("range float", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%", ImGuiSliderFlags_AlwaysClamp); + ImGui::DragIntRange2("range int", &begin_i, &end_i, 5, 0, 1000, "Min: %d units", "Max: %d units"); + ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units"); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Data Types"); + if (ImGui::TreeNode("Data Types")) + { + // DragScalar/InputScalar/SliderScalar functions allow various data types + // - signed/unsigned + // - 8/16/32/64-bits + // - integer/float/double + // To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum + // to pass the type, and passing all arguments by pointer. + // This is the reason the test code below creates local variables to hold "zero" "one" etc. for each type. + // In practice, if you frequently use a given type that is not covered by the normal API entry points, + // you can wrap it yourself inside a 1 line function which can take typed argument as value instead of void*, + // and then pass their address to the generic function. For example: + // bool MySliderU64(const char *label, u64* value, u64 min = 0, u64 max = 0, const char* format = "%lld") + // { + // return SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format); + // } + + // Setup limits (as helper variables so we can take their address, as explained above) + // Note: SliderScalar() functions have a maximum usable range of half the natural type maximum, hence the /2. + #ifndef LLONG_MIN + ImS64 LLONG_MIN = -9223372036854775807LL - 1; + ImS64 LLONG_MAX = 9223372036854775807LL; + ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1); + #endif + const char s8_zero = 0, s8_one = 1, s8_fifty = 50, s8_min = -128, s8_max = 127; + const ImU8 u8_zero = 0, u8_one = 1, u8_fifty = 50, u8_min = 0, u8_max = 255; + const short s16_zero = 0, s16_one = 1, s16_fifty = 50, s16_min = -32768, s16_max = 32767; + const ImU16 u16_zero = 0, u16_one = 1, u16_fifty = 50, u16_min = 0, u16_max = 65535; + const ImS32 s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN/2, s32_max = INT_MAX/2, s32_hi_a = INT_MAX/2 - 100, s32_hi_b = INT_MAX/2; + const ImU32 u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX/2, u32_hi_a = UINT_MAX/2 - 100, u32_hi_b = UINT_MAX/2; + const ImS64 s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN/2, s64_max = LLONG_MAX/2, s64_hi_a = LLONG_MAX/2 - 100, s64_hi_b = LLONG_MAX/2; + const ImU64 u64_zero = 0, u64_one = 1, u64_fifty = 50, u64_min = 0, u64_max = ULLONG_MAX/2, u64_hi_a = ULLONG_MAX/2 - 100, u64_hi_b = ULLONG_MAX/2; + const float f32_zero = 0.f, f32_one = 1.f, f32_lo_a = -10000000000.0f, f32_hi_a = +10000000000.0f; + const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0; + + // State + static char s8_v = 127; + static ImU8 u8_v = 255; + static short s16_v = 32767; + static ImU16 u16_v = 65535; + static ImS32 s32_v = -1; + static ImU32 u32_v = (ImU32)-1; + static ImS64 s64_v = -1; + static ImU64 u64_v = (ImU64)-1; + static float f32_v = 0.123f; + static double f64_v = 90000.01234567890123456789; + + const float drag_speed = 0.2f; + static bool drag_clamp = false; + IMGUI_DEMO_MARKER("Widgets/Data Types/Drags"); + ImGui::SeparatorText("Drags"); + ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); + ImGui::SameLine(); HelpMarker( + "As with every widget in dear imgui, we never modify values unless there is a user interaction.\n" + "You can override the clamping limits by using CTRL+Click to input a value."); + ImGui::DragScalar("drag s8", ImGuiDataType_S8, &s8_v, drag_speed, drag_clamp ? &s8_zero : NULL, drag_clamp ? &s8_fifty : NULL); + ImGui::DragScalar("drag u8", ImGuiDataType_U8, &u8_v, drag_speed, drag_clamp ? &u8_zero : NULL, drag_clamp ? &u8_fifty : NULL, "%u ms"); + ImGui::DragScalar("drag s16", ImGuiDataType_S16, &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL); + ImGui::DragScalar("drag u16", ImGuiDataType_U16, &u16_v, drag_speed, drag_clamp ? &u16_zero : NULL, drag_clamp ? &u16_fifty : NULL, "%u ms"); + ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL); + ImGui::DragScalar("drag s32 hex", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL, "0x%08X"); + ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms"); + ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL); + ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL); + ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f"); + ImGui::DragScalar("drag float log", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", ImGuiSliderFlags_Logarithmic); + ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams"); + ImGui::DragScalar("drag double log",ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", ImGuiSliderFlags_Logarithmic); + + IMGUI_DEMO_MARKER("Widgets/Data Types/Sliders"); + ImGui::SeparatorText("Sliders"); + ImGui::SliderScalar("slider s8 full", ImGuiDataType_S8, &s8_v, &s8_min, &s8_max, "%d"); + ImGui::SliderScalar("slider u8 full", ImGuiDataType_U8, &u8_v, &u8_min, &u8_max, "%u"); + ImGui::SliderScalar("slider s16 full", ImGuiDataType_S16, &s16_v, &s16_min, &s16_max, "%d"); + ImGui::SliderScalar("slider u16 full", ImGuiDataType_U16, &u16_v, &u16_min, &u16_max, "%u"); + ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d"); + ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d"); + ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d"); + ImGui::SliderScalar("slider s32 hex", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty, "0x%04X"); + ImGui::SliderScalar("slider u32 low", ImGuiDataType_U32, &u32_v, &u32_zero, &u32_fifty,"%u"); + ImGui::SliderScalar("slider u32 high", ImGuiDataType_U32, &u32_v, &u32_hi_a, &u32_hi_b, "%u"); + ImGui::SliderScalar("slider u32 full", ImGuiDataType_U32, &u32_v, &u32_min, &u32_max, "%u"); + ImGui::SliderScalar("slider s64 low", ImGuiDataType_S64, &s64_v, &s64_zero, &s64_fifty,"%" IM_PRId64); + ImGui::SliderScalar("slider s64 high", ImGuiDataType_S64, &s64_v, &s64_hi_a, &s64_hi_b, "%" IM_PRId64); + ImGui::SliderScalar("slider s64 full", ImGuiDataType_S64, &s64_v, &s64_min, &s64_max, "%" IM_PRId64); + ImGui::SliderScalar("slider u64 low", ImGuiDataType_U64, &u64_v, &u64_zero, &u64_fifty,"%" IM_PRIu64 " ms"); + ImGui::SliderScalar("slider u64 high", ImGuiDataType_U64, &u64_v, &u64_hi_a, &u64_hi_b, "%" IM_PRIu64 " ms"); + ImGui::SliderScalar("slider u64 full", ImGuiDataType_U64, &u64_v, &u64_min, &u64_max, "%" IM_PRIu64 " ms"); + ImGui::SliderScalar("slider float low", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one); + ImGui::SliderScalar("slider float low log", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one, "%.10f", ImGuiSliderFlags_Logarithmic); + ImGui::SliderScalar("slider float high", ImGuiDataType_Float, &f32_v, &f32_lo_a, &f32_hi_a, "%e"); + ImGui::SliderScalar("slider double low", ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f grams"); + ImGui::SliderScalar("slider double low log",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f", ImGuiSliderFlags_Logarithmic); + ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams"); + + ImGui::SeparatorText("Sliders (reverse)"); + ImGui::SliderScalar("slider s8 reverse", ImGuiDataType_S8, &s8_v, &s8_max, &s8_min, "%d"); + ImGui::SliderScalar("slider u8 reverse", ImGuiDataType_U8, &u8_v, &u8_max, &u8_min, "%u"); + ImGui::SliderScalar("slider s32 reverse", ImGuiDataType_S32, &s32_v, &s32_fifty, &s32_zero, "%d"); + ImGui::SliderScalar("slider u32 reverse", ImGuiDataType_U32, &u32_v, &u32_fifty, &u32_zero, "%u"); + ImGui::SliderScalar("slider s64 reverse", ImGuiDataType_S64, &s64_v, &s64_fifty, &s64_zero, "%" IM_PRId64); + ImGui::SliderScalar("slider u64 reverse", ImGuiDataType_U64, &u64_v, &u64_fifty, &u64_zero, "%" IM_PRIu64 " ms"); + + IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs"); + static bool inputs_step = true; + ImGui::SeparatorText("Inputs"); + ImGui::Checkbox("Show step buttons", &inputs_step); + ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d"); + ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u"); + ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d"); + ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u"); + ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); + ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X"); + ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); + ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X"); + ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL); + ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL); + ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL); + ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Multi-component Widgets"); + if (ImGui::TreeNode("Multi-component Widgets")) + { + static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; + static int vec4i[4] = { 1, 5, 100, 255 }; + + ImGui::SeparatorText("2-wide"); + ImGui::InputFloat2("input float2", vec4f); + ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); + ImGui::InputInt2("input int2", vec4i); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); + ImGui::SliderInt2("slider int2", vec4i, 0, 255); + + ImGui::SeparatorText("3-wide"); + ImGui::InputFloat3("input float3", vec4f); + ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); + ImGui::InputInt3("input int3", vec4i); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); + ImGui::SliderInt3("slider int3", vec4i, 0, 255); + + ImGui::SeparatorText("4-wide"); + ImGui::InputFloat4("input float4", vec4f); + ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); + ImGui::InputInt4("input int4", vec4i); + ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); + ImGui::SliderInt4("slider int4", vec4i, 0, 255); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Vertical Sliders"); + if (ImGui::TreeNode("Vertical Sliders")) + { + const float spacing = 4; + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); + + static int int_value = 0; + ImGui::VSliderInt("##int", ImVec2(18, 160), &int_value, 0, 5); + ImGui::SameLine(); + + static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; + ImGui::PushID("set1"); + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_FrameBg, (ImVec4)ImColor::HSV(i / 7.0f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)ImColor::HSV(i / 7.0f, 0.9f, 0.9f)); + ImGui::VSliderFloat("##v", ImVec2(18, 160), &values[i], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values[i]); + ImGui::PopStyleColor(4); + ImGui::PopID(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set2"); + static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; + const int rows = 3; + const ImVec2 small_slider_size(18, (float)(int)((160.0f - (rows - 1) * spacing) / rows)); + for (int nx = 0; nx < 4; nx++) + { + if (nx > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + for (int ny = 0; ny < rows; ny++) + { + ImGui::PushID(nx * rows + ny); + ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values2[nx]); + ImGui::PopID(); + } + ImGui::EndGroup(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set3"); + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); + ImGui::VSliderFloat("##v", ImVec2(40, 160), &values[i], 0.0f, 1.0f, "%.2f\nsec"); + ImGui::PopStyleVar(); + ImGui::PopID(); + } + ImGui::PopID(); + ImGui::PopStyleVar(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and drop"); + if (ImGui::TreeNode("Drag and Drop")) + { + IMGUI_DEMO_MARKER("Widgets/Drag and drop/Standard widgets"); + if (ImGui::TreeNode("Drag and drop in standard widgets")) + { + // ColorEdit widgets automatically act as drag source and drag target. + // They are using standardized payload strings IMGUI_PAYLOAD_TYPE_COLOR_3F and IMGUI_PAYLOAD_TYPE_COLOR_4F + // to allow your own widgets to use colors in their drag and drop interaction. + // Also see 'Demo->Widgets->Color/Picker Widgets->Palette' demo. + HelpMarker("You can drag from the color squares."); + static float col1[3] = { 1.0f, 0.0f, 0.2f }; + static float col2[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; + ImGui::ColorEdit3("color 1", col1); + ImGui::ColorEdit4("color 2", col2); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and drop/Copy-swap items"); + if (ImGui::TreeNode("Drag and drop to copy/swap items")) + { + enum Mode + { + Mode_Copy, + Mode_Move, + Mode_Swap + }; + static int mode = 0; + if (ImGui::RadioButton("Copy", mode == Mode_Copy)) { mode = Mode_Copy; } ImGui::SameLine(); + if (ImGui::RadioButton("Move", mode == Mode_Move)) { mode = Mode_Move; } ImGui::SameLine(); + if (ImGui::RadioButton("Swap", mode == Mode_Swap)) { mode = Mode_Swap; } + static const char* names[9] = + { + "Bobby", "Beatrice", "Betty", + "Brianna", "Barry", "Bernard", + "Bibi", "Blaine", "Bryn" + }; + for (int n = 0; n < IM_ARRAYSIZE(names); n++) + { + ImGui::PushID(n); + if ((n % 3) != 0) + ImGui::SameLine(); + ImGui::Button(names[n], ImVec2(60, 60)); + + // Our buttons are both drag sources and drag targets here! + if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) + { + // Set payload to carry the index of our item (could be anything) + ImGui::SetDragDropPayload("DND_DEMO_CELL", &n, sizeof(int)); + + // Display preview (could be anything, e.g. when dragging an image we could decide to display + // the filename and a small preview of the image, etc.) + if (mode == Mode_Copy) { ImGui::Text("Copy %s", names[n]); } + if (mode == Mode_Move) { ImGui::Text("Move %s", names[n]); } + if (mode == Mode_Swap) { ImGui::Text("Swap %s", names[n]); } + ImGui::EndDragDropSource(); + } + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("DND_DEMO_CELL")) + { + IM_ASSERT(payload->DataSize == sizeof(int)); + int payload_n = *(const int*)payload->Data; + if (mode == Mode_Copy) + { + names[n] = names[payload_n]; + } + if (mode == Mode_Move) + { + names[n] = names[payload_n]; + names[payload_n] = ""; + } + if (mode == Mode_Swap) + { + const char* tmp = names[n]; + names[n] = names[payload_n]; + names[payload_n] = tmp; + } + } + ImGui::EndDragDropTarget(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Drag and Drop/Drag to reorder items (simple)"); + if (ImGui::TreeNode("Drag to reorder items (simple)")) + { + // Simple reordering + HelpMarker( + "We don't use the drag and drop api at all here! " + "Instead we query when the item is held but not hovered, and order items accordingly."); + static const char* item_names[] = { "Item One", "Item Two", "Item Three", "Item Four", "Item Five" }; + for (int n = 0; n < IM_ARRAYSIZE(item_names); n++) + { + const char* item = item_names[n]; + ImGui::Selectable(item); + + if (ImGui::IsItemActive() && !ImGui::IsItemHovered()) + { + int n_next = n + (ImGui::GetMouseDragDelta(0).y < 0.f ? -1 : 1); + if (n_next >= 0 && n_next < IM_ARRAYSIZE(item_names)) + { + item_names[n] = item_names[n_next]; + item_names[n_next] = item; + ImGui::ResetMouseDragDelta(); + } + } + } + ImGui::TreePop(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Querying Item Status (Edited,Active,Hovered etc.)"); + if (ImGui::TreeNode("Querying Item Status (Edited/Active/Hovered etc.)")) + { + // Select an item type + const char* item_names[] = + { + "Text", "Button", "Button (w/ repeat)", "Checkbox", "SliderFloat", "InputText", "InputTextMultiline", "InputFloat", + "InputFloat3", "ColorEdit4", "Selectable", "MenuItem", "TreeNode", "TreeNode (w/ double-click)", "Combo", "ListBox" + }; + static int item_type = 4; + static bool item_disabled = false; + ImGui::Combo("Item Type", &item_type, item_names, IM_ARRAYSIZE(item_names), IM_ARRAYSIZE(item_names)); + ImGui::SameLine(); + HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered()."); + ImGui::Checkbox("Item Disabled", &item_disabled); + + // Submit selected items so we can query their status in the code following it. + bool ret = false; + static bool b = false; + static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f }; + static char str[16] = {}; + if (item_disabled) + ImGui::BeginDisabled(true); + if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction + if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button + if (item_type == 2) { ImGui::PushButtonRepeat(true); ret = ImGui::Button("ITEM: Button"); ImGui::PopButtonRepeat(); } // Testing button (with repeater) + if (item_type == 3) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); } // Testing checkbox + if (item_type == 4) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item + if (item_type == 5) { ret = ImGui::InputText("ITEM: InputText", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which handles tabbing) + if (item_type == 6) { ret = ImGui::InputTextMultiline("ITEM: InputTextMultiline", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which uses a child window) + if (item_type == 7) { ret = ImGui::InputFloat("ITEM: InputFloat", col4f, 1.0f); } // Testing +/- buttons on scalar input + if (item_type == 8) { ret = ImGui::InputFloat3("ITEM: InputFloat3", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) + if (item_type == 9) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) + if (item_type == 10){ ret = ImGui::Selectable("ITEM: Selectable"); } // Testing selectable item + if (item_type == 11){ ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy) + if (item_type == 12){ ret = ImGui::TreeNode("ITEM: TreeNode"); if (ret) ImGui::TreePop(); } // Testing tree node + if (item_type == 13){ ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy. + if (item_type == 14){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::Combo("ITEM: Combo", ¤t, items, IM_ARRAYSIZE(items)); } + if (item_type == 15){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", ¤t, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); } + + bool hovered_delay_none = ImGui::IsItemHovered(); + bool hovered_delay_stationary = ImGui::IsItemHovered(ImGuiHoveredFlags_Stationary); + bool hovered_delay_short = ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort); + bool hovered_delay_normal = ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal); + bool hovered_delay_tooltip = ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip); // = Normal + Stationary + + // Display the values of IsItemHovered() and other common item state functions. + // Note that the ImGuiHoveredFlags_XXX flags can be combined. + // Because BulletText is an item itself and that would affect the output of IsItemXXX functions, + // we query every state in a single call to avoid storing them and to simplify the code. + ImGui::BulletText( + "Return value = %d\n" + "IsItemFocused() = %d\n" + "IsItemHovered() = %d\n" + "IsItemHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsItemHovered(_AllowWhenOverlappedByItem) = %d\n" + "IsItemHovered(_AllowWhenOverlappedByWindow) = %d\n" + "IsItemHovered(_AllowWhenDisabled) = %d\n" + "IsItemHovered(_RectOnly) = %d\n" + "IsItemActive() = %d\n" + "IsItemEdited() = %d\n" + "IsItemActivated() = %d\n" + "IsItemDeactivated() = %d\n" + "IsItemDeactivatedAfterEdit() = %d\n" + "IsItemVisible() = %d\n" + "IsItemClicked() = %d\n" + "IsItemToggledOpen() = %d\n" + "GetItemRectMin() = (%.1f, %.1f)\n" + "GetItemRectMax() = (%.1f, %.1f)\n" + "GetItemRectSize() = (%.1f, %.1f)", + ret, + ImGui::IsItemFocused(), + ImGui::IsItemHovered(), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByItem), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlappedByWindow), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled), + ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly), + ImGui::IsItemActive(), + ImGui::IsItemEdited(), + ImGui::IsItemActivated(), + ImGui::IsItemDeactivated(), + ImGui::IsItemDeactivatedAfterEdit(), + ImGui::IsItemVisible(), + ImGui::IsItemClicked(), + ImGui::IsItemToggledOpen(), + ImGui::GetItemRectMin().x, ImGui::GetItemRectMin().y, + ImGui::GetItemRectMax().x, ImGui::GetItemRectMax().y, + ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y + ); + ImGui::BulletText( + "with Hovering Delay or Stationary test:\n" + "IsItemHovered() = = %d\n" + "IsItemHovered(_Stationary) = %d\n" + "IsItemHovered(_DelayShort) = %d\n" + "IsItemHovered(_DelayNormal) = %d\n" + "IsItemHovered(_Tooltip) = %d", + hovered_delay_none, hovered_delay_stationary, hovered_delay_short, hovered_delay_normal, hovered_delay_tooltip); + + if (item_disabled) + ImGui::EndDisabled(); + + char buf[1] = ""; + ImGui::InputText("unused", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_ReadOnly); + ImGui::SameLine(); + HelpMarker("This widget is only here to be able to tab-out of the widgets above and see e.g. Deactivated() status."); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Querying Window Status (Focused,Hovered etc.)"); + if (ImGui::TreeNode("Querying Window Status (Focused/Hovered etc.)")) + { + static bool embed_all_inside_a_child_window = false; + ImGui::Checkbox("Embed everything inside a child window for testing _RootWindow flag.", &embed_all_inside_a_child_window); + if (embed_all_inside_a_child_window) + ImGui::BeginChild("outer_child", ImVec2(0, ImGui::GetFontSize() * 20.0f), true); + + // Testing IsWindowFocused() function with its various flags. + ImGui::BulletText( + "IsWindowFocused() = %d\n" + "IsWindowFocused(_ChildWindows) = %d\n" + "IsWindowFocused(_ChildWindows|_NoPopupHierarchy) = %d\n" + "IsWindowFocused(_ChildWindows|_RootWindow) = %d\n" + "IsWindowFocused(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowFocused(_RootWindow) = %d\n" + "IsWindowFocused(_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowFocused(_AnyWindow) = %d\n", + ImGui::IsWindowFocused(), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy), + ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)); + + // Testing IsWindowHovered() function with its various flags. + ImGui::BulletText( + "IsWindowHovered() = %d\n" + "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsWindowHovered(_ChildWindows) = %d\n" + "IsWindowHovered(_ChildWindows|_NoPopupHierarchy) = %d\n" + "IsWindowHovered(_ChildWindows|_RootWindow) = %d\n" + "IsWindowHovered(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowHovered(_RootWindow) = %d\n" + "IsWindowHovered(_RootWindow|_NoPopupHierarchy) = %d\n" + "IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n" + "IsWindowHovered(_AnyWindow) = %d\n" + "IsWindowHovered(_Stationary) = %d\n", + ImGui::IsWindowHovered(), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_Stationary)); + + ImGui::BeginChild("child", ImVec2(0, 50), true); + ImGui::Text("This is another child window for testing the _ChildWindows flag."); + ImGui::EndChild(); + if (embed_all_inside_a_child_window) + ImGui::EndChild(); + + // Calling IsItemHovered() after begin returns the hovered status of the title bar. + // This is useful in particular if you want to create a context menu associated to the title bar of a window. + static bool test_window = false; + ImGui::Checkbox("Hovered/Active tests after Begin() for title bar testing", &test_window); + if (test_window) + { + ImGui::Begin("Title bar Hovered/Active tests", &test_window); + if (ImGui::BeginPopupContextItem()) // <-- This is using IsItemHovered() + { + if (ImGui::MenuItem("Close")) { test_window = false; } + ImGui::EndPopup(); + } + ImGui::Text( + "IsItemHovered() after begin = %d (== is title bar hovered)\n" + "IsItemActive() after begin = %d (== is window being clicked/moved)\n", + ImGui::IsItemHovered(), ImGui::IsItemActive()); + ImGui::End(); + } + + ImGui::TreePop(); + } + + // Demonstrate BeginDisabled/EndDisabled using a checkbox located at the bottom of the section (which is a bit odd: + // logically we'd have this checkbox at the top of the section, but we don't want this feature to steal that space) + if (disable_all) + ImGui::EndDisabled(); + + IMGUI_DEMO_MARKER("Widgets/Disable Block"); + if (ImGui::TreeNode("Disable block")) + { + ImGui::Checkbox("Disable entire section above", &disable_all); + ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across this section."); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Text Filter"); + if (ImGui::TreeNode("Text Filter")) + { + // Helper class to easy setup a text filter. + // You may want to implement a more feature-full filtering scheme in your own application. + HelpMarker("Not a widget per-se, but ImGuiTextFilter is a helper to perform simple filtering on text strings."); + static ImGuiTextFilter filter; + ImGui::Text("Filter usage:\n" + " \"\" display all lines\n" + " \"xxx\" display lines containing \"xxx\"\n" + " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" + " \"-xxx\" hide lines containing \"xxx\""); + filter.Draw(); + const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; + for (int i = 0; i < IM_ARRAYSIZE(lines); i++) + if (filter.PassFilter(lines[i])) + ImGui::BulletText("%s", lines[i]); + ImGui::TreePop(); + } +} + +static void ShowDemoWindowLayout() +{ + IMGUI_DEMO_MARKER("Layout"); + if (!ImGui::CollapsingHeader("Layout & Scrolling")) + return; + + IMGUI_DEMO_MARKER("Layout/Child windows"); + if (ImGui::TreeNode("Child windows")) + { + ImGui::SeparatorText("Child windows"); + + HelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window."); + static bool disable_mouse_wheel = false; + static bool disable_menu = false; + ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); + ImGui::Checkbox("Disable Menu", &disable_menu); + + // Child 1: no border, enable horizontal scrollbar + { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar; + if (disable_mouse_wheel) + window_flags |= ImGuiWindowFlags_NoScrollWithMouse; + ImGui::BeginChild("ChildL", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 260), false, window_flags); + for (int i = 0; i < 100; i++) + ImGui::Text("%04d: scrollable region", i); + ImGui::EndChild(); + } + + ImGui::SameLine(); + + // Child 2: rounded border + { + ImGuiWindowFlags window_flags = ImGuiWindowFlags_None; + if (disable_mouse_wheel) + window_flags |= ImGuiWindowFlags_NoScrollWithMouse; + if (!disable_menu) + window_flags |= ImGuiWindowFlags_MenuBar; + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); + ImGui::BeginChild("ChildR", ImVec2(0, 260), true, window_flags); + if (!disable_menu && ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + if (ImGui::BeginTable("split", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings)) + { + for (int i = 0; i < 100; i++) + { + char buf[32]; + sprintf(buf, "%03d", i); + ImGui::TableNextColumn(); + ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f)); + } + ImGui::EndTable(); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + } + + ImGui::SeparatorText("Misc/Advanced"); + + // Demonstrate a few extra things + // - Changing ImGuiCol_ChildBg (which is transparent black in default styles) + // - Using SetCursorPos() to position child window (the child window is an item from the POV of parent window) + // You can also call SetNextWindowPos() to position the child window. The parent window will effectively + // layout from this position. + // - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from + // the POV of the parent window). See 'Demo->Querying Status (Edited/Active/Hovered etc.)' for details. + { + static int offset_x = 0; + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::DragInt("Offset X", &offset_x, 1.0f, -1000, 1000); + + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + (float)offset_x); + ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100)); + ImGui::BeginChild("Red", ImVec2(200, 100), true, ImGuiWindowFlags_None); + for (int n = 0; n < 50; n++) + ImGui::Text("Some test %d", n); + ImGui::EndChild(); + bool child_is_hovered = ImGui::IsItemHovered(); + ImVec2 child_rect_min = ImGui::GetItemRectMin(); + ImVec2 child_rect_max = ImGui::GetItemRectMax(); + ImGui::PopStyleColor(); + ImGui::Text("Hovered: %d", child_is_hovered); + ImGui::Text("Rect of child window is: (%.0f,%.0f) (%.0f,%.0f)", child_rect_min.x, child_rect_min.y, child_rect_max.x, child_rect_max.y); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Widgets Width"); + if (ImGui::TreeNode("Widgets Width")) + { + static float f = 0.0f; + static bool show_indented_items = true; + ImGui::Checkbox("Show indented items", &show_indented_items); + + // Use SetNextItemWidth() to set the width of a single upcoming item. + // Use PushItemWidth()/PopItemWidth() to set the width of a group of items. + // In real code use you'll probably want to choose width values that are proportional to your font size + // e.g. Using '20.0f * GetFontSize()' as width instead of '200.0f', etc. + + ImGui::Text("SetNextItemWidth/PushItemWidth(100)"); + ImGui::SameLine(); HelpMarker("Fixed width."); + ImGui::PushItemWidth(100); + ImGui::DragFloat("float##1b", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##1b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::Text("SetNextItemWidth/PushItemWidth(-100)"); + ImGui::SameLine(); HelpMarker("Align to right edge minus 100"); + ImGui::PushItemWidth(-100); + ImGui::DragFloat("float##2a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##2b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::Text("SetNextItemWidth/PushItemWidth(GetContentRegionAvail().x * 0.5f)"); + ImGui::SameLine(); HelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x * 0.5f); + ImGui::DragFloat("float##3a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##3b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::Text("SetNextItemWidth/PushItemWidth(-GetContentRegionAvail().x * 0.5f)"); + ImGui::SameLine(); HelpMarker("Align to right edge minus half"); + ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.5f); + ImGui::DragFloat("float##4a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##4b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + // Demonstrate using PushItemWidth to surround three items. + // Calling SetNextItemWidth() before each of them would have the same effect. + ImGui::Text("SetNextItemWidth/PushItemWidth(-FLT_MIN)"); + ImGui::SameLine(); HelpMarker("Align to right edge"); + ImGui::PushItemWidth(-FLT_MIN); + ImGui::DragFloat("##float5a", &f); + if (show_indented_items) + { + ImGui::Indent(); + ImGui::DragFloat("float (indented)##5b", &f); + ImGui::Unindent(); + } + ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout"); + if (ImGui::TreeNode("Basic Horizontal Layout")) + { + ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceding item)"); + + // Text + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine"); + ImGui::Text("Two items: Hello"); ImGui::SameLine(); + ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); + + // Adjust spacing + ImGui::Text("More spacing: Hello"); ImGui::SameLine(0, 20); + ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); + + // Button + ImGui::AlignTextToFramePadding(); + ImGui::Text("Normal buttons"); ImGui::SameLine(); + ImGui::Button("Banana"); ImGui::SameLine(); + ImGui::Button("Apple"); ImGui::SameLine(); + ImGui::Button("Corniflower"); + + // Button + ImGui::Text("Small buttons"); ImGui::SameLine(); + ImGui::SmallButton("Like this one"); ImGui::SameLine(); + ImGui::Text("can fit within a text block."); + + // Aligned to arbitrary position. Easy/cheap column. + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine (with offset)"); + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::Text("x=150"); + ImGui::SameLine(300); ImGui::Text("x=300"); + ImGui::Text("Aligned"); + ImGui::SameLine(150); ImGui::SmallButton("x=150"); + ImGui::SameLine(300); ImGui::SmallButton("x=300"); + + // Checkbox + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/SameLine (more)"); + static bool c1 = false, c2 = false, c3 = false, c4 = false; + ImGui::Checkbox("My", &c1); ImGui::SameLine(); + ImGui::Checkbox("Tailor", &c2); ImGui::SameLine(); + ImGui::Checkbox("Is", &c3); ImGui::SameLine(); + ImGui::Checkbox("Rich", &c4); + + // Various + static float f0 = 1.0f, f1 = 2.0f, f2 = 3.0f; + ImGui::PushItemWidth(80); + const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" }; + static int item = -1; + ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); ImGui::SameLine(); + ImGui::SliderFloat("X", &f0, 0.0f, 5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Y", &f1, 0.0f, 5.0f); ImGui::SameLine(); + ImGui::SliderFloat("Z", &f2, 0.0f, 5.0f); + ImGui::PopItemWidth(); + + ImGui::PushItemWidth(80); + ImGui::Text("Lists:"); + static int selection[4] = { 0, 1, 2, 3 }; + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); + ImGui::PopID(); + //ImGui::SetItemTooltip("ListBox %d hovered", i); + } + ImGui::PopItemWidth(); + + // Dummy + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/Dummy"); + ImVec2 button_sz(40, 40); + ImGui::Button("A", button_sz); ImGui::SameLine(); + ImGui::Dummy(button_sz); ImGui::SameLine(); + ImGui::Button("B", button_sz); + + // Manually wrapping + // (we should eventually provide this as an automatic layout feature, but for now you can do it manually) + IMGUI_DEMO_MARKER("Layout/Basic Horizontal Layout/Manual wrapping"); + ImGui::Text("Manual wrapping:"); + ImGuiStyle& style = ImGui::GetStyle(); + int buttons_count = 20; + float window_visible_x2 = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x; + for (int n = 0; n < buttons_count; n++) + { + ImGui::PushID(n); + ImGui::Button("Box", button_sz); + float last_button_x2 = ImGui::GetItemRectMax().x; + float next_button_x2 = last_button_x2 + style.ItemSpacing.x + button_sz.x; // Expected position if next button was on same line + if (n + 1 < buttons_count && next_button_x2 < window_visible_x2) + ImGui::SameLine(); + ImGui::PopID(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Groups"); + if (ImGui::TreeNode("Groups")) + { + HelpMarker( + "BeginGroup() basically locks the horizontal position for new line. " + "EndGroup() bundles the whole group so that you can use \"item\" functions such as " + "IsItemHovered()/IsItemActive() or SameLine() etc. on the whole group."); + ImGui::BeginGroup(); + { + ImGui::BeginGroup(); + ImGui::Button("AAA"); + ImGui::SameLine(); + ImGui::Button("BBB"); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Button("CCC"); + ImGui::Button("DDD"); + ImGui::EndGroup(); + ImGui::SameLine(); + ImGui::Button("EEE"); + ImGui::EndGroup(); + ImGui::SetItemTooltip("First group hovered"); + } + // Capture the group size and create widgets using the same size + ImVec2 size = ImGui::GetItemRectSize(); + const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f }; + ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); + + ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x) * 0.5f, size.y)); + ImGui::SameLine(); + ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x) * 0.5f, size.y)); + ImGui::EndGroup(); + ImGui::SameLine(); + + ImGui::Button("LEVERAGE\nBUZZWORD", size); + ImGui::SameLine(); + + if (ImGui::BeginListBox("List", size)) + { + ImGui::Selectable("Selected", true); + ImGui::Selectable("Not Selected", false); + ImGui::EndListBox(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Text Baseline Alignment"); + if (ImGui::TreeNode("Text Baseline Alignment")) + { + { + ImGui::BulletText("Text baseline:"); + ImGui::SameLine(); HelpMarker( + "This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. " + "Lines only composed of text or \"small\" widgets use less vertical space than lines with framed widgets."); + ImGui::Indent(); + + ImGui::Text("KO Blahblah"); ImGui::SameLine(); + ImGui::Button("Some framed item"); ImGui::SameLine(); + HelpMarker("Baseline of button will look misaligned with text.."); + + // If your line starts with text, call AlignTextToFramePadding() to align text to upcoming widgets. + // (because we don't know what's coming after the Text() statement, we need to move the text baseline + // down by FramePadding.y ahead of time) + ImGui::AlignTextToFramePadding(); + ImGui::Text("OK Blahblah"); ImGui::SameLine(); + ImGui::Button("Some framed item"); ImGui::SameLine(); + HelpMarker("We call AlignTextToFramePadding() to vertically align the text baseline by +FramePadding.y"); + + // SmallButton() uses the same vertical padding as Text + ImGui::Button("TEST##1"); ImGui::SameLine(); + ImGui::Text("TEST"); ImGui::SameLine(); + ImGui::SmallButton("TEST##2"); + + // If your line starts with text, call AlignTextToFramePadding() to align text to upcoming widgets. + ImGui::AlignTextToFramePadding(); + ImGui::Text("Text aligned to framed item"); ImGui::SameLine(); + ImGui::Button("Item##1"); ImGui::SameLine(); + ImGui::Text("Item"); ImGui::SameLine(); + ImGui::SmallButton("Item##2"); ImGui::SameLine(); + ImGui::Button("Item##3"); + + ImGui::Unindent(); + } + + ImGui::Spacing(); + + { + ImGui::BulletText("Multi-line text:"); + ImGui::Indent(); + ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("One\nTwo\nThree"); + + ImGui::Button("HOP##1"); ImGui::SameLine(); + ImGui::Text("Banana"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("HOP##2"); ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); ImGui::SameLine(); + ImGui::Text("Banana"); + ImGui::Unindent(); + } + + ImGui::Spacing(); + + { + ImGui::BulletText("Misc items:"); + ImGui::Indent(); + + // SmallButton() sets FramePadding to zero. Text baseline is aligned to match baseline of previous Button. + ImGui::Button("80x80", ImVec2(80, 80)); + ImGui::SameLine(); + ImGui::Button("50x50", ImVec2(50, 50)); + ImGui::SameLine(); + ImGui::Button("Button()"); + ImGui::SameLine(); + ImGui::SmallButton("SmallButton()"); + + // Tree + const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + ImGui::Button("Button##1"); + ImGui::SameLine(0.0f, spacing); + if (ImGui::TreeNode("Node##1")) + { + // Placeholder tree data + for (int i = 0; i < 6; i++) + ImGui::BulletText("Item %d..", i); + ImGui::TreePop(); + } + + // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. + // Otherwise you can use SmallButton() (smaller fit). + ImGui::AlignTextToFramePadding(); + + // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add + // other contents below the node. + bool node_open = ImGui::TreeNode("Node##2"); + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); + if (node_open) + { + // Placeholder tree data + for (int i = 0; i < 6; i++) + ImGui::BulletText("Item %d..", i); + ImGui::TreePop(); + } + + // Bullet + ImGui::Button("Button##3"); + ImGui::SameLine(0.0f, spacing); + ImGui::BulletText("Bullet text"); + + ImGui::AlignTextToFramePadding(); + ImGui::BulletText("Node"); + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##4"); + ImGui::Unindent(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Scrolling"); + if (ImGui::TreeNode("Scrolling")) + { + // Vertical scroll functions + IMGUI_DEMO_MARKER("Layout/Scrolling/Vertical"); + HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given vertical position."); + + static int track_item = 50; + static bool enable_track = true; + static bool enable_extra_decorations = false; + static float scroll_to_off_px = 0.0f; + static float scroll_to_pos_px = 200.0f; + + ImGui::Checkbox("Decoration", &enable_extra_decorations); + + ImGui::Checkbox("Track", &enable_track); + ImGui::PushItemWidth(100); + ImGui::SameLine(140); enable_track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d"); + + bool scroll_to_off = ImGui::Button("Scroll Offset"); + ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, FLT_MAX, "+%.0f px"); + + bool scroll_to_pos = ImGui::Button("Scroll To Pos"); + ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, -10, FLT_MAX, "X/Y = %.0f px"); + ImGui::PopItemWidth(); + + if (scroll_to_off || scroll_to_pos) + enable_track = false; + + ImGuiStyle& style = ImGui::GetStyle(); + float child_w = (ImGui::GetContentRegionAvail().x - 4 * style.ItemSpacing.x) / 5; + if (child_w < 1.0f) + child_w = 1.0f; + ImGui::PushID("##VerticalScrolling"); + for (int i = 0; i < 5; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + const char* names[] = { "Top", "25%", "Center", "75%", "Bottom" }; + ImGui::TextUnformatted(names[i]); + + const ImGuiWindowFlags child_flags = enable_extra_decorations ? ImGuiWindowFlags_MenuBar : 0; + const ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i); + const bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(child_w, 200.0f), true, child_flags); + if (ImGui::BeginMenuBar()) + { + ImGui::TextUnformatted("abc"); + ImGui::EndMenuBar(); + } + if (scroll_to_off) + ImGui::SetScrollY(scroll_to_off_px); + if (scroll_to_pos) + ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_pos_px, i * 0.25f); + if (child_is_visible) // Avoid calling SetScrollHereY when running with culled items + { + for (int item = 0; item < 100; item++) + { + if (enable_track && item == track_item) + { + ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item); + ImGui::SetScrollHereY(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom + } + else + { + ImGui::Text("Item %d", item); + } + } + } + float scroll_y = ImGui::GetScrollY(); + float scroll_max_y = ImGui::GetScrollMaxY(); + ImGui::EndChild(); + ImGui::Text("%.0f/%.0f", scroll_y, scroll_max_y); + ImGui::EndGroup(); + } + ImGui::PopID(); + + // Horizontal scroll functions + IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal"); + ImGui::Spacing(); + HelpMarker( + "Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\n" + "Because the clipping rectangle of most window hides half worth of WindowPadding on the " + "left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the " + "equivalent SetScrollFromPosY(+1) wouldn't."); + ImGui::PushID("##HorizontalScrolling"); + for (int i = 0; i < 5; i++) + { + float child_height = ImGui::GetTextLineHeight() + style.ScrollbarSize + style.WindowPadding.y * 2.0f; + ImGuiWindowFlags child_flags = ImGuiWindowFlags_HorizontalScrollbar | (enable_extra_decorations ? ImGuiWindowFlags_AlwaysVerticalScrollbar : 0); + ImGuiID child_id = ImGui::GetID((void*)(intptr_t)i); + bool child_is_visible = ImGui::BeginChild(child_id, ImVec2(-100, child_height), true, child_flags); + if (scroll_to_off) + ImGui::SetScrollX(scroll_to_off_px); + if (scroll_to_pos) + ImGui::SetScrollFromPosX(ImGui::GetCursorStartPos().x + scroll_to_pos_px, i * 0.25f); + if (child_is_visible) // Avoid calling SetScrollHereY when running with culled items + { + for (int item = 0; item < 100; item++) + { + if (item > 0) + ImGui::SameLine(); + if (enable_track && item == track_item) + { + ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item); + ImGui::SetScrollHereX(i * 0.25f); // 0.0f:left, 0.5f:center, 1.0f:right + } + else + { + ImGui::Text("Item %d", item); + } + } + } + float scroll_x = ImGui::GetScrollX(); + float scroll_max_x = ImGui::GetScrollMaxX(); + ImGui::EndChild(); + ImGui::SameLine(); + const char* names[] = { "Left", "25%", "Center", "75%", "Right" }; + ImGui::Text("%s\n%.0f/%.0f", names[i], scroll_x, scroll_max_x); + ImGui::Spacing(); + } + ImGui::PopID(); + + // Miscellaneous Horizontal Scrolling Demo + IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal (more)"); + HelpMarker( + "Horizontal scrolling for a window is enabled via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\n" + "You may want to also explicitly specify content width by using SetNextWindowContentWidth() before Begin()."); + static int lines = 7; + ImGui::SliderInt("Lines", &lines, 1, 15); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f)); + ImVec2 scrolling_child_size = ImVec2(0, ImGui::GetFrameHeightWithSpacing() * 7 + 30); + ImGui::BeginChild("scrolling", scrolling_child_size, true, ImGuiWindowFlags_HorizontalScrollbar); + for (int line = 0; line < lines; line++) + { + // Display random stuff. For the sake of this trivial demo we are using basic Button() + SameLine() + // If you want to create your own time line for a real application you may be better off manipulating + // the cursor position yourself, aka using SetCursorPos/SetCursorScreenPos to position the widgets + // yourself. You may also want to use the lower-level ImDrawList API. + int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3); + for (int n = 0; n < num_buttons; n++) + { + if (n > 0) ImGui::SameLine(); + ImGui::PushID(n + line * 1000); + char num_buf[16]; + sprintf(num_buf, "%d", n); + const char* label = (!(n % 15)) ? "FizzBuzz" : (!(n % 3)) ? "Fizz" : (!(n % 5)) ? "Buzz" : num_buf; + float hue = n * 0.05f; + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(hue, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(hue, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(hue, 0.8f, 0.8f)); + ImGui::Button(label, ImVec2(40.0f + sinf((float)(line + n)) * 20.0f, 0.0f)); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + } + float scroll_x = ImGui::GetScrollX(); + float scroll_max_x = ImGui::GetScrollMaxX(); + ImGui::EndChild(); + ImGui::PopStyleVar(2); + float scroll_x_delta = 0.0f; + ImGui::SmallButton("<<"); + if (ImGui::IsItemActive()) + scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SameLine(); + ImGui::Text("Scroll from code"); ImGui::SameLine(); + ImGui::SmallButton(">>"); + if (ImGui::IsItemActive()) + scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SameLine(); + ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x); + if (scroll_x_delta != 0.0f) + { + // Demonstrate a trick: you can use Begin to set yourself in the context of another window + // (here we are already out of your child window) + ImGui::BeginChild("scrolling"); + ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta); + ImGui::EndChild(); + } + ImGui::Spacing(); + + static bool show_horizontal_contents_size_demo_window = false; + ImGui::Checkbox("Show Horizontal contents size demo window", &show_horizontal_contents_size_demo_window); + + if (show_horizontal_contents_size_demo_window) + { + static bool show_h_scrollbar = true; + static bool show_button = true; + static bool show_tree_nodes = true; + static bool show_text_wrapped = false; + static bool show_columns = true; + static bool show_tab_bar = true; + static bool show_child = false; + static bool explicit_content_size = false; + static float contents_size_x = 300.0f; + if (explicit_content_size) + ImGui::SetNextWindowContentSize(ImVec2(contents_size_x, 0.0f)); + ImGui::Begin("Horizontal contents size demo window", &show_horizontal_contents_size_demo_window, show_h_scrollbar ? ImGuiWindowFlags_HorizontalScrollbar : 0); + IMGUI_DEMO_MARKER("Layout/Scrolling/Horizontal contents size demo window"); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 0)); + HelpMarker("Test of different widgets react and impact the work rectangle growing when horizontal scrolling is enabled.\n\nUse 'Metrics->Tools->Show windows rectangles' to visualize rectangles."); + ImGui::Checkbox("H-scrollbar", &show_h_scrollbar); + ImGui::Checkbox("Button", &show_button); // Will grow contents size (unless explicitly overwritten) + ImGui::Checkbox("Tree nodes", &show_tree_nodes); // Will grow contents size and display highlight over full width + ImGui::Checkbox("Text wrapped", &show_text_wrapped);// Will grow and use contents size + ImGui::Checkbox("Columns", &show_columns); // Will use contents size + ImGui::Checkbox("Tab bar", &show_tab_bar); // Will use contents size + ImGui::Checkbox("Child", &show_child); // Will grow and use contents size + ImGui::Checkbox("Explicit content size", &explicit_content_size); + ImGui::Text("Scroll %.1f/%.1f %.1f/%.1f", ImGui::GetScrollX(), ImGui::GetScrollMaxX(), ImGui::GetScrollY(), ImGui::GetScrollMaxY()); + if (explicit_content_size) + { + ImGui::SameLine(); + ImGui::SetNextItemWidth(100); + ImGui::DragFloat("##csx", &contents_size_x); + ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + 10, p.y + 10), IM_COL32_WHITE); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(p.x + contents_size_x - 10, p.y), ImVec2(p.x + contents_size_x, p.y + 10), IM_COL32_WHITE); + ImGui::Dummy(ImVec2(0, 10)); + } + ImGui::PopStyleVar(2); + ImGui::Separator(); + if (show_button) + { + ImGui::Button("this is a 300-wide button", ImVec2(300, 0)); + } + if (show_tree_nodes) + { + bool open = true; + if (ImGui::TreeNode("this is a tree node")) + { + if (ImGui::TreeNode("another one of those tree node...")) + { + ImGui::Text("Some tree contents"); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + ImGui::CollapsingHeader("CollapsingHeader", &open); + } + if (show_text_wrapped) + { + ImGui::TextWrapped("This text should automatically wrap on the edge of the work rectangle."); + } + if (show_columns) + { + ImGui::Text("Tables:"); + if (ImGui::BeginTable("table", 4, ImGuiTableFlags_Borders)) + { + for (int n = 0; n < 4; n++) + { + ImGui::TableNextColumn(); + ImGui::Text("Width %.2f", ImGui::GetContentRegionAvail().x); + } + ImGui::EndTable(); + } + ImGui::Text("Columns:"); + ImGui::Columns(4); + for (int n = 0; n < 4; n++) + { + ImGui::Text("Width %.2f", ImGui::GetColumnWidth()); + ImGui::NextColumn(); + } + ImGui::Columns(1); + } + if (show_tab_bar && ImGui::BeginTabBar("Hello")) + { + if (ImGui::BeginTabItem("OneOneOne")) { ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("TwoTwoTwo")) { ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("ThreeThreeThree")) { ImGui::EndTabItem(); } + if (ImGui::BeginTabItem("FourFourFour")) { ImGui::EndTabItem(); } + ImGui::EndTabBar(); + } + if (show_child) + { + ImGui::BeginChild("child", ImVec2(0, 0), true); + ImGui::EndChild(); + } + ImGui::End(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Layout/Clipping"); + if (ImGui::TreeNode("Clipping")) + { + static ImVec2 size(100.0f, 100.0f); + static ImVec2 offset(30.0f, 30.0f); + ImGui::DragFloat2("size", (float*)&size, 0.5f, 1.0f, 200.0f, "%.0f"); + ImGui::TextWrapped("(Click and drag to scroll)"); + + HelpMarker( + "(Left) Using ImGui::PushClipRect():\n" + "Will alter ImGui hit-testing logic + ImDrawList rendering.\n" + "(use this if you want your clipping rectangle to affect interactions)\n\n" + "(Center) Using ImDrawList::PushClipRect():\n" + "Will alter ImDrawList rendering only.\n" + "(use this as a shortcut if you are only using ImDrawList calls)\n\n" + "(Right) Using ImDrawList::AddText() with a fine ClipRect:\n" + "Will alter only this specific ImDrawList::AddText() rendering.\n" + "This is often used internally to avoid altering the clipping rectangle and minimize draw calls."); + + for (int n = 0; n < 3; n++) + { + if (n > 0) + ImGui::SameLine(); + + ImGui::PushID(n); + ImGui::InvisibleButton("##canvas", size); + if (ImGui::IsItemActive() && ImGui::IsMouseDragging(ImGuiMouseButton_Left)) + { + offset.x += ImGui::GetIO().MouseDelta.x; + offset.y += ImGui::GetIO().MouseDelta.y; + } + ImGui::PopID(); + if (!ImGui::IsItemVisible()) // Skip rendering as ImDrawList elements are not clipped. + continue; + + const ImVec2 p0 = ImGui::GetItemRectMin(); + const ImVec2 p1 = ImGui::GetItemRectMax(); + const char* text_str = "Line 1 hello\nLine 2 clip me!"; + const ImVec2 text_pos = ImVec2(p0.x + offset.x, p0.y + offset.y); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + switch (n) + { + case 0: + ImGui::PushClipRect(p0, p1, true); + draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255)); + draw_list->AddText(text_pos, IM_COL32_WHITE, text_str); + ImGui::PopClipRect(); + break; + case 1: + draw_list->PushClipRect(p0, p1, true); + draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255)); + draw_list->AddText(text_pos, IM_COL32_WHITE, text_str); + draw_list->PopClipRect(); + break; + case 2: + ImVec4 clip_rect(p0.x, p0.y, p1.x, p1.y); // AddText() takes a ImVec4* here so let's convert. + draw_list->AddRectFilled(p0, p1, IM_COL32(90, 90, 120, 255)); + draw_list->AddText(ImGui::GetFont(), ImGui::GetFontSize(), text_pos, IM_COL32_WHITE, text_str, NULL, 0.0f, &clip_rect); + break; + } + } + + ImGui::TreePop(); + } +} + +static void ShowDemoWindowPopups() +{ + IMGUI_DEMO_MARKER("Popups"); + if (!ImGui::CollapsingHeader("Popups & Modal windows")) + return; + + // The properties of popups windows are: + // - They block normal mouse hovering detection outside them. (*) + // - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE. + // - Their visibility state (~bool) is held internally by Dear ImGui instead of being held by the programmer as + // we are used to with regular Begin() calls. User can manipulate the visibility state by calling OpenPopup(). + // (*) One can use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) to bypass it and detect hovering even + // when normally blocked by a popup. + // Those three properties are connected. The library needs to hold their visibility state BECAUSE it can close + // popups at any time. + + // Typical use for regular windows: + // bool my_tool_is_active = false; if (ImGui::Button("Open")) my_tool_is_active = true; [...] if (my_tool_is_active) Begin("My Tool", &my_tool_is_active) { [...] } End(); + // Typical use for popups: + // if (ImGui::Button("Open")) ImGui::OpenPopup("MyPopup"); if (ImGui::BeginPopup("MyPopup") { [...] EndPopup(); } + + // With popups we have to go through a library call (here OpenPopup) to manipulate the visibility state. + // This may be a bit confusing at first but it should quickly make sense. Follow on the examples below. + + IMGUI_DEMO_MARKER("Popups/Popups"); + if (ImGui::TreeNode("Popups")) + { + ImGui::TextWrapped( + "When a popup is active, it inhibits interacting with windows that are behind the popup. " + "Clicking outside the popup closes it."); + + static int selected_fish = -1; + const char* names[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" }; + static bool toggles[] = { true, false, false, false, false }; + + // Simple selection popup (if you want to show the current selection inside the Button itself, + // you may want to build a string using the "###" operator to preserve a constant ID with a variable label) + if (ImGui::Button("Select..")) + ImGui::OpenPopup("my_select_popup"); + ImGui::SameLine(); + ImGui::TextUnformatted(selected_fish == -1 ? "" : names[selected_fish]); + if (ImGui::BeginPopup("my_select_popup")) + { + ImGui::SeparatorText("Aquarium"); + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + if (ImGui::Selectable(names[i])) + selected_fish = i; + ImGui::EndPopup(); + } + + // Showing a menu with toggles + if (ImGui::Button("Toggle..")) + ImGui::OpenPopup("my_toggle_popup"); + if (ImGui::BeginPopup("my_toggle_popup")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + ImGui::EndMenu(); + } + + ImGui::Separator(); + ImGui::Text("Tooltip here"); + ImGui::SetItemTooltip("I am a tooltip over a popup"); + + if (ImGui::Button("Stacked Popup")) + ImGui::OpenPopup("another popup"); + if (ImGui::BeginPopup("another popup")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + if (ImGui::Button("Stacked Popup")) + ImGui::OpenPopup("another popup"); + if (ImGui::BeginPopup("another popup")) + { + ImGui::Text("I am the last one here."); + ImGui::EndPopup(); + } + ImGui::EndMenu(); + } + ImGui::EndPopup(); + } + ImGui::EndPopup(); + } + + // Call the more complete ShowExampleMenuFile which we use in various places of this demo + if (ImGui::Button("With a menu..")) + ImGui::OpenPopup("my_file_popup"); + if (ImGui::BeginPopup("my_file_popup", ImGuiWindowFlags_MenuBar)) + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + ImGui::MenuItem("Dummy"); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + ImGui::Text("Hello from popup!"); + ImGui::Button("This is a dummy button.."); + ImGui::EndPopup(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Popups/Context menus"); + if (ImGui::TreeNode("Context menus")) + { + HelpMarker("\"Context\" functions are simple helpers to associate a Popup to a given Item or Window identifier."); + + // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: + // if (id == 0) + // id = GetItemID(); // Use last item id + // if (IsItemHovered() && IsMouseReleased(ImGuiMouseButton_Right)) + // OpenPopup(id); + // return BeginPopup(id); + // For advanced uses you may want to replicate and customize this code. + // See more details in BeginPopupContextItem(). + + // Example 1 + // When used after an item that has an ID (e.g. Button), we can skip providing an ID to BeginPopupContextItem(), + // and BeginPopupContextItem() will use the last item ID as the popup ID. + { + const char* names[5] = { "Label1", "Label2", "Label3", "Label4", "Label5" }; + static int selected = -1; + for (int n = 0; n < 5; n++) + { + if (ImGui::Selectable(names[n], selected == n)) + selected = n; + if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id + { + selected = n; + ImGui::Text("This a popup for \"%s\"!", names[n]); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::SetItemTooltip("Right-click to open popup"); + } + } + + // Example 2 + // Popup on a Text() element which doesn't have an identifier: we need to provide an identifier to BeginPopupContextItem(). + // Using an explicit identifier is also convenient if you want to activate the popups from different locations. + { + HelpMarker("Text() elements don't have stable identifiers so we need to provide one."); + static float value = 0.5f; + ImGui::Text("Value = %.3f <-- (1) right-click this text", value); + if (ImGui::BeginPopupContextItem("my popup")) + { + if (ImGui::Selectable("Set to zero")) value = 0.0f; + if (ImGui::Selectable("Set to PI")) value = 3.1415f; + ImGui::SetNextItemWidth(-FLT_MIN); + ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); + ImGui::EndPopup(); + } + + // We can also use OpenPopupOnItemClick() to toggle the visibility of a given popup. + // Here we make it that right-clicking this other text element opens the same popup as above. + // The popup itself will be submitted by the code above. + ImGui::Text("(2) Or right-click this text"); + ImGui::OpenPopupOnItemClick("my popup", ImGuiPopupFlags_MouseButtonRight); + + // Back to square one: manually open the same popup. + if (ImGui::Button("(3) Or click this button")) + ImGui::OpenPopup("my popup"); + } + + // Example 3 + // When using BeginPopupContextItem() with an implicit identifier (NULL == use last item ID), + // we need to make sure your item identifier is stable. + // In this example we showcase altering the item label while preserving its identifier, using the ### operator (see FAQ). + { + HelpMarker("Showcase using a popup ID linked to item ID, with the item having a changing label + stable ID using the ### operator."); + static char name[32] = "Label1"; + char buf[64]; + sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label + ImGui::Button(buf); + if (ImGui::BeginPopupContextItem()) + { + ImGui::Text("Edit name:"); + ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::SameLine(); ImGui::Text("(<-- right-click here)"); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Popups/Modals"); + if (ImGui::TreeNode("Modals")) + { + ImGui::TextWrapped("Modal windows are like popups but the user cannot close them by clicking outside."); + + if (ImGui::Button("Delete..")) + ImGui::OpenPopup("Delete?"); + + // Always center this window when appearing + ImVec2 center = ImGui::GetMainViewport()->GetCenter(); + ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + + if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!"); + ImGui::Separator(); + + //static int unused_i = 0; + //ImGui::Combo("Combo", &unused_i, "Delete\0Delete harder\0"); + + static bool dont_ask_me_next_time = false; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time); + ImGui::PopStyleVar(); + + if (ImGui::Button("OK", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); } + ImGui::SetItemDefaultFocus(); + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); } + ImGui::EndPopup(); + } + + if (ImGui::Button("Stacked modals..")) + ImGui::OpenPopup("Stacked 1"); + if (ImGui::BeginPopupModal("Stacked 1", NULL, ImGuiWindowFlags_MenuBar)) + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Some menu item")) {} + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDimBg] behind it."); + + // Testing behavior of widgets stacking their own regular popups over the modal. + static int item = 1; + static float color[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; + ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + ImGui::ColorEdit4("color", color); + + if (ImGui::Button("Add another modal..")) + ImGui::OpenPopup("Stacked 2"); + + // Also demonstrate passing a bool* to BeginPopupModal(), this will create a regular close button which + // will close the popup. Note that the visibility state of popups is owned by imgui, so the input value + // of the bool actually doesn't matter here. + bool unused_open = true; + if (ImGui::BeginPopupModal("Stacked 2", &unused_open)) + { + ImGui::Text("Hello from Stacked The Second!"); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Popups/Menus inside a regular window"); + if (ImGui::TreeNode("Menus inside a regular window")) + { + ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); + ImGui::Separator(); + + ImGui::MenuItem("Menu item", "CTRL+M"); + if (ImGui::BeginMenu("Menu inside a regular window")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::Separator(); + ImGui::TreePop(); + } +} + +// Dummy data structure that we use for the Table demo. +// (pre-C++11 doesn't allow us to instantiate ImVector template if this structure is defined inside the demo function) +namespace +{ +// We are passing our own identifier to TableSetupColumn() to facilitate identifying columns in the sorting code. +// This identifier will be passed down into ImGuiTableSortSpec::ColumnUserID. +// But it is possible to omit the user id parameter of TableSetupColumn() and just use the column index instead! (ImGuiTableSortSpec::ColumnIndex) +// If you don't use sorting, you will generally never care about giving column an ID! +enum MyItemColumnID +{ + MyItemColumnID_ID, + MyItemColumnID_Name, + MyItemColumnID_Action, + MyItemColumnID_Quantity, + MyItemColumnID_Description +}; + +struct MyItem +{ + int ID; + const char* Name; + int Quantity; + + // We have a problem which is affecting _only this demo_ and should not affect your code: + // As we don't rely on std:: or other third-party library to compile dear imgui, we only have reliable access to qsort(), + // however qsort doesn't allow passing user data to comparing function. + // As a workaround, we are storing the sort specs in a static/global for the comparing function to access. + // In your own use case you would probably pass the sort specs to your sorting/comparing functions directly and not use a global. + // We could technically call ImGui::TableGetSortSpecs() in CompareWithSortSpecs(), but considering that this function is called + // very often by the sorting algorithm it would be a little wasteful. + static const ImGuiTableSortSpecs* s_current_sort_specs; + + // Compare function to be used by qsort() + static int IMGUI_CDECL CompareWithSortSpecs(const void* lhs, const void* rhs) + { + const MyItem* a = (const MyItem*)lhs; + const MyItem* b = (const MyItem*)rhs; + for (int n = 0; n < s_current_sort_specs->SpecsCount; n++) + { + // Here we identify columns using the ColumnUserID value that we ourselves passed to TableSetupColumn() + // We could also choose to identify columns based on their index (sort_spec->ColumnIndex), which is simpler! + const ImGuiTableColumnSortSpecs* sort_spec = &s_current_sort_specs->Specs[n]; + int delta = 0; + switch (sort_spec->ColumnUserID) + { + case MyItemColumnID_ID: delta = (a->ID - b->ID); break; + case MyItemColumnID_Name: delta = (strcmp(a->Name, b->Name)); break; + case MyItemColumnID_Quantity: delta = (a->Quantity - b->Quantity); break; + case MyItemColumnID_Description: delta = (strcmp(a->Name, b->Name)); break; + default: IM_ASSERT(0); break; + } + if (delta > 0) + return (sort_spec->SortDirection == ImGuiSortDirection_Ascending) ? +1 : -1; + if (delta < 0) + return (sort_spec->SortDirection == ImGuiSortDirection_Ascending) ? -1 : +1; + } + + // qsort() is instable so always return a way to differenciate items. + // Your own compare function may want to avoid fallback on implicit sort specs e.g. a Name compare if it wasn't already part of the sort specs. + return (a->ID - b->ID); + } +}; +const ImGuiTableSortSpecs* MyItem::s_current_sort_specs = NULL; +} + +// Make the UI compact because there are so many fields +static void PushStyleCompact() +{ + ImGuiStyle& style = ImGui::GetStyle(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(style.FramePadding.x, (float)(int)(style.FramePadding.y * 0.60f))); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x, (float)(int)(style.ItemSpacing.y * 0.60f))); +} + +static void PopStyleCompact() +{ + ImGui::PopStyleVar(2); +} + +// Show a combo box with a choice of sizing policies +static void EditTableSizingFlags(ImGuiTableFlags* p_flags) +{ + struct EnumDesc { ImGuiTableFlags Value; const char* Name; const char* Tooltip; }; + static const EnumDesc policies[] = + { + { ImGuiTableFlags_None, "Default", "Use default sizing policy:\n- ImGuiTableFlags_SizingFixedFit if ScrollX is on or if host window has ImGuiWindowFlags_AlwaysAutoResize.\n- ImGuiTableFlags_SizingStretchSame otherwise." }, + { ImGuiTableFlags_SizingFixedFit, "ImGuiTableFlags_SizingFixedFit", "Columns default to _WidthFixed (if resizable) or _WidthAuto (if not resizable), matching contents width." }, + { ImGuiTableFlags_SizingFixedSame, "ImGuiTableFlags_SizingFixedSame", "Columns are all the same width, matching the maximum contents width.\nImplicitly disable ImGuiTableFlags_Resizable and enable ImGuiTableFlags_NoKeepColumnsVisible." }, + { ImGuiTableFlags_SizingStretchProp, "ImGuiTableFlags_SizingStretchProp", "Columns default to _WidthStretch with weights proportional to their widths." }, + { ImGuiTableFlags_SizingStretchSame, "ImGuiTableFlags_SizingStretchSame", "Columns default to _WidthStretch with same weights." } + }; + int idx; + for (idx = 0; idx < IM_ARRAYSIZE(policies); idx++) + if (policies[idx].Value == (*p_flags & ImGuiTableFlags_SizingMask_)) + break; + const char* preview_text = (idx < IM_ARRAYSIZE(policies)) ? policies[idx].Name + (idx > 0 ? strlen("ImGuiTableFlags") : 0) : ""; + if (ImGui::BeginCombo("Sizing Policy", preview_text)) + { + for (int n = 0; n < IM_ARRAYSIZE(policies); n++) + if (ImGui::Selectable(policies[n].Name, idx == n)) + *p_flags = (*p_flags & ~ImGuiTableFlags_SizingMask_) | policies[n].Value; + ImGui::EndCombo(); + } + ImGui::SameLine(); + ImGui::TextDisabled("(?)"); + if (ImGui::BeginItemTooltip()) + { + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 50.0f); + for (int m = 0; m < IM_ARRAYSIZE(policies); m++) + { + ImGui::Separator(); + ImGui::Text("%s:", policies[m].Name); + ImGui::Separator(); + ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetStyle().IndentSpacing * 0.5f); + ImGui::TextUnformatted(policies[m].Tooltip); + } + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } +} + +static void EditTableColumnsFlags(ImGuiTableColumnFlags* p_flags) +{ + ImGui::CheckboxFlags("_Disabled", p_flags, ImGuiTableColumnFlags_Disabled); ImGui::SameLine(); HelpMarker("Master disable flag (also hide from context menu)"); + ImGui::CheckboxFlags("_DefaultHide", p_flags, ImGuiTableColumnFlags_DefaultHide); + ImGui::CheckboxFlags("_DefaultSort", p_flags, ImGuiTableColumnFlags_DefaultSort); + if (ImGui::CheckboxFlags("_WidthStretch", p_flags, ImGuiTableColumnFlags_WidthStretch)) + *p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthStretch); + if (ImGui::CheckboxFlags("_WidthFixed", p_flags, ImGuiTableColumnFlags_WidthFixed)) + *p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthFixed); + ImGui::CheckboxFlags("_NoResize", p_flags, ImGuiTableColumnFlags_NoResize); + ImGui::CheckboxFlags("_NoReorder", p_flags, ImGuiTableColumnFlags_NoReorder); + ImGui::CheckboxFlags("_NoHide", p_flags, ImGuiTableColumnFlags_NoHide); + ImGui::CheckboxFlags("_NoClip", p_flags, ImGuiTableColumnFlags_NoClip); + ImGui::CheckboxFlags("_NoSort", p_flags, ImGuiTableColumnFlags_NoSort); + ImGui::CheckboxFlags("_NoSortAscending", p_flags, ImGuiTableColumnFlags_NoSortAscending); + ImGui::CheckboxFlags("_NoSortDescending", p_flags, ImGuiTableColumnFlags_NoSortDescending); + ImGui::CheckboxFlags("_NoHeaderLabel", p_flags, ImGuiTableColumnFlags_NoHeaderLabel); + ImGui::CheckboxFlags("_NoHeaderWidth", p_flags, ImGuiTableColumnFlags_NoHeaderWidth); + ImGui::CheckboxFlags("_PreferSortAscending", p_flags, ImGuiTableColumnFlags_PreferSortAscending); + ImGui::CheckboxFlags("_PreferSortDescending", p_flags, ImGuiTableColumnFlags_PreferSortDescending); + ImGui::CheckboxFlags("_IndentEnable", p_flags, ImGuiTableColumnFlags_IndentEnable); ImGui::SameLine(); HelpMarker("Default for column 0"); + ImGui::CheckboxFlags("_IndentDisable", p_flags, ImGuiTableColumnFlags_IndentDisable); ImGui::SameLine(); HelpMarker("Default for column >0"); +} + +static void ShowTableColumnsStatusFlags(ImGuiTableColumnFlags flags) +{ + ImGui::CheckboxFlags("_IsEnabled", &flags, ImGuiTableColumnFlags_IsEnabled); + ImGui::CheckboxFlags("_IsVisible", &flags, ImGuiTableColumnFlags_IsVisible); + ImGui::CheckboxFlags("_IsSorted", &flags, ImGuiTableColumnFlags_IsSorted); + ImGui::CheckboxFlags("_IsHovered", &flags, ImGuiTableColumnFlags_IsHovered); +} + +static void ShowDemoWindowTables() +{ + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); + IMGUI_DEMO_MARKER("Tables"); + if (!ImGui::CollapsingHeader("Tables & Columns")) + return; + + // Using those as a base value to create width/height that are factor of the size of our font + const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x; + const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing(); + + ImGui::PushID("Tables"); + + int open_action = -1; + if (ImGui::Button("Open all")) + open_action = 1; + ImGui::SameLine(); + if (ImGui::Button("Close all")) + open_action = 0; + ImGui::SameLine(); + + // Options + static bool disable_indent = false; + ImGui::Checkbox("Disable tree indentation", &disable_indent); + ImGui::SameLine(); + HelpMarker("Disable the indenting of tree nodes so demo tables can use the full window width."); + ImGui::Separator(); + if (disable_indent) + ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 0.0f); + + // About Styling of tables + // Most settings are configured on a per-table basis via the flags passed to BeginTable() and TableSetupColumns APIs. + // There are however a few settings that a shared and part of the ImGuiStyle structure: + // style.CellPadding // Padding within each cell + // style.Colors[ImGuiCol_TableHeaderBg] // Table header background + // style.Colors[ImGuiCol_TableBorderStrong] // Table outer and header borders + // style.Colors[ImGuiCol_TableBorderLight] // Table inner borders + // style.Colors[ImGuiCol_TableRowBg] // Table row background when ImGuiTableFlags_RowBg is enabled (even rows) + // style.Colors[ImGuiCol_TableRowBgAlt] // Table row background when ImGuiTableFlags_RowBg is enabled (odds rows) + + // Demos + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Basic"); + if (ImGui::TreeNode("Basic")) + { + // Here we will showcase three different ways to output a table. + // They are very simple variations of a same thing! + + // [Method 1] Using TableNextRow() to create a new row, and TableSetColumnIndex() to select the column. + // In many situations, this is the most flexible and easy to use pattern. + HelpMarker("Using TableNextRow() + calling TableSetColumnIndex() _before_ each cell, in a loop."); + if (ImGui::BeginTable("table1", 3)) + { + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Row %d Column %d", row, column); + } + } + ImGui::EndTable(); + } + + // [Method 2] Using TableNextColumn() called multiple times, instead of using a for loop + TableSetColumnIndex(). + // This is generally more convenient when you have code manually submitting the contents of each column. + HelpMarker("Using TableNextRow() + calling TableNextColumn() _before_ each cell, manually."); + if (ImGui::BeginTable("table2", 3)) + { + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("Row %d", row); + ImGui::TableNextColumn(); + ImGui::Text("Some contents"); + ImGui::TableNextColumn(); + ImGui::Text("123.456"); + } + ImGui::EndTable(); + } + + // [Method 3] We call TableNextColumn() _before_ each cell. We never call TableNextRow(), + // as TableNextColumn() will automatically wrap around and create new rows as needed. + // This is generally more convenient when your cells all contains the same type of data. + HelpMarker( + "Only using TableNextColumn(), which tends to be convenient for tables where every cell contains the same type of contents.\n" + "This is also more similar to the old NextColumn() function of the Columns API, and provided to facilitate the Columns->Tables API transition."); + if (ImGui::BeginTable("table3", 3)) + { + for (int item = 0; item < 14; item++) + { + ImGui::TableNextColumn(); + ImGui::Text("Item %d", item); + } + ImGui::EndTable(); + } + + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Borders, background"); + if (ImGui::TreeNode("Borders, background")) + { + // Expose a few Borders related flags interactively + enum ContentsType { CT_Text, CT_FillButton }; + static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + static bool display_headers = false; + static int contents_type = CT_Text; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags, ImGuiTableFlags_RowBg); + ImGui::CheckboxFlags("ImGuiTableFlags_Borders", &flags, ImGuiTableFlags_Borders); + ImGui::SameLine(); HelpMarker("ImGuiTableFlags_Borders\n = ImGuiTableFlags_BordersInnerV\n | ImGuiTableFlags_BordersOuterV\n | ImGuiTableFlags_BordersInnerV\n | ImGuiTableFlags_BordersOuterH"); + ImGui::Indent(); + + ImGui::CheckboxFlags("ImGuiTableFlags_BordersH", &flags, ImGuiTableFlags_BordersH); + ImGui::Indent(); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterH", &flags, ImGuiTableFlags_BordersOuterH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerH", &flags, ImGuiTableFlags_BordersInnerH); + ImGui::Unindent(); + + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV); + ImGui::Indent(); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV); + ImGui::Unindent(); + + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuter", &flags, ImGuiTableFlags_BordersOuter); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInner", &flags, ImGuiTableFlags_BordersInner); + ImGui::Unindent(); + + ImGui::AlignTextToFramePadding(); ImGui::Text("Cell contents:"); + ImGui::SameLine(); ImGui::RadioButton("Text", &contents_type, CT_Text); + ImGui::SameLine(); ImGui::RadioButton("FillButton", &contents_type, CT_FillButton); + ImGui::Checkbox("Display headers", &display_headers); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers"); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + // Display headers so we can inspect their interaction with borders. + // (Headers are not the main purpose of this section of the demo, so we are not elaborating on them too much. See other sections for details) + if (display_headers) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + } + + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + char buf[32]; + sprintf(buf, "Hello %d,%d", column, row); + if (contents_type == CT_Text) + ImGui::TextUnformatted(buf); + else if (contents_type == CT_FillButton) + ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f)); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Resizable, stretch"); + if (ImGui::TreeNode("Resizable, stretch")) + { + // By default, if we don't enable ScrollX the sizing policy for each column is "Stretch" + // All columns maintain a sizing weight, and they will occupy all available width. + static ImGuiTableFlags flags = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV); + ImGui::SameLine(); HelpMarker("Using the _Resizable flag automatically enables the _BordersInnerV flag as well, this is why the resize borders are still showing when unchecking this."); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Resizable, fixed"); + if (ImGui::TreeNode("Resizable, fixed")) + { + // Here we use ImGuiTableFlags_SizingFixedFit (even though _ScrollX is not set) + // So columns will adopt the "Fixed" policy and will maintain a fixed width regardless of the whole available width (unless table is small) + // If there is not enough available width to fit all columns, they will however be resized down. + // FIXME-TABLE: Providing a stretch-on-init would make sense especially for tables which don't have saved settings + HelpMarker( + "Using _Resizable + _SizingFixedFit flags.\n" + "Fixed-width columns generally makes more sense if you want to use horizontal scrolling.\n\n" + "Double-click a column border to auto-fit the column to its contents."); + PushStyleCompact(); + static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody; + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Resizable, mixed"); + if (ImGui::TreeNode("Resizable, mixed")) + { + HelpMarker( + "Using TableSetupColumn() to alter resizing policy on a per-column basis.\n\n" + "When combining Fixed and Stretch columns, generally you only want one, maybe two trailing columns to use _WidthStretch."); + static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; + + if (ImGui::BeginTable("table1", 3, flags)) + { + ImGui::TableSetupColumn("AAA", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("BBB", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CCC", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableHeadersRow(); + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%s %d,%d", (column == 2) ? "Stretch" : "Fixed", column, row); + } + } + ImGui::EndTable(); + } + if (ImGui::BeginTable("table2", 6, flags)) + { + ImGui::TableSetupColumn("AAA", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("BBB", ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("CCC", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_DefaultHide); + ImGui::TableSetupColumn("DDD", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("EEE", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("FFF", ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_DefaultHide); + ImGui::TableHeadersRow(); + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 6; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%s %d,%d", (column >= 3) ? "Stretch" : "Fixed", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Reorderable, hideable, with headers"); + if (ImGui::TreeNode("Reorderable, hideable, with headers")) + { + HelpMarker( + "Click and drag column headers to reorder columns.\n\n" + "Right-click on a header to open a context menu."); + static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_Reorderable", &flags, ImGuiTableFlags_Reorderable); + ImGui::CheckboxFlags("ImGuiTableFlags_Hideable", &flags, ImGuiTableFlags_Hideable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags, ImGuiTableFlags_NoBordersInBodyUntilResize); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appear in Headers)"); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 3, flags)) + { + // Submit columns name with TableSetupColumn() and call TableHeadersRow() to create a row with a header in each column. + // (Later we will show how TableSetupColumn() has other uses, optional flags, sizing weight etc.) + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + for (int row = 0; row < 6; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + // Use outer_size.x == 0.0f instead of default to make the table as tight as possible (only valid when no scrolling and no stretch column) + if (ImGui::BeginTable("table2", 3, flags | ImGuiTableFlags_SizingFixedFit, ImVec2(0.0f, 0.0f))) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + for (int row = 0; row < 6; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Fixed %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Padding"); + if (ImGui::TreeNode("Padding")) + { + // First example: showcase use of padding flags and effect of BorderOuterV/BorderInnerV on X padding. + // We don't expose BorderOuterH/BorderInnerH here because they have no effect on X padding. + HelpMarker( + "We often want outer padding activated when any using features which makes the edges of a column visible:\n" + "e.g.:\n" + "- BorderOuterV\n" + "- any form of row selection\n" + "Because of this, activating BorderOuterV sets the default to PadOuterX. Using PadOuterX or NoPadOuterX you can override the default.\n\n" + "Actual padding values are using style.CellPadding.\n\n" + "In this demo we don't show horizontal borders to emphasize how they don't affect default horizontal padding."); + + static ImGuiTableFlags flags1 = ImGuiTableFlags_BordersV; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", &flags1, ImGuiTableFlags_PadOuterX); + ImGui::SameLine(); HelpMarker("Enable outer-most padding (default if ImGuiTableFlags_BordersOuterV is set)"); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadOuterX", &flags1, ImGuiTableFlags_NoPadOuterX); + ImGui::SameLine(); HelpMarker("Disable outer-most padding (default if ImGuiTableFlags_BordersOuterV is not set)"); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadInnerX", &flags1, ImGuiTableFlags_NoPadInnerX); + ImGui::SameLine(); HelpMarker("Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off)"); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags1, ImGuiTableFlags_BordersOuterV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags1, ImGuiTableFlags_BordersInnerV); + static bool show_headers = false; + ImGui::Checkbox("show_headers", &show_headers); + PopStyleCompact(); + + if (ImGui::BeginTable("table_padding", 3, flags1)) + { + if (show_headers) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + } + + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + if (row == 0) + { + ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x); + } + else + { + char buf[32]; + sprintf(buf, "Hello %d,%d", column, row); + ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f)); + } + //if (ImGui::TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) + // ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, IM_COL32(0, 100, 0, 255)); + } + } + ImGui::EndTable(); + } + + // Second example: set style.CellPadding to (0.0) or a custom value. + // FIXME-TABLE: Vertical border effectively not displayed the same way as horizontal one... + HelpMarker("Setting style.CellPadding to (0,0) or a custom value."); + static ImGuiTableFlags flags2 = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg; + static ImVec2 cell_padding(0.0f, 0.0f); + static bool show_widget_frame_bg = true; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Borders", &flags2, ImGuiTableFlags_Borders); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersH", &flags2, ImGuiTableFlags_BordersH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags2, ImGuiTableFlags_BordersV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInner", &flags2, ImGuiTableFlags_BordersInner); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuter", &flags2, ImGuiTableFlags_BordersOuter); + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags2, ImGuiTableFlags_RowBg); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags2, ImGuiTableFlags_Resizable); + ImGui::Checkbox("show_widget_frame_bg", &show_widget_frame_bg); + ImGui::SliderFloat2("CellPadding", &cell_padding.x, 0.0f, 10.0f, "%.0f"); + PopStyleCompact(); + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cell_padding); + if (ImGui::BeginTable("table_padding_2", 3, flags2)) + { + static char text_bufs[3 * 5][16]; // Mini text storage for 3x5 cells + static bool init = true; + if (!show_widget_frame_bg) + ImGui::PushStyleColor(ImGuiCol_FrameBg, 0); + for (int cell = 0; cell < 3 * 5; cell++) + { + ImGui::TableNextColumn(); + if (init) + strcpy(text_bufs[cell], "edit me"); + ImGui::SetNextItemWidth(-FLT_MIN); + ImGui::PushID(cell); + ImGui::InputText("##cell", text_bufs[cell], IM_ARRAYSIZE(text_bufs[cell])); + ImGui::PopID(); + } + if (!show_widget_frame_bg) + ImGui::PopStyleColor(); + init = false; + ImGui::EndTable(); + } + ImGui::PopStyleVar(); + + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Explicit widths"); + if (ImGui::TreeNode("Sizing policies")) + { + static ImGuiTableFlags flags1 = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags1, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags1, ImGuiTableFlags_NoHostExtendX); + PopStyleCompact(); + + static ImGuiTableFlags sizing_policy_flags[4] = { ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingFixedSame, ImGuiTableFlags_SizingStretchProp, ImGuiTableFlags_SizingStretchSame }; + for (int table_n = 0; table_n < 4; table_n++) + { + ImGui::PushID(table_n); + ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * 30); + EditTableSizingFlags(&sizing_policy_flags[table_n]); + + // To make it easier to understand the different sizing policy, + // For each policy: we display one table where the columns have equal contents width, and one where the columns have different contents width. + if (ImGui::BeginTable("table1", 3, sizing_policy_flags[table_n] | flags1)) + { + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); ImGui::Text("Oh dear"); + ImGui::TableNextColumn(); ImGui::Text("Oh dear"); + ImGui::TableNextColumn(); ImGui::Text("Oh dear"); + } + ImGui::EndTable(); + } + if (ImGui::BeginTable("table2", 3, sizing_policy_flags[table_n] | flags1)) + { + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); ImGui::Text("AAAA"); + ImGui::TableNextColumn(); ImGui::Text("BBBBBBBB"); + ImGui::TableNextColumn(); ImGui::Text("CCCCCCCCCCCC"); + } + ImGui::EndTable(); + } + ImGui::PopID(); + } + + ImGui::Spacing(); + ImGui::TextUnformatted("Advanced"); + ImGui::SameLine(); + HelpMarker("This section allows you to interact and see the effect of various sizing policies depending on whether Scroll is enabled and the contents of your columns."); + + enum ContentsType { CT_ShowWidth, CT_ShortText, CT_LongText, CT_Button, CT_FillButton, CT_InputText }; + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable; + static int contents_type = CT_ShowWidth; + static int column_count = 3; + + PushStyleCompact(); + ImGui::PushID("Advanced"); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30); + EditTableSizingFlags(&flags); + ImGui::Combo("Contents", &contents_type, "Show width\0Short Text\0Long Text\0Button\0Fill Button\0InputText\0"); + if (contents_type == CT_FillButton) + { + ImGui::SameLine(); + HelpMarker("Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop where contents width can feed into auto-column width can feed into contents width."); + } + ImGui::DragInt("Columns", &column_count, 0.1f, 1, 64, "%d", ImGuiSliderFlags_AlwaysClamp); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths); + ImGui::SameLine(); HelpMarker("Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth."); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + ImGui::CheckboxFlags("ImGuiTableFlags_NoClip", &flags, ImGuiTableFlags_NoClip); + ImGui::PopItemWidth(); + ImGui::PopID(); + PopStyleCompact(); + + if (ImGui::BeginTable("table2", column_count, flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 7))) + { + for (int cell = 0; cell < 10 * column_count; cell++) + { + ImGui::TableNextColumn(); + int column = ImGui::TableGetColumnIndex(); + int row = ImGui::TableGetRowIndex(); + + ImGui::PushID(cell); + char label[32]; + static char text_buf[32] = ""; + sprintf(label, "Hello %d,%d", column, row); + switch (contents_type) + { + case CT_ShortText: ImGui::TextUnformatted(label); break; + case CT_LongText: ImGui::Text("Some %s text %d,%d\nOver two lines..", column == 0 ? "long" : "longeeer", column, row); break; + case CT_ShowWidth: ImGui::Text("W: %.1f", ImGui::GetContentRegionAvail().x); break; + case CT_Button: ImGui::Button(label); break; + case CT_FillButton: ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f)); break; + case CT_InputText: ImGui::SetNextItemWidth(-FLT_MIN); ImGui::InputText("##", text_buf, IM_ARRAYSIZE(text_buf)); break; + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Vertical scrolling, with clipping"); + if (ImGui::TreeNode("Vertical scrolling, with clipping")) + { + HelpMarker("Here we activate ScrollY, which will create a child window container to allow hosting scrollable contents.\n\nWe also demonstrate using ImGuiListClipper to virtualize the submission of many items."); + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + PopStyleCompact(); + + // When using ScrollX or ScrollY we need to specify a size for our table container! + // Otherwise by default the table will fit all available space, like a BeginChild() call. + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8); + if (ImGui::BeginTable("table_scrolly", 3, flags, outer_size)) + { + ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible + ImGui::TableSetupColumn("One", ImGuiTableColumnFlags_None); + ImGui::TableSetupColumn("Two", ImGuiTableColumnFlags_None); + ImGui::TableSetupColumn("Three", ImGuiTableColumnFlags_None); + ImGui::TableHeadersRow(); + + // Demonstrate using clipper for large vertical lists + ImGuiListClipper clipper; + clipper.Begin(1000); + while (clipper.Step()) + { + for (int row = clipper.DisplayStart; row < clipper.DisplayEnd; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Hello %d,%d", column, row); + } + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Horizontal scrolling"); + if (ImGui::TreeNode("Horizontal scrolling")) + { + HelpMarker( + "When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_SizingFixedFit, " + "as automatically stretching columns doesn't make much sense with horizontal scrolling.\n\n" + "Also note that as of the current version, you will almost always want to enable ScrollY along with ScrollX," + "because the container window won't automatically extend vertically to fix contents (this may be improved in future versions)."); + static ImGuiTableFlags flags = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable; + static int freeze_cols = 1; + static int freeze_rows = 1; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_cols", &freeze_cols, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_rows", &freeze_rows, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + PopStyleCompact(); + + // When using ScrollX or ScrollY we need to specify a size for our table container! + // Otherwise by default the table will fit all available space, like a BeginChild() call. + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8); + if (ImGui::BeginTable("table_scrollx", 7, flags, outer_size)) + { + ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows); + ImGui::TableSetupColumn("Line #", ImGuiTableColumnFlags_NoHide); // Make the first column not hideable to match our use of TableSetupScrollFreeze() + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableSetupColumn("Four"); + ImGui::TableSetupColumn("Five"); + ImGui::TableSetupColumn("Six"); + ImGui::TableHeadersRow(); + for (int row = 0; row < 20; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 7; column++) + { + // Both TableNextColumn() and TableSetColumnIndex() return true when a column is visible or performing width measurement. + // Because here we know that: + // - A) all our columns are contributing the same to row height + // - B) column 0 is always visible, + // We only always submit this one column and can skip others. + // More advanced per-column clipping behaviors may benefit from polling the status flags via TableGetColumnFlags(). + if (!ImGui::TableSetColumnIndex(column) && column > 0) + continue; + if (column == 0) + ImGui::Text("Line %d", row); + else + ImGui::Text("Hello world %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + ImGui::Spacing(); + ImGui::TextUnformatted("Stretch + ScrollX"); + ImGui::SameLine(); + HelpMarker( + "Showcase using Stretch columns + ScrollX together: " + "this is rather unusual and only makes sense when specifying an 'inner_width' for the table!\n" + "Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns + ScrollX together doesn't make sense."); + static ImGuiTableFlags flags2 = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody; + static float inner_width = 1000.0f; + PushStyleCompact(); + ImGui::PushID("flags3"); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags2, ImGuiTableFlags_ScrollX); + ImGui::DragFloat("inner_width", &inner_width, 1.0f, 0.0f, FLT_MAX, "%.1f"); + ImGui::PopItemWidth(); + ImGui::PopID(); + PopStyleCompact(); + if (ImGui::BeginTable("table2", 7, flags2, outer_size, inner_width)) + { + for (int cell = 0; cell < 20 * 7; cell++) + { + ImGui::TableNextColumn(); + ImGui::Text("Hello world %d,%d", ImGui::TableGetColumnIndex(), ImGui::TableGetRowIndex()); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Columns flags"); + if (ImGui::TreeNode("Columns flags")) + { + // Create a first table just to show all the options/flags we want to make visible in our example! + const int column_count = 3; + const char* column_names[column_count] = { "One", "Two", "Three" }; + static ImGuiTableColumnFlags column_flags[column_count] = { ImGuiTableColumnFlags_DefaultSort, ImGuiTableColumnFlags_None, ImGuiTableColumnFlags_DefaultHide }; + static ImGuiTableColumnFlags column_flags_out[column_count] = { 0, 0, 0 }; // Output from TableGetColumnFlags() + + if (ImGui::BeginTable("table_columns_flags_checkboxes", column_count, ImGuiTableFlags_None)) + { + PushStyleCompact(); + for (int column = 0; column < column_count; column++) + { + ImGui::TableNextColumn(); + ImGui::PushID(column); + ImGui::AlignTextToFramePadding(); // FIXME-TABLE: Workaround for wrong text baseline propagation across columns + ImGui::Text("'%s'", column_names[column]); + ImGui::Spacing(); + ImGui::Text("Input flags:"); + EditTableColumnsFlags(&column_flags[column]); + ImGui::Spacing(); + ImGui::Text("Output flags:"); + ImGui::BeginDisabled(); + ShowTableColumnsStatusFlags(column_flags_out[column]); + ImGui::EndDisabled(); + ImGui::PopID(); + } + PopStyleCompact(); + ImGui::EndTable(); + } + + // Create the real table we care about for the example! + // We use a scrolling table to be able to showcase the difference between the _IsEnabled and _IsVisible flags above, otherwise in + // a non-scrolling table columns are always visible (unless using ImGuiTableFlags_NoKeepColumnsVisible + resizing the parent window down) + const ImGuiTableFlags flags + = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY + | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV + | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable; + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 9); + if (ImGui::BeginTable("table_columns_flags", column_count, flags, outer_size)) + { + for (int column = 0; column < column_count; column++) + ImGui::TableSetupColumn(column_names[column], column_flags[column]); + ImGui::TableHeadersRow(); + for (int column = 0; column < column_count; column++) + column_flags_out[column] = ImGui::TableGetColumnFlags(column); + float indent_step = (float)((int)TEXT_BASE_WIDTH / 2); + for (int row = 0; row < 8; row++) + { + ImGui::Indent(indent_step); // Add some indentation to demonstrate usage of per-column IndentEnable/IndentDisable flags. + ImGui::TableNextRow(); + for (int column = 0; column < column_count; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%s %s", (column == 0) ? "Indented" : "Hello", ImGui::TableGetColumnName(column)); + } + } + ImGui::Unindent(indent_step * 8.0f); + + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Columns widths"); + if (ImGui::TreeNode("Columns widths")) + { + HelpMarker("Using TableSetupColumn() to setup default width."); + + static ImGuiTableFlags flags1 = ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBodyUntilResize; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags1, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags1, ImGuiTableFlags_NoBordersInBodyUntilResize); + PopStyleCompact(); + if (ImGui::BeginTable("table1", 3, flags1)) + { + // We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed. + ImGui::TableSetupColumn("one", ImGuiTableColumnFlags_WidthFixed, 100.0f); // Default to 100.0f + ImGui::TableSetupColumn("two", ImGuiTableColumnFlags_WidthFixed, 200.0f); // Default to 200.0f + ImGui::TableSetupColumn("three", ImGuiTableColumnFlags_WidthFixed); // Default to auto + ImGui::TableHeadersRow(); + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableSetColumnIndex(column); + if (row == 0) + ImGui::Text("(w: %5.1f)", ImGui::GetContentRegionAvail().x); + else + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + HelpMarker("Using TableSetupColumn() to setup explicit width.\n\nUnless _NoKeepColumnsVisible is set, fixed columns with set width may still be shrunk down if there's not enough space in the host."); + + static ImGuiTableFlags flags2 = ImGuiTableFlags_None; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags2, ImGuiTableFlags_NoKeepColumnsVisible); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags2, ImGuiTableFlags_BordersInnerV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags2, ImGuiTableFlags_BordersOuterV); + PopStyleCompact(); + if (ImGui::BeginTable("table2", 4, flags2)) + { + // We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed. + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f); + ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f); + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 4; column++) + { + ImGui::TableSetColumnIndex(column); + if (row == 0) + ImGui::Text("(w: %5.1f)", ImGui::GetContentRegionAvail().x); + else + ImGui::Text("Hello %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Nested tables"); + if (ImGui::TreeNode("Nested tables")) + { + HelpMarker("This demonstrates embedding a table into another table cell."); + + if (ImGui::BeginTable("table_nested1", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("A0"); + ImGui::TableSetupColumn("A1"); + ImGui::TableHeadersRow(); + + ImGui::TableNextColumn(); + ImGui::Text("A0 Row 0"); + { + float rows_height = TEXT_BASE_HEIGHT * 2; + if (ImGui::BeginTable("table_nested2", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("B0"); + ImGui::TableSetupColumn("B1"); + ImGui::TableHeadersRow(); + + ImGui::TableNextRow(ImGuiTableRowFlags_None, rows_height); + ImGui::TableNextColumn(); + ImGui::Text("B0 Row 0"); + ImGui::TableNextColumn(); + ImGui::Text("B1 Row 0"); + ImGui::TableNextRow(ImGuiTableRowFlags_None, rows_height); + ImGui::TableNextColumn(); + ImGui::Text("B0 Row 1"); + ImGui::TableNextColumn(); + ImGui::Text("B1 Row 1"); + + ImGui::EndTable(); + } + } + ImGui::TableNextColumn(); ImGui::Text("A1 Row 0"); + ImGui::TableNextColumn(); ImGui::Text("A0 Row 1"); + ImGui::TableNextColumn(); ImGui::Text("A1 Row 1"); + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Row height"); + if (ImGui::TreeNode("Row height")) + { + HelpMarker("You can pass a 'min_row_height' to TableNextRow().\n\nRows are padded with 'style.CellPadding.y' on top and bottom, so effectively the minimum row height will always be >= 'style.CellPadding.y * 2.0f'.\n\nWe cannot honor a _maximum_ row height as that would require a unique clipping rectangle per row."); + if (ImGui::BeginTable("table_row_height", 1, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersInnerV)) + { + for (int row = 0; row < 10; row++) + { + float min_row_height = (float)(int)(TEXT_BASE_HEIGHT * 0.30f * row); + ImGui::TableNextRow(ImGuiTableRowFlags_None, min_row_height); + ImGui::TableNextColumn(); + ImGui::Text("min_row_height = %.2f", min_row_height); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Outer size"); + if (ImGui::TreeNode("Outer size")) + { + // Showcasing use of ImGuiTableFlags_NoHostExtendX and ImGuiTableFlags_NoHostExtendY + // Important to that note how the two flags have slightly different behaviors! + ImGui::Text("Using NoHostExtendX and NoHostExtendY:"); + PushStyleCompact(); + static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX; + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX); + ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY); + ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible."); + PopStyleCompact(); + + ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 5.5f); + if (ImGui::BeginTable("table1", 3, flags, outer_size)) + { + for (int row = 0; row < 10; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableNextColumn(); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::SameLine(); + ImGui::Text("Hello!"); + + ImGui::Spacing(); + + ImGui::Text("Using explicit size:"); + if (ImGui::BeginTable("table2", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f))) + { + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + ImGui::TableNextColumn(); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + ImGui::SameLine(); + if (ImGui::BeginTable("table3", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg, ImVec2(TEXT_BASE_WIDTH * 30, 0.0f))) + { + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(0, TEXT_BASE_HEIGHT * 1.5f); + for (int column = 0; column < 3; column++) + { + ImGui::TableNextColumn(); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Background color"); + if (ImGui::TreeNode("Background color")) + { + static ImGuiTableFlags flags = ImGuiTableFlags_RowBg; + static int row_bg_type = 1; + static int row_bg_target = 1; + static int cell_bg_type = 1; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Borders", &flags, ImGuiTableFlags_Borders); + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags, ImGuiTableFlags_RowBg); + ImGui::SameLine(); HelpMarker("ImGuiTableFlags_RowBg automatically sets RowBg0 to alternative colors pulled from the Style."); + ImGui::Combo("row bg type", (int*)&row_bg_type, "None\0Red\0Gradient\0"); + ImGui::Combo("row bg target", (int*)&row_bg_target, "RowBg0\0RowBg1\0"); ImGui::SameLine(); HelpMarker("Target RowBg0 to override the alternating odd/even colors,\nTarget RowBg1 to blend with them."); + ImGui::Combo("cell bg type", (int*)&cell_bg_type, "None\0Blue\0"); ImGui::SameLine(); HelpMarker("We are colorizing cells to B1->C2 here."); + IM_ASSERT(row_bg_type >= 0 && row_bg_type <= 2); + IM_ASSERT(row_bg_target >= 0 && row_bg_target <= 1); + IM_ASSERT(cell_bg_type >= 0 && cell_bg_type <= 1); + PopStyleCompact(); + + if (ImGui::BeginTable("table1", 5, flags)) + { + for (int row = 0; row < 6; row++) + { + ImGui::TableNextRow(); + + // Demonstrate setting a row background color with 'ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBgX, ...)' + // We use a transparent color so we can see the one behind in case our target is RowBg1 and RowBg0 was already targeted by the ImGuiTableFlags_RowBg flag. + if (row_bg_type != 0) + { + ImU32 row_bg_color = ImGui::GetColorU32(row_bg_type == 1 ? ImVec4(0.7f, 0.3f, 0.3f, 0.65f) : ImVec4(0.2f + row * 0.1f, 0.2f, 0.2f, 0.65f)); // Flat or Gradient? + ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0 + row_bg_target, row_bg_color); + } + + // Fill cells + for (int column = 0; column < 5; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("%c%c", 'A' + row, '0' + column); + + // Change background of Cells B1->C2 + // Demonstrate setting a cell background color with 'ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, ...)' + // (the CellBg color will be blended over the RowBg and ColumnBg colors) + // We can also pass a column number as a third parameter to TableSetBgColor() and do this outside the column loop. + if (row >= 1 && row <= 2 && column >= 1 && column <= 2 && cell_bg_type == 1) + { + ImU32 cell_bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 0.65f)); + ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color); + } + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Tree view"); + if (ImGui::TreeNode("Tree view")) + { + static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; + + if (ImGui::BeginTable("3ways", 3, flags)) + { + // The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide); + ImGui::TableSetupColumn("Size", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); + ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 18.0f); + ImGui::TableHeadersRow(); + + // Simple storage to output a dummy file-system. + struct MyTreeNode + { + const char* Name; + const char* Type; + int Size; + int ChildIdx; + int ChildCount; + static void DisplayNode(const MyTreeNode* node, const MyTreeNode* all_nodes) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + const bool is_folder = (node->ChildCount > 0); + if (is_folder) + { + bool open = ImGui::TreeNodeEx(node->Name, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::TextDisabled("--"); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + if (open) + { + for (int child_n = 0; child_n < node->ChildCount; child_n++) + DisplayNode(&all_nodes[node->ChildIdx + child_n], all_nodes); + ImGui::TreePop(); + } + } + else + { + ImGui::TreeNodeEx(node->Name, ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::TableNextColumn(); + ImGui::Text("%d", node->Size); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(node->Type); + } + } + }; + static const MyTreeNode nodes[] = + { + { "Root", "Folder", -1, 1, 3 }, // 0 + { "Music", "Folder", -1, 4, 2 }, // 1 + { "Textures", "Folder", -1, 6, 3 }, // 2 + { "desktop.ini", "System file", 1024, -1,-1 }, // 3 + { "File1_a.wav", "Audio file", 123000, -1,-1 }, // 4 + { "File1_b.wav", "Audio file", 456000, -1,-1 }, // 5 + { "Image001.png", "Image file", 203128, -1,-1 }, // 6 + { "Copy of Image001.png", "Image file", 203256, -1,-1 }, // 7 + { "Copy of Image001 (Final2).png","Image file", 203512, -1,-1 }, // 8 + }; + + MyTreeNode::DisplayNode(&nodes[0], nodes); + + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Item width"); + if (ImGui::TreeNode("Item width")) + { + HelpMarker( + "Showcase using PushItemWidth() and how it is preserved on a per-column basis.\n\n" + "Note that on auto-resizing non-resizable fixed columns, querying the content width for e.g. right-alignment doesn't make sense."); + if (ImGui::BeginTable("table_item_width", 3, ImGuiTableFlags_Borders)) + { + ImGui::TableSetupColumn("small"); + ImGui::TableSetupColumn("half"); + ImGui::TableSetupColumn("right-align"); + ImGui::TableHeadersRow(); + + for (int row = 0; row < 3; row++) + { + ImGui::TableNextRow(); + if (row == 0) + { + // Setup ItemWidth once (instead of setting up every time, which is also possible but less efficient) + ImGui::TableSetColumnIndex(0); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 3.0f); // Small + ImGui::TableSetColumnIndex(1); + ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.5f); + ImGui::TableSetColumnIndex(2); + ImGui::PushItemWidth(-FLT_MIN); // Right-aligned + } + + // Draw our contents + static float dummy_f = 0.0f; + ImGui::PushID(row); + ImGui::TableSetColumnIndex(0); + ImGui::SliderFloat("float0", &dummy_f, 0.0f, 1.0f); + ImGui::TableSetColumnIndex(1); + ImGui::SliderFloat("float1", &dummy_f, 0.0f, 1.0f); + ImGui::TableSetColumnIndex(2); + ImGui::SliderFloat("##float2", &dummy_f, 0.0f, 1.0f); // No visible label since right-aligned + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + // Demonstrate using TableHeader() calls instead of TableHeadersRow() + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Custom headers"); + if (ImGui::TreeNode("Custom headers")) + { + const int COLUMNS_COUNT = 3; + if (ImGui::BeginTable("table_custom_headers", COLUMNS_COUNT, ImGuiTableFlags_Borders | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("Apricot"); + ImGui::TableSetupColumn("Banana"); + ImGui::TableSetupColumn("Cherry"); + + // Dummy entire-column selection storage + // FIXME: It would be nice to actually demonstrate full-featured selection using those checkbox. + static bool column_selected[3] = {}; + + // Instead of calling TableHeadersRow() we'll submit custom headers ourselves + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + for (int column = 0; column < COLUMNS_COUNT; column++) + { + ImGui::TableSetColumnIndex(column); + const char* column_name = ImGui::TableGetColumnName(column); // Retrieve name passed to TableSetupColumn() + ImGui::PushID(column); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::Checkbox("##checkall", &column_selected[column]); + ImGui::PopStyleVar(); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::TableHeader(column_name); + ImGui::PopID(); + } + + for (int row = 0; row < 5; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < 3; column++) + { + char buf[32]; + sprintf(buf, "Cell %d,%d", column, row); + ImGui::TableSetColumnIndex(column); + ImGui::Selectable(buf, column_selected[column]); + } + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + // Demonstrate creating custom context menus inside columns, while playing it nice with context menus provided by TableHeadersRow()/TableHeader() + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Context menus"); + if (ImGui::TreeNode("Context menus")) + { + HelpMarker("By default, right-clicking over a TableHeadersRow()/TableHeader() line will open the default context-menu.\nUsing ImGuiTableFlags_ContextMenuInBody we also allow right-clicking over columns body."); + static ImGuiTableFlags flags1 = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_ContextMenuInBody; + + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", &flags1, ImGuiTableFlags_ContextMenuInBody); + PopStyleCompact(); + + // Context Menus: first example + // [1.1] Right-click on the TableHeadersRow() line to open the default table context menu. + // [1.2] Right-click in columns also open the default table context menu (if ImGuiTableFlags_ContextMenuInBody is set) + const int COLUMNS_COUNT = 3; + if (ImGui::BeginTable("table_context_menu", COLUMNS_COUNT, flags1)) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + + // [1.1]] Right-click on the TableHeadersRow() line to open the default table context menu. + ImGui::TableHeadersRow(); + + // Submit dummy contents + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < COLUMNS_COUNT; column++) + { + ImGui::TableSetColumnIndex(column); + ImGui::Text("Cell %d,%d", column, row); + } + } + ImGui::EndTable(); + } + + // Context Menus: second example + // [2.1] Right-click on the TableHeadersRow() line to open the default table context menu. + // [2.2] Right-click on the ".." to open a custom popup + // [2.3] Right-click in columns to open another custom popup + HelpMarker("Demonstrate mixing table context menu (over header), item context button (over button) and custom per-colum context menu (over column body)."); + ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders; + if (ImGui::BeginTable("table_context_menu_2", COLUMNS_COUNT, flags2)) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + + // [2.1] Right-click on the TableHeadersRow() line to open the default table context menu. + ImGui::TableHeadersRow(); + for (int row = 0; row < 4; row++) + { + ImGui::TableNextRow(); + for (int column = 0; column < COLUMNS_COUNT; column++) + { + // Submit dummy contents + ImGui::TableSetColumnIndex(column); + ImGui::Text("Cell %d,%d", column, row); + ImGui::SameLine(); + + // [2.2] Right-click on the ".." to open a custom popup + ImGui::PushID(row * COLUMNS_COUNT + column); + ImGui::SmallButton(".."); + if (ImGui::BeginPopupContextItem()) + { + ImGui::Text("This is the popup for Button(\"..\") in Cell %d,%d", column, row); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::PopID(); + } + } + + // [2.3] Right-click anywhere in columns to open another custom popup + // (instead of testing for !IsAnyItemHovered() we could also call OpenPopup() with ImGuiPopupFlags_NoOpenOverExistingPopup + // to manage popup priority as the popups triggers, here "are we hovering a column" are overlapping) + int hovered_column = -1; + for (int column = 0; column < COLUMNS_COUNT + 1; column++) + { + ImGui::PushID(column); + if (ImGui::TableGetColumnFlags(column) & ImGuiTableColumnFlags_IsHovered) + hovered_column = column; + if (hovered_column == column && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(1)) + ImGui::OpenPopup("MyPopup"); + if (ImGui::BeginPopup("MyPopup")) + { + if (column == COLUMNS_COUNT) + ImGui::Text("This is a custom popup for unused space after the last column."); + else + ImGui::Text("This is a custom popup for Column %d", column); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::PopID(); + } + + ImGui::EndTable(); + ImGui::Text("Hovered column: %d", hovered_column); + } + ImGui::TreePop(); + } + + // Demonstrate creating multiple tables with the same ID + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Synced instances"); + if (ImGui::TreeNode("Synced instances")) + { + HelpMarker("Multiple tables with the same identifier will share their settings, width, visibility, order etc."); + + static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings; + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + ImGui::CheckboxFlags("ImGuiTableFlags_SizingFixedFit", &flags, ImGuiTableFlags_SizingFixedFit); + for (int n = 0; n < 3; n++) + { + char buf[32]; + sprintf(buf, "Synced Table %d", n); + bool open = ImGui::CollapsingHeader(buf, ImGuiTreeNodeFlags_DefaultOpen); + if (open && ImGui::BeginTable("Table", 3, flags, ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 5))) + { + ImGui::TableSetupColumn("One"); + ImGui::TableSetupColumn("Two"); + ImGui::TableSetupColumn("Three"); + ImGui::TableHeadersRow(); + const int cell_count = (n == 1) ? 27 : 9; // Make second table have a scrollbar to verify that additional decoration is not affecting column positions. + for (int cell = 0; cell < cell_count; cell++) + { + ImGui::TableNextColumn(); + ImGui::Text("this cell %d", cell); + } + ImGui::EndTable(); + } + } + ImGui::TreePop(); + } + + // Demonstrate using Sorting facilities + // This is a simplified version of the "Advanced" example, where we mostly focus on the code necessary to handle sorting. + // Note that the "Advanced" example also showcase manually triggering a sort (e.g. if item quantities have been modified) + static const char* template_items_names[] = + { + "Banana", "Apple", "Cherry", "Watermelon", "Grapefruit", "Strawberry", "Mango", + "Kiwi", "Orange", "Pineapple", "Blueberry", "Plum", "Coconut", "Pear", "Apricot" + }; + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Sorting"); + if (ImGui::TreeNode("Sorting")) + { + // Create item list + static ImVector items; + if (items.Size == 0) + { + items.resize(50, MyItem()); + for (int n = 0; n < items.Size; n++) + { + const int template_n = n % IM_ARRAYSIZE(template_items_names); + MyItem& item = items[n]; + item.ID = n; + item.Name = template_items_names[template_n]; + item.Quantity = (n * n - n) % 20; // Assign default quantities + } + } + + // Options + static ImGuiTableFlags flags = + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti + | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody + | ImGuiTableFlags_ScrollY; + PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_SortMulti", &flags, ImGuiTableFlags_SortMulti); + ImGui::SameLine(); HelpMarker("When sorting is enabled: hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1)."); + ImGui::CheckboxFlags("ImGuiTableFlags_SortTristate", &flags, ImGuiTableFlags_SortTristate); + ImGui::SameLine(); HelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0)."); + PopStyleCompact(); + + if (ImGui::BeginTable("table_sorting", 4, flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 15), 0.0f)) + { + // Declare columns + // We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications. + // This is so our sort function can identify a column given our own identifier. We could also identify them based on their index! + // Demonstrate using a mixture of flags among available sort-related flags: + // - ImGuiTableColumnFlags_DefaultSort + // - ImGuiTableColumnFlags_NoSort / ImGuiTableColumnFlags_NoSortAscending / ImGuiTableColumnFlags_NoSortDescending + // - ImGuiTableColumnFlags_PreferSortAscending / ImGuiTableColumnFlags_PreferSortDescending + ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_ID); + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name); + ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action); + ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Quantity); + ImGui::TableSetupScrollFreeze(0, 1); // Make row always visible + ImGui::TableHeadersRow(); + + // Sort our data if sort specs have been changed! + if (ImGuiTableSortSpecs* sorts_specs = ImGui::TableGetSortSpecs()) + if (sorts_specs->SpecsDirty) + { + MyItem::s_current_sort_specs = sorts_specs; // Store in variable accessible by the sort function. + if (items.Size > 1) + qsort(&items[0], (size_t)items.Size, sizeof(items[0]), MyItem::CompareWithSortSpecs); + MyItem::s_current_sort_specs = NULL; + sorts_specs->SpecsDirty = false; + } + + // Demonstrate using clipper for large vertical lists + ImGuiListClipper clipper; + clipper.Begin(items.Size); + while (clipper.Step()) + for (int row_n = clipper.DisplayStart; row_n < clipper.DisplayEnd; row_n++) + { + // Display a data item + MyItem* item = &items[row_n]; + ImGui::PushID(item->ID); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("%04d", item->ID); + ImGui::TableNextColumn(); + ImGui::TextUnformatted(item->Name); + ImGui::TableNextColumn(); + ImGui::SmallButton("None"); + ImGui::TableNextColumn(); + ImGui::Text("%d", item->Quantity); + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + + // In this example we'll expose most table flags and settings. + // For specific flags and settings refer to the corresponding section for more detailed explanation. + // This section is mostly useful to experiment with combining certain flags or settings with each others. + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); // [DEBUG] + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + IMGUI_DEMO_MARKER("Tables/Advanced"); + if (ImGui::TreeNode("Advanced")) + { + static ImGuiTableFlags flags = + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable + | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti + | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBody + | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY + | ImGuiTableFlags_SizingFixedFit; + + enum ContentsType { CT_Text, CT_Button, CT_SmallButton, CT_FillButton, CT_Selectable, CT_SelectableSpanRow }; + static int contents_type = CT_SelectableSpanRow; + const char* contents_type_names[] = { "Text", "Button", "SmallButton", "FillButton", "Selectable", "Selectable (span row)" }; + static int freeze_cols = 1; + static int freeze_rows = 1; + static int items_count = IM_ARRAYSIZE(template_items_names) * 2; + static ImVec2 outer_size_value = ImVec2(0.0f, TEXT_BASE_HEIGHT * 12); + static float row_min_height = 0.0f; // Auto + static float inner_width_with_scroll = 0.0f; // Auto-extend + static bool outer_size_enabled = true; + static bool show_headers = true; + static bool show_wrapped_text = false; + //static ImGuiTextFilter filter; + //ImGui::SetNextItemOpen(true, ImGuiCond_Once); // FIXME-TABLE: Enabling this results in initial clipped first pass on table which tend to affect column sizing + if (ImGui::TreeNode("Options")) + { + // Make the UI compact because there are so many fields + PushStyleCompact(); + ImGui::PushItemWidth(TEXT_BASE_WIDTH * 28.0f); + + if (ImGui::TreeNodeEx("Features:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); + ImGui::CheckboxFlags("ImGuiTableFlags_Reorderable", &flags, ImGuiTableFlags_Reorderable); + ImGui::CheckboxFlags("ImGuiTableFlags_Hideable", &flags, ImGuiTableFlags_Hideable); + ImGui::CheckboxFlags("ImGuiTableFlags_Sortable", &flags, ImGuiTableFlags_Sortable); + ImGui::CheckboxFlags("ImGuiTableFlags_NoSavedSettings", &flags, ImGuiTableFlags_NoSavedSettings); + ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", &flags, ImGuiTableFlags_ContextMenuInBody); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Decorations:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_RowBg", &flags, ImGuiTableFlags_RowBg); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersH", &flags, ImGuiTableFlags_BordersH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterH", &flags, ImGuiTableFlags_BordersOuterH); + ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerH", &flags, ImGuiTableFlags_BordersInnerH); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers"); + ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags, ImGuiTableFlags_NoBordersInBodyUntilResize); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appear in Headers)"); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Sizing:", ImGuiTreeNodeFlags_DefaultOpen)) + { + EditTableSizingFlags(&flags); + ImGui::SameLine(); HelpMarker("In the Advanced demo we override the policy of each column so those table-wide settings have less effect that typical."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX); + ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY); + ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible); + ImGui::SameLine(); HelpMarker("Only available if ScrollX is disabled."); + ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths); + ImGui::SameLine(); HelpMarker("Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth."); + ImGui::CheckboxFlags("ImGuiTableFlags_NoClip", &flags, ImGuiTableFlags_NoClip); + ImGui::SameLine(); HelpMarker("Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with ScrollFreeze options."); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Padding:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", &flags, ImGuiTableFlags_PadOuterX); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadOuterX", &flags, ImGuiTableFlags_NoPadOuterX); + ImGui::CheckboxFlags("ImGuiTableFlags_NoPadInnerX", &flags, ImGuiTableFlags_NoPadInnerX); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Scrolling:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_cols", &freeze_cols, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); + ImGui::DragInt("freeze_rows", &freeze_rows, 0.2f, 0, 9, NULL, ImGuiSliderFlags_NoInput); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Sorting:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::CheckboxFlags("ImGuiTableFlags_SortMulti", &flags, ImGuiTableFlags_SortMulti); + ImGui::SameLine(); HelpMarker("When sorting is enabled: hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1)."); + ImGui::CheckboxFlags("ImGuiTableFlags_SortTristate", &flags, ImGuiTableFlags_SortTristate); + ImGui::SameLine(); HelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0)."); + ImGui::TreePop(); + } + + if (ImGui::TreeNodeEx("Other:", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::Checkbox("show_headers", &show_headers); + ImGui::Checkbox("show_wrapped_text", &show_wrapped_text); + + ImGui::DragFloat2("##OuterSize", &outer_size_value.x); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Checkbox("outer_size", &outer_size_enabled); + ImGui::SameLine(); + HelpMarker("If scrolling is disabled (ScrollX and ScrollY not set):\n" + "- The table is output directly in the parent window.\n" + "- OuterSize.x < 0.0f will right-align the table.\n" + "- OuterSize.x = 0.0f will narrow fit the table unless there are any Stretch columns.\n" + "- OuterSize.y then becomes the minimum size for the table, which will extend vertically if there are more rows (unless NoHostExtendY is set)."); + + // From a user point of view we will tend to use 'inner_width' differently depending on whether our table is embedding scrolling. + // To facilitate toying with this demo we will actually pass 0.0f to the BeginTable() when ScrollX is disabled. + ImGui::DragFloat("inner_width (when ScrollX active)", &inner_width_with_scroll, 1.0f, 0.0f, FLT_MAX); + + ImGui::DragFloat("row_min_height", &row_min_height, 1.0f, 0.0f, FLT_MAX); + ImGui::SameLine(); HelpMarker("Specify height of the Selectable item."); + + ImGui::DragInt("items_count", &items_count, 0.1f, 0, 9999); + ImGui::Combo("items_type (first column)", &contents_type, contents_type_names, IM_ARRAYSIZE(contents_type_names)); + //filter.Draw("filter"); + ImGui::TreePop(); + } + + ImGui::PopItemWidth(); + PopStyleCompact(); + ImGui::Spacing(); + ImGui::TreePop(); + } + + // Update item list if we changed the number of items + static ImVector items; + static ImVector selection; + static bool items_need_sort = false; + if (items.Size != items_count) + { + items.resize(items_count, MyItem()); + for (int n = 0; n < items_count; n++) + { + const int template_n = n % IM_ARRAYSIZE(template_items_names); + MyItem& item = items[n]; + item.ID = n; + item.Name = template_items_names[template_n]; + item.Quantity = (template_n == 3) ? 10 : (template_n == 4) ? 20 : 0; // Assign default quantities + } + } + + const ImDrawList* parent_draw_list = ImGui::GetWindowDrawList(); + const int parent_draw_list_draw_cmd_count = parent_draw_list->CmdBuffer.Size; + ImVec2 table_scroll_cur, table_scroll_max; // For debug display + const ImDrawList* table_draw_list = NULL; // " + + // Submit table + const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : 0.0f; + if (ImGui::BeginTable("table_advanced", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use)) + { + // Declare columns + // We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications. + // This is so our sort function can identify a column given our own identifier. We could also identify them based on their index! + ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHide, 0.0f, MyItemColumnID_ID); + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name); + ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action); + ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, 0.0f, MyItemColumnID_Quantity); + ImGui::TableSetupColumn("Description", (flags & ImGuiTableFlags_NoHostExtendX) ? 0 : ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Description); + ImGui::TableSetupColumn("Hidden", ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort); + ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows); + + // Sort our data if sort specs have been changed! + ImGuiTableSortSpecs* sorts_specs = ImGui::TableGetSortSpecs(); + if (sorts_specs && sorts_specs->SpecsDirty) + items_need_sort = true; + if (sorts_specs && items_need_sort && items.Size > 1) + { + MyItem::s_current_sort_specs = sorts_specs; // Store in variable accessible by the sort function. + qsort(&items[0], (size_t)items.Size, sizeof(items[0]), MyItem::CompareWithSortSpecs); + MyItem::s_current_sort_specs = NULL; + sorts_specs->SpecsDirty = false; + } + items_need_sort = false; + + // Take note of whether we are currently sorting based on the Quantity field, + // we will use this to trigger sorting when we know the data of this column has been modified. + const bool sorts_specs_using_quantity = (ImGui::TableGetColumnFlags(3) & ImGuiTableColumnFlags_IsSorted) != 0; + + // Show headers + if (show_headers) + ImGui::TableHeadersRow(); + + // Show data + // FIXME-TABLE FIXME-NAV: How we can get decent up/down even though we have the buttons here? + ImGui::PushButtonRepeat(true); +#if 1 + // Demonstrate using clipper for large vertical lists + ImGuiListClipper clipper; + clipper.Begin(items.Size); + while (clipper.Step()) + { + for (int row_n = clipper.DisplayStart; row_n < clipper.DisplayEnd; row_n++) +#else + // Without clipper + { + for (int row_n = 0; row_n < items.Size; row_n++) +#endif + { + MyItem* item = &items[row_n]; + //if (!filter.PassFilter(item->Name)) + // continue; + + const bool item_is_selected = selection.contains(item->ID); + ImGui::PushID(item->ID); + ImGui::TableNextRow(ImGuiTableRowFlags_None, row_min_height); + + // For the demo purpose we can select among different type of items submitted in the first column + ImGui::TableSetColumnIndex(0); + char label[32]; + sprintf(label, "%04d", item->ID); + if (contents_type == CT_Text) + ImGui::TextUnformatted(label); + else if (contents_type == CT_Button) + ImGui::Button(label); + else if (contents_type == CT_SmallButton) + ImGui::SmallButton(label); + else if (contents_type == CT_FillButton) + ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f)); + else if (contents_type == CT_Selectable || contents_type == CT_SelectableSpanRow) + { + ImGuiSelectableFlags selectable_flags = (contents_type == CT_SelectableSpanRow) ? ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap : ImGuiSelectableFlags_None; + if (ImGui::Selectable(label, item_is_selected, selectable_flags, ImVec2(0, row_min_height))) + { + if (ImGui::GetIO().KeyCtrl) + { + if (item_is_selected) + selection.find_erase_unsorted(item->ID); + else + selection.push_back(item->ID); + } + else + { + selection.clear(); + selection.push_back(item->ID); + } + } + } + + if (ImGui::TableSetColumnIndex(1)) + ImGui::TextUnformatted(item->Name); + + // Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity, + // and we are currently sorting on the column showing the Quantity. + // To avoid triggering a sort while holding the button, we only trigger it when the button has been released. + // You will probably need a more advanced system in your code if you want to automatically sort when a specific entry changes. + if (ImGui::TableSetColumnIndex(2)) + { + if (ImGui::SmallButton("Chop")) { item->Quantity += 1; } + if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } + ImGui::SameLine(); + if (ImGui::SmallButton("Eat")) { item->Quantity -= 1; } + if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; } + } + + if (ImGui::TableSetColumnIndex(3)) + ImGui::Text("%d", item->Quantity); + + ImGui::TableSetColumnIndex(4); + if (show_wrapped_text) + ImGui::TextWrapped("Lorem ipsum dolor sit amet"); + else + ImGui::Text("Lorem ipsum dolor sit amet"); + + if (ImGui::TableSetColumnIndex(5)) + ImGui::Text("1234"); + + ImGui::PopID(); + } + } + ImGui::PopButtonRepeat(); + + // Store some info to display debug details below + table_scroll_cur = ImVec2(ImGui::GetScrollX(), ImGui::GetScrollY()); + table_scroll_max = ImVec2(ImGui::GetScrollMaxX(), ImGui::GetScrollMaxY()); + table_draw_list = ImGui::GetWindowDrawList(); + ImGui::EndTable(); + } + static bool show_debug_details = false; + ImGui::Checkbox("Debug details", &show_debug_details); + if (show_debug_details && table_draw_list) + { + ImGui::SameLine(0.0f, 0.0f); + const int table_draw_list_draw_cmd_count = table_draw_list->CmdBuffer.Size; + if (table_draw_list == parent_draw_list) + ImGui::Text(": DrawCmd: +%d (in same window)", + table_draw_list_draw_cmd_count - parent_draw_list_draw_cmd_count); + else + ImGui::Text(": DrawCmd: +%d (in child window), Scroll: (%.f/%.f) (%.f/%.f)", + table_draw_list_draw_cmd_count - 1, table_scroll_cur.x, table_scroll_max.x, table_scroll_cur.y, table_scroll_max.y); + } + ImGui::TreePop(); + } + + ImGui::PopID(); + + ShowDemoWindowColumns(); + + if (disable_indent) + ImGui::PopStyleVar(); +} + +// Demonstrate old/legacy Columns API! +// [2020: Columns are under-featured and not maintained. Prefer using the more flexible and powerful BeginTable() API!] +static void ShowDemoWindowColumns() +{ + IMGUI_DEMO_MARKER("Columns (legacy API)"); + bool open = ImGui::TreeNode("Legacy Columns API"); + ImGui::SameLine(); + HelpMarker("Columns() is an old API! Prefer using the more flexible and powerful BeginTable() API!"); + if (!open) + return; + + // Basic columns + IMGUI_DEMO_MARKER("Columns (legacy API)/Basic"); + if (ImGui::TreeNode("Basic")) + { + ImGui::Text("Without border:"); + ImGui::Columns(3, "mycolumns3", false); // 3-ways, no border + ImGui::Separator(); + for (int n = 0; n < 14; n++) + { + char label[32]; + sprintf(label, "Item %d", n); + if (ImGui::Selectable(label)) {} + //if (ImGui::Button(label, ImVec2(-FLT_MIN,0.0f))) {} + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + + ImGui::Text("With border:"); + ImGui::Columns(4, "mycolumns"); // 4-ways, with border + ImGui::Separator(); + ImGui::Text("ID"); ImGui::NextColumn(); + ImGui::Text("Name"); ImGui::NextColumn(); + ImGui::Text("Path"); ImGui::NextColumn(); + ImGui::Text("Hovered"); ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = { "One", "Two", "Three" }; + const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; + static int selected = -1; + for (int i = 0; i < 3; i++) + { + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + bool hovered = ImGui::IsItemHovered(); + ImGui::NextColumn(); + ImGui::Text(names[i]); ImGui::NextColumn(); + ImGui::Text(paths[i]); ImGui::NextColumn(); + ImGui::Text("%d", hovered); ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Columns (legacy API)/Borders"); + if (ImGui::TreeNode("Borders")) + { + // NB: Future columns API should allow automatic horizontal borders. + static bool h_borders = true; + static bool v_borders = true; + static int columns_count = 4; + const int lines_count = 3; + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::DragInt("##columns_count", &columns_count, 0.1f, 2, 10, "%d columns"); + if (columns_count < 2) + columns_count = 2; + ImGui::SameLine(); + ImGui::Checkbox("horizontal", &h_borders); + ImGui::SameLine(); + ImGui::Checkbox("vertical", &v_borders); + ImGui::Columns(columns_count, NULL, v_borders); + for (int i = 0; i < columns_count * lines_count; i++) + { + if (h_borders && ImGui::GetColumnIndex() == 0) + ImGui::Separator(); + ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i); + ImGui::Text("Width %.2f", ImGui::GetColumnWidth()); + ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x); + ImGui::Text("Offset %.2f", ImGui::GetColumnOffset()); + ImGui::Text("Long text that is likely to clip"); + ImGui::Button("Button", ImVec2(-FLT_MIN, 0.0f)); + ImGui::NextColumn(); + } + ImGui::Columns(1); + if (h_borders) + ImGui::Separator(); + ImGui::TreePop(); + } + + // Create multiple items in a same cell before switching to next column + IMGUI_DEMO_MARKER("Columns (legacy API)/Mixed items"); + if (ImGui::TreeNode("Mixed items")) + { + ImGui::Columns(3, "mixed"); + ImGui::Separator(); + + ImGui::Text("Hello"); + ImGui::Button("Banana"); + ImGui::NextColumn(); + + ImGui::Text("ImGui"); + ImGui::Button("Apple"); + static float foo = 1.0f; + ImGui::InputFloat("red", &foo, 0.05f, 0, "%.3f"); + ImGui::Text("An extra line here."); + ImGui::NextColumn(); + + ImGui::Text("Sailor"); + ImGui::Button("Corniflower"); + static float bar = 1.0f; + ImGui::InputFloat("blue", &bar, 0.05f, 0, "%.3f"); + ImGui::NextColumn(); + + if (ImGui::CollapsingHeader("Category A")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category B")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category C")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + // Word wrapping + IMGUI_DEMO_MARKER("Columns (legacy API)/Word-wrapping"); + if (ImGui::TreeNode("Word-wrapping")) + { + ImGui::Columns(2, "word-wrapping"); + ImGui::Separator(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Left"); + ImGui::NextColumn(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Right"); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Columns (legacy API)/Horizontal Scrolling"); + if (ImGui::TreeNode("Horizontal Scrolling")) + { + ImGui::SetNextWindowContentSize(ImVec2(1500.0f, 0.0f)); + ImVec2 child_size = ImVec2(0, ImGui::GetFontSize() * 20.0f); + ImGui::BeginChild("##ScrollingRegion", child_size, false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::Columns(10); + + // Also demonstrate using clipper for large vertical lists + int ITEMS_COUNT = 2000; + ImGuiListClipper clipper; + clipper.Begin(ITEMS_COUNT); + while (clipper.Step()) + { + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + for (int j = 0; j < 10; j++) + { + ImGui::Text("Line %d Column %d...", i, j); + ImGui::NextColumn(); + } + } + ImGui::Columns(1); + ImGui::EndChild(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Columns (legacy API)/Tree"); + if (ImGui::TreeNode("Tree")) + { + ImGui::Columns(2, "tree", true); + for (int x = 0; x < 3; x++) + { + bool open1 = ImGui::TreeNode((void*)(intptr_t)x, "Node%d", x); + ImGui::NextColumn(); + ImGui::Text("Node contents"); + ImGui::NextColumn(); + if (open1) + { + for (int y = 0; y < 3; y++) + { + bool open2 = ImGui::TreeNode((void*)(intptr_t)y, "Node%d.%d", x, y); + ImGui::NextColumn(); + ImGui::Text("Node contents"); + if (open2) + { + ImGui::Text("Even more contents"); + if (ImGui::TreeNode("Tree in column")) + { + ImGui::Text("The quick brown fox jumps over the lazy dog"); + ImGui::TreePop(); + } + } + ImGui::NextColumn(); + if (open2) + ImGui::TreePop(); + } + ImGui::TreePop(); + } + } + ImGui::Columns(1); + ImGui::TreePop(); + } + + ImGui::TreePop(); +} + +static void ShowDemoWindowInputs() +{ + IMGUI_DEMO_MARKER("Inputs & Focus"); + if (ImGui::CollapsingHeader("Inputs & Focus")) + { + ImGuiIO& io = ImGui::GetIO(); + + // Display inputs submitted to ImGuiIO + IMGUI_DEMO_MARKER("Inputs & Focus/Inputs"); + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (ImGui::TreeNode("Inputs")) + { + HelpMarker( + "This is a simplified view. See more detailed input state:\n" + "- in 'Tools->Metrics/Debugger->Inputs'.\n" + "- in 'Tools->Debug Log->IO'."); + if (ImGui::IsMousePosValid()) + ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); + else + ImGui::Text("Mouse pos: "); + ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y); + ImGui::Text("Mouse down:"); + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } + ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); + + // We iterate both legacy native range and named ImGuiKey ranges, which is a little odd but this allows displaying the data for old/new backends. + // User code should never have to go through such hoops! You can generally iterate between ImGuiKey_NamedKey_BEGIN and ImGuiKey_NamedKey_END. +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } }; + ImGuiKey start_key = ImGuiKey_NamedKey_BEGIN; +#else + struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array + ImGuiKey start_key = (ImGuiKey)0; +#endif + ImGui::Text("Keys down:"); for (ImGuiKey key = start_key; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !ImGui::IsKeyDown(key)) continue; ImGui::SameLine(); ImGui::Text((key < ImGuiKey_NamedKey_BEGIN) ? "\"%s\"" : "\"%s\" %d", ImGui::GetKeyName(key), key); } + ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); + ImGui::Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine(); ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public. + + ImGui::TreePop(); + } + + // Display ImGuiIO output flags + IMGUI_DEMO_MARKER("Inputs & Focus/Outputs"); + ImGui::SetNextItemOpen(true, ImGuiCond_Once); + if (ImGui::TreeNode("Outputs")) + { + HelpMarker( + "The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui " + "to instruct your application of how to route inputs. Typically, when a value is true, it means " + "Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n" + "The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, " + "and underlying application should ignore mouse inputs (in practice there are many and more subtle " + "rules leading to how those flags are set)."); + ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse); + ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose); + ImGui::Text("io.WantCaptureKeyboard: %d", io.WantCaptureKeyboard); + ImGui::Text("io.WantTextInput: %d", io.WantTextInput); + ImGui::Text("io.WantSetMousePos: %d", io.WantSetMousePos); + ImGui::Text("io.NavActive: %d, io.NavVisible: %d", io.NavActive, io.NavVisible); + + IMGUI_DEMO_MARKER("Inputs & Focus/Outputs/WantCapture override"); + if (ImGui::TreeNode("WantCapture override")) + { + HelpMarker( + "Hovering the colored canvas will override io.WantCaptureXXX fields.\n" + "Notice how normally (when set to none), the value of io.WantCaptureKeyboard would be false when hovering and true when clicking."); + static int capture_override_mouse = -1; + static int capture_override_keyboard = -1; + const char* capture_override_desc[] = { "None", "Set to false", "Set to true" }; + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15); + ImGui::SliderInt("SetNextFrameWantCaptureMouse() on hover", &capture_override_mouse, -1, +1, capture_override_desc[capture_override_mouse + 1], ImGuiSliderFlags_AlwaysClamp); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15); + ImGui::SliderInt("SetNextFrameWantCaptureKeyboard() on hover", &capture_override_keyboard, -1, +1, capture_override_desc[capture_override_keyboard + 1], ImGuiSliderFlags_AlwaysClamp); + + ImGui::ColorButton("##panel", ImVec4(0.7f, 0.1f, 0.7f, 1.0f), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoDragDrop, ImVec2(128.0f, 96.0f)); // Dummy item + if (ImGui::IsItemHovered() && capture_override_mouse != -1) + ImGui::SetNextFrameWantCaptureMouse(capture_override_mouse == 1); + if (ImGui::IsItemHovered() && capture_override_keyboard != -1) + ImGui::SetNextFrameWantCaptureKeyboard(capture_override_keyboard == 1); + + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + // Display mouse cursors + IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors"); + if (ImGui::TreeNode("Mouse Cursors")) + { + const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" }; + IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT); + + ImGuiMouseCursor current = ImGui::GetMouseCursor(); + ImGui::Text("Current mouse cursor = %d: %s", current, mouse_cursors_names[current]); + ImGui::BeginDisabled(true); + ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors); + ImGui::EndDisabled(); + + ImGui::Text("Hover to see mouse cursors:"); + ImGui::SameLine(); HelpMarker( + "Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. " + "If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, " + "otherwise your backend needs to handle it."); + for (int i = 0; i < ImGuiMouseCursor_COUNT; i++) + { + char label[32]; + sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]); + ImGui::Bullet(); ImGui::Selectable(label, false); + if (ImGui::IsItemHovered()) + ImGui::SetMouseCursor(i); + } + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Inputs & Focus/Tabbing"); + if (ImGui::TreeNode("Tabbing")) + { + ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields."); + static char buf[32] = "hello"; + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); + ImGui::PushTabStop(false); + ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); + ImGui::SameLine(); HelpMarker("Item won't be cycled through when using TAB or Shift+Tab."); + ImGui::PopTabStop(); + ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Inputs & Focus/Focus from code"); + if (ImGui::TreeNode("Focus from code")) + { + bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine(); + bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine(); + bool focus_3 = ImGui::Button("Focus on 3"); + int has_focus = 0; + static char buf[128] = "click on a button to set focus"; + + if (focus_1) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 1; + + if (focus_2) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 2; + + ImGui::PushTabStop(false); + if (focus_3) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 3; + ImGui::SameLine(); HelpMarker("Item won't be cycled through when using TAB or Shift+Tab."); + ImGui::PopTabStop(); + + if (has_focus) + ImGui::Text("Item with focus: %d", has_focus); + else + ImGui::Text("Item with focus: "); + + // Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item + static float f3[3] = { 0.0f, 0.0f, 0.0f }; + int focus_ahead = -1; + if (ImGui::Button("Focus on X")) { focus_ahead = 0; } ImGui::SameLine(); + if (ImGui::Button("Focus on Y")) { focus_ahead = 1; } ImGui::SameLine(); + if (ImGui::Button("Focus on Z")) { focus_ahead = 2; } + if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead); + ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f); + + ImGui::TextWrapped("NB: Cursor & selection are preserved when refocusing last used item in code."); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Inputs & Focus/Dragging"); + if (ImGui::TreeNode("Dragging")) + { + ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); + for (int button = 0; button < 3; button++) + { + ImGui::Text("IsMouseDragging(%d):", button); + ImGui::Text(" w/ default threshold: %d,", ImGui::IsMouseDragging(button)); + ImGui::Text(" w/ zero threshold: %d,", ImGui::IsMouseDragging(button, 0.0f)); + ImGui::Text(" w/ large threshold: %d,", ImGui::IsMouseDragging(button, 20.0f)); + } + + ImGui::Button("Drag Me"); + if (ImGui::IsItemActive()) + ImGui::GetForegroundDrawList()->AddLine(io.MouseClickedPos[0], io.MousePos, ImGui::GetColorU32(ImGuiCol_Button), 4.0f); // Draw a line between the button and the mouse cursor + + // Drag operations gets "unlocked" when the mouse has moved past a certain threshold + // (the default threshold is stored in io.MouseDragThreshold). You can request a lower or higher + // threshold using the second parameter of IsMouseDragging() and GetMouseDragDelta(). + ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f); + ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0); + ImVec2 mouse_delta = io.MouseDelta; + ImGui::Text("GetMouseDragDelta(0):"); + ImGui::Text(" w/ default threshold: (%.1f, %.1f)", value_with_lock_threshold.x, value_with_lock_threshold.y); + ImGui::Text(" w/ zero threshold: (%.1f, %.1f)", value_raw.x, value_raw.y); + ImGui::Text("io.MouseDelta: (%.1f, %.1f)", mouse_delta.x, mouse_delta.y); + ImGui::TreePop(); + } + } +} + +//----------------------------------------------------------------------------- +// [SECTION] About Window / ShowAboutWindow() +// Access from Dear ImGui Demo -> Tools -> About +//----------------------------------------------------------------------------- + +void ImGui::ShowAboutWindow(bool* p_open) +{ + if (!ImGui::Begin("About Dear ImGui", p_open, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Tools/About Dear ImGui"); + ImGui::Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM); + ImGui::Separator(); + ImGui::Text("By Omar Cornut and all Dear ImGui contributors."); + ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information."); + ImGui::Text("If your company uses this, please consider sponsoring the project!"); + + static bool show_config_info = false; + ImGui::Checkbox("Config/Build Information", &show_config_info); + if (show_config_info) + { + ImGuiIO& io = ImGui::GetIO(); + ImGuiStyle& style = ImGui::GetStyle(); + + bool copy_to_clipboard = ImGui::Button("Copy to clipboard"); + ImVec2 child_size = ImVec2(0, ImGui::GetTextLineHeightWithSpacing() * 18); + ImGui::BeginChildFrame(ImGui::GetID("cfg_infos"), child_size, ImGuiWindowFlags_NoMove); + if (copy_to_clipboard) + { + ImGui::LogToClipboard(); + ImGui::LogText("```\n"); // Back quotes will make text appears without formatting when pasting on GitHub + } + + ImGui::Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM); + ImGui::Separator(); + ImGui::Text("sizeof(size_t): %d, sizeof(ImDrawIdx): %d, sizeof(ImDrawVert): %d", (int)sizeof(size_t), (int)sizeof(ImDrawIdx), (int)sizeof(ImDrawVert)); + ImGui::Text("define: __cplusplus=%d", (int)__cplusplus); +#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO + ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_KEYIO"); +#endif +#ifdef IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_WIN32_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_WIN32_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_FILE_FUNCTIONS + ImGui::Text("define: IMGUI_DISABLE_FILE_FUNCTIONS"); +#endif +#ifdef IMGUI_DISABLE_DEFAULT_ALLOCATORS + ImGui::Text("define: IMGUI_DISABLE_DEFAULT_ALLOCATORS"); +#endif +#ifdef IMGUI_USE_BGRA_PACKED_COLOR + ImGui::Text("define: IMGUI_USE_BGRA_PACKED_COLOR"); +#endif +#ifdef _WIN32 + ImGui::Text("define: _WIN32"); +#endif +#ifdef _WIN64 + ImGui::Text("define: _WIN64"); +#endif +#ifdef __linux__ + ImGui::Text("define: __linux__"); +#endif +#ifdef __APPLE__ + ImGui::Text("define: __APPLE__"); +#endif +#ifdef _MSC_VER + ImGui::Text("define: _MSC_VER=%d", _MSC_VER); +#endif +#ifdef _MSVC_LANG + ImGui::Text("define: _MSVC_LANG=%d", (int)_MSVC_LANG); +#endif +#ifdef __MINGW32__ + ImGui::Text("define: __MINGW32__"); +#endif +#ifdef __MINGW64__ + ImGui::Text("define: __MINGW64__"); +#endif +#ifdef __GNUC__ + ImGui::Text("define: __GNUC__=%d", (int)__GNUC__); +#endif +#ifdef __clang_version__ + ImGui::Text("define: __clang_version__=%s", __clang_version__); +#endif +#ifdef __EMSCRIPTEN__ + ImGui::Text("define: __EMSCRIPTEN__"); +#endif + ImGui::Separator(); + ImGui::Text("io.BackendPlatformName: %s", io.BackendPlatformName ? io.BackendPlatformName : "NULL"); + ImGui::Text("io.BackendRendererName: %s", io.BackendRendererName ? io.BackendRendererName : "NULL"); + ImGui::Text("io.ConfigFlags: 0x%08X", io.ConfigFlags); + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) ImGui::Text(" NavEnableKeyboard"); + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) ImGui::Text(" NavEnableGamepad"); + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) ImGui::Text(" NavEnableSetMousePos"); + if (io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard) ImGui::Text(" NavNoCaptureKeyboard"); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse"); + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange"); + if (io.MouseDrawCursor) ImGui::Text("io.MouseDrawCursor"); + if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors"); + if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink"); + if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges"); + if (io.ConfigWindowsMoveFromTitleBarOnly) ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly"); + if (io.ConfigMemoryCompactTimer >= 0.0f) ImGui::Text("io.ConfigMemoryCompactTimer = %.1f", io.ConfigMemoryCompactTimer); + ImGui::Text("io.BackendFlags: 0x%08X", io.BackendFlags); + if (io.BackendFlags & ImGuiBackendFlags_HasGamepad) ImGui::Text(" HasGamepad"); + if (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) ImGui::Text(" HasMouseCursors"); + if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) ImGui::Text(" HasSetMousePos"); + if (io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) ImGui::Text(" RendererHasVtxOffset"); + ImGui::Separator(); + ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", io.Fonts->Fonts.Size, io.Fonts->Flags, io.Fonts->TexWidth, io.Fonts->TexHeight); + ImGui::Text("io.DisplaySize: %.2f,%.2f", io.DisplaySize.x, io.DisplaySize.y); + ImGui::Text("io.DisplayFramebufferScale: %.2f,%.2f", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y); + ImGui::Separator(); + ImGui::Text("style.WindowPadding: %.2f,%.2f", style.WindowPadding.x, style.WindowPadding.y); + ImGui::Text("style.WindowBorderSize: %.2f", style.WindowBorderSize); + ImGui::Text("style.FramePadding: %.2f,%.2f", style.FramePadding.x, style.FramePadding.y); + ImGui::Text("style.FrameRounding: %.2f", style.FrameRounding); + ImGui::Text("style.FrameBorderSize: %.2f", style.FrameBorderSize); + ImGui::Text("style.ItemSpacing: %.2f,%.2f", style.ItemSpacing.x, style.ItemSpacing.y); + ImGui::Text("style.ItemInnerSpacing: %.2f,%.2f", style.ItemInnerSpacing.x, style.ItemInnerSpacing.y); + + if (copy_to_clipboard) + { + ImGui::LogText("\n```\n"); + ImGui::LogFinish(); + } + ImGui::EndChildFrame(); + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Style Editor / ShowStyleEditor() +//----------------------------------------------------------------------------- +// - ShowFontSelector() +// - ShowStyleSelector() +// - ShowStyleEditor() +//----------------------------------------------------------------------------- + +// Forward declare ShowFontAtlas() which isn't worth putting in public API yet +namespace ImGui { IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); } + +// Demo helper function to select among loaded fonts. +// Here we use the regular BeginCombo()/EndCombo() api which is the more flexible one. +void ImGui::ShowFontSelector(const char* label) +{ + ImGuiIO& io = ImGui::GetIO(); + ImFont* font_current = ImGui::GetFont(); + if (ImGui::BeginCombo(label, font_current->GetDebugName())) + { + for (int n = 0; n < io.Fonts->Fonts.Size; n++) + { + ImFont* font = io.Fonts->Fonts[n]; + ImGui::PushID((void*)font); + if (ImGui::Selectable(font->GetDebugName(), font == font_current)) + io.FontDefault = font; + ImGui::PopID(); + } + ImGui::EndCombo(); + } + ImGui::SameLine(); + HelpMarker( + "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n" + "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" + "- Read FAQ and docs/FONTS.md for more details.\n" + "- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame()."); +} + +// Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options. +// Here we use the simplified Combo() api that packs items into a single literal string. +// Useful for quick combo boxes where the choices are known locally. +bool ImGui::ShowStyleSelector(const char* label) +{ + static int style_idx = -1; + if (ImGui::Combo(label, &style_idx, "Dark\0Light\0Classic\0")) + { + switch (style_idx) + { + case 0: ImGui::StyleColorsDark(); break; + case 1: ImGui::StyleColorsLight(); break; + case 2: ImGui::StyleColorsClassic(); break; + } + return true; + } + return false; +} + +void ImGui::ShowStyleEditor(ImGuiStyle* ref) +{ + IMGUI_DEMO_MARKER("Tools/Style Editor"); + // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to + // (without a reference style pointer, we will use one compared locally as a reference) + ImGuiStyle& style = ImGui::GetStyle(); + static ImGuiStyle ref_saved_style; + + // Default to using internal storage as reference + static bool init = true; + if (init && ref == NULL) + ref_saved_style = style; + init = false; + if (ref == NULL) + ref = &ref_saved_style; + + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f); + + if (ImGui::ShowStyleSelector("Colors##Selector")) + ref_saved_style = style; + ImGui::ShowFontSelector("Fonts##Selector"); + + // Simplified Settings (expose floating-pointer border sizes as boolean representing 0.0f or 1.0f) + if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) + style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding + { bool border = (style.WindowBorderSize > 0.0f); if (ImGui::Checkbox("WindowBorder", &border)) { style.WindowBorderSize = border ? 1.0f : 0.0f; } } + ImGui::SameLine(); + { bool border = (style.FrameBorderSize > 0.0f); if (ImGui::Checkbox("FrameBorder", &border)) { style.FrameBorderSize = border ? 1.0f : 0.0f; } } + ImGui::SameLine(); + { bool border = (style.PopupBorderSize > 0.0f); if (ImGui::Checkbox("PopupBorder", &border)) { style.PopupBorderSize = border ? 1.0f : 0.0f; } } + + // Save/Revert button + if (ImGui::Button("Save Ref")) + *ref = ref_saved_style = style; + ImGui::SameLine(); + if (ImGui::Button("Revert Ref")) + style = *ref; + ImGui::SameLine(); + HelpMarker( + "Save/Revert in local non-persistent storage. Default Colors definition are not affected. " + "Use \"Export\" below to save them somewhere."); + + ImGui::Separator(); + + if (ImGui::BeginTabBar("##tabs", ImGuiTabBarFlags_None)) + { + if (ImGui::BeginTabItem("Sizes")) + { + ImGui::SeparatorText("Main"); + ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); + ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); + + ImGui::SeparatorText("Borders"); + ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f"); + + ImGui::SeparatorText("Rounding"); + ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f"); + + ImGui::SeparatorText("Widgets"); + ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); + int window_menu_button_position = style.WindowMenuButtonPosition + 1; + if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0")) + style.WindowMenuButtonPosition = window_menu_button_position - 1; + ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0"); + ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content."); + ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content."); + ImGui::SliderFloat("SeparatorTextBorderSize", &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f"); + ImGui::SliderFloat2("SeparatorTextAlign", (float*)&style.SeparatorTextAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%.0f"); + ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f"); + + ImGui::SeparatorText("Tooltips"); + for (int n = 0; n < 2; n++) + if (ImGui::TreeNodeEx(n == 0 ? "HoverFlagsForTooltipMouse" : "HoverFlagsForTooltipNav")) + { + ImGuiHoveredFlags* p = (n == 0) ? &style.HoverFlagsForTooltipMouse : &style.HoverFlagsForTooltipNav; + ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNone", p, ImGuiHoveredFlags_DelayNone); + ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayShort", p, ImGuiHoveredFlags_DelayShort); + ImGui::CheckboxFlags("ImGuiHoveredFlags_DelayNormal", p, ImGuiHoveredFlags_DelayNormal); + ImGui::CheckboxFlags("ImGuiHoveredFlags_Stationary", p, ImGuiHoveredFlags_Stationary); + ImGui::CheckboxFlags("ImGuiHoveredFlags_NoSharedDelay", p, ImGuiHoveredFlags_NoSharedDelay); + ImGui::TreePop(); + } + + ImGui::SeparatorText("Misc"); + ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Colors")) + { + static int output_dest = 0; + static bool output_only_modified = true; + if (ImGui::Button("Export")) + { + if (output_dest == 0) + ImGui::LogToClipboard(); + else + ImGui::LogToTTY(); + ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const ImVec4& col = style.Colors[i]; + const char* name = ImGui::GetStyleColorName(i); + if (!output_only_modified || memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0) + ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, + name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w); + } + ImGui::LogFinish(); + } + ImGui::SameLine(); ImGui::SetNextItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); + ImGui::SameLine(); ImGui::Checkbox("Only Modified Colors", &output_only_modified); + + static ImGuiTextFilter filter; + filter.Draw("Filter colors", ImGui::GetFontSize() * 16); + + static ImGuiColorEditFlags alpha_flags = 0; + if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine(); + if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine(); + if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine(); + HelpMarker( + "In the color list:\n" + "Left-click on color square to open color picker,\n" + "Right-click to open edit options menu."); + + ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened); + ImGui::PushItemWidth(-160); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColorName(i); + if (!filter.PassFilter(name)) + continue; + ImGui::PushID(i); + ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags); + if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) + { + // Tips: in a real user application, you may want to merge and use an icon font into the main font, + // so instead of "Save"/"Revert" you'd use icons! + // Read the FAQ and docs/FONTS.md about using icon fonts. It's really easy and super convenient! + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Save")) { ref->Colors[i] = style.Colors[i]; } + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Revert")) { style.Colors[i] = ref->Colors[i]; } + } + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); + ImGui::TextUnformatted(name); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::EndChild(); + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Fonts")) + { + ImGuiIO& io = ImGui::GetIO(); + ImFontAtlas* atlas = io.Fonts; + HelpMarker("Read FAQ and docs/FONTS.md for details on font loading."); + ImGui::ShowFontAtlas(atlas); + + // Post-baking font scaling. Note that this is NOT the nice way of scaling fonts, read below. + // (we enforce hard clamping manually as by default DragFloat/SliderFloat allows CTRL+Click text to get out of bounds). + const float MIN_SCALE = 0.3f; + const float MAX_SCALE = 2.0f; + HelpMarker( + "Those are old settings provided for convenience.\n" + "However, the _correct_ way of scaling your UI is currently to reload your font at the designed size, " + "rebuild the font atlas, and call style.ScaleAllSizes() on a reference ImGuiStyle structure.\n" + "Using those settings here will give you poor quality results."); + static float window_scale = 1.0f; + ImGui::PushItemWidth(ImGui::GetFontSize() * 8); + if (ImGui::DragFloat("window scale", &window_scale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp)) // Scale only this window + ImGui::SetWindowFontScale(window_scale); + ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, MIN_SCALE, MAX_SCALE, "%.2f", ImGuiSliderFlags_AlwaysClamp); // Scale everything + ImGui::PopItemWidth(); + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Rendering")) + { + ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); + ImGui::SameLine(); + HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); + + ImGui::Checkbox("Anti-aliased lines use texture", &style.AntiAliasedLinesUseTex); + ImGui::SameLine(); + HelpMarker("Faster lines using texture data. Require backend to render with bilinear filtering (not point/nearest filtering)."); + + ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); + ImGui::PushItemWidth(ImGui::GetFontSize() * 8); + ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, 10.0f, "%.2f"); + if (style.CurveTessellationTol < 0.10f) style.CurveTessellationTol = 0.10f; + + // When editing the "Circle Segment Max Error" value, draw a preview of its effect on auto-tessellated circles. + ImGui::DragFloat("Circle Tessellation Max Error", &style.CircleTessellationMaxError , 0.005f, 0.10f, 5.0f, "%.2f", ImGuiSliderFlags_AlwaysClamp); + const bool show_samples = ImGui::IsItemActive(); + if (show_samples) + ImGui::SetNextWindowPos(ImGui::GetCursorScreenPos()); + if (show_samples && ImGui::BeginTooltip()) + { + ImGui::TextUnformatted("(R = radius, N = number of segments)"); + ImGui::Spacing(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + const float min_widget_width = ImGui::CalcTextSize("N: MMM\nR: MMM").x; + for (int n = 0; n < 8; n++) + { + const float RAD_MIN = 5.0f; + const float RAD_MAX = 70.0f; + const float rad = RAD_MIN + (RAD_MAX - RAD_MIN) * (float)n / (8.0f - 1.0f); + + ImGui::BeginGroup(); + + ImGui::Text("R: %.f\nN: %d", rad, draw_list->_CalcCircleAutoSegmentCount(rad)); + + const float canvas_width = IM_MAX(min_widget_width, rad * 2.0f); + const float offset_x = floorf(canvas_width * 0.5f); + const float offset_y = floorf(RAD_MAX); + + const ImVec2 p1 = ImGui::GetCursorScreenPos(); + draw_list->AddCircle(ImVec2(p1.x + offset_x, p1.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); + ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); + + /* + const ImVec2 p2 = ImGui::GetCursorScreenPos(); + draw_list->AddCircleFilled(ImVec2(p2.x + offset_x, p2.y + offset_y), rad, ImGui::GetColorU32(ImGuiCol_Text)); + ImGui::Dummy(ImVec2(canvas_width, RAD_MAX * 2)); + */ + + ImGui::EndGroup(); + ImGui::SameLine(); + } + ImGui::EndTooltip(); + } + ImGui::SameLine(); + HelpMarker("When drawing circle primitives with \"num_segments == 0\" tesselation will be calculated automatically."); + + ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. + ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Additional alpha multiplier for disabled items (multiply over current value of Alpha)."); + ImGui::PopItemWidth(); + + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + ImGui::PopItemWidth(); +} + +//----------------------------------------------------------------------------- +// [SECTION] User Guide / ShowUserGuide() +//----------------------------------------------------------------------------- + +void ImGui::ShowUserGuide() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGui::BulletText("Double-click on title bar to collapse window."); + ImGui::BulletText( + "Click and drag on lower corner to resize window\n" + "(double-click to auto fit window to its contents)."); + ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text."); + ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); + ImGui::BulletText("CTRL+Tab to select a window."); + if (io.FontAllowUserScaling) + ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); + ImGui::BulletText("While inputing text:\n"); + ImGui::Indent(); + ImGui::BulletText("CTRL+Left/Right to word jump."); + ImGui::BulletText("CTRL+A or double-click to select all."); + ImGui::BulletText("CTRL+X/C/V to use clipboard cut/copy/paste."); + ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo."); + ImGui::BulletText("ESCAPE to revert."); + ImGui::Unindent(); + ImGui::BulletText("With keyboard navigation enabled:"); + ImGui::Indent(); + ImGui::BulletText("Arrow keys to navigate."); + ImGui::BulletText("Space to activate a widget."); + ImGui::BulletText("Return to input text into a widget."); + ImGui::BulletText("Escape to deactivate a widget, close popup, exit child window."); + ImGui::BulletText("Alt to jump to the menu layer of a window."); + ImGui::Unindent(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Main Menu Bar / ShowExampleAppMainMenuBar() +//----------------------------------------------------------------------------- +// - ShowExampleAppMainMenuBar() +// - ShowExampleMenuFile() +//----------------------------------------------------------------------------- + +// Demonstrate creating a "main" fullscreen menu bar and populating it. +// Note the difference between BeginMainMenuBar() and BeginMenuBar(): +// - BeginMenuBar() = menu-bar inside current window (which needs the ImGuiWindowFlags_MenuBar flag!) +// - BeginMainMenuBar() = helper to create menu-bar-sized window at the top of the main viewport + call BeginMenuBar() into it. +static void ShowExampleAppMainMenuBar() +{ + if (ImGui::BeginMainMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + if (ImGui::MenuItem("Undo", "CTRL+Z")) {} + if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item + ImGui::Separator(); + if (ImGui::MenuItem("Cut", "CTRL+X")) {} + if (ImGui::MenuItem("Copy", "CTRL+C")) {} + if (ImGui::MenuItem("Paste", "CTRL+V")) {} + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } +} + +// Note that shortcuts are currently provided for display only +// (future version will add explicit flags to BeginMenu() to request processing shortcuts) +static void ShowExampleMenuFile() +{ + IMGUI_DEMO_MARKER("Examples/Menu"); + ImGui::MenuItem("(demo menu)", NULL, false, false); + if (ImGui::MenuItem("New")) {} + if (ImGui::MenuItem("Open", "Ctrl+O")) {} + if (ImGui::BeginMenu("Open Recent")) + { + ImGui::MenuItem("fish_hat.c"); + ImGui::MenuItem("fish_hat.inl"); + ImGui::MenuItem("fish_hat.h"); + if (ImGui::BeginMenu("More..")) + { + ImGui::MenuItem("Hello"); + ImGui::MenuItem("Sailor"); + if (ImGui::BeginMenu("Recurse..")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Save", "Ctrl+S")) {} + if (ImGui::MenuItem("Save As..")) {} + + ImGui::Separator(); + IMGUI_DEMO_MARKER("Examples/Menu/Options"); + if (ImGui::BeginMenu("Options")) + { + static bool enabled = true; + ImGui::MenuItem("Enabled", "", &enabled); + ImGui::BeginChild("child", ImVec2(0, 60), true); + for (int i = 0; i < 10; i++) + ImGui::Text("Scrolling Text %d", i); + ImGui::EndChild(); + static float f = 0.5f; + static int n = 0; + ImGui::SliderFloat("Value", &f, 0.0f, 1.0f); + ImGui::InputFloat("Input", &f, 0.1f); + ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0"); + ImGui::EndMenu(); + } + + IMGUI_DEMO_MARKER("Examples/Menu/Colors"); + if (ImGui::BeginMenu("Colors")) + { + float sz = ImGui::GetTextLineHeight(); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColorName((ImGuiCol)i); + ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + sz, p.y + sz), ImGui::GetColorU32((ImGuiCol)i)); + ImGui::Dummy(ImVec2(sz, sz)); + ImGui::SameLine(); + ImGui::MenuItem(name); + } + ImGui::EndMenu(); + } + + // Here we demonstrate appending again to the "Options" menu (which we already created above) + // Of course in this demo it is a little bit silly that this function calls BeginMenu("Options") twice. + // In a real code-base using it would make senses to use this feature from very different code locations. + if (ImGui::BeginMenu("Options")) // <-- Append! + { + IMGUI_DEMO_MARKER("Examples/Menu/Append to an existing menu"); + static bool b = true; + ImGui::Checkbox("SomeOption", &b); + ImGui::EndMenu(); + } + + if (ImGui::BeginMenu("Disabled", false)) // Disabled + { + IM_ASSERT(0); + } + if (ImGui::MenuItem("Checked", NULL, true)) {} + ImGui::Separator(); + if (ImGui::MenuItem("Quit", "Alt+F4")) {} +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Debug Console / ShowExampleAppConsole() +//----------------------------------------------------------------------------- + +// Demonstrate creating a simple console window, with scrolling, filtering, completion and history. +// For the console example, we are using a more C++ like approach of declaring a class to hold both data and functions. +struct ExampleAppConsole +{ + char InputBuf[256]; + ImVector Items; + ImVector Commands; + ImVector History; + int HistoryPos; // -1: new line, 0..History.Size-1 browsing history. + ImGuiTextFilter Filter; + bool AutoScroll; + bool ScrollToBottom; + + ExampleAppConsole() + { + IMGUI_DEMO_MARKER("Examples/Console"); + ClearLog(); + memset(InputBuf, 0, sizeof(InputBuf)); + HistoryPos = -1; + + // "CLASSIFY" is here to provide the test case where "C"+[tab] completes to "CL" and display multiple matches. + Commands.push_back("HELP"); + Commands.push_back("HISTORY"); + Commands.push_back("CLEAR"); + Commands.push_back("CLASSIFY"); + AutoScroll = true; + ScrollToBottom = false; + AddLog("Welcome to Dear ImGui!"); + } + ~ExampleAppConsole() + { + ClearLog(); + for (int i = 0; i < History.Size; i++) + free(History[i]); + } + + // Portable helpers + static int Stricmp(const char* s1, const char* s2) { int d; while ((d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; } return d; } + static int Strnicmp(const char* s1, const char* s2, int n) { int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; n--; } return d; } + static char* Strdup(const char* s) { IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)s, len); } + static void Strtrim(char* s) { char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; } + + void ClearLog() + { + for (int i = 0; i < Items.Size; i++) + free(Items[i]); + Items.clear(); + } + + void AddLog(const char* fmt, ...) IM_FMTARGS(2) + { + // FIXME-OPT + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf)-1] = 0; + va_end(args); + Items.push_back(Strdup(buf)); + } + + void Draw(const char* title, bool* p_open) + { + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin(title, p_open)) + { + ImGui::End(); + return; + } + + // As a specific feature guaranteed by the library, after calling Begin() the last Item represent the title bar. + // So e.g. IsItemHovered() will return true when hovering the title bar. + // Here we create a context menu only available from the title bar. + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::MenuItem("Close Console")) + *p_open = false; + ImGui::EndPopup(); + } + + ImGui::TextWrapped( + "This example implements a console with basic coloring, completion (TAB key) and history (Up/Down keys). A more elaborate " + "implementation may want to store entries along with extra data such as timestamp, emitter, etc."); + ImGui::TextWrapped("Enter 'HELP' for help."); + + // TODO: display items starting from the bottom + + if (ImGui::SmallButton("Add Debug Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } + ImGui::SameLine(); + if (ImGui::SmallButton("Add Debug Error")) { AddLog("[error] something went wrong"); } + ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) { ClearLog(); } + ImGui::SameLine(); + bool copy_to_clipboard = ImGui::SmallButton("Copy"); + //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } + + ImGui::Separator(); + + // Options menu + if (ImGui::BeginPopup("Options")) + { + ImGui::Checkbox("Auto-scroll", &AutoScroll); + ImGui::EndPopup(); + } + + // Options, Filter + if (ImGui::Button("Options")) + ImGui::OpenPopup("Options"); + ImGui::SameLine(); + Filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180); + ImGui::Separator(); + + // Reserve enough left-over height for 1 separator + 1 input text + const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); + if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar)) + { + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::Selectable("Clear")) ClearLog(); + ImGui::EndPopup(); + } + + // Display every line as a separate entry so we can change their color or add custom widgets. + // If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end()); + // NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping + // to only process visible items. The clipper will automatically measure the height of your first item and then + // "seek" to display only items in the visible area. + // To use the clipper we can replace your standard loop: + // for (int i = 0; i < Items.Size; i++) + // With: + // ImGuiListClipper clipper; + // clipper.Begin(Items.Size); + // while (clipper.Step()) + // for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + // - That your items are evenly spaced (same height) + // - That you have cheap random access to your elements (you can access them given their index, + // without processing all the ones before) + // You cannot this code as-is if a filter is active because it breaks the 'cheap random-access' property. + // We would need random-access on the post-filtered list. + // A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices + // or offsets of items that passed the filtering test, recomputing this array when user changes the filter, + // and appending newly elements as they are inserted. This is left as a task to the user until we can manage + // to improve this example code! + // If your items are of variable height: + // - Split them into same height items would be simpler and facilitate random-seeking into your list. + // - Consider using manual call to IsRectVisible() and skipping extraneous decoration from your items. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); // Tighten spacing + if (copy_to_clipboard) + ImGui::LogToClipboard(); + for (int i = 0; i < Items.Size; i++) + { + const char* item = Items[i]; + if (!Filter.PassFilter(item)) + continue; + + // Normally you would store more information in your item than just a string. + // (e.g. make Items[] an array of structure, store color/type etc.) + ImVec4 color; + bool has_color = false; + if (strstr(item, "[error]")) { color = ImVec4(1.0f, 0.4f, 0.4f, 1.0f); has_color = true; } + else if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.0f, 0.8f, 0.6f, 1.0f); has_color = true; } + if (has_color) + ImGui::PushStyleColor(ImGuiCol_Text, color); + ImGui::TextUnformatted(item); + if (has_color) + ImGui::PopStyleColor(); + } + if (copy_to_clipboard) + ImGui::LogFinish(); + + // Keep up at the bottom of the scroll region if we were already at the bottom at the beginning of the frame. + // Using a scrollbar or mouse-wheel will take away from the bottom edge. + if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) + ImGui::SetScrollHereY(1.0f); + ScrollToBottom = false; + + ImGui::PopStyleVar(); + } + ImGui::EndChild(); + ImGui::Separator(); + + // Command-line + bool reclaim_focus = false; + ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory; + if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags, &TextEditCallbackStub, (void*)this)) + { + char* s = InputBuf; + Strtrim(s); + if (s[0]) + ExecCommand(s); + strcpy(s, ""); + reclaim_focus = true; + } + + // Auto-focus on window apparition + ImGui::SetItemDefaultFocus(); + if (reclaim_focus) + ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget + + ImGui::End(); + } + + void ExecCommand(const char* command_line) + { + AddLog("# %s\n", command_line); + + // Insert into history. First find match and delete it so it can be pushed to the back. + // This isn't trying to be smart or optimal. + HistoryPos = -1; + for (int i = History.Size - 1; i >= 0; i--) + if (Stricmp(History[i], command_line) == 0) + { + free(History[i]); + History.erase(History.begin() + i); + break; + } + History.push_back(Strdup(command_line)); + + // Process command + if (Stricmp(command_line, "CLEAR") == 0) + { + ClearLog(); + } + else if (Stricmp(command_line, "HELP") == 0) + { + AddLog("Commands:"); + for (int i = 0; i < Commands.Size; i++) + AddLog("- %s", Commands[i]); + } + else if (Stricmp(command_line, "HISTORY") == 0) + { + int first = History.Size - 10; + for (int i = first > 0 ? first : 0; i < History.Size; i++) + AddLog("%3d: %s\n", i, History[i]); + } + else + { + AddLog("Unknown command: '%s'\n", command_line); + } + + // On command input, we scroll to bottom even if AutoScroll==false + ScrollToBottom = true; + } + + // In C++11 you'd be better off using lambdas for this sort of forwarding callbacks + static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) + { + ExampleAppConsole* console = (ExampleAppConsole*)data->UserData; + return console->TextEditCallback(data); + } + + int TextEditCallback(ImGuiInputTextCallbackData* data) + { + //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd); + switch (data->EventFlag) + { + case ImGuiInputTextFlags_CallbackCompletion: + { + // Example of TEXT COMPLETION + + // Locate beginning of current word + const char* word_end = data->Buf + data->CursorPos; + const char* word_start = word_end; + while (word_start > data->Buf) + { + const char c = word_start[-1]; + if (c == ' ' || c == '\t' || c == ',' || c == ';') + break; + word_start--; + } + + // Build a list of candidates + ImVector candidates; + for (int i = 0; i < Commands.Size; i++) + if (Strnicmp(Commands[i], word_start, (int)(word_end - word_start)) == 0) + candidates.push_back(Commands[i]); + + if (candidates.Size == 0) + { + // No match + AddLog("No match for \"%.*s\"!\n", (int)(word_end - word_start), word_start); + } + else if (candidates.Size == 1) + { + // Single match. Delete the beginning of the word and replace it entirely so we've got nice casing. + data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start)); + data->InsertChars(data->CursorPos, candidates[0]); + data->InsertChars(data->CursorPos, " "); + } + else + { + // Multiple matches. Complete as much as we can.. + // So inputing "C"+Tab will complete to "CL" then display "CLEAR" and "CLASSIFY" as matches. + int match_len = (int)(word_end - word_start); + for (;;) + { + int c = 0; + bool all_candidates_matches = true; + for (int i = 0; i < candidates.Size && all_candidates_matches; i++) + if (i == 0) + c = toupper(candidates[i][match_len]); + else if (c == 0 || c != toupper(candidates[i][match_len])) + all_candidates_matches = false; + if (!all_candidates_matches) + break; + match_len++; + } + + if (match_len > 0) + { + data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start)); + data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); + } + + // List matches + AddLog("Possible matches:\n"); + for (int i = 0; i < candidates.Size; i++) + AddLog("- %s\n", candidates[i]); + } + + break; + } + case ImGuiInputTextFlags_CallbackHistory: + { + // Example of HISTORY + const int prev_history_pos = HistoryPos; + if (data->EventKey == ImGuiKey_UpArrow) + { + if (HistoryPos == -1) + HistoryPos = History.Size - 1; + else if (HistoryPos > 0) + HistoryPos--; + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + if (HistoryPos != -1) + if (++HistoryPos >= History.Size) + HistoryPos = -1; + } + + // A better implementation would preserve the data on the current input line along with cursor position. + if (prev_history_pos != HistoryPos) + { + const char* history_str = (HistoryPos >= 0) ? History[HistoryPos] : ""; + data->DeleteChars(0, data->BufTextLen); + data->InsertChars(0, history_str); + } + } + } + return 0; + } +}; + +static void ShowExampleAppConsole(bool* p_open) +{ + static ExampleAppConsole console; + console.Draw("Example: Console", p_open); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Debug Log / ShowExampleAppLog() +//----------------------------------------------------------------------------- + +// Usage: +// static ExampleAppLog my_log; +// my_log.AddLog("Hello %d world\n", 123); +// my_log.Draw("title"); +struct ExampleAppLog +{ + ImGuiTextBuffer Buf; + ImGuiTextFilter Filter; + ImVector LineOffsets; // Index to lines offset. We maintain this with AddLog() calls. + bool AutoScroll; // Keep scrolling if already at the bottom. + + ExampleAppLog() + { + AutoScroll = true; + Clear(); + } + + void Clear() + { + Buf.clear(); + LineOffsets.clear(); + LineOffsets.push_back(0); + } + + void AddLog(const char* fmt, ...) IM_FMTARGS(2) + { + int old_size = Buf.size(); + va_list args; + va_start(args, fmt); + Buf.appendfv(fmt, args); + va_end(args); + for (int new_size = Buf.size(); old_size < new_size; old_size++) + if (Buf[old_size] == '\n') + LineOffsets.push_back(old_size + 1); + } + + void Draw(const char* title, bool* p_open = NULL) + { + if (!ImGui::Begin(title, p_open)) + { + ImGui::End(); + return; + } + + // Options menu + if (ImGui::BeginPopup("Options")) + { + ImGui::Checkbox("Auto-scroll", &AutoScroll); + ImGui::EndPopup(); + } + + // Main window + if (ImGui::Button("Options")) + ImGui::OpenPopup("Options"); + ImGui::SameLine(); + bool clear = ImGui::Button("Clear"); + ImGui::SameLine(); + bool copy = ImGui::Button("Copy"); + ImGui::SameLine(); + Filter.Draw("Filter", -100.0f); + + ImGui::Separator(); + + if (ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar)) + { + if (clear) + Clear(); + if (copy) + ImGui::LogToClipboard(); + + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + const char* buf = Buf.begin(); + const char* buf_end = Buf.end(); + if (Filter.IsActive()) + { + // In this example we don't use the clipper when Filter is enabled. + // This is because we don't have random access to the result of our filter. + // A real application processing logs with ten of thousands of entries may want to store the result of + // search/filter.. especially if the filtering function is not trivial (e.g. reg-exp). + for (int line_no = 0; line_no < LineOffsets.Size; line_no++) + { + const char* line_start = buf + LineOffsets[line_no]; + const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end; + if (Filter.PassFilter(line_start, line_end)) + ImGui::TextUnformatted(line_start, line_end); + } + } + else + { + // The simplest and easy way to display the entire buffer: + // ImGui::TextUnformatted(buf_begin, buf_end); + // And it'll just work. TextUnformatted() has specialization for large blob of text and will fast-forward + // to skip non-visible lines. Here we instead demonstrate using the clipper to only process lines that are + // within the visible area. + // If you have tens of thousands of items and their processing cost is non-negligible, coarse clipping them + // on your side is recommended. Using ImGuiListClipper requires + // - A) random access into your data + // - B) items all being the same height, + // both of which we can handle since we have an array pointing to the beginning of each line of text. + // When using the filter (in the block of code above) we don't have random access into the data to display + // anymore, which is why we don't use the clipper. Storing or skimming through the search result would make + // it possible (and would be recommended if you want to search through tens of thousands of entries). + ImGuiListClipper clipper; + clipper.Begin(LineOffsets.Size); + while (clipper.Step()) + { + for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++) + { + const char* line_start = buf + LineOffsets[line_no]; + const char* line_end = (line_no + 1 < LineOffsets.Size) ? (buf + LineOffsets[line_no + 1] - 1) : buf_end; + ImGui::TextUnformatted(line_start, line_end); + } + } + clipper.End(); + } + ImGui::PopStyleVar(); + + // Keep up at the bottom of the scroll region if we were already at the bottom at the beginning of the frame. + // Using a scrollbar or mouse-wheel will take away from the bottom edge. + if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) + ImGui::SetScrollHereY(1.0f); + } + ImGui::EndChild(); + ImGui::End(); + } +}; + +// Demonstrate creating a simple log window with basic filtering. +static void ShowExampleAppLog(bool* p_open) +{ + static ExampleAppLog log; + + // For the demo: add a debug button _BEFORE_ the normal log window contents + // We take advantage of a rarely used feature: multiple calls to Begin()/End() are appending to the _same_ window. + // Most of the contents of the window will be added by the log.Draw() call. + ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver); + ImGui::Begin("Example: Log", p_open); + IMGUI_DEMO_MARKER("Examples/Log"); + if (ImGui::SmallButton("[Debug] Add 5 entries")) + { + static int counter = 0; + const char* categories[3] = { "info", "warn", "error" }; + const char* words[] = { "Bumfuzzled", "Cattywampus", "Snickersnee", "Abibliophobia", "Absquatulate", "Nincompoop", "Pauciloquent" }; + for (int n = 0; n < 5; n++) + { + const char* category = categories[counter % IM_ARRAYSIZE(categories)]; + const char* word = words[counter % IM_ARRAYSIZE(words)]; + log.AddLog("[%05d] [%s] Hello, current time is %.1f, here's a word: '%s'\n", + ImGui::GetFrameCount(), category, ImGui::GetTime(), word); + counter++; + } + } + ImGui::End(); + + // Actually call in the regular Log helper (which will Begin() into the same window as we just did) + log.Draw("Example: Log", p_open); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Simple Layout / ShowExampleAppLayout() +//----------------------------------------------------------------------------- + +// Demonstrate create a window with multiple child windows. +static void ShowExampleAppLayout(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiCond_FirstUseEver); + if (ImGui::Begin("Example: Simple layout", p_open, ImGuiWindowFlags_MenuBar)) + { + IMGUI_DEMO_MARKER("Examples/Simple layout"); + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Close", "Ctrl+W")) { *p_open = false; } + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + // Left + static int selected = 0; + { + ImGui::BeginChild("left pane", ImVec2(150, 0), true); + for (int i = 0; i < 100; i++) + { + // FIXME: Good candidate to use ImGuiSelectableFlags_SelectOnNav + char label[128]; + sprintf(label, "MyObject %d", i); + if (ImGui::Selectable(label, selected == i)) + selected = i; + } + ImGui::EndChild(); + } + ImGui::SameLine(); + + // Right + { + ImGui::BeginGroup(); + ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us + ImGui::Text("MyObject: %d", selected); + ImGui::Separator(); + if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) + { + if (ImGui::BeginTabItem("Description")) + { + ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Details")) + { + ImGui::Text("ID: 0123456789"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + ImGui::EndChild(); + if (ImGui::Button("Revert")) {} + ImGui::SameLine(); + if (ImGui::Button("Save")) {} + ImGui::EndGroup(); + } + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Property Editor / ShowExampleAppPropertyEditor() +//----------------------------------------------------------------------------- + +static void ShowPlaceholderObject(const char* prefix, int uid) +{ + // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. + ImGui::PushID(uid); + + // Text and Tree nodes are less high than framed widgets, using AlignTextToFramePadding() we add vertical spacing to make the tree lines equal high. + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::AlignTextToFramePadding(); + bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid); + ImGui::TableSetColumnIndex(1); + ImGui::Text("my sailor is rich"); + + if (node_open) + { + static float placeholder_members[8] = { 0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f }; + for (int i = 0; i < 8; i++) + { + ImGui::PushID(i); // Use field index as identifier. + if (i < 2) + { + ShowPlaceholderObject("Child", 424242); + } + else + { + // Here we use a TreeNode to highlight on hover (we could use e.g. Selectable as well) + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::AlignTextToFramePadding(); + ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_Bullet; + ImGui::TreeNodeEx("Field", flags, "Field_%d", i); + + ImGui::TableSetColumnIndex(1); + ImGui::SetNextItemWidth(-FLT_MIN); + if (i >= 5) + ImGui::InputFloat("##value", &placeholder_members[i], 1.0f); + else + ImGui::DragFloat("##value", &placeholder_members[i], 0.01f); + ImGui::NextColumn(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } + ImGui::PopID(); +} + +// Demonstrate create a simple property editor. +static void ShowExampleAppPropertyEditor(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(430, 450), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Example: Property editor", p_open)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Property Editor"); + + HelpMarker( + "This example shows how you may implement a property editor using two columns.\n" + "All objects/fields data are dummies here.\n" + "Remember that in many simple cases, you can use ImGui::SameLine(xxx) to position\n" + "your cursor horizontally instead of using the Columns() API."); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + if (ImGui::BeginTable("split", 2, ImGuiTableFlags_BordersOuter | ImGuiTableFlags_Resizable)) + { + // Iterate placeholder objects (all the same data) + for (int obj_i = 0; obj_i < 4; obj_i++) + { + ShowPlaceholderObject("Object", obj_i); + //ImGui::Separator(); + } + ImGui::EndTable(); + } + ImGui::PopStyleVar(); + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Long Text / ShowExampleAppLongText() +//----------------------------------------------------------------------------- + +// Demonstrate/test rendering huge amount of text, and the incidence of clipping. +static void ShowExampleAppLongText(bool* p_open) +{ + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Example: Long text display", p_open)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Long text display"); + + static int test_type = 0; + static ImGuiTextBuffer log; + static int lines = 0; + ImGui::Text("Printing unusually long amount of text."); + ImGui::Combo("Test type", &test_type, + "Single call to TextUnformatted()\0" + "Multiple calls to Text(), clipped\0" + "Multiple calls to Text(), not clipped (slow)\0"); + ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); + if (ImGui::Button("Clear")) { log.clear(); lines = 0; } + ImGui::SameLine(); + if (ImGui::Button("Add 1000 lines")) + { + for (int i = 0; i < 1000; i++) + log.appendf("%i The quick brown fox jumps over the lazy dog\n", lines + i); + lines += 1000; + } + ImGui::BeginChild("Log"); + switch (test_type) + { + case 0: + // Single call to TextUnformatted() with a big buffer + ImGui::TextUnformatted(log.begin(), log.end()); + break; + case 1: + { + // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGuiListClipper clipper; + clipper.Begin(lines); + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); + ImGui::PopStyleVar(); + break; + } + case 2: + // Multiple calls to Text(), not clipped (slow) + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + for (int i = 0; i < lines; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); + ImGui::PopStyleVar(); + break; + } + ImGui::EndChild(); + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Auto Resize / ShowExampleAppAutoResize() +//----------------------------------------------------------------------------- + +// Demonstrate creating a window which gets auto-resized according to its content. +static void ShowExampleAppAutoResize(bool* p_open) +{ + if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Auto-resizing window"); + + static int lines = 10; + ImGui::TextUnformatted( + "Window will resize every-frame to the size of its content.\n" + "Note that you probably don't want to query the window size to\n" + "output your content because that would create a feedback loop."); + ImGui::SliderInt("Number of lines", &lines, 1, 20); + for (int i = 0; i < lines; i++) + ImGui::Text("%*sThis is line %d", i * 4, "", i); // Pad with space to extend size horizontally + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Constrained Resize / ShowExampleAppConstrainedResize() +//----------------------------------------------------------------------------- + +// Demonstrate creating a window with custom resize constraints. +// Note that size constraints currently don't work on a docked window (when in 'docking' branch) +static void ShowExampleAppConstrainedResize(bool* p_open) +{ + struct CustomConstraints + { + // Helper functions to demonstrate programmatic constraints + // FIXME: This doesn't take account of decoration size (e.g. title bar), library should make this easier. + static void AspectRatio(ImGuiSizeCallbackData* data) { float aspect_ratio = *(float*)data->UserData; data->DesiredSize.x = IM_MAX(data->CurrentSize.x, data->CurrentSize.y); data->DesiredSize.y = (float)(int)(data->DesiredSize.x / aspect_ratio); } + static void Square(ImGuiSizeCallbackData* data) { data->DesiredSize.x = data->DesiredSize.y = IM_MAX(data->CurrentSize.x, data->CurrentSize.y); } + static void Step(ImGuiSizeCallbackData* data) { float step = *(float*)data->UserData; data->DesiredSize = ImVec2((int)(data->CurrentSize.x / step + 0.5f) * step, (int)(data->CurrentSize.y / step + 0.5f) * step); } + }; + + const char* test_desc[] = + { + "Between 100x100 and 500x500", + "At least 100x100", + "Resize vertical only", + "Resize horizontal only", + "Width Between 400 and 500", + "Custom: Aspect Ratio 16:9", + "Custom: Always Square", + "Custom: Fixed Steps (100)", + }; + + // Options + static bool auto_resize = false; + static bool window_padding = true; + static int type = 5; // Aspect Ratio + static int display_lines = 10; + + // Submit constraint + float aspect_ratio = 16.0f / 9.0f; + float fixed_step = 100.0f; + if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(500, 500)); // Between 100x100 and 500x500 + if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100 + if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only + if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only + if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width Between and 400 and 500 + if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::AspectRatio, (void*)&aspect_ratio); // Aspect ratio + if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square + if (type == 7) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)&fixed_step); // Fixed Step + + // Submit window + if (!window_padding) + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f)); + const ImGuiWindowFlags window_flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0; + const bool window_open = ImGui::Begin("Example: Constrained Resize", p_open, window_flags); + if (!window_padding) + ImGui::PopStyleVar(); + if (window_open) + { + IMGUI_DEMO_MARKER("Examples/Constrained Resizing window"); + if (ImGui::GetIO().KeyShift) + { + // Display a dummy viewport (in your real app you would likely use ImageButton() to display a texture. + ImVec2 avail_size = ImGui::GetContentRegionAvail(); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::ColorButton("viewport", ImVec4(0.5f, 0.2f, 0.5f, 1.0f), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoDragDrop, avail_size); + ImGui::SetCursorScreenPos(ImVec2(pos.x + 10, pos.y + 10)); + ImGui::Text("%.2f x %.2f", avail_size.x, avail_size.y); + } + else + { + ImGui::Text("(Hold SHIFT to display a dummy viewport)"); + if (ImGui::Button("Set 200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine(); + if (ImGui::Button("Set 500x500")) { ImGui::SetWindowSize(ImVec2(500, 500)); } ImGui::SameLine(); + if (ImGui::Button("Set 800x200")) { ImGui::SetWindowSize(ImVec2(800, 200)); } + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 20); + ImGui::Combo("Constraint", &type, test_desc, IM_ARRAYSIZE(test_desc)); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 20); + ImGui::DragInt("Lines", &display_lines, 0.2f, 1, 100); + ImGui::Checkbox("Auto-resize", &auto_resize); + ImGui::Checkbox("Window padding", &window_padding); + for (int i = 0; i < display_lines; i++) + ImGui::Text("%*sHello, sailor! Making this line long enough for the example.", i * 4, ""); + } + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Simple overlay / ShowExampleAppSimpleOverlay() +//----------------------------------------------------------------------------- + +// Demonstrate creating a simple static window with no decoration +// + a context-menu to choose which corner of the screen to use. +static void ShowExampleAppSimpleOverlay(bool* p_open) +{ + static int location = 0; + ImGuiIO& io = ImGui::GetIO(); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav; + if (location >= 0) + { + const float PAD = 10.0f; + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImVec2 work_pos = viewport->WorkPos; // Use work area to avoid menu-bar/task-bar, if any! + ImVec2 work_size = viewport->WorkSize; + ImVec2 window_pos, window_pos_pivot; + window_pos.x = (location & 1) ? (work_pos.x + work_size.x - PAD) : (work_pos.x + PAD); + window_pos.y = (location & 2) ? (work_pos.y + work_size.y - PAD) : (work_pos.y + PAD); + window_pos_pivot.x = (location & 1) ? 1.0f : 0.0f; + window_pos_pivot.y = (location & 2) ? 1.0f : 0.0f; + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); + window_flags |= ImGuiWindowFlags_NoMove; + } + else if (location == -2) + { + // Center window + ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f)); + window_flags |= ImGuiWindowFlags_NoMove; + } + ImGui::SetNextWindowBgAlpha(0.35f); // Transparent background + if (ImGui::Begin("Example: Simple overlay", p_open, window_flags)) + { + IMGUI_DEMO_MARKER("Examples/Simple Overlay"); + ImGui::Text("Simple overlay\n" "(right-click to change position)"); + ImGui::Separator(); + if (ImGui::IsMousePosValid()) + ImGui::Text("Mouse Position: (%.1f,%.1f)", io.MousePos.x, io.MousePos.y); + else + ImGui::Text("Mouse Position: "); + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::MenuItem("Custom", NULL, location == -1)) location = -1; + if (ImGui::MenuItem("Center", NULL, location == -2)) location = -2; + if (ImGui::MenuItem("Top-left", NULL, location == 0)) location = 0; + if (ImGui::MenuItem("Top-right", NULL, location == 1)) location = 1; + if (ImGui::MenuItem("Bottom-left", NULL, location == 2)) location = 2; + if (ImGui::MenuItem("Bottom-right", NULL, location == 3)) location = 3; + if (p_open && ImGui::MenuItem("Close")) *p_open = false; + ImGui::EndPopup(); + } + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Fullscreen window / ShowExampleAppFullscreen() +//----------------------------------------------------------------------------- + +// Demonstrate creating a window covering the entire screen/viewport +static void ShowExampleAppFullscreen(bool* p_open) +{ + static bool use_work_area = true; + static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings; + + // We demonstrate using the full viewport area or the work area (without menu-bars, task-bars etc.) + // Based on your use case you may want one or the other. + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + ImGui::SetNextWindowPos(use_work_area ? viewport->WorkPos : viewport->Pos); + ImGui::SetNextWindowSize(use_work_area ? viewport->WorkSize : viewport->Size); + + if (ImGui::Begin("Example: Fullscreen window", p_open, flags)) + { + ImGui::Checkbox("Use work area instead of main area", &use_work_area); + ImGui::SameLine(); + HelpMarker("Main Area = entire viewport,\nWork Area = entire viewport minus sections used by the main menu bars, task bars etc.\n\nEnable the main-menu bar in Examples menu to see the difference."); + + ImGui::CheckboxFlags("ImGuiWindowFlags_NoBackground", &flags, ImGuiWindowFlags_NoBackground); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoDecoration", &flags, ImGuiWindowFlags_NoDecoration); + ImGui::Indent(); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoTitleBar", &flags, ImGuiWindowFlags_NoTitleBar); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoCollapse", &flags, ImGuiWindowFlags_NoCollapse); + ImGui::CheckboxFlags("ImGuiWindowFlags_NoScrollbar", &flags, ImGuiWindowFlags_NoScrollbar); + ImGui::Unindent(); + + if (p_open && ImGui::Button("Close this window")) + *p_open = false; + } + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Manipulating Window Titles / ShowExampleAppWindowTitles() +//----------------------------------------------------------------------------- + +// Demonstrate the use of "##" and "###" in identifiers to manipulate ID generation. +// This applies to all regular items as well. +// Read FAQ section "How can I have multiple widgets with the same label?" for details. +static void ShowExampleAppWindowTitles(bool*) +{ + const ImGuiViewport* viewport = ImGui::GetMainViewport(); + const ImVec2 base_pos = viewport->Pos; + + // By default, Windows are uniquely identified by their title. + // You can use the "##" and "###" markers to manipulate the display/ID. + + // Using "##" to display same title but have unique identifier. + ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 100), ImGuiCond_FirstUseEver); + ImGui::Begin("Same title as another window##1"); + IMGUI_DEMO_MARKER("Examples/Manipulating window titles"); + ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); + ImGui::End(); + + ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 200), ImGuiCond_FirstUseEver); + ImGui::Begin("Same title as another window##2"); + ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique."); + ImGui::End(); + + // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" + char buf[128]; + sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime() / 0.25f) & 3], ImGui::GetFrameCount()); + ImGui::SetNextWindowPos(ImVec2(base_pos.x + 100, base_pos.y + 300), ImGuiCond_FirstUseEver); + ImGui::Begin(buf); + ImGui::Text("This window has a changing title."); + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering() +//----------------------------------------------------------------------------- + +// Demonstrate using the low-level ImDrawList to draw custom shapes. +static void ShowExampleAppCustomRendering(bool* p_open) +{ + if (!ImGui::Begin("Example: Custom rendering", p_open)) + { + ImGui::End(); + return; + } + IMGUI_DEMO_MARKER("Examples/Custom Rendering"); + + // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of + // overloaded operators, etc. Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your + // types and ImVec2/ImVec4. Dear ImGui defines overloaded operators but they are internal to imgui.cpp and not + // exposed outside (to avoid messing with your types) In this example we are not using the maths operators! + + if (ImGui::BeginTabBar("##TabBar")) + { + if (ImGui::BeginTabItem("Primitives")) + { + ImGui::PushItemWidth(-ImGui::GetFontSize() * 15); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + + // Draw gradients + // (note that those are currently exacerbating our sRGB/Linear issues) + // Calling ImGui::GetColorU32() multiplies the given colors by the current Style Alpha, but you may pass the IM_COL32() directly as well.. + ImGui::Text("Gradients"); + ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight()); + { + ImVec2 p0 = ImGui::GetCursorScreenPos(); + ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y); + ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 0, 0, 255)); + ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 255, 255, 255)); + draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a); + ImGui::InvisibleButton("##gradient1", gradient_size); + } + { + ImVec2 p0 = ImGui::GetCursorScreenPos(); + ImVec2 p1 = ImVec2(p0.x + gradient_size.x, p0.y + gradient_size.y); + ImU32 col_a = ImGui::GetColorU32(IM_COL32(0, 255, 0, 255)); + ImU32 col_b = ImGui::GetColorU32(IM_COL32(255, 0, 0, 255)); + draw_list->AddRectFilledMultiColor(p0, p1, col_a, col_b, col_b, col_a); + ImGui::InvisibleButton("##gradient2", gradient_size); + } + + // Draw a bunch of primitives + ImGui::Text("All primitives"); + static float sz = 36.0f; + static float thickness = 3.0f; + static int ngon_sides = 6; + static bool circle_segments_override = false; + static int circle_segments_override_v = 12; + static bool curve_segments_override = false; + static int curve_segments_override_v = 8; + static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f); + ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 100.0f, "%.0f"); + ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f"); + ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12); + ImGui::Checkbox("##circlesegmentoverride", &circle_segments_override); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + circle_segments_override |= ImGui::SliderInt("Circle segments override", &circle_segments_override_v, 3, 40); + ImGui::Checkbox("##curvessegmentoverride", &curve_segments_override); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + curve_segments_override |= ImGui::SliderInt("Curves segments override", &curve_segments_override_v, 3, 40); + ImGui::ColorEdit4("Color", &colf.x); + + const ImVec2 p = ImGui::GetCursorScreenPos(); + const ImU32 col = ImColor(colf); + const float spacing = 10.0f; + const ImDrawFlags corners_tl_br = ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBottomRight; + const float rounding = sz / 5.0f; + const int circle_segments = circle_segments_override ? circle_segments_override_v : 0; + const int curve_segments = curve_segments_override ? curve_segments_override_v : 0; + float x = p.x + 4.0f; + float y = p.y + 4.0f; + for (int n = 0; n < 2; n++) + { + // First line uses a thickness of 1.0f, second line uses the configurable thickness + float th = (n == 0) ? 1.0f : thickness; + draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon + draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners + draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle + //draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle + draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) + draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) + draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line + + // Quadratic Bezier Curve (3 control points) + ImVec2 cp3[3] = { ImVec2(x, y + sz * 0.6f), ImVec2(x + sz * 0.5f, y - sz * 0.4f), ImVec2(x + sz, y + sz) }; + draw_list->AddBezierQuadratic(cp3[0], cp3[1], cp3[2], col, th, curve_segments); x += sz + spacing; + + // Cubic Bezier Curve (4 control points) + ImVec2 cp4[4] = { ImVec2(x, y), ImVec2(x + sz * 1.3f, y + sz * 0.3f), ImVec2(x + sz - sz * 1.3f, y + sz - sz * 0.3f), ImVec2(x + sz, y + sz) }; + draw_list->AddBezierCubic(cp4[0], cp4[1], cp4[2], cp4[3], col, th, curve_segments); + + x = p.x + 4; + y += sz + spacing; + } + draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon + draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments); x += sz + spacing; // Circle + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners + draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle + //draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness) + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness) + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine) + draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255)); + + ImGui::Dummy(ImVec2((sz + spacing) * 10.2f, (sz + spacing) * 3.0f)); + ImGui::PopItemWidth(); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Canvas")) + { + static ImVector points; + static ImVec2 scrolling(0.0f, 0.0f); + static bool opt_enable_grid = true; + static bool opt_enable_context_menu = true; + static bool adding_line = false; + + ImGui::Checkbox("Enable grid", &opt_enable_grid); + ImGui::Checkbox("Enable context menu", &opt_enable_context_menu); + ImGui::Text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu."); + + // Typically you would use a BeginChild()/EndChild() pair to benefit from a clipping region + own scrolling. + // Here we demonstrate that this can be replaced by simple offsetting + custom drawing + PushClipRect/PopClipRect() calls. + // To use a child window instead we could use, e.g: + // ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Disable padding + // ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(50, 50, 50, 255)); // Set a background color + // ImGui::BeginChild("canvas", ImVec2(0.0f, 0.0f), true, ImGuiWindowFlags_NoMove); + // ImGui::PopStyleColor(); + // ImGui::PopStyleVar(); + // [...] + // ImGui::EndChild(); + + // Using InvisibleButton() as a convenience 1) it will advance the layout cursor and 2) allows us to use IsItemHovered()/IsItemActive() + ImVec2 canvas_p0 = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! + ImVec2 canvas_sz = ImGui::GetContentRegionAvail(); // Resize canvas to what's available + if (canvas_sz.x < 50.0f) canvas_sz.x = 50.0f; + if (canvas_sz.y < 50.0f) canvas_sz.y = 50.0f; + ImVec2 canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y); + + // Draw border and background color + ImGuiIO& io = ImGui::GetIO(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(50, 50, 50, 255)); + draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255)); + + // This will catch our interactions + ImGui::InvisibleButton("canvas", canvas_sz, ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); + const bool is_hovered = ImGui::IsItemHovered(); // Hovered + const bool is_active = ImGui::IsItemActive(); // Held + const ImVec2 origin(canvas_p0.x + scrolling.x, canvas_p0.y + scrolling.y); // Lock scrolled origin + const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, io.MousePos.y - origin.y); + + // Add first and second point + if (is_hovered && !adding_line && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) + { + points.push_back(mouse_pos_in_canvas); + points.push_back(mouse_pos_in_canvas); + adding_line = true; + } + if (adding_line) + { + points.back() = mouse_pos_in_canvas; + if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) + adding_line = false; + } + + // Pan (we use a zero mouse threshold when there's no context menu) + // You may decide to make that threshold dynamic based on whether the mouse is hovering something etc. + const float mouse_threshold_for_pan = opt_enable_context_menu ? -1.0f : 0.0f; + if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right, mouse_threshold_for_pan)) + { + scrolling.x += io.MouseDelta.x; + scrolling.y += io.MouseDelta.y; + } + + // Context menu (under default mouse threshold) + ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right); + if (opt_enable_context_menu && drag_delta.x == 0.0f && drag_delta.y == 0.0f) + ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); + if (ImGui::BeginPopup("context")) + { + if (adding_line) + points.resize(points.size() - 2); + adding_line = false; + if (ImGui::MenuItem("Remove one", NULL, false, points.Size > 0)) { points.resize(points.size() - 2); } + if (ImGui::MenuItem("Remove all", NULL, false, points.Size > 0)) { points.clear(); } + ImGui::EndPopup(); + } + + // Draw grid + all lines in the canvas + draw_list->PushClipRect(canvas_p0, canvas_p1, true); + if (opt_enable_grid) + { + const float GRID_STEP = 64.0f; + for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP) + draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), ImVec2(canvas_p0.x + x, canvas_p1.y), IM_COL32(200, 200, 200, 40)); + for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP) + draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40)); + } + for (int n = 0; n < points.Size; n += 2) + draw_list->AddLine(ImVec2(origin.x + points[n].x, origin.y + points[n].y), ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y), IM_COL32(255, 255, 0, 255), 2.0f); + draw_list->PopClipRect(); + + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("BG/FG draw lists")) + { + static bool draw_bg = true; + static bool draw_fg = true; + ImGui::Checkbox("Draw in Background draw list", &draw_bg); + ImGui::SameLine(); HelpMarker("The Background draw list will be rendered below every Dear ImGui windows."); + ImGui::Checkbox("Draw in Foreground draw list", &draw_fg); + ImGui::SameLine(); HelpMarker("The Foreground draw list will be rendered over every Dear ImGui windows."); + ImVec2 window_pos = ImGui::GetWindowPos(); + ImVec2 window_size = ImGui::GetWindowSize(); + ImVec2 window_center = ImVec2(window_pos.x + window_size.x * 0.5f, window_pos.y + window_size.y * 0.5f); + if (draw_bg) + ImGui::GetBackgroundDrawList()->AddCircle(window_center, window_size.x * 0.6f, IM_COL32(255, 0, 0, 200), 0, 10 + 4); + if (draw_fg) + ImGui::GetForegroundDrawList()->AddCircle(window_center, window_size.y * 0.6f, IM_COL32(0, 255, 0, 200), 0, 10); + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } + + ImGui::End(); +} + +//----------------------------------------------------------------------------- +// [SECTION] Example App: Documents Handling / ShowExampleAppDocuments() +//----------------------------------------------------------------------------- + +// Simplified structure to mimic a Document model +struct MyDocument +{ + const char* Name; // Document title + bool Open; // Set when open (we keep an array of all available documents to simplify demo code!) + bool OpenPrev; // Copy of Open from last update. + bool Dirty; // Set when the document has been modified + bool WantClose; // Set when the document + ImVec4 Color; // An arbitrary variable associated to the document + + MyDocument(const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f)) + { + Name = name; + Open = OpenPrev = open; + Dirty = false; + WantClose = false; + Color = color; + } + void DoOpen() { Open = true; } + void DoQueueClose() { WantClose = true; } + void DoForceClose() { Open = false; Dirty = false; } + void DoSave() { Dirty = false; } + + // Display placeholder contents for the Document + static void DisplayContents(MyDocument* doc) + { + ImGui::PushID(doc); + ImGui::Text("Document \"%s\"", doc->Name); + ImGui::PushStyleColor(ImGuiCol_Text, doc->Color); + ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); + ImGui::PopStyleColor(); + if (ImGui::Button("Modify", ImVec2(100, 0))) + doc->Dirty = true; + ImGui::SameLine(); + if (ImGui::Button("Save", ImVec2(100, 0))) + doc->DoSave(); + ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior. + ImGui::PopID(); + } + + // Display context menu for the Document + static void DisplayContextMenu(MyDocument* doc) + { + if (!ImGui::BeginPopupContextItem()) + return; + + char buf[256]; + sprintf(buf, "Save %s", doc->Name); + if (ImGui::MenuItem(buf, "CTRL+S", false, doc->Open)) + doc->DoSave(); + if (ImGui::MenuItem("Close", "CTRL+W", false, doc->Open)) + doc->DoQueueClose(); + ImGui::EndPopup(); + } +}; + +struct ExampleAppDocuments +{ + ImVector Documents; + + ExampleAppDocuments() + { + Documents.push_back(MyDocument("Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f))); + Documents.push_back(MyDocument("Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f))); + Documents.push_back(MyDocument("Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f))); + Documents.push_back(MyDocument("Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f))); + Documents.push_back(MyDocument("A Rather Long Title", false)); + Documents.push_back(MyDocument("Some Document", false)); + } +}; + +// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface. +// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo, +// as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for +// the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has +// disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively +// give the impression of a flicker for one frame. +// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch. +// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag. +static void NotifyOfDocumentsClosedElsewhere(ExampleAppDocuments& app) +{ + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (!doc->Open && doc->OpenPrev) + ImGui::SetTabItemClosed(doc->Name); + doc->OpenPrev = doc->Open; + } +} + +void ShowExampleAppDocuments(bool* p_open) +{ + static ExampleAppDocuments app; + + // Options + static bool opt_reorderable = true; + static ImGuiTabBarFlags opt_fitting_flags = ImGuiTabBarFlags_FittingPolicyDefault_; + + bool window_contents_visible = ImGui::Begin("Example: Documents", p_open, ImGuiWindowFlags_MenuBar); + if (!window_contents_visible) + { + ImGui::End(); + return; + } + + // Menu + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + int open_count = 0; + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + open_count += app.Documents[doc_n].Open ? 1 : 0; + + if (ImGui::BeginMenu("Open", open_count < app.Documents.Size)) + { + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (!doc->Open) + if (ImGui::MenuItem(doc->Name)) + doc->DoOpen(); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Close All Documents", NULL, false, open_count > 0)) + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + app.Documents[doc_n].DoQueueClose(); + if (ImGui::MenuItem("Exit", "Ctrl+F4") && p_open) + *p_open = false; + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + // [Debug] List documents with one checkbox for each + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (doc_n > 0) + ImGui::SameLine(); + ImGui::PushID(doc); + if (ImGui::Checkbox(doc->Name, &doc->Open)) + if (!doc->Open) + doc->DoForceClose(); + ImGui::PopID(); + } + + ImGui::Separator(); + + // About the ImGuiWindowFlags_UnsavedDocument / ImGuiTabItemFlags_UnsavedDocument flags. + // They have multiple effects: + // - Display a dot next to the title. + // - Tab is selected when clicking the X close button. + // - Closure is not assumed (will wait for user to stop submitting the tab). + // Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar. + // We need to assume closure by default otherwise waiting for "lack of submission" on the next frame would leave an empty + // hole for one-frame, both in the tab-bar and in tab-contents when closing a tab/window. + // The rarely used SetTabItemClosed() function is a way to notify of programmatic closure to avoid the one-frame hole. + + // Submit Tab Bar and Tabs + { + ImGuiTabBarFlags tab_bar_flags = (opt_fitting_flags) | (opt_reorderable ? ImGuiTabBarFlags_Reorderable : 0); + if (ImGui::BeginTabBar("##tabs", tab_bar_flags)) + { + if (opt_reorderable) + NotifyOfDocumentsClosedElsewhere(app); + + // [DEBUG] Stress tests + //if ((ImGui::GetFrameCount() % 30) == 0) docs[1].Open ^= 1; // [DEBUG] Automatically show/hide a tab. Test various interactions e.g. dragging with this on. + //if (ImGui::GetIO().KeyCtrl) ImGui::SetTabItemSelected(docs[1].Name); // [DEBUG] Test SetTabItemSelected(), probably not very useful as-is anyway.. + + // Submit Tabs + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (!doc->Open) + continue; + + ImGuiTabItemFlags tab_flags = (doc->Dirty ? ImGuiTabItemFlags_UnsavedDocument : 0); + bool visible = ImGui::BeginTabItem(doc->Name, &doc->Open, tab_flags); + + // Cancel attempt to close when unsaved add to save queue so we can display a popup. + if (!doc->Open && doc->Dirty) + { + doc->Open = true; + doc->DoQueueClose(); + } + + MyDocument::DisplayContextMenu(doc); + if (visible) + { + MyDocument::DisplayContents(doc); + ImGui::EndTabItem(); + } + } + + ImGui::EndTabBar(); + } + } + + // Update closing queue + static ImVector close_queue; + if (close_queue.empty()) + { + // Close queue is locked once we started a popup + for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) + { + MyDocument* doc = &app.Documents[doc_n]; + if (doc->WantClose) + { + doc->WantClose = false; + close_queue.push_back(doc); + } + } + } + + // Display closing confirmation UI + if (!close_queue.empty()) + { + int close_queue_unsaved_documents = 0; + for (int n = 0; n < close_queue.Size; n++) + if (close_queue[n]->Dirty) + close_queue_unsaved_documents++; + + if (close_queue_unsaved_documents == 0) + { + // Close documents when all are unsaved + for (int n = 0; n < close_queue.Size; n++) + close_queue[n]->DoForceClose(); + close_queue.clear(); + } + else + { + if (!ImGui::IsPopupOpen("Save?")) + ImGui::OpenPopup("Save?"); + if (ImGui::BeginPopupModal("Save?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Save change to the following items?"); + float item_height = ImGui::GetTextLineHeightWithSpacing(); + if (ImGui::BeginChildFrame(ImGui::GetID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height))) + { + for (int n = 0; n < close_queue.Size; n++) + if (close_queue[n]->Dirty) + ImGui::Text("%s", close_queue[n]->Name); + } + ImGui::EndChildFrame(); + + ImVec2 button_size(ImGui::GetFontSize() * 7.0f, 0.0f); + if (ImGui::Button("Yes", button_size)) + { + for (int n = 0; n < close_queue.Size; n++) + { + if (close_queue[n]->Dirty) + close_queue[n]->DoSave(); + close_queue[n]->DoForceClose(); + } + close_queue.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("No", button_size)) + { + for (int n = 0; n < close_queue.Size; n++) + close_queue[n]->DoForceClose(); + close_queue.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::SameLine(); + if (ImGui::Button("Cancel", button_size)) + { + close_queue.clear(); + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + } + } + + ImGui::End(); +} + +// End of Demo code +#else + +void ImGui::ShowAboutWindow(bool*) {} +void ImGui::ShowDemoWindow(bool*) {} +void ImGui::ShowUserGuide() {} +void ImGui::ShowStyleEditor(ImGuiStyle*) {} + +#endif + +#endif // #ifndef IMGUI_DISABLE diff --git a/Externals/imgui/imgui_draw.cpp b/Externals/imgui/imgui_draw.cpp index 30b100bbe0..a50255b595 100644 --- a/Externals/imgui/imgui_draw.cpp +++ b/Externals/imgui/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.85 +// dear imgui, v1.89.7 // (drawing and font code) /* @@ -26,38 +26,24 @@ Index of this file: #define _CRT_SECURE_NO_WARNINGS #endif -#include "imgui.h" -#ifndef IMGUI_DISABLE - #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS #endif +#include "imgui.h" +#ifndef IMGUI_DISABLE #include "imgui_internal.h" #ifdef IMGUI_ENABLE_FREETYPE #include "misc/freetype/imgui_freetype.h" #endif #include // vsnprintf, sscanf, printf -#if !defined(alloca) -#if defined(__GLIBC__) || defined(__sun) || defined(__APPLE__) || defined(__NEWLIB__) -#include // alloca (glibc uses . Note that Cygwin may have _WIN32 defined, so the order matters here) -#elif defined(_WIN32) -#include // alloca -#if !defined(alloca) -#define alloca _alloca // for clang with MS Codegen -#endif -#else -#include // alloca -#endif -#endif // Visual Studio warnings #ifdef _MSC_VER #pragma warning (disable: 4127) // condition expression is constant #pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen -#pragma warning (disable: 6255) // [Static Analyzer] _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead. #pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2). #pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer) #endif @@ -67,9 +53,6 @@ Index of this file: #if __has_warning("-Wunknown-warning-option") #pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great! #endif -#if __has_warning("-Walloca") -#pragma clang diagnostic ignored "-Walloca" // warning: use of function '__builtin_alloca' is discouraged -#endif #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok. @@ -90,7 +73,7 @@ Index of this file: #endif //------------------------------------------------------------------------- -// [SECTION] STB libraries implementation +// [SECTION] STB libraries implementation (for stb_truetype and stb_rect_pack) //------------------------------------------------------------------------- // Compile time options: @@ -393,7 +376,7 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error) for (int i = 0; i < IM_ARRAYSIZE(CircleSegmentCounts); i++) { const float radius = (float)i; - CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : 0); + CircleSegmentCounts[i] = (ImU8)((i > 0) ? IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, CircleSegmentMaxError) : IM_DRAWLIST_ARCFAST_SAMPLE_MAX); } ArcFastRadiusCutoff = IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(IM_DRAWLIST_ARCFAST_SAMPLE_MAX, CircleSegmentMaxError); } @@ -402,10 +385,11 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error) void ImDrawList::_ResetForNewFrame() { // Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory. - // (those should be IM_STATIC_ASSERT() in theory but with our pre C++11 setup the whole check doesn't compile with GCC) - IM_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0); - IM_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4)); - IM_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID)); + IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0); + IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4)); + IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID)); + if (_Splitter._Count > 1) + _Splitter.Merge(this); CmdBuffer.resize(0); IdxBuffer.resize(0); @@ -464,15 +448,18 @@ void ImDrawList::AddDrawCmd() // Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL void ImDrawList::_PopUnusedDrawCmd() { - if (CmdBuffer.Size == 0) - return; - ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; - if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL) + while (CmdBuffer.Size > 0) + { + ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; + if (curr_cmd->ElemCount != 0 || curr_cmd->UserCallback != NULL) + return;// break; CmdBuffer.pop_back(); + } } void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) { + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; IM_ASSERT(curr_cmd->UserCallback == NULL); if (curr_cmd->ElemCount != 0) @@ -487,16 +474,18 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) } // Compare ClipRect, TextureId and VtxOffset with a single memcmp() -#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int)) -#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset -#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset +#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int)) +#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset +#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset +#define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset) // Try to merge two last draw commands void ImDrawList::_TryMergeDrawCmds() { + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; ImDrawCmd* prev_cmd = curr_cmd - 1; - if (ImDrawCmd_HeaderCompare(curr_cmd, prev_cmd) == 0 && curr_cmd->UserCallback == NULL && prev_cmd->UserCallback == NULL) + if (ImDrawCmd_HeaderCompare(curr_cmd, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && curr_cmd->UserCallback == NULL && prev_cmd->UserCallback == NULL) { prev_cmd->ElemCount += curr_cmd->ElemCount; CmdBuffer.pop_back(); @@ -508,6 +497,7 @@ void ImDrawList::_TryMergeDrawCmds() void ImDrawList::_OnChangedClipRect() { // If current command is used with different settings we need to add a new command + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; if (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &_CmdHeader.ClipRect, sizeof(ImVec4)) != 0) { @@ -518,7 +508,7 @@ void ImDrawList::_OnChangedClipRect() // Try to merge with previous command if it matches, else use current command ImDrawCmd* prev_cmd = curr_cmd - 1; - if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && prev_cmd->UserCallback == NULL) + if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && prev_cmd->UserCallback == NULL) { CmdBuffer.pop_back(); return; @@ -530,6 +520,7 @@ void ImDrawList::_OnChangedClipRect() void ImDrawList::_OnChangedTextureID() { // If current command is used with different settings we need to add a new command + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; if (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != _CmdHeader.TextureId) { @@ -540,7 +531,7 @@ void ImDrawList::_OnChangedTextureID() // Try to merge with previous command if it matches, else use current command ImDrawCmd* prev_cmd = curr_cmd - 1; - if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && prev_cmd->UserCallback == NULL) + if (curr_cmd->ElemCount == 0 && CmdBuffer.Size > 1 && ImDrawCmd_HeaderCompare(&_CmdHeader, prev_cmd) == 0 && ImDrawCmd_AreSequentialIdxOffset(prev_cmd, curr_cmd) && prev_cmd->UserCallback == NULL) { CmdBuffer.pop_back(); return; @@ -553,6 +544,7 @@ void ImDrawList::_OnChangedVtxOffset() { // We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this. _VtxCurrentIdx = 0; + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; //IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset); // See #3349 if (curr_cmd->ElemCount != 0) @@ -575,7 +567,7 @@ int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const } // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) -void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect) +void ImDrawList::PushClipRect(const ImVec2& cr_min, const ImVec2& cr_max, bool intersect_with_current_clip_rect) { ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y); if (intersect_with_current_clip_rect) @@ -715,7 +707,7 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c // We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds. void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness) { - if (points_count < 2) + if (points_count < 2 || (col & IM_COL32_A_MASK) == 0) return; const bool closed = (flags & ImDrawFlags_Closed) != 0; @@ -748,7 +740,8 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 // Temporary buffer // The first items are normals at each line point, then after that there are either 2 or 4 temp points for each line point - ImVec2* temp_normals = (ImVec2*)alloca(points_count * ((use_texture || !thick_line) ? 3 : 5) * sizeof(ImVec2)); //-V630 + _Data->TempBuffer.reserve_discard(points_count * ((use_texture || !thick_line) ? 3 : 5)); + ImVec2* temp_normals = _Data->TempBuffer.Data; ImVec2* temp_points = temp_normals + points_count; // Calculate normals (tangents) for each line segment @@ -968,10 +961,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 } } -// We intentionally avoid using ImVec2 and its math operators here to reduce cost to a minimum for debug/non-inlined builds. +// - We intentionally avoid using ImVec2 and its math operators here to reduce cost to a minimum for debug/non-inlined builds. +// - Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing. void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col) { - if (points_count < 3) + if (points_count < 3 || (col & IM_COL32_A_MASK) == 0) return; const ImVec2 uv = _Data->TexUvWhitePixel; @@ -995,7 +989,8 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun } // Compute normals - ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); //-V630 + _Data->TempBuffer.reserve_discard(points_count); + ImVec2* temp_normals = _Data->TempBuffer.Data; for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) { const ImVec2& p0 = points[i0]; @@ -1052,7 +1047,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_sample, int a_max_sample, int a_step) { - if (radius <= 0.0f) + if (radius < 0.5f) { _Path.push_back(center); return; @@ -1144,7 +1139,7 @@ void ImDrawList::_PathArcToFastEx(const ImVec2& center, float radius, int a_min_ void ImDrawList::_PathArcToN(const ImVec2& center, float radius, float a_min, float a_max, int num_segments) { - if (radius <= 0.0f) + if (radius < 0.5f) { _Path.push_back(center); return; @@ -1163,7 +1158,7 @@ void ImDrawList::_PathArcToN(const ImVec2& center, float radius, float a_min, fl // 0: East, 3: South, 6: West, 9: North, 12: East void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12) { - if (radius <= 0.0f) + if (radius < 0.5f) { _Path.push_back(center); return; @@ -1173,7 +1168,7 @@ void ImDrawList::PathArcToFast(const ImVec2& center, float radius, int a_min_of_ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments) { - if (radius <= 0.0f) + if (radius < 0.5f) { _Path.push_back(center); return; @@ -1201,8 +1196,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; - const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f; - const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f; + const bool a_emit_start = ImAbs(a_min_segment_angle - a_min) >= 1e-5f; + const bool a_emit_end = ImAbs(a_max - a_max_segment_angle) >= 1e-5f; _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0))); if (a_emit_start) @@ -1289,6 +1284,7 @@ void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, cons ImVec2 p1 = _Path.back(); if (num_segments == 0) { + IM_ASSERT(_Data->CurveTessellationTol > 0.0f); PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated } else @@ -1304,6 +1300,7 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, ImVec2 p1 = _Path.back(); if (num_segments == 0) { + IM_ASSERT(_Data->CurveTessellationTol > 0.0f); PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, _Data->CurveTessellationTol, 0);// Auto-tessellated } else @@ -1318,6 +1315,7 @@ IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4)); static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags) { #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // Obsoleted in 1.82 (from February 2021) // Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All) // ~0 --> ImDrawFlags_RoundCornersAll or 0 if (flags == ~0) @@ -1354,7 +1352,7 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDr rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f ) - 1.0f); rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f ) - 1.0f); - if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) + if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) { PathLineTo(a); PathLineTo(ImVec2(b.x, a.y)); @@ -1400,7 +1398,7 @@ void ImDrawList::AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 c { if ((col & IM_COL32_A_MASK) == 0) return; - if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) + if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) { PrimReserve(6, 4); PrimRect(p_min, p_max, col); @@ -1476,7 +1474,7 @@ void ImDrawList::AddTriangleFilled(const ImVec2& p1, const ImVec2& p2, const ImV void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness) { - if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f) + if ((col & IM_COL32_A_MASK) == 0 || radius < 0.5f) return; if (num_segments <= 0) @@ -1500,7 +1498,7 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments) { - if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f) + if ((col & IM_COL32_A_MASK) == 0 || radius < 0.5f) return; if (num_segments <= 0) @@ -1640,7 +1638,7 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_mi return; flags = FixRectCornerFlags(flags); - if (rounding <= 0.0f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) + if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone) { AddImage(user_texture_id, p_min, p_max, uv_min, uv_max, col); return; @@ -1728,13 +1726,13 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list) for (int i = 1; i < _Count; i++) { ImDrawChannel& ch = _Channels[i]; - - // Equivalent of PopUnusedDrawCmd() for this channel's cmdbuffer and except we don't need to test for UserCallback. - if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0) + if (ch._CmdBuffer.Size > 0 && ch._CmdBuffer.back().ElemCount == 0 && ch._CmdBuffer.back().UserCallback == NULL) // Equivalent of PopUnusedDrawCmd() ch._CmdBuffer.pop_back(); if (ch._CmdBuffer.Size > 0 && last_cmd != NULL) { + // Do not include ImDrawCmd_AreSequentialIdxOffset() in the compare as we rebuild IdxOffset values ourselves. + // Manipulating IdxOffset (e.g. by reordering draw commands like done by RenderDimmedBackgroundBehindWindow()) is not supported within a splitter. ImDrawCmd* next_cmd = &ch._CmdBuffer[0]; if (ImDrawCmd_HeaderCompare(last_cmd, next_cmd) == 0 && last_cmd->UserCallback == NULL && next_cmd->UserCallback == NULL) { @@ -1919,37 +1917,38 @@ ImFontConfig::ImFontConfig() // A work of art lies ahead! (. = white layer, X = black layer, others are blank) // The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes. -const int FONT_ATLAS_DEFAULT_TEX_DATA_W = 108; // Actual texture will be 2 times that + 1 spacing. +// (This is used when io.MouseDrawCursor = true) +const int FONT_ATLAS_DEFAULT_TEX_DATA_W = 122; // Actual texture will be 2 times that + 1 spacing. const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = { - "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX " - "..- -X.....X- X.X - X.X -X.....X - X.....X- X..X " - "--- -XXX.XXX- X...X - X...X -X....X - X....X- X..X " - "X - X.X - X.....X - X.....X -X...X - X...X- X..X " - "XX - X.X -X.......X- X.......X -X..X.X - X.X..X- X..X " - "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X- X..XXX " - "X..X - X.X - X.X - X.X -XX X.X - X.X XX- X..X..XXX " - "X...X - X.X - X.X - XX X.X XX - X.X - X.X - X..X..X..XX " - "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X - X..X..X..X.X " - "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X -XXX X..X..X..X..X" - "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X -X..XX........X..X" - "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X -X...X...........X" - "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X - X..............X" - "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X - X.............X" - "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X - X.............X" - "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X - X............X" - "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX - X...........X " - "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------- X..........X " - "X.X X..X - -X.......X- X.......X - XX XX - - X..........X " - "XX X..X - - X.....X - X.....X - X.X X.X - - X........X " - " X..X - X...X - X...X - X..X X..X - - X........X " - " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - - XXXXXXXXXX " - "------------ - X - X -X.....................X- ------------------" - " ----------------------------------- X...XXXXXXXXXXXXX...X - " - " - X..X X..X - " - " - X.X X.X - " - " - XX XX - " + "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX- XX - XX XX " + "..- -X.....X- X.X - X.X -X.....X - X.....X- X..X -X..X X..X" + "--- -XXX.XXX- X...X - X...X -X....X - X....X- X..X -X...X X...X" + "X - X.X - X.....X - X.....X -X...X - X...X- X..X - X...X X...X " + "XX - X.X -X.......X- X.......X -X..X.X - X.X..X- X..X - X...X...X " + "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X- X..XXX - X.....X " + "X..X - X.X - X.X - X.X -XX X.X - X.X XX- X..X..XXX - X...X " + "X...X - X.X - X.X - XX X.X XX - X.X - X.X - X..X..X..XX - X.X " + "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X - X..X..X..X.X - X...X " + "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X -XXX X..X..X..X..X- X.....X " + "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X -X..XX........X..X- X...X...X " + "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X -X...X...........X- X...X X...X " + "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X - X..............X-X...X X...X" + "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X - X.............X-X..X X..X" + "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X - X.............X- XX XX " + "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X - X............X--------------" + "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX - X...........X - " + "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------- X..........X - " + "X.X X..X - -X.......X- X.......X - XX XX - - X..........X - " + "XX X..X - - X.....X - X.....X - X.X X.X - - X........X - " + " X..X - - X...X - X...X - X..X X..X - - X........X - " + " XX - - X.X - X.X - X...XXXXXXXXXXXXX...X - - XXXXXXXXXX - " + "------------- - X - X -X.....................X- ------------------- " + " ----------------------------------- X...XXXXXXXXXXXXX...X - " + " - X..X X..X - " + " - X.X X.X - " + " - XX XX - " }; static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3] = @@ -1963,6 +1962,7 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3 { ImVec2(73,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNESW { ImVec2(55,0), ImVec2(17,17), ImVec2( 8, 8) }, // ImGuiMouseCursor_ResizeNWSE { ImVec2(91,0), ImVec2(17,22), ImVec2( 5, 0) }, // ImGuiMouseCursor_Hand + { ImVec2(109,0),ImVec2(13,15), ImVec2( 6, 7) }, // ImGuiMouseCursor_NotAllowed }; ImFontAtlas::ImFontAtlas() @@ -2290,10 +2290,11 @@ void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], fl void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride) { + IM_ASSERT_PARANOID(w <= stride); unsigned char* data = pixels + x + y * stride; - for (int j = h; j > 0; j--, data += stride) - for (int i = 0; i < w; i++) - data[i] = table[data[i]]; + for (int j = h; j > 0; j--, data += stride - w) + for (int i = w; i > 0; i--, data++) + *data = table[*data]; } #ifdef IMGUI_ENABLE_STB_TRUETYPE @@ -2310,7 +2311,7 @@ struct ImFontBuildSrcData int GlyphsHighest; // Highest requested codepoint int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font) ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB) - ImVector GlyphsList; // Glyph codepoints list (flattened version of GlyphsMap) + ImVector GlyphsList; // Glyph codepoints list (flattened version of GlyphsSet) }; // Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont) @@ -2382,7 +2383,12 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex]; src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault(); for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2) + { + // Check for valid range. This may also help detect *some* dangling pointers, because a common + // user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent. + IM_ASSERT(src_range[0] <= src_range[1]); src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]); + } dst_tmp.SrcCount++; dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest); } @@ -2547,13 +2553,10 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) // 9. Setup ImFont and glyphs for runtime for (int src_i = 0; src_i < src_tmp_array.Size; src_i++) { - ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; - if (src_tmp.GlyphsCount == 0) - continue; - // When merging fonts with MergeMode=true: // - We can have multiple input fonts writing into a same destination font. // - dst_font->ConfigData is != from cfg which is our source configuration. + ImFontBuildSrcData& src_tmp = src_tmp_array[src_i]; ImFontConfig& cfg = atlas->ConfigData[src_i]; ImFont* dst_font = cfg.DstFont; @@ -2617,6 +2620,9 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa ImVector& user_rects = atlas->CustomRects; IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong. +#ifdef __GNUC__ + if (user_rects.Size < 1) { __builtin_unreachable(); } // Workaround for GCC bug if IM_ASSERT() is defined to conditionally throw (see #5343) +#endif ImVector pack_rects; pack_rects.resize(user_rects.Size); @@ -2630,8 +2636,8 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa for (int i = 0; i < pack_rects.Size; i++) if (pack_rects[i].was_packed) { - user_rects[i].X = pack_rects[i].x; - user_rects[i].Y = pack_rects[i].y; + user_rects[i].X = (unsigned short)pack_rects[i].x; + user_rects[i].Y = (unsigned short)pack_rects[i].y; IM_ASSERT(pack_rects[i].w == user_rects[i].Width && pack_rects[i].h == user_rects[i].Height); atlas->TexHeight = ImMax(atlas->TexHeight, pack_rects[i].y + pack_rects[i].h); } @@ -2731,13 +2737,13 @@ static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas) { unsigned int* write_ptr = &atlas->TexPixelsRGBA32[r->X + ((r->Y + y) * atlas->TexWidth)]; for (unsigned int i = 0; i < pad_left; i++) - *(write_ptr + i) = IM_COL32_BLACK_TRANS; + *(write_ptr + i) = IM_COL32(255, 255, 255, 0); for (unsigned int i = 0; i < line_width; i++) *(write_ptr + pad_left + i) = IM_COL32_WHITE; for (unsigned int i = 0; i < pad_right; i++) - *(write_ptr + pad_left + line_width + i) = IM_COL32_BLACK_TRANS; + *(write_ptr + pad_left + line_width + i) = IM_COL32(255, 255, 255, 0); } // Calculate UVs for this line @@ -2810,6 +2816,17 @@ const ImWchar* ImFontAtlas::GetGlyphRangesDefault() return &ranges[0]; } +const ImWchar* ImFontAtlas::GetGlyphRangesGreek() +{ + static const ImWchar ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x0370, 0x03FF, // Greek and Coptic + 0, + }; + return &ranges[0]; +} + const ImWchar* ImFontAtlas::GetGlyphRangesKorean() { static const ImWchar ranges[] = @@ -2926,19 +2943,19 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() // 2999 ideograms code points for Japanese // - 2136 Joyo (meaning "for regular use" or "for common use") Kanji code points // - 863 Jinmeiyo (meaning "for personal name") Kanji code points - // - Sourced from the character information database of the Information-technology Promotion Agency, Japan - // - https://mojikiban.ipa.go.jp/mji/ - // - Available under the terms of the Creative Commons Attribution-ShareAlike 2.1 Japan (CC BY-SA 2.1 JP). - // - https://creativecommons.org/licenses/by-sa/2.1/jp/deed.en - // - https://creativecommons.org/licenses/by-sa/2.1/jp/legalcode - // - You can generate this code by the script at: - // - https://github.com/vaiorabbit/everyday_use_kanji + // - Sourced from official information provided by the government agencies of Japan: + // - List of Joyo Kanji by the Agency for Cultural Affairs + // - https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kijun/naikaku/kanji/ + // - List of Jinmeiyo Kanji by the Ministry of Justice + // - http://www.moj.go.jp/MINJI/minji86.html + // - Available under the terms of the Creative Commons Attribution 4.0 International (CC BY 4.0). + // - https://creativecommons.org/licenses/by/4.0/legalcode + // - You can generate this code by the script at: + // - https://github.com/vaiorabbit/everyday_use_kanji // - References: // - List of Joyo Kanji - // - (Official list by the Agency for Cultural Affairs) https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kakuki/14/tosin02/index.html // - (Wikipedia) https://en.wikipedia.org/wiki/List_of_j%C5%8Dy%C5%8D_kanji // - List of Jinmeiyo Kanji - // - (Official list by the Ministry of Justice) http://www.moj.go.jp/MINJI/minji86.html // - (Wikipedia) https://en.wikipedia.org/wiki/Jinmeiy%C5%8D_kanji // - Missing 1 Joyo Kanji: U+20B9F (Kun'yomi: Shikaru, On'yomi: Shitsu,shichi), see https://github.com/ocornut/imgui/pull/3627 for details. // You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters. @@ -3073,8 +3090,8 @@ void ImFontGlyphRangesBuilder::AddText(const char* text, const char* text_end) void ImFontGlyphRangesBuilder::AddRanges(const ImWchar* ranges) { for (; ranges[0]; ranges += 2) - for (ImWchar c = ranges[0]; c <= ranges[1]; c++) - AddChar(c); + for (unsigned int c = ranges[0]; c <= ranges[1] && c <= IM_UNICODE_CODEPOINT_MAX; c++) //-V560 + AddChar((ImWchar)c); } void ImFontGlyphRangesBuilder::BuildRanges(ImVector* out_ranges) @@ -3101,7 +3118,8 @@ ImFont::ImFont() FallbackAdvanceX = 0.0f; FallbackChar = (ImWchar)-1; EllipsisChar = (ImWchar)-1; - DotChar = (ImWchar)-1; + EllipsisWidth = EllipsisCharStep = 0.0f; + EllipsisCharCount = 0; FallbackGlyph = NULL; ContainerAtlas = NULL; ConfigData = NULL; @@ -3182,17 +3200,7 @@ void ImFont::BuildLookupTable() SetGlyphVisible((ImWchar)' ', false); SetGlyphVisible((ImWchar)'\t', false); - // Ellipsis character is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis). - // However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character. - // FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots. - const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 }; - const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E }; - if (EllipsisChar == (ImWchar)-1) - EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars)); - if (DotChar == (ImWchar)-1) - DotChar = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars)); - - // Setup fallback character + // Setup Fallback character const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' }; FallbackGlyph = FindGlyphNoFallback(FallbackChar); if (FallbackGlyph == NULL) @@ -3205,11 +3213,32 @@ void ImFont::BuildLookupTable() FallbackChar = (ImWchar)FallbackGlyph->Codepoint; } } - FallbackAdvanceX = FallbackGlyph->AdvanceX; for (int i = 0; i < max_codepoint + 1; i++) if (IndexAdvanceX[i] < 0.0f) IndexAdvanceX[i] = FallbackAdvanceX; + + // Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis). + // However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character. + // FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots. + const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 }; + const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E }; + if (EllipsisChar == (ImWchar)-1) + EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars)); + const ImWchar dot_char = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars)); + if (EllipsisChar != (ImWchar)-1) + { + EllipsisCharCount = 1; + EllipsisWidth = EllipsisCharStep = FindGlyph(EllipsisChar)->X1; + } + else if (dot_char != (ImWchar)-1) + { + const ImFontGlyph* glyph = FindGlyph(dot_char); + EllipsisChar = dot_char; + EllipsisCharCount = 3; + EllipsisCharStep = (glyph->X1 - glyph->X0) + 1.0f; + EllipsisWidth = EllipsisCharStep * 3.0f - 1.0f; + } } // API is designed this way to avoid exposing the 4K page size @@ -3322,11 +3351,21 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const return &Glyphs.Data[i]; } +// Wrapping skips upcoming blanks +static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end) +{ + while (text < text_end && ImCharIsBlankA(*text)) + text++; + if (*text == '\n') + text++; + return text; +} + +// Simple word-wrapping for English, not full-featured. Please submit failing cases! +// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end. +// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const { - // Simple word-wrapping for English, not full-featured. Please submit failing cases! - // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) - // For references, possible wrap point marked with ^ // "aaa bbb, ccc,ddd. eee fff. ggg!" // ^ ^ ^ ^ ^__ ^ ^ @@ -3338,7 +3377,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c // Cut words that cannot possibly fit within one line. // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish" - float line_width = 0.0f; float word_width = 0.0f; float blank_width = 0.0f; @@ -3349,6 +3387,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c bool inside_word = true; const char* s = text; + IM_ASSERT(text_end != NULL); while (s < text_end) { unsigned int c = (unsigned int)*s; @@ -3357,8 +3396,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c next_s = s + 1; else next_s = s + ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) - break; if (c < 32) { @@ -3418,6 +3455,10 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c s = next_s; } + // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. + // +1 may not be a character start point in UTF-8 but it's ok because caller loops use (text >= word_wrap_eol). + if (s == text && text < text_end) + return s + 1; return s; } @@ -3442,11 +3483,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons { // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. if (!word_wrap_eol) - { word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width); - if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. - word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below - } if (s >= word_wrap_eol) { @@ -3455,13 +3492,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons text_size.y += line_height; line_width = 0.0f; word_wrap_eol = NULL; - - // Wrapping skips upcoming blanks - while (s < text_end) - { - const char c = *s; - if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } - } + s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks continue; } } @@ -3470,15 +3501,9 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons const char* prev_s = s; unsigned int c = (unsigned int)*s; if (c < 0x80) - { s += 1; - } else - { s += ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) // Malformed UTF-8? - break; - } if (c < 32) { @@ -3516,7 +3541,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons } // Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. -void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const +void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c) const { const ImFontGlyph* glyph = FindGlyph(c); if (!glyph || !glyph->Visible) @@ -3524,38 +3549,47 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col if (glyph->Colored) col |= ~IM_COL32_A_MASK; float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; - pos.x = IM_FLOOR(pos.x); - pos.y = IM_FLOOR(pos.y); + float x = IM_FLOOR(pos.x); + float y = IM_FLOOR(pos.y); draw_list->PrimReserve(6, 4); - draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); + draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); } // Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound. -void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const +void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const { if (!text_end) text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls. // Align to be pixel perfect - pos.x = IM_FLOOR(pos.x); - pos.y = IM_FLOOR(pos.y); - float x = pos.x; - float y = pos.y; + float x = IM_FLOOR(pos.x); + float y = IM_FLOOR(pos.y); if (y > clip_rect.w) return; + const float start_x = x; const float scale = size / FontSize; const float line_height = FontSize * scale; const bool word_wrap_enabled = (wrap_width > 0.0f); - const char* word_wrap_eol = NULL; // Fast-forward to first visible line const char* s = text_begin; - if (y + line_height < clip_rect.y && !word_wrap_enabled) + if (y + line_height < clip_rect.y) while (y + line_height < clip_rect.y && s < text_end) { - s = (const char*)memchr(s, '\n', text_end - s); - s = s ? s + 1 : text_end; + const char* line_end = (const char*)memchr(s, '\n', text_end - s); + if (word_wrap_enabled) + { + // FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA(). + // If the specs for CalcWordWrapPositionA() were reworked to optionally return on \n we could combine both. + // However it is still better than nothing performing the fast-forward! + s = CalcWordWrapPositionA(scale, s, line_end ? line_end : text_end, wrap_width); + s = CalcWordWrapNextLineStartA(s, text_end); + } + else + { + s = line_end ? line_end + 1 : text_end; + } y += line_height; } @@ -3581,12 +3615,12 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col const int idx_count_max = (int)(text_end - s) * 6; const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max; draw_list->PrimReserve(idx_count_max, vtx_count_max); - - ImDrawVert* vtx_write = draw_list->_VtxWritePtr; - ImDrawIdx* idx_write = draw_list->_IdxWritePtr; - unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx; + ImDrawVert* vtx_write = draw_list->_VtxWritePtr; + ImDrawIdx* idx_write = draw_list->_IdxWritePtr; + unsigned int vtx_index = draw_list->_VtxCurrentIdx; const ImU32 col_untinted = col | ~IM_COL32_A_MASK; + const char* word_wrap_eol = NULL; while (s < text_end) { @@ -3594,24 +3628,14 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col { // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. if (!word_wrap_eol) - { - word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - pos.x)); - if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. - word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below - } + word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - start_x)); if (s >= word_wrap_eol) { - x = pos.x; + x = start_x; y += line_height; word_wrap_eol = NULL; - - // Wrapping skips upcoming blanks - while (s < text_end) - { - const char c = *s; - if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } - } + s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks continue; } } @@ -3619,21 +3643,15 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col // Decode and advance source unsigned int c = (unsigned int)*s; if (c < 0x80) - { s += 1; - } else - { s += ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) // Malformed UTF-8? - break; - } if (c < 32) { if (c == '\n') { - x = pos.x; + x = start_x; y += line_height; if (y > clip_rect.w) break; // break out of main loop @@ -3698,14 +3716,14 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here: { - idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); - idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = glyph_col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1; vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = glyph_col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1; vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = glyph_col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2; vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = glyph_col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2; + idx_write[0] = (ImDrawIdx)(vtx_index); idx_write[1] = (ImDrawIdx)(vtx_index + 1); idx_write[2] = (ImDrawIdx)(vtx_index + 2); + idx_write[3] = (ImDrawIdx)(vtx_index); idx_write[4] = (ImDrawIdx)(vtx_index + 2); idx_write[5] = (ImDrawIdx)(vtx_index + 3); vtx_write += 4; - vtx_current_idx += 4; + vtx_index += 4; idx_write += 6; } } @@ -3719,7 +3737,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size); draw_list->_VtxWritePtr = vtx_write; draw_list->_IdxWritePtr = idx_write; - draw_list->_VtxCurrentIdx = vtx_current_idx; + draw_list->_VtxCurrentIdx = vtx_index; } //----------------------------------------------------------------------------- @@ -3729,7 +3747,6 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col // - RenderArrow() // - RenderBullet() // - RenderCheckMark() -// - RenderMouseCursor() // - RenderArrowPointingAt() // - RenderRectFilledRangeH() // - RenderRectFilledWithHole() @@ -3772,6 +3789,7 @@ void ImGui::RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir d void ImGui::RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col) { + // FIXME-OPT: This should be baked in font. draw_list->AddCircleFilled(pos, draw_list->_Data->FontSize * 0.20f, col, 8); } @@ -3790,27 +3808,6 @@ void ImGui::RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float draw_list->PathStroke(col, 0, thickness); } -void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow) -{ - if (mouse_cursor == ImGuiMouseCursor_None) - return; - IM_ASSERT(mouse_cursor > ImGuiMouseCursor_None && mouse_cursor < ImGuiMouseCursor_COUNT); - - ImFontAtlas* font_atlas = draw_list->_Data->Font->ContainerAtlas; - ImVec2 offset, size, uv[4]; - if (font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2])) - { - pos -= offset; - ImTextureID tex_id = font_atlas->TexID; - draw_list->PushTextureID(tex_id); - draw_list->AddImage(tex_id, pos + ImVec2(1, 0) * scale, pos + (ImVec2(1, 0) + size) * scale, uv[2], uv[3], col_shadow); - draw_list->AddImage(tex_id, pos + ImVec2(2, 0) * scale, pos + (ImVec2(2, 0) + size) * scale, uv[2], uv[3], col_shadow); - draw_list->AddImage(tex_id, pos, pos + size * scale, uv[2], uv[3], col_border); - draw_list->AddImage(tex_id, pos, pos + size * scale, uv[0], uv[1], col_fill); - draw_list->PopTextureID(); - } -} - // Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side. void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col) { @@ -3893,16 +3890,16 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im draw_list->PathFillConvex(col); } -void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding) +void ImGui::RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer, const ImRect& inner, ImU32 col, float rounding) { const bool fill_L = (inner.Min.x > outer.Min.x); const bool fill_R = (inner.Max.x < outer.Max.x); const bool fill_U = (inner.Min.y > outer.Min.y); const bool fill_D = (inner.Max.y < outer.Max.y); - if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomLeft)); - if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, (fill_U ? 0 : ImDrawFlags_RoundCornersTopRight) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomRight)); - if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, (fill_L ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersTopRight)); - if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, (fill_L ? 0 : ImDrawFlags_RoundCornersBottomLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersBottomRight)); + if (fill_L) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Min.y), ImVec2(inner.Min.x, inner.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_U ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomLeft)); + if (fill_R) draw_list->AddRectFilled(ImVec2(inner.Max.x, inner.Min.y), ImVec2(outer.Max.x, inner.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_U ? 0 : ImDrawFlags_RoundCornersTopRight) | (fill_D ? 0 : ImDrawFlags_RoundCornersBottomRight)); + if (fill_U) draw_list->AddRectFilled(ImVec2(inner.Min.x, outer.Min.y), ImVec2(inner.Max.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_L ? 0 : ImDrawFlags_RoundCornersTopLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersTopRight)); + if (fill_D) draw_list->AddRectFilled(ImVec2(inner.Min.x, inner.Max.y), ImVec2(inner.Max.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersNone | (fill_L ? 0 : ImDrawFlags_RoundCornersBottomLeft) | (fill_R ? 0 : ImDrawFlags_RoundCornersBottomRight)); if (fill_L && fill_U) draw_list->AddRectFilled(ImVec2(outer.Min.x, outer.Min.y), ImVec2(inner.Min.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopLeft); if (fill_R && fill_U) draw_list->AddRectFilled(ImVec2(inner.Max.x, outer.Min.y), ImVec2(outer.Max.x, inner.Min.y), col, rounding, ImDrawFlags_RoundCornersTopRight); if (fill_L && fill_D) draw_list->AddRectFilled(ImVec2(outer.Min.x, inner.Max.y), ImVec2(inner.Min.x, outer.Max.y), col, rounding, ImDrawFlags_RoundCornersBottomLeft); diff --git a/Externals/imgui/imgui_internal.h b/Externals/imgui/imgui_internal.h index fa5dec3e2f..30990481d8 100644 --- a/Externals/imgui/imgui_internal.h +++ b/Externals/imgui/imgui_internal.h @@ -1,10 +1,12 @@ -// dear imgui, v1.85 +// dear imgui, v1.89.7 // (internal structures/api) -// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! -// Set: -// #define IMGUI_DEFINE_MATH_OPERATORS -// To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators) +// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. +// To implement maths operators for ImVec2 (disabled by default to not conflict with using IM_VEC2_CLASS_EXTRA with your own math types+operators), use: +/* +#define IMGUI_DEFINE_MATH_OPERATORS +#include "imgui_internal.h" +*/ /* @@ -18,12 +20,15 @@ Index of this file: // [SECTION] Generic helpers // [SECTION] ImDrawList support // [SECTION] Widgets support: flags, enums, data structures +// [SECTION] Inputs support +// [SECTION] Clipper support // [SECTION] Navigation support // [SECTION] Columns support // [SECTION] Multi-select support // [SECTION] Docking support // [SECTION] Viewport support // [SECTION] Settings support +// [SECTION] Localization support // [SECTION] Metrics, Debug tools // [SECTION] Generic context hooks // [SECTION] ImGuiContext (main imgui context) @@ -53,7 +58,7 @@ Index of this file: #include // INT_MIN, INT_MAX // Enable SSE intrinsics if available -#if (defined __SSE__ || defined __x86_64__ || defined _M_X64) && !defined(IMGUI_DISABLE_SSE) +#if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE) #define IMGUI_ENABLE_SSE #include #endif @@ -90,6 +95,12 @@ Index of this file: #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #endif +// In 1.89.4, we moved the implementation of "courtesy maths operators" from imgui_internal.h in imgui.h +// As they are frequently requested, we do not want to encourage to many people using imgui_internal.h +#if defined(IMGUI_DEFINE_MATH_OPERATORS) && !defined(IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED) +#error Please '#define IMGUI_DEFINE_MATH_OPERATORS' _BEFORE_ including imgui.h! +#endif + // Legacy defines #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Renamed in 1.74 #error Use IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS @@ -115,10 +126,13 @@ struct ImDrawListSharedData; // Data shared between all ImDrawList instan struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiContext; // Main Dear ImGui context struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine +struct ImGuiDataVarInfo; // Variable information (e.g. to avoid style variables from an enum) struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box +struct ImGuiInputTextDeactivateData;// Short term storage to backup text of a deactivating InputText() while another is stealing active id struct ImGuiLastItemData; // Status storage for last submitted items +struct ImGuiLocEntry; // A localization entry. struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions @@ -134,6 +148,7 @@ struct ImGuiTabBar; // Storage for a tab bar struct ImGuiTabItem; // Storage for a tab item (within a tab bar) struct ImGuiTable; // Storage for a table struct ImGuiTableColumn; // Storage for one column of a table +struct ImGuiTableInstanceData; // Storage for one instance of a same table struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables. struct ImGuiTableSettings; // Storage for a table .ini settings struct ImGuiTableColumnsSettings; // Storage for a column .ini settings @@ -141,14 +156,20 @@ struct ImGuiWindow; // Storage for one window struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window) struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session) +// Enumerations // Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. +enum ImGuiLocKey : int; // -> enum ImGuiLocKey // Enum: a localization entry for translation. typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical + +// Flags typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) -typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() -typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags +typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags +typedef int ImGuiFocusRequestFlags; // -> enum ImGuiFocusRequestFlags_ // Flags: for FocusWindow(); +typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc. +typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags +typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() -typedef int ImGuiNavDirSourceFlags; // -> enum ImGuiNavDirSourceFlags_ // Flags: for GetNavInputAmount2d() typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions @@ -190,23 +211,32 @@ namespace ImStb // [SECTION] Macros //----------------------------------------------------------------------------- -// Debug Logging -#ifndef IMGUI_DEBUG_LOG -#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__) +// Debug Printing Into TTY +// (since IMGUI_VERSION_NUM >= 18729: IMGUI_DEBUG_LOG was reworked into IMGUI_DEBUG_PRINTF (and removed framecount from it). If you were using a #define IMGUI_DEBUG_LOG please rename) +#ifndef IMGUI_DEBUG_PRINTF +#ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS +#define IMGUI_DEBUG_PRINTF(_FMT,...) printf(_FMT, __VA_ARGS__) +#else +#define IMGUI_DEBUG_PRINTF(_FMT,...) ((void)0) +#endif #endif -// Debug Logging for selected systems. Remove the '((void)0) //' to enable. -//#define IMGUI_DEBUG_LOG_POPUP IMGUI_DEBUG_LOG // Enable log -//#define IMGUI_DEBUG_LOG_NAV IMGUI_DEBUG_LOG // Enable log -#define IMGUI_DEBUG_LOG_POPUP(...) ((void)0) // Disable log -#define IMGUI_DEBUG_LOG_NAV(...) ((void)0) // Disable log +// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam. +#ifndef IMGUI_DISABLE_DEBUG_TOOLS +#define IMGUI_DEBUG_LOG(...) ImGui::DebugLog(__VA_ARGS__) +#else +#define IMGUI_DEBUG_LOG(...) ((void)0) +#endif +#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) +#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) +#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) +#define IMGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventNav) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) +#define IMGUI_DEBUG_LOG_SELECTION(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection)IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) +#define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) +#define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) // Static Asserts -#if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100) #define IM_STATIC_ASSERT(_COND) static_assert(_COND, "") -#else -#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1] -#endif // "Paranoid" Debug Asserts are meant to only be enabled during specific debugging/work, otherwise would slow down the code too much. // We currently don't have many of those so the effect is currently negligible, but onward intent to add more aggressive ones in the code. @@ -230,12 +260,16 @@ namespace ImStb #else #define IM_NEWLINE "\n" #endif +#ifndef IM_TABSIZE // Until we move this to runtime and/or add proper tab support, at least allow users to compile-time override #define IM_TABSIZE (4) -#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + (_ALIGN - 1)) & ~(_ALIGN - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8 +#endif +#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8 #define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose #define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 #define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds #define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // +#define IM_STRINGIFY_HELPER(_X) #_X +#define IM_STRINGIFY(_X) IM_STRINGIFY_HELPER(_X) // Preprocessor idiom to stringify e.g. an integer. // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall #ifdef _MSC_VER @@ -252,12 +286,19 @@ namespace ImStb #endif // Debug Tools -// Use 'Metrics->Tools->Item Picker' to break into the call-stack of a specific item. +// Use 'Metrics/Debugger->Tools->Item Picker' to break into the call-stack of a specific item. +// This will call IM_DEBUG_BREAK() which you may redefine yourself. See https://github.com/scottt/debugbreak for more reference. #ifndef IM_DEBUG_BREAK -#if defined(__clang__) -#define IM_DEBUG_BREAK() __builtin_debugtrap() -#elif defined (_MSC_VER) +#if defined (_MSC_VER) #define IM_DEBUG_BREAK() __debugbreak() +#elif defined(__clang__) +#define IM_DEBUG_BREAK() __builtin_debugtrap() +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define IM_DEBUG_BREAK() __asm__ volatile("int $0x03") +#elif defined(__GNUC__) && defined(__thumb__) +#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xde01") +#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__) +#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0"); #else #define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger! #endif @@ -271,7 +312,8 @@ namespace ImStb // - Helpers: Hashing // - Helpers: Sorting // - Helpers: Bit manipulation -// - Helpers: String, Formatting +// - Helpers: String +// - Helpers: Formatting // - Helpers: UTF-8 <> wchar conversions // - Helpers: ImVec2/ImVec4 operators // - Helpers: Maths @@ -284,17 +326,17 @@ namespace ImStb // - Helper: ImSpan<>, ImSpanAllocator<> // - Helper: ImPool<> // - Helper: ImChunkStream<> +// - Helper: ImGuiTextIndex //----------------------------------------------------------------------------- // Helpers: Hashing -IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImU32 seed = 0); -IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImU32 seed = 0); -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -static inline ImGuiID ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68] -#endif +IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImGuiID seed = 0); +IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImGuiID seed = 0); // Helpers: Sorting -#define ImQsort qsort +#ifndef ImQsort +static inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); } +#endif // Helpers: Color Blending IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b); @@ -304,7 +346,7 @@ static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } -// Helpers: String, Formatting +// Helpers: String IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); @@ -317,14 +359,23 @@ IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* bu IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); IMGUI_API void ImStrTrimBlanks(char* str); IMGUI_API const char* ImStrSkipBlank(const char* str); +IM_MSVC_RUNTIME_CHECKS_OFF +static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; } +static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } +static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } +IM_MSVC_RUNTIME_CHECKS_RESTORE + +// Helpers: Formatting IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); +IMGUI_API void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) IM_FMTLIST(3); IMGUI_API const char* ImParseFormatFindStart(const char* format); IMGUI_API const char* ImParseFormatFindEnd(const char* format); IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size); +IMGUI_API void ImParseFormatSanitizeForPrinting(const char* fmt_in, char* fmt_out, size_t fmt_out_size); +IMGUI_API const char* ImParseFormatSanitizeForScanning(const char* fmt_in, char* fmt_out, size_t fmt_out_size); IMGUI_API int ImParseFormatPrecision(const char* format, int default_value); -static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } -static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } // Helpers: UTF-8 <> wchar conversions IMGUI_API const char* ImTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf @@ -335,29 +386,6 @@ IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char IMGUI_API int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end); // return number of bytes to express one char in UTF-8 IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string in UTF-8 -// Helpers: ImVec2/ImVec4 operators -// We are keeping those disabled by default so they don't leak in user space, to allow user enabling implicit cast operators between ImVec2 and their own types (using IM_VEC2_CLASS_EXTRA etc.) -// We unfortunately don't have a unary- operator for ImVec2 because this would needs to be defined inside the class itself. -#ifdef IMGUI_DEFINE_MATH_OPERATORS -IM_MSVC_RUNTIME_CHECKS_OFF -static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); } -static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } -static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } -static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } -static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } -static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); } -static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } -static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } -static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } -static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } -static inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; } -static inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; } -static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } -static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } -static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } -IM_MSVC_RUNTIME_CHECKS_RESTORE -#endif - // Helpers: File System #ifdef IMGUI_DISABLE_FILE_FUNCTIONS #define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS @@ -401,8 +429,8 @@ static inline double ImLog(double x) { return log(x); } static inline int ImAbs(int x) { return x < 0 ? -x : x; } static inline float ImAbs(float x) { return fabsf(x); } static inline double ImAbs(double x) { return fabs(x); } -static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : ((x > 0.0f) ? 1.0f : 0.0f); } // Sign operator - returns -1, 0 or 1 based on sign of argument -static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : ((x > 0.0) ? 1.0 : 0.0); } +static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f) ? 1.0f : 0.0f; } // Sign operator - returns -1, 0 or 1 based on sign of argument +static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; } #ifdef IMGUI_ENABLE_SSE static inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); } #else @@ -431,13 +459,16 @@ static inline float ImLengthSqr(const ImVec2& lhs) static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; } static inline float ImFloor(float f) { return (float)(int)(f); } -static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() +static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } +static inline ImVec2 ImFloorSigned(const ImVec2& v) { return ImVec2(ImFloorSigned(v.x), ImFloorSigned(v.y)); } static inline int ImModPositive(int a, int b) { return (a + b) % b; } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; } +static inline float ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; } IM_MSVC_RUNTIME_CHECKS_RESTORE // Helpers: Geometry @@ -450,7 +481,6 @@ IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, c IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; } -IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy); // Helper: ImVec1 (1D vector) // (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches) @@ -458,17 +488,17 @@ IM_MSVC_RUNTIME_CHECKS_OFF struct ImVec1 { float x; - ImVec1() { x = 0.0f; } - ImVec1(float _x) { x = _x; } + constexpr ImVec1() : x(0.0f) { } + constexpr ImVec1(float _x) : x(_x) { } }; // Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage) struct ImVec2ih { short x, y; - ImVec2ih() { x = y = 0; } - ImVec2ih(short _x, short _y) { x = _x; y = _y; } - explicit ImVec2ih(const ImVec2& rhs) { x = (short)rhs.x; y = (short)rhs.y; } + constexpr ImVec2ih() : x(0), y(0) {} + constexpr ImVec2ih(short _x, short _y) : x(_x), y(_y) {} + constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {} }; // Helper: ImRect (2D axis aligned bounding-box) @@ -478,10 +508,10 @@ struct IMGUI_API ImRect ImVec2 Min; // Upper-left ImVec2 Max; // Lower-right - ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} - ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} - ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} - ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} + constexpr ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} + constexpr ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} + constexpr ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} + constexpr ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } @@ -508,9 +538,12 @@ struct IMGUI_API ImRect bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); } }; -IM_MSVC_RUNTIME_CHECKS_RESTORE // Helper: ImBitArray +#define IM_BITARRAY_TESTBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] & ((ImU32)1 << ((_N) & 31))) != 0) // Macro version of ImBitArrayTestBit(): ensure args have side-effect or are costly! +#define IM_BITARRAY_CLEARBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] &= ~((ImU32)1 << ((_N) & 31)))) // Macro version of ImBitArrayClearBit(): ensure args have side-effect or are costly! +inline size_t ImBitArrayGetStorageSizeInBytes(int bitcount) { return (size_t)((bitcount + 31) >> 5) << 2; } +inline void ImBitArrayClearAllBits(ImU32* arr, int bitcount){ memset(arr, 0, ImBitArrayGetStorageSizeInBytes(bitcount)); } inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; } inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; } inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; } @@ -527,19 +560,22 @@ inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on ran } } +typedef ImU32* ImBitArrayPtr; // Name for use in structs + // Helper: ImBitArray class (wrapper over ImBitArray functions) // Store 1-bit per value. -template -struct IMGUI_API ImBitArray +template +struct ImBitArray { ImU32 Storage[(BITCOUNT + 31) >> 5]; ImBitArray() { ClearAllBits(); } void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); } void SetAllBits() { memset(Storage, 255, sizeof(Storage)); } - bool TestBit(int n) const { IM_ASSERT(n < BITCOUNT); return ImBitArrayTestBit(Storage, n); } - void SetBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArraySetBit(Storage, n); } - void ClearBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArrayClearBit(Storage, n); } - void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2) + bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); } + void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); } + void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); } + void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2) + bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); } }; // Helper: ImBitVector @@ -549,10 +585,11 @@ struct IMGUI_API ImBitVector ImVector Storage; void Create(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); } void Clear() { Storage.clear(); } - bool TestBit(int n) const { IM_ASSERT(n < (Storage.Size << 5)); return ImBitArrayTestBit(Storage.Data, n); } + bool TestBit(int n) const { IM_ASSERT(n < (Storage.Size << 5)); return IM_BITARRAY_TESTBIT(Storage.Data, n); } void SetBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArraySetBit(Storage.Data, n); } void ClearBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArrayClearBit(Storage.Data, n); } }; +IM_MSVC_RUNTIME_CHECKS_RESTORE // Helper: ImSpan<> // Pointing to a span of data we don't own. @@ -610,7 +647,7 @@ struct ImSpanAllocator // Honor constructor/destructor. Add/remove invalidate all pointers. Indexes have the same lifetime as the associated object. typedef int ImPoolIdx; template -struct IMGUI_API ImPool +struct ImPool { ImVector Buf; // Contiguous data ImGuiStorage Map; // ID->Index @@ -647,7 +684,7 @@ struct IMGUI_API ImPool // We store the chunk size first, and align the final size on 4 bytes boundaries. // The tedious/zealous amount of casting is to avoid -Wcast-align warnings. template -struct IMGUI_API ImChunkStream +struct ImChunkStream { ImVector Buf; @@ -665,6 +702,20 @@ struct IMGUI_API ImChunkStream }; +// Helper: ImGuiTextIndex<> +// Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API. +struct ImGuiTextIndex +{ + ImVector LineOffsets; + int EndOffset = 0; // Because we don't own text buffer we need to maintain EndOffset (may bake in LineOffsets?) + + void clear() { LineOffsets.clear(); EndOffset = 0; } + int size() { return LineOffsets.Size; } + const char* get_line_begin(const char* base, int n) { return base + LineOffsets[n]; } + const char* get_line_end(const char* base, int n) { return base + (n + 1 < LineOffsets.Size ? (LineOffsets[n + 1] - 1) : EndOffset); } + void append(const char* base, int old_size, int new_size); +}; + //----------------------------------------------------------------------------- // [SECTION] ImDrawList support //----------------------------------------------------------------------------- @@ -679,7 +730,6 @@ struct IMGUI_API ImChunkStream // // Rendering circles with an odd number of segments, while mathematically correct will produce // asymmetrical results on the raster grid. Therefore we're rounding N to next even number (7->8, 8->8, 9->10 etc.) -// #define IM_ROUNDUP_TO_EVEN(_V) ((((_V) + 1) / 2) * 2) #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 4 #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512 @@ -707,6 +757,9 @@ struct IMGUI_API ImDrawListSharedData ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards) + // [Internal] Temp write buffer + ImVector TempBuffer; + // [Internal] Lookup tables ImVec2 ArcFastVtx[IM_DRAWLIST_ARCFAST_TABLE_SIZE]; // Sample points on the quarter of the circle. float ArcFastRadiusCutoff; // Cutoff radius after which arc drawing will fallback to slower PathArcTo() @@ -731,23 +784,32 @@ struct ImDrawDataBuilder // [SECTION] Widgets support: flags, enums, data structures //----------------------------------------------------------------------------- -// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin(). +// Flags used by upcoming items +// - input: PushItemFlag() manipulates g.CurrentItemFlags, ItemAdd() calls may add extra flags. +// - output: stored in g.LastItemData.InFlags +// Current window shared by all windows. // This is going to be exposed in imgui.h when stabilized enough. enum ImGuiItemFlags_ { + // Controlled by user ImGuiItemFlags_None = 0, - ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing (FIXME: should merge with _NoNav) + ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing. This is a "lighter" version of ImGuiItemFlags_NoNav. ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. ImGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See BeginDisabled()/EndDisabled(). See github.com/ocornut/imgui/issues/211 - ImGuiItemFlags_NoNav = 1 << 3, // false // Disable keyboard/gamepad directional navigation (FIXME: should merge with _NoTabStop) + ImGuiItemFlags_NoNav = 1 << 3, // false // Disable any form of focusing (keyboard/gamepad directional navigation and SetKeyboardFocusHere() calls) ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false // Disable item being a candidate for default focus (e.g. used by title bar items) ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. - ImGuiItemFlags_Inputable = 1 << 8 // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. + ImGuiItemFlags_NoWindowHoverableCheck = 1 << 8, // false // Disable hoverable check in ItemHoverable() + ImGuiItemflags_AllowOverlap = 1 << 9, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame. + + // Controlled by widget code + ImGuiItemFlags_Inputable = 1 << 10, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. }; -// Storage for LastItem data +// Status flags for an already submitted item +// - output: stored in g.LastItemData.StatusFlags enum ImGuiItemStatusFlags_ { ImGuiItemStatusFlags_None = 0, @@ -759,24 +821,34 @@ enum ImGuiItemStatusFlags_ ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag. ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing. - ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8 // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon) + ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon) + ImGuiItemStatusFlags_Visible = 1 << 9, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()). + // Additional status + semantic for ImGuiTestEngine #ifdef IMGUI_ENABLE_TEST_ENGINE - , // [imgui_tests only] - ImGuiItemStatusFlags_Openable = 1 << 20, // - ImGuiItemStatusFlags_Opened = 1 << 21, // - ImGuiItemStatusFlags_Checkable = 1 << 22, // - ImGuiItemStatusFlags_Checked = 1 << 23 // + ImGuiItemStatusFlags_Openable = 1 << 20, // Item is an openable (e.g. TreeNode) + ImGuiItemStatusFlags_Opened = 1 << 21, // Opened status + ImGuiItemStatusFlags_Checkable = 1 << 22, // Item is a checkable (e.g. CheckBox, MenuItem) + ImGuiItemStatusFlags_Checked = 1 << 23, // Checked status + ImGuiItemStatusFlags_Inputable = 1 << 24, // Item is a text-inputable (e.g. InputText, SliderXXX, DragXXX) #endif }; +// Extend ImGuiHoveredFlags_ +enum ImGuiHoveredFlagsPrivate_ +{ + ImGuiHoveredFlags_DelayMask_ = ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay, + ImGuiHoveredFlags_AllowedMaskForIsWindowHovered = ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary, + ImGuiHoveredFlags_AllowedMaskForIsItemHovered = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayMask_, +}; + // Extend ImGuiInputTextFlags_ enum ImGuiInputTextFlagsPrivate_ { // [Internal] ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline() ImGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data - ImGuiInputTextFlags_MergedItem = 1 << 28 // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match. + ImGuiInputTextFlags_MergedItem = 1 << 28, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match. }; // Extend ImGuiButtonFlags_ @@ -790,29 +862,31 @@ enum ImGuiButtonFlagsPrivate_ ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping - ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap() + ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable. ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED] //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) - ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated + ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used everytime an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags) ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item + ImGuiButtonFlags_NoSetKeyOwner = 1 << 20, // don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) + ImGuiButtonFlags_NoTestKeyOwner = 1 << 21, // don't test key/input owner when polling the key (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold, - ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease + ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease, }; // Extend ImGuiComboFlags_ enum ImGuiComboFlagsPrivate_ { - ImGuiComboFlags_CustomPreview = 1 << 20 // enable BeginComboPreview() + ImGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview() }; // Extend ImGuiSliderFlags_ enum ImGuiSliderFlagsPrivate_ { ImGuiSliderFlags_Vertical = 1 << 20, // Should this slider be orientated vertically? - ImGuiSliderFlags_ReadOnly = 1 << 21 + ImGuiSliderFlags_ReadOnly = 1 << 21, }; // Extend ImGuiSelectableFlags_ @@ -824,35 +898,46 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release) ImGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release) ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) - ImGuiSelectableFlags_DrawHoveredWhenHeld = 1 << 25, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow. - ImGuiSelectableFlags_SetNavIdOnHover = 1 << 26, // Set Nav/Focus ID on mouse hover (used by MenuItem) - ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 27 // Disable padding each side with ItemSpacing * 0.5f + ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25, // Set Nav/Focus ID on mouse hover (used by MenuItem) + ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 26, // Disable padding each side with ItemSpacing * 0.5f + ImGuiSelectableFlags_NoSetKeyOwner = 1 << 27, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) }; // Extend ImGuiTreeNodeFlags_ enum ImGuiTreeNodeFlagsPrivate_ { - ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20 + ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20, + ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 21,// (FIXME-WIP) Turn Down arrow into an Up arrow, but reversed trees (#6517) }; enum ImGuiSeparatorFlags_ { - ImGuiSeparatorFlags_None = 0, - ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar - ImGuiSeparatorFlags_Vertical = 1 << 1, - ImGuiSeparatorFlags_SpanAllColumns = 1 << 2 + ImGuiSeparatorFlags_None = 0, + ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar + ImGuiSeparatorFlags_Vertical = 1 << 1, + ImGuiSeparatorFlags_SpanAllColumns = 1 << 2, // Make separator cover all columns of a legacy Columns() set. +}; + +// Flags for FocusWindow(). This is not called ImGuiFocusFlags to avoid confusion with public-facing ImGuiFocusedFlags. +// FIXME: Once we finishing replacing more uses of GetTopMostPopupModal()+IsWindowWithinBeginStackOf() +// and FindBlockingModal() with this, we may want to change the flag to be opt-out instead of opt-in. +enum ImGuiFocusRequestFlags_ +{ + ImGuiFocusRequestFlags_None = 0, + ImGuiFocusRequestFlags_RestoreFocusedChild = 1 << 0, // Find last focused child (if any) and focus it instead. + ImGuiFocusRequestFlags_UnlessBelowModal = 1 << 1, // Do not set focus if the window is below a modal. }; enum ImGuiTextFlags_ { - ImGuiTextFlags_None = 0, - ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0 + ImGuiTextFlags_None = 0, + ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0, }; enum ImGuiTooltipFlags_ { - ImGuiTooltipFlags_None = 0, - ImGuiTooltipFlags_OverridePreviousTooltip = 1 << 0 // Override will clear/ignore previously submitted tooltip (defaults to append) + ImGuiTooltipFlags_None = 0, + ImGuiTooltipFlags_OverridePrevious = 1 << 1, // Clear/ignore previously submitted tooltip (defaults to append) }; // FIXME: this is in development, not exposed/functional as a generic feature yet. @@ -869,7 +954,7 @@ enum ImGuiLogType ImGuiLogType_TTY, ImGuiLogType_File, ImGuiLogType_Buffer, - ImGuiLogType_Clipboard + ImGuiLogType_Clipboard, }; // X/Y enums are fixed to 0/1 so they may be used to index ImVec2 @@ -883,36 +968,22 @@ enum ImGuiAxis enum ImGuiPlotType { ImGuiPlotType_Lines, - ImGuiPlotType_Histogram -}; - -enum ImGuiInputSource -{ - ImGuiInputSource_None = 0, - ImGuiInputSource_Mouse, - ImGuiInputSource_Keyboard, - ImGuiInputSource_Gamepad, - ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only - ImGuiInputSource_Clipboard, // Currently only used by InputText() - ImGuiInputSource_COUNT -}; - -// FIXME-NAV: Clarify/expose various repeat delay/rate -enum ImGuiInputReadMode -{ - ImGuiInputReadMode_Down, - ImGuiInputReadMode_Pressed, - ImGuiInputReadMode_Released, - ImGuiInputReadMode_Repeat, - ImGuiInputReadMode_RepeatSlow, - ImGuiInputReadMode_RepeatFast + ImGuiPlotType_Histogram, }; enum ImGuiPopupPositionPolicy { ImGuiPopupPositionPolicy_Default, ImGuiPopupPositionPolicy_ComboBox, - ImGuiPopupPositionPolicy_Tooltip + ImGuiPopupPositionPolicy_Tooltip, +}; + +struct ImGuiDataVarInfo +{ + ImGuiDataType Type; + ImU32 Count; // 1+ + ImU32 Offset; // Offset in parent structure + void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); } }; struct ImGuiDataTypeTempStorage @@ -934,14 +1005,14 @@ enum ImGuiDataTypePrivate_ { ImGuiDataType_String = ImGuiDataType_COUNT + 1, ImGuiDataType_Pointer, - ImGuiDataType_ID + ImGuiDataType_ID, }; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiColorMod { - ImGuiCol Col; - ImVec4 BackupValue; + ImGuiCol Col; + ImVec4 BackupValue; }; // Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable. @@ -1001,10 +1072,20 @@ struct IMGUI_API ImGuiMenuColumns void CalcNextTotalWidth(bool update_offsets); }; +// Internal temporary state for deactivating InputText() instances. +struct IMGUI_API ImGuiInputTextDeactivatedState +{ + ImGuiID ID; // widget id owning the text state (which just got deactivated) + ImVector TextA; // text buffer + + ImGuiInputTextDeactivatedState() { memset(this, 0, sizeof(*this)); } + void ClearFreeMemory() { ID = 0; TextA.clear(); } +}; // Internal state of the currently focused/edited text input box // For a given item ID, access with ImGui::GetInputTextState() struct IMGUI_API ImGuiInputTextState { + ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent). ImGuiID ID; // widget id owning the text state int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 length is valid even if TextA is not. ImVector TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. @@ -1018,9 +1099,7 @@ struct IMGUI_API ImGuiInputTextState bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!) bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection bool Edited; // edited this frame - ImGuiInputTextFlags Flags; // copy of InputText() flags - ImGuiInputTextCallback UserCallback; // " - void* UserCallbackData; // " + ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set. ImGuiInputTextState() { memset(this, 0, sizeof(*this)); } void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); } @@ -1045,13 +1124,14 @@ struct ImGuiPopupData { ImGuiID PopupId; // Set on OpenPopup() ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() - ImGuiWindow* SourceWindow; // Set on OpenPopup() copy of NavWindow at the time of opening the popup + ImGuiWindow* BackupNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close + int ParentNavLayer; // Resolved on BeginPopup(). Actually a ImGuiNavLayer type (declared down below), initialized to -1 which is not part of an enum, but serves well-enough as "not any of layers" value int OpenFrameCount; // Set on OpenPopup() ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup - ImGuiPopupData() { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; } + ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; } }; enum ImGuiNextWindowDataFlags_ @@ -1064,7 +1144,7 @@ enum ImGuiNextWindowDataFlags_ ImGuiNextWindowDataFlags_HasSizeConstraint = 1 << 4, ImGuiNextWindowDataFlags_HasFocus = 1 << 5, ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6, - ImGuiNextWindowDataFlags_HasScroll = 1 << 7 + ImGuiNextWindowDataFlags_HasScroll = 1 << 7, }; // Storage for SetNexWindow** functions @@ -1094,19 +1174,20 @@ enum ImGuiNextItemDataFlags_ { ImGuiNextItemDataFlags_None = 0, ImGuiNextItemDataFlags_HasWidth = 1 << 0, - ImGuiNextItemDataFlags_HasOpen = 1 << 1 + ImGuiNextItemDataFlags_HasOpen = 1 << 1, }; struct ImGuiNextItemData { ImGuiNextItemDataFlags Flags; + ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemflags_AllowOverlap. float Width; // Set by SetNextItemWidth() ImGuiID FocusScopeId; // Set by SetNextItemMultiSelectData() (!= 0 signify value has been set, so it's an alternate version of HasSelectionData, we don't use Flags for this because they are cleared too early. This is mostly used for debugging) ImGuiCond OpenCond; bool OpenVal; // Set by SetNextItemOpen() ImGuiNextItemData() { memset(this, 0, sizeof(*this)); } - inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; } // Also cleared manually by ItemAdd()! + inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! }; // Status storage for the last submitted item @@ -1135,8 +1216,8 @@ struct IMGUI_API ImGuiStackSizes short SizeOfDisabledStack; ImGuiStackSizes() { memset(this, 0, sizeof(*this)); } - void SetToCurrentState(); - void CompareWithCurrentState(); + void SetToContextState(ImGuiContext* ctx); + void CompareWithContextState(ImGuiContext* ctx); }; // Data saved for each window pushed into the stack @@ -1151,6 +1232,7 @@ struct ImGuiShrinkWidthItem { int Index; float Width; + float InitialWidth; }; struct ImGuiPtrOrIndex @@ -1162,6 +1244,205 @@ struct ImGuiPtrOrIndex ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; } }; +//----------------------------------------------------------------------------- +// [SECTION] Inputs support +//----------------------------------------------------------------------------- + +// Bit array for named keys +typedef ImBitArray ImBitArrayForNamedKeys; + +// [Internal] Key ranges +#define ImGuiKey_LegacyNativeKey_BEGIN 0 +#define ImGuiKey_LegacyNativeKey_END 512 +#define ImGuiKey_Keyboard_BEGIN (ImGuiKey_NamedKey_BEGIN) +#define ImGuiKey_Keyboard_END (ImGuiKey_GamepadStart) +#define ImGuiKey_Gamepad_BEGIN (ImGuiKey_GamepadStart) +#define ImGuiKey_Gamepad_END (ImGuiKey_GamepadRStickDown + 1) +#define ImGuiKey_Mouse_BEGIN (ImGuiKey_MouseLeft) +#define ImGuiKey_Mouse_END (ImGuiKey_MouseWheelY + 1) +#define ImGuiKey_Aliases_BEGIN (ImGuiKey_Mouse_BEGIN) +#define ImGuiKey_Aliases_END (ImGuiKey_Mouse_END) + +// [Internal] Named shortcuts for Navigation +#define ImGuiKey_NavKeyboardTweakSlow ImGuiMod_Ctrl +#define ImGuiKey_NavKeyboardTweakFast ImGuiMod_Shift +#define ImGuiKey_NavGamepadTweakSlow ImGuiKey_GamepadL1 +#define ImGuiKey_NavGamepadTweakFast ImGuiKey_GamepadR1 +#define ImGuiKey_NavGamepadActivate ImGuiKey_GamepadFaceDown +#define ImGuiKey_NavGamepadCancel ImGuiKey_GamepadFaceRight +#define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceLeft +#define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceUp + +enum ImGuiInputEventType +{ + ImGuiInputEventType_None = 0, + ImGuiInputEventType_MousePos, + ImGuiInputEventType_MouseWheel, + ImGuiInputEventType_MouseButton, + ImGuiInputEventType_Key, + ImGuiInputEventType_Text, + ImGuiInputEventType_Focus, + ImGuiInputEventType_COUNT +}; + +enum ImGuiInputSource +{ + ImGuiInputSource_None = 0, + ImGuiInputSource_Mouse, // Note: may be Mouse or TouchScreen or Pen. See io.MouseSource to distinguish them. + ImGuiInputSource_Keyboard, + ImGuiInputSource_Gamepad, + ImGuiInputSource_Clipboard, // Currently only used by InputText() + ImGuiInputSource_COUNT +}; + +// FIXME: Structures in the union below need to be declared as anonymous unions appears to be an extension? +// Using ImVec2() would fail on Clang 'union member 'MousePos' has a non-trivial default constructor' +struct ImGuiInputEventMousePos { float PosX, PosY; ImGuiMouseSource MouseSource; }; +struct ImGuiInputEventMouseWheel { float WheelX, WheelY; ImGuiMouseSource MouseSource; }; +struct ImGuiInputEventMouseButton { int Button; bool Down; ImGuiMouseSource MouseSource; }; +struct ImGuiInputEventKey { ImGuiKey Key; bool Down; float AnalogValue; }; +struct ImGuiInputEventText { unsigned int Char; }; +struct ImGuiInputEventAppFocused { bool Focused; }; + +struct ImGuiInputEvent +{ + ImGuiInputEventType Type; + ImGuiInputSource Source; + ImU32 EventId; // Unique, sequential increasing integer to identify an event (if you need to correlate them to other data). + union + { + ImGuiInputEventMousePos MousePos; // if Type == ImGuiInputEventType_MousePos + ImGuiInputEventMouseWheel MouseWheel; // if Type == ImGuiInputEventType_MouseWheel + ImGuiInputEventMouseButton MouseButton; // if Type == ImGuiInputEventType_MouseButton + ImGuiInputEventKey Key; // if Type == ImGuiInputEventType_Key + ImGuiInputEventText Text; // if Type == ImGuiInputEventType_Text + ImGuiInputEventAppFocused AppFocused; // if Type == ImGuiInputEventType_Focus + }; + bool AddedByTestEngine; + + ImGuiInputEvent() { memset(this, 0, sizeof(*this)); } +}; + +// Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior. +#define ImGuiKeyOwner_Any ((ImGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease. +#define ImGuiKeyOwner_None ((ImGuiID)-1) // Require key to have no owner. + +typedef ImS16 ImGuiKeyRoutingIndex; + +// Routing table entry (sizeof() == 16 bytes) +struct ImGuiKeyRoutingData +{ + ImGuiKeyRoutingIndex NextEntryIndex; + ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits. ImGuiMod_Shortcut is already translated to Ctrl/Super. + ImU8 RoutingNextScore; // Lower is better (0: perfect score) + ImGuiID RoutingCurr; + ImGuiID RoutingNext; + + ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; } +}; + +// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching. +// Stored in main context (1 instance) +struct ImGuiKeyRoutingTable +{ + ImGuiKeyRoutingIndex Index[ImGuiKey_NamedKey_COUNT]; // Index of first entry in Entries[] + ImVector Entries; + ImVector EntriesNext; // Double-buffer to avoid reallocation (could use a shared buffer) + + ImGuiKeyRoutingTable() { Clear(); } + void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); } +}; + +// This extends ImGuiKeyData but only for named keys (legacy keys don't support the new features) +// Stored in main context (1 per named key). In the future it might be merged into ImGuiKeyData. +struct ImGuiKeyOwnerData +{ + ImGuiID OwnerCurr; + ImGuiID OwnerNext; + bool LockThisFrame; // Reading this key requires explicit owner id (until end of frame). Set by ImGuiInputFlags_LockThisFrame. + bool LockUntilRelease; // Reading this key requires explicit owner id (until key is released). Set by ImGuiInputFlags_LockUntilRelease. When this is true LockThisFrame is always true as well. + + ImGuiKeyOwnerData() { OwnerCurr = OwnerNext = ImGuiKeyOwner_None; LockThisFrame = LockUntilRelease = false; } +}; + +// Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner() +// Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function) +enum ImGuiInputFlags_ +{ + // Flags for IsKeyPressed(), IsMouseClicked(), Shortcut() + ImGuiInputFlags_None = 0, + ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1. + ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default) + ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast + ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster + ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak, + + // Flags for SetItemKeyOwner() + ImGuiInputFlags_CondHovered = 1 << 4, // Only set if item is hovered (default to both) + ImGuiInputFlags_CondActive = 1 << 5, // Only set if item is active (default to both) + ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, + ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, + + // Flags for SetKeyOwner(), SetItemKeyOwner() + ImGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. + ImGuiInputFlags_LockUntilRelease = 1 << 7, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. + + // Routing policies for Shortcut() + low-level SetShortcutRouting() + // - The general idea is that several callers register interest in a shortcut, and only one owner gets it. + // - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(), + // allowing the system to decide where to route the input among other route-aware calls. + // - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll + // will register a route and only succeed when parent window is in the focus stack and if no-one + // with a higher priority is claiming the shortcut. + // - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods. + // - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow. + // - Can select only 1 policy among all available. + ImGuiInputFlags_RouteFocused = 1 << 8, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window. + ImGuiInputFlags_RouteGlobalLow = 1 << 9, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority. + ImGuiInputFlags_RouteGlobal = 1 << 10, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText). + ImGuiInputFlags_RouteGlobalHigh = 1 << 11, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items) + ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this! + ImGuiInputFlags_RouteAlways = 1 << 12, // Do not register route, poll keys directly. + ImGuiInputFlags_RouteUnlessBgFocused= 1 << 13, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. + ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused, + + // [Internal] Mask of which function support which flags + ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_, + ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_, + ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, + ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, +}; + +//----------------------------------------------------------------------------- +// [SECTION] Clipper support +//----------------------------------------------------------------------------- + +// Note that Max is exclusive, so perhaps should be using a Begin/End convention. +struct ImGuiListClipperRange +{ + int Min; + int Max; + bool PosToIndexConvert; // Begin/End are absolute position (will be converted to indices later) + ImS8 PosToIndexOffsetMin; // Add to Min after converting to indices + ImS8 PosToIndexOffsetMax; // Add to Min after converting to indices + + static ImGuiListClipperRange FromIndices(int min, int max) { ImGuiListClipperRange r = { min, max, false, 0, 0 }; return r; } + static ImGuiListClipperRange FromPositions(float y1, float y2, int off_min, int off_max) { ImGuiListClipperRange r = { (int)y1, (int)y2, true, (ImS8)off_min, (ImS8)off_max }; return r; } +}; + +// Temporary clipper data, buffers shared/reused between instances +struct ImGuiListClipperData +{ + ImGuiListClipper* ListClipper; + float LossynessOffset; + int StepNo; + int ItemsFrozen; + ImVector Ranges; + + ImGuiListClipperData() { memset(this, 0, sizeof(*this)); } + void Reset(ImGuiListClipper* clipper) { ListClipper = clipper; StepNo = ItemsFrozen = 0; Ranges.resize(0); } +}; + //----------------------------------------------------------------------------- // [SECTION] Navigation support //----------------------------------------------------------------------------- @@ -1169,9 +1450,9 @@ struct ImGuiPtrOrIndex enum ImGuiActivateFlags_ { ImGuiActivateFlags_None = 0, - ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default if keyboard is available. - ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default if keyboard is not available. - ImGuiActivateFlags_TryToPreserveState = 1 << 2 // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection) + ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default for Enter key. + ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default for Space key and if keyboard is not used. + ImGuiActivateFlags_TryToPreserveState = 1 << 2, // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection) }; // Early work-in-progress API for ScrollToItem() @@ -1186,7 +1467,7 @@ enum ImGuiScrollFlags_ ImGuiScrollFlags_AlwaysCenterY = 1 << 5, // Always center the result item on Y axis [default for Y axis for appearing window) ImGuiScrollFlags_NoScrollParent = 1 << 6, // Disable forwarding scrolling to parent window if required to keep item/rect visible (only scroll window the function was applied to). ImGuiScrollFlags_MaskX_ = ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleCenterX | ImGuiScrollFlags_AlwaysCenterX, - ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY + ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY, }; enum ImGuiNavHighlightFlags_ @@ -1195,15 +1476,7 @@ enum ImGuiNavHighlightFlags_ ImGuiNavHighlightFlags_TypeDefault = 1 << 0, ImGuiNavHighlightFlags_TypeThin = 1 << 1, ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse. - ImGuiNavHighlightFlags_NoRounding = 1 << 3 -}; - -enum ImGuiNavDirSourceFlags_ -{ - ImGuiNavDirSourceFlags_None = 0, - ImGuiNavDirSourceFlags_Keyboard = 1 << 0, - ImGuiNavDirSourceFlags_PadDPad = 1 << 1, - ImGuiNavDirSourceFlags_PadLStick = 1 << 2 + ImGuiNavHighlightFlags_NoRounding = 1 << 3, }; enum ImGuiNavMoveFlags_ @@ -1213,20 +1486,23 @@ enum ImGuiNavMoveFlags_ ImGuiNavMoveFlags_LoopY = 1 << 1, ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left) ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful but provided for completeness + ImGuiNavMoveFlags_WrapMask_ = ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_WrapY, ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown) ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary ImGuiNavMoveFlags_Forwarded = 1 << 7, ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result - ImGuiNavMoveFlags_Tabbing = 1 << 9, // == Focus + Activate if item is Inputable + DontChangeNavHighlight - ImGuiNavMoveFlags_Activate = 1 << 10, - ImGuiNavMoveFlags_DontSetNavHighlight = 1 << 11 // Do not alter the visible state of keyboard vs mouse nav highlight + ImGuiNavMoveFlags_FocusApi = 1 << 9, // Requests from focus API can land/focus/activate items even if they are marked with _NoTabStop (see NavProcessItemForTabbingRequest() for details) + ImGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight + ImGuiNavMoveFlags_Activate = 1 << 11, // Activate/select target item. + ImGuiNavMoveFlags_NoSelect = 1 << 12, // Don't trigger selection by not setting g.NavJustMovedTo + ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 13, // Do not alter the visible state of keyboard vs mouse nav highlight }; enum ImGuiNavLayer { ImGuiNavLayer_Main = 0, // Main scrolling layer - ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt/ImGuiNavInput_Menu) + ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt) ImGuiNavLayer_COUNT }; @@ -1257,24 +1533,24 @@ enum ImGuiOldColumnFlags_ ImGuiOldColumnFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers ImGuiOldColumnFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns ImGuiOldColumnFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window - ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. + ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4, // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. // Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None, + ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None, ImGuiColumnsFlags_NoBorder = ImGuiOldColumnFlags_NoBorder, ImGuiColumnsFlags_NoResize = ImGuiOldColumnFlags_NoResize, ImGuiColumnsFlags_NoPreserveWidths = ImGuiOldColumnFlags_NoPreserveWidths, ImGuiColumnsFlags_NoForceWithinWindow = ImGuiOldColumnFlags_NoForceWithinWindow, - ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize + ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize, #endif }; struct ImGuiOldColumnData { - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) float OffsetNormBeforeResize; - ImGuiOldColumnFlags Flags; // Not exposed + ImGuiOldColumnFlags Flags; // Not exposed ImRect ClipRect; ImGuiOldColumnData() { memset(this, 0, sizeof(*this)); } @@ -1363,6 +1639,7 @@ struct ImGuiWindowSettings ImVec2ih Size; bool Collapsed; bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context) + bool WantDelete; // Set to invalidate/delete the settings entry ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); } char* GetName() { return (char*)(this + 1); } @@ -1383,32 +1660,62 @@ struct ImGuiSettingsHandler ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } }; +//----------------------------------------------------------------------------- +// [SECTION] Localization support +//----------------------------------------------------------------------------- + +// This is experimental and not officially supported, it'll probably fall short of features, if/when it does we may backtrack. +enum ImGuiLocKey : int +{ + ImGuiLocKey_VersionStr, + ImGuiLocKey_TableSizeOne, + ImGuiLocKey_TableSizeAllFit, + ImGuiLocKey_TableSizeAllDefault, + ImGuiLocKey_TableResetOrder, + ImGuiLocKey_WindowingMainMenuBar, + ImGuiLocKey_WindowingPopup, + ImGuiLocKey_WindowingUntitled, + ImGuiLocKey_COUNT +}; + +struct ImGuiLocEntry +{ + ImGuiLocKey Key; + const char* Text; +}; + + //----------------------------------------------------------------------------- // [SECTION] Metrics, Debug Tools //----------------------------------------------------------------------------- +enum ImGuiDebugLogFlags_ +{ + // Event types + ImGuiDebugLogFlags_None = 0, + ImGuiDebugLogFlags_EventActiveId = 1 << 0, + ImGuiDebugLogFlags_EventFocus = 1 << 1, + ImGuiDebugLogFlags_EventPopup = 1 << 2, + ImGuiDebugLogFlags_EventNav = 1 << 3, + ImGuiDebugLogFlags_EventClipper = 1 << 4, + ImGuiDebugLogFlags_EventSelection = 1 << 5, + ImGuiDebugLogFlags_EventIO = 1 << 6, + ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO, + ImGuiDebugLogFlags_OutputToTTY = 1 << 10, // Also send output to TTY +}; + struct ImGuiMetricsConfig { - bool ShowStackTool; - bool ShowWindowsRects; - bool ShowWindowsBeginOrder; - bool ShowTablesRects; - bool ShowDrawCmdMesh; - bool ShowDrawCmdBoundingBoxes; - int ShowWindowsRectsType; - int ShowTablesRectsType; - - ImGuiMetricsConfig() - { - ShowStackTool = false; - ShowWindowsRects = false; - ShowWindowsBeginOrder = false; - ShowTablesRects = false; - ShowDrawCmdMesh = true; - ShowDrawCmdBoundingBoxes = true; - ShowWindowsRectsType = -1; - ShowTablesRectsType = -1; - } + bool ShowDebugLog = false; + bool ShowStackTool = false; + bool ShowWindowsRects = false; + bool ShowWindowsBeginOrder = false; + bool ShowTablesRects = false; + bool ShowDrawCmdMesh = true; + bool ShowDrawCmdBoundingBoxes = true; + bool ShowAtlasTintedWithTextColor = false; + int ShowWindowsRectsType = -1; + int ShowTablesRectsType = -1; }; struct ImGuiStackLevelInfo @@ -1416,7 +1723,8 @@ struct ImGuiStackLevelInfo ImGuiID ID; ImS8 QueryFrameCount; // >= 1: Query in progress bool QuerySuccess; // Obtained result from DebugHookIdInfo() - char Desc[58]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) + ImGuiDataType DataType : 8; + char Desc[57]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) FIXME: Now that we added CTRL+C this should be fixed. ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); } }; @@ -1428,8 +1736,10 @@ struct ImGuiStackTool int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level ImGuiID QueryId; // ID to query details for ImVector Results; + bool CopyToClipboardOnCtrlC; + float CopyToClipboardLastTime; - ImGuiStackTool() { memset(this, 0, sizeof(*this)); } + ImGuiStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; } }; //----------------------------------------------------------------------------- @@ -1451,7 +1761,7 @@ struct ImGuiContextHook }; //----------------------------------------------------------------------------- -// [SECTION] ImGuiContext (main imgui context) +// [SECTION] ImGuiContext (main Dear ImGui context) //----------------------------------------------------------------------------- struct ImGuiContext @@ -1475,6 +1785,12 @@ struct ImGuiContext bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log() void* TestEngine; // Test engine user data + // Inputs + ImVector InputEventsQueue; // Input events which will be trickled/written into IO structure. + ImVector InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail. + ImGuiMouseSource InputEventsNextMouseSource; + ImU32 InputEventsNextEventId; + // Windows state ImVector Windows; // Windows, sorted in display order, back to front ImVector WindowsFocusOrder; // Root windows, sorted in focus order, back to front. @@ -1489,15 +1805,16 @@ struct ImGuiContext ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindow. ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window. ImVec2 WheelingWindowRefMousePos; - float WheelingWindowTimer; + int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL + float WheelingWindowReleaseTimer; + ImVec2 WheelingWindowWheelRemainder; + ImVec2 WheelingAxisAvg; // Item/widgets state and tracking information ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] ImGuiID HoveredId; // Hovered widget, filled during the frame ImGuiID HoveredIdPreviousFrame; bool HoveredIdAllowOverlap; - bool HoveredIdUsingMouseWheel; // Hovered widget will use mouse wheel. Blocks scrolling the underlying window. - bool HoveredIdPreviousFrameUsingMouseWheel; bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. float HoveredIdTimer; // Measure contiguous hovering time float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active @@ -1510,13 +1827,9 @@ struct ImGuiContext bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch. bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state. bool ActiveIdHasBeenEditedThisFrame; - bool ActiveIdUsingMouseWheel; // Active widget will want to read mouse wheel. Blocks scrolling the underlying window. - ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it) - ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs. - ImU64 ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array. ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) ImGuiWindow* ActiveIdWindow; - ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard) + ImGuiInputSource ActiveIdSource; // Activating source: ImGuiInputSource_Mouse OR ImGuiInputSource_Keyboard OR ImGuiInputSource_Gamepad int ActiveIdMouseButton; ImGuiID ActiveIdPreviousFrame; bool ActiveIdPreviousFrameIsAlive; @@ -1525,8 +1838,22 @@ struct ImGuiContext ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation. float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation. + // [EXPERIMENTAL] Key/Input Ownership + Shortcut Routing system + // - The idea is that instead of "eating" a given key, we can link to an owner. + // - Input query can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID. + // - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame(). + ImGuiKeyOwnerData KeysOwnerData[ImGuiKey_NamedKey_COUNT]; + ImGuiKeyRoutingTable KeysRoutingTable; + ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it) + bool ActiveIdUsingAllKeyboardKeys; // Active widget will want to read all keyboard keys inputs. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency) +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + ImU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);' +#endif + // Next window/item data - ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back() + ImGuiID CurrentFocusScopeId; // == g.FocusScopeStack.back() + ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back() + ImGuiID DebugLocateId; // Storage for DebugLocateItemOnHover() feature: this is read by ItemAdd() so we keep it in a hot/cached location ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd) ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions @@ -1535,33 +1862,31 @@ struct ImGuiContext ImVector ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin() ImVector StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin() ImVector FontStack; // Stack for PushFont()/PopFont() - inherited by Begin() - ImVector FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - not inherited by Begin(), unless child window + ImVector FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin() ImVectorItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin() ImVectorGroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin() ImVectorOpenPopupStack; // Which popups are open (persistent) ImVectorBeginPopupStack; // Which level of BeginPopup() we are in (reset every frame) + int BeginMenuCount; // Viewports ImVector Viewports; // Active viewports (Size==1 in 'master' branch). Each viewports hold their copy of ImDrawData. // Gamepad/keyboard Navigation - ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusWindow' + ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow' ImGuiID NavId; // Focused item for navigation ImGuiID NavFocusScopeId; // Identify a selection scope (selection code often wants to "clear other items" when landing on an item of the selection set) - ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set when calling ActivateItem() - ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0 - ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0 - ImGuiID NavActivateInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0; ImGuiActivateFlags_PreferInput will be set and NavActivateId will be 0. + ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem() + ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0 + ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat) ImGuiActivateFlags NavActivateFlags; - ImGuiID NavJustTabbedId; // Just tabbed to this id. ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest). ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest). - ImGuiKeyModFlags NavJustMovedToKeyMods; + ImGuiKeyChord NavJustMovedToKeyMods; ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame. ImGuiActivateFlags NavNextActivateFlags; - ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard. + ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. - int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) @@ -1571,42 +1896,40 @@ struct ImGuiContext bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd() bool NavInitRequest; // Init request for appearing window to select first item bool NavInitRequestFromMove; - ImGuiID NavInitResultId; // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) - ImRect NavInitResultRectRel; // Init request result rectangle (relative to parent window) + ImGuiNavItemData NavInitResult; // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) bool NavMoveSubmitted; // Move request submitted, will process result on next NewFrame() bool NavMoveScoringItems; // Move request submitted, still scoring incoming items bool NavMoveForwardToNextFrame; ImGuiNavMoveFlags NavMoveFlags; ImGuiScrollFlags NavMoveScrollFlags; - ImGuiKeyModFlags NavMoveKeyMods; + ImGuiKeyChord NavMoveKeyMods; ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down) ImGuiDir NavMoveDirForDebug; ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename? ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring. + ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted int NavScoringDebugCount; // Metrics for debugging - int NavTabbingInputableRemaining; // >0 when counting items for tabbing + int NavTabbingDir; // Generally -1 or +1, 0 when tabbing without a nav id + int NavTabbingCounter; // >0 when counting items for tabbing ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow ImGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) + ImGuiNavItemData NavTabbingResultFirst; // First tabbing request candidate within NavWindow and flattened hierarchy // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) + ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab, for reconfiguration (see #4828) + ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab ImGuiWindow* NavWindowingTarget; // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most! ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it. ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the CTRL+Tab contents float NavWindowingTimer; float NavWindowingHighlightAlpha; bool NavWindowingToggleLayer; - - // Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a redesign!) - ImGuiWindow* TabFocusRequestCurrWindow; // - ImGuiWindow* TabFocusRequestNextWindow; // - int TabFocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index - int TabFocusRequestNextCounterTabStop; // " - bool TabFocusPressed; // Set in NewFrame() when user pressed Tab + ImVec2 NavWindowingAccumDeltaPos; + ImVec2 NavWindowingAccumDeltaSize; // Render float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) - ImGuiMouseCursor MouseCursor; // Drag and Drop bool DragDropActive; @@ -1627,11 +1950,15 @@ struct ImGuiContext ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads - // Table + // Clipper + int ClipperTempDataStacked; + ImVector ClipperTempData; + + // Tables ImGuiTable* CurrentTable; - int CurrentTableStackIdx; - ImPool Tables; - ImVector TablesTempDataStack; + int TablesTempDataStacked; // Temporary table data size (because we leave previous instances undestructed, we generally don't use TablesTempData.Size) + ImVector TablesTempData; // Temporary table data (buffers reused/shared across instances, support nesting) + ImPool Tables; // Persistent table data ImVector TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC) ImVector DrawChannelsTempMergeBuffer; @@ -1641,17 +1968,33 @@ struct ImGuiContext ImVector CurrentTabBarStack; ImVector ShrinkWidthBuffer; - // Widget state + // Hover Delay system + ImGuiID HoverItemDelayId; + ImGuiID HoverItemDelayIdPreviousFrame; + float HoverItemDelayTimer; // Currently used by IsItemHovered() + float HoverItemDelayClearTimer; // Currently used by IsItemHovered(): grace time before g.TooltipHoverTimer gets cleared. + ImGuiID HoverItemUnlockedStationaryId; // Mouse has once been stationary on this item. Only reset after departing the item. + ImGuiID HoverWindowUnlockedStationaryId; // Mouse has once been stationary on this window. Only reset after departing the window. + + // Mouse state + ImGuiMouseCursor MouseCursor; + float MouseStationaryTimer; // Time the mouse has been stationary (with some loose heuristic) ImVec2 MouseLastValidPos; + + // Widget state ImGuiInputTextState InputTextState; + ImGuiInputTextDeactivatedState InputTextDeactivatedState; ImFont InputTextPasswordFont; ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets - float ColorEditLastHue; // Backup of last Hue associated to LastColor, so we can restore Hue in lossy RGB<>HSV round trips - float ColorEditLastSat; // Backup of last Saturation associated to LastColor, so we can restore Saturation in lossy RGB<>HSV round trips - ImU32 ColorEditLastColor; // RGB value with alpha set to 0. + ImGuiID ColorEditCurrentID; // Set temporarily while inside of the parent-most ColorEdit4/ColorPicker4 (because they call each others). + ImGuiID ColorEditSavedID; // ID we are saving/restoring HS for + float ColorEditSavedHue; // Backup of last Hue associated to LastColor, so we can restore Hue in lossy RGB<>HSV round trips + float ColorEditSavedSat; // Backup of last Saturation associated to LastColor, so we can restore Saturation in lossy RGB<>HSV round trips + ImU32 ColorEditSavedColor; // RGB value with alpha set to 0. ImVec4 ColorPickerRef; // Initial/reference color at the time of opening the color picker. ImGuiComboPreviewData ComboPreviewData; + float SliderGrabClickOffset; float SliderCurrentAccum; // Accumulated slider delta when using navigation controls. bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it? bool DragCurrentAccumDirty; @@ -1661,13 +2004,12 @@ struct ImGuiContext float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled() short DisabledStackSize; short TooltipOverrideCount; - float TooltipSlowDelay; // Time before slow tooltips appears (FIXME: This is temporary until we merge in tooltip timer+priority work) ImVector ClipboardHandlerData; // If no custom clipboard handler is defined ImVector MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once // Platform support - ImVec2 PlatformImePos; // Cursor position request & last passed to the OS Input Method Editor - ImVec2 PlatformImeLastPos; + ImGuiPlatformImeData PlatformImeData; // Data updated by current frame + ImGuiPlatformImeData PlatformImeDataPrev; // Previous frame data (when changing we will call io.SetPlatformImeDataFn char PlatformLocaleDecimalPoint; // '.' or *localeconv()->decimal_point // Settings @@ -1680,6 +2022,9 @@ struct ImGuiContext ImVector Hooks; // Hooks for extensions (e.g. test engine) ImGuiID HookIdNext; // Next available HookId + // Localization + const char* LocalizationTable[ImGuiLocKey_COUNT]; + // Capture/Logging bool LogEnabled; // Currently capturing ImGuiLogType LogType; // Capture target @@ -1694,23 +2039,33 @@ struct ImGuiContext int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call. // Debug Tools + ImGuiDebugLogFlags DebugLogFlags; + ImGuiTextBuffer DebugLogBuf; + ImGuiTextIndex DebugLogIndex; + ImU8 DebugLogClipperAutoDisableFrames; + ImU8 DebugLocateFrames; // For DebugLocateItemOnHover(). This is used together with DebugLocateId which is in a hot/cached spot above. + ImS8 DebugBeginReturnValueCullDepth; // Cycle between 0..9 then wrap around. bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker()) + ImU8 DebugItemPickerMouseButton; ImGuiID DebugItemPickerBreakId; // Will call IM_DEBUG_BREAK() when encountering this ID ImGuiMetricsConfig DebugMetricsConfig; ImGuiStackTool DebugStackTool; // Misc - float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. + float FramerateSecPerFrame[60]; // Calculate estimate of framerate for user over the last 60 frames.. int FramerateSecPerFrameIdx; int FramerateSecPerFrameCount; float FramerateSecPerFrameAccum; - int WantCaptureMouseNextFrame; // Explicit capture via CaptureKeyboardFromApp()/CaptureMouseFromApp() sets those flags - int WantCaptureKeyboardNextFrame; + int WantCaptureMouseNextFrame; // Explicit capture override via SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard(). Default to -1. + int WantCaptureKeyboardNextFrame; // " int WantTextInputNextFrame; - char TempBuffer[1024 * 3 + 1]; // Temporary text buffer + ImVector TempBuffer; // Temporary text buffer ImGuiContext(ImFontAtlas* shared_font_atlas) { + IO.Ctx = this; + InputTextState.Ctx = this; + Initialized = false; FontAtlasOwnedByContext = shared_font_atlas ? false : true; Font = NULL; @@ -1724,18 +2079,21 @@ struct ImGuiContext TestEngineHookItems = false; TestEngine = NULL; + InputEventsNextMouseSource = ImGuiMouseSource_Mouse; + InputEventsNextEventId = 1; + WindowsActiveCount = 0; CurrentWindow = NULL; HoveredWindow = NULL; HoveredWindowUnderMovingWindow = NULL; MovingWindow = NULL; WheelingWindow = NULL; - WheelingWindowTimer = 0.0f; + WheelingWindowStartFrame = -1; + WheelingWindowReleaseTimer = 0.0f; DebugHookIdInfo = 0; HoveredId = HoveredIdPreviousFrame = 0; HoveredIdAllowOverlap = false; - HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false; HoveredIdDisabled = false; HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f; ActiveId = 0; @@ -1747,10 +2105,6 @@ struct ImGuiContext ActiveIdHasBeenPressedBefore = false; ActiveIdHasBeenEditedBefore = false; ActiveIdHasBeenEditedThisFrame = false; - ActiveIdUsingMouseWheel = false; - ActiveIdUsingNavDirMask = 0x00; - ActiveIdUsingNavInputMask = 0x00; - ActiveIdUsingKeyInputMask = 0x00; ActiveIdClickOffset = ImVec2(-1, -1); ActiveIdWindow = NULL; ActiveIdSource = ImGuiInputSource_None; @@ -1762,16 +2116,23 @@ struct ImGuiContext LastActiveId = 0; LastActiveIdTimer = 0.0f; + ActiveIdUsingNavDirMask = 0x00; + ActiveIdUsingAllKeyboardKeys = false; +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + ActiveIdUsingNavInputMask = 0x00; +#endif + + CurrentFocusScopeId = 0; CurrentItemFlags = ImGuiItemFlags_None; + BeginMenuCount = 0; NavWindow = NULL; - NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavActivateInputId = 0; - NavJustTabbedId = NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; + NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0; + NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None; - NavJustMovedToKeyMods = ImGuiKeyModFlags_None; - NavInputSource = ImGuiInputSource_None; + NavJustMovedToKeyMods = ImGuiMod_None; + NavInputSource = ImGuiInputSource_Keyboard; NavLayer = ImGuiNavLayer_Main; - NavIdTabCounter = INT_MAX; NavIdIsAlive = false; NavMousePosDirty = false; NavDisableHighlight = true; @@ -1779,28 +2140,24 @@ struct ImGuiContext NavAnyRequest = false; NavInitRequest = false; NavInitRequestFromMove = false; - NavInitResultId = 0; NavMoveSubmitted = false; NavMoveScoringItems = false; NavMoveForwardToNextFrame = false; NavMoveFlags = ImGuiNavMoveFlags_None; NavMoveScrollFlags = ImGuiScrollFlags_None; - NavMoveKeyMods = ImGuiKeyModFlags_None; + NavMoveKeyMods = ImGuiMod_None; NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None; NavScoringDebugCount = 0; - NavTabbingInputableRemaining = 0; + NavTabbingDir = 0; + NavTabbingCounter = 0; + ConfigNavWindowingKeyNext = ImGuiMod_Ctrl | ImGuiKey_Tab; + ConfigNavWindowingKeyPrev = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab; NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingToggleLayer = false; - TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL; - TabFocusRequestCurrCounterTabStop = INT_MAX; - TabFocusRequestNextCounterTabStop = INT_MAX; - TabFocusPressed = false; - DimBgRatio = 0.0f; - MouseCursor = ImGuiMouseCursor_Arrow; DragDropActive = DragDropWithinSource = DragDropWithinTarget = false; DragDropSourceFlags = ImGuiDragDropFlags_None; @@ -1814,32 +2171,44 @@ struct ImGuiContext DragDropHoldJustPressedId = 0; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); + ClipperTempDataStacked = 0; + CurrentTable = NULL; - CurrentTableStackIdx = -1; + TablesTempDataStacked = 0; CurrentTabBar = NULL; + HoverItemDelayId = HoverItemDelayIdPreviousFrame = HoverItemUnlockedStationaryId = HoverWindowUnlockedStationaryId = 0; + HoverItemDelayTimer = HoverItemDelayClearTimer = 0.0f; + + MouseCursor = ImGuiMouseCursor_Arrow; + MouseStationaryTimer = 0.0f; + TempInputId = 0; ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_; - ColorEditLastHue = ColorEditLastSat = 0.0f; - ColorEditLastColor = 0; + ColorEditCurrentID = ColorEditSavedID = 0; + ColorEditSavedHue = ColorEditSavedSat = 0.0f; + ColorEditSavedColor = 0; + SliderGrabClickOffset = 0.0f; SliderCurrentAccum = 0.0f; SliderCurrentAccumDirty = false; DragCurrentAccumDirty = false; DragCurrentAccum = 0.0f; DragSpeedDefaultRatio = 1.0f / 100.0f; + ScrollbarClickDeltaToGrabCenter = 0.0f; DisabledAlphaBackup = 0.0f; DisabledStackSize = 0; - ScrollbarClickDeltaToGrabCenter = 0.0f; TooltipOverrideCount = 0; - TooltipSlowDelay = 0.50f; - PlatformImePos = PlatformImeLastPos = ImVec2(FLT_MAX, FLT_MAX); + PlatformImeData.InputPos = ImVec2(0.0f, 0.0f); + PlatformImeDataPrev.InputPos = ImVec2(-1.0f, -1.0f); // Different to ensure initial submission PlatformLocaleDecimalPoint = '.'; SettingsLoaded = false; SettingsDirtyTimer = 0.0f; HookIdNext = 0; + memset(LocalizationTable, 0, sizeof(LocalizationTable)); + LogEnabled = false; LogType = ImGuiLogType_None; LogNextPrefix = LogNextSuffix = NULL; @@ -1849,14 +2218,19 @@ struct ImGuiContext LogDepthRef = 0; LogDepthToExpand = LogDepthToExpandDefault = 2; + DebugLogFlags = ImGuiDebugLogFlags_OutputToTTY; + DebugLocateId = 0; + DebugLogClipperAutoDisableFrames = 0; + DebugLocateFrames = 0; + DebugBeginReturnValueCullDepth = -1; DebugItemPickerActive = false; + DebugItemPickerMouseButton = ImGuiMouseButton_Left; DebugItemPickerBreakId = 0; memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0; FramerateSecPerFrameAccum = 0.0f; WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1; - memset(TempBuffer, 0, sizeof(TempBuffer)); } }; @@ -1879,17 +2253,20 @@ struct IMGUI_API ImGuiWindowTempData ImVec2 PrevLineSize; float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added). float PrevLineTextBaseOffset; + bool IsSameLine; + bool IsSetPos; ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) ImVec1 ColumnsOffset; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. ImVec1 GroupOffset; + ImVec2 CursorStartPosLossyness;// Record the loss of precision of CursorStartPos due to really large scrolling amount. This is used by clipper to compensate and fix the most common use case of large scroll area. // Keyboard/Gamepad navigation ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1) short NavLayersActiveMask; // Which layers have been written to (result from previous frame) short NavLayersActiveMaskNext;// Which layers have been written to (accumulator for current frame) - ImGuiID NavFocusScopeIdCurrent; // Current focus scope ID while appending + bool NavIsScrollPushableX; // Set when current work location may be scrolled horizontally when moving left / right. This is generally always true UNLESS within a column. bool NavHideHighlightOneFrame; - bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f) + bool NavWindowHasScrollY; // Set per window when scrolling can be used (== ScrollMax.y > 0.0f) // Miscellaneous bool MenuBarAppending; // FIXME: Remove this @@ -1903,7 +2280,6 @@ struct IMGUI_API ImGuiWindowTempData int CurrentTableIdx; // Current table index (into g.Tables) ImGuiLayoutType LayoutType; ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin() - int FocusCounterTabStop; // (Legacy Focus/Tabbing system) Same, but only count widgets which you can Tab through. // Local parameters stacks // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. @@ -1916,9 +2292,11 @@ struct IMGUI_API ImGuiWindowTempData // Storage for one window struct IMGUI_API ImGuiWindow { + ImGuiContext* Ctx; // Parent UI context (needs to be set explicitly by parent). char* Name; // Window name, owned by the window. ImGuiID ID; // == ImHashStr(Name) ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ + ImGuiViewportP* Viewport; // Always set in Begin(). Inactive windows may have a NULL value here if their viewport was discarded. ImVec2 Pos; // Position (always rounded-up to nearest pixel) ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 SizeFull; // Size when non collapsed @@ -1928,6 +2306,9 @@ struct IMGUI_API ImGuiWindow ImVec2 WindowPadding; // Window padding at the time of Begin(). float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc. float WindowBorderSize; // Window border size at the time of Begin(). + float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin(). + float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y). + float DecoInnerSizeX1, DecoInnerSizeY1; // Applied AFTER/OVER InnerRect. Specialized for Tables as they use specialized form of clipping and frozen rows/columns are inside InnerRect (and not part of regular decoration sizes). int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)! ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window) @@ -1947,9 +2328,11 @@ struct IMGUI_API ImGuiWindow bool Appearing; // Set during the frame where the window is appearing (or re-appearing) bool Hidden; // Do not display (== HiddenFrames*** > 0) bool IsFallbackWindow; // Set on the "Debug##Default" window. + bool IsExplicitChild; // Set when passed _ChildWindow, left to false by BeginDocked() bool HasCloseButton; // Set when the window has a close button (p_open != NULL) signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) + short BeginCountPreviousFrame; // Number of Begin() during the previous frame short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0. short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues. short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused. @@ -1994,6 +2377,7 @@ struct IMGUI_API ImGuiWindow ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer) ImDrawList DrawListInst; ImGuiWindow* ParentWindow; // If we are a child _or_ popup _or_ docked window, this is pointing to our parent. Otherwise NULL. + ImGuiWindow* ParentWindowInBeginStack; ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. Doesn't cross through popups/dock nodes. ImGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child. ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active. @@ -2002,6 +2386,8 @@ struct IMGUI_API ImGuiWindow ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.) ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1) ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space + ImVec2 NavPreferredScoringPosRel[ImGuiNavLayer_COUNT]; // Preferred X/Y position updated when moving on a given axis, reset to FLT_MAX. + ImGuiID NavRootFocusScopeId; // Focus Scope ID at the time of Begin() int MemoryDrawListIdxCapacity; // Backup of last idx/vtx count, so when waking up the window we can preallocate and avoid iterative alloc/copy int MemoryDrawListVtxCapacity; @@ -2014,17 +2400,14 @@ public: ImGuiID GetID(const char* str, const char* str_end = NULL); ImGuiID GetID(const void* ptr); ImGuiID GetID(int n); - ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); - ImGuiID GetIDNoKeepAlive(const void* ptr); - ImGuiID GetIDNoKeepAlive(int n); ImGuiID GetIDFromRectangle(const ImRect& r_abs); - // We don't use g.FontSize because the window may be != g.CurrentWidow. + // We don't use g.FontSize because the window may be != g.CurrentWindow. ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } - float CalcFontSize() const { ImGuiContext& g = *GImGui; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; } - float TitleBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; } + float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; } + float TitleBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; } ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } - float MenuBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; } + float MenuBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; } ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } }; @@ -2037,7 +2420,7 @@ enum ImGuiTabBarFlagsPrivate_ { ImGuiTabBarFlags_DockNode = 1 << 20, // Part of a dock node [we don't use this in the master branch but it facilitate branch syncing to keep this around] ImGuiTabBarFlags_IsFocused = 1 << 21, - ImGuiTabBarFlags_SaveSettings = 1 << 22 // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs + ImGuiTabBarFlags_SaveSettings = 1 << 22, // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs }; // Extend ImGuiTabItemFlags_ @@ -2045,7 +2428,7 @@ enum ImGuiTabItemFlagsPrivate_ { ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing, ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout) - ImGuiTabItemFlags_Button = 1 << 21 // Used by TabItemButton, change the tab item behavior to mimic a button + ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button }; // Storage for one active tab item (sizeof() 40 bytes) @@ -2058,16 +2441,17 @@ struct ImGuiTabItem float Offset; // Position relative to beginning of tab float Width; // Width currently displayed float ContentWidth; // Width of label, stored during BeginTabItem() call + float RequestedWidth; // Width optionally requested by caller, -1.0f is unused ImS32 NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames ImS16 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling ImGuiTabBarFlags_Reorderable - ImS16 IndexDuringLayout; // Index only used during TabBarLayout() + ImS16 IndexDuringLayout; // Index only used during TabBarLayout(). Tabs gets reordered so 'Tabs[n].IndexDuringLayout == n' but may mismatch during additions. bool WantClose; // Marked as closed by SetTabItemClosed() - ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; } + ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; } }; // Storage for a tab bar (sizeof() 152 bytes) -struct ImGuiTabBar +struct IMGUI_API ImGuiTabBar { ImVector Tabs; ImGuiTabBarFlags Flags; @@ -2102,12 +2486,6 @@ struct ImGuiTabBar ImGuiTextBuffer TabsNames; // For non-docking tab bar we re-append names in a contiguous buffer. ImGuiTabBar(); - int GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); } - const char* GetTabName(const ImGuiTabItem* tab) const - { - IM_ASSERT(tab->NameOffset != -1 && tab->NameOffset < TabsNames.Buf.Size); - return TabsNames.Buf.Data + tab->NameOffset; - } }; //----------------------------------------------------------------------------- @@ -2115,14 +2493,13 @@ struct ImGuiTabBar //----------------------------------------------------------------------------- #define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color. -#define IMGUI_TABLE_MAX_COLUMNS 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64. -#define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels() +#define IMGUI_TABLE_MAX_COLUMNS 512 // May be further lifted // Our current column maximum is 64 but we may raise that in the future. -typedef ImS8 ImGuiTableColumnIdx; -typedef ImU8 ImGuiTableDrawChannelIdx; +typedef ImS16 ImGuiTableColumnIdx; +typedef ImU16 ImGuiTableDrawChannelIdx; -// [Internal] sizeof() ~ 104 +// [Internal] sizeof() ~ 112 // We use the terminology "Enabled" to refer to a column that is not Hidden by user/api. // We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping. // This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped". @@ -2168,7 +2545,7 @@ struct ImGuiTableColumn ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3) ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each) - ImU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each) + ImU8 SortDirectionsAvailList; // Ordered list of available sort directions (2-bits each, total 8-bits) ImGuiTableColumn() { @@ -2191,8 +2568,20 @@ struct ImGuiTableCellData ImGuiTableColumnIdx Column; // Column number }; -// FIXME-TABLE: more transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData -struct ImGuiTable +// Per-instance data that needs preserving across frames (seemingly most others do not need to be preserved aside from debug needs. Does that means they could be moved to ImGuiTableTempData?) +struct ImGuiTableInstanceData +{ + ImGuiID TableInstanceID; + float LastOuterHeight; // Outer height from last frame + float LastFirstRowHeight; // Height of first row from last frame (FIXME: this is used as "header height" and may be reworked) + float LastFrozenHeight; // Height of frozen section from last frame + + ImGuiTableInstanceData() { TableInstanceID = 0; LastOuterHeight = LastFirstRowHeight = LastFrozenHeight = 0.0f; } +}; + +// FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs, incoming RowData +// sizeof() ~ 580 bytes + heap allocs described in TableBeginInitMemory() +struct IMGUI_API ImGuiTable { ImGuiID ID; ImGuiTableFlags Flags; @@ -2201,10 +2590,9 @@ struct ImGuiTable ImSpan Columns; // Point within RawData[] ImSpan DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1) ImSpan RowCellData; // Point within RawData[]. Store cells background requests for current row. - ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map - ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data - ImU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect) - ImU64 RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items) + ImBitArrayPtr EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map + ImBitArrayPtr EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data + ImBitArrayPtr VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect) ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order) int SettingsOffset; // Offset in g.SettingsTables int LastFrameActive; @@ -2233,11 +2621,10 @@ struct ImGuiTable float CellPaddingY; float CellSpacingX1; // Spacing between non-bordered cells float CellSpacingX2; - float LastOuterHeight; // Outer height from last frame - float LastFirstRowHeight; // Height of first row from last frame float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details. float ColumnsGivenWidth; // Sum of current column width float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window + float ColumnsStretchSumWeights; // Sum of weight of all enabled stretching columns float ResizedColumnNextWidth; float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table. float RefScale; // Reference scale to be able to rescale columns on font/dpi changes. @@ -2245,7 +2632,7 @@ struct ImGuiTable ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is ImRect WorkRect; ImRect InnerClipRect; - ImRect BgClipRect; // We use this to cpu-clip cell background color fill + ImRect BgClipRect; // We use this to cpu-clip cell background color fill, evolve during the frame as we cross frozen rows boundaries ImRect Bg0ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG0/1 channel. This tends to be == OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped ImRect Bg2ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG2 channel. This tends to be a correct, tight-fit, because output to BG2 are done by widgets relying on regular ClipRect. ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window. @@ -2254,6 +2641,8 @@ struct ImGuiTable ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window) ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names ImDrawListSplitter* DrawSplitter; // Shortcut to TempData->DrawSplitter while in table. Isolate draw commands per columns to avoid switching clip rect constantly + ImGuiTableInstanceData InstanceDataFirst; + ImVector InstanceDataExtra; // FIXME-OPT: Using a small-vector pattern would be good. ImGuiTableColumnSortSpecs SortSpecsSingle; ImVector SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would be good. ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs() @@ -2295,17 +2684,20 @@ struct ImGuiTable bool IsResetDisplayOrderRequest; bool IsUnfrozenRows; // Set when we got past the frozen row. bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable() + bool HasScrollbarYCurr; // Whether ANY instance of this table had a vertical scrollbar during the current frame. + bool HasScrollbarYPrev; // Whether ANY instance of this table had a vertical scrollbar during the previous. bool MemoryCompacted; bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis - IMGUI_API ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; } - IMGUI_API ~ImGuiTable() { IM_FREE(RawData); } + ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; } + ~ImGuiTable() { IM_FREE(RawData); } }; // Transient data that are only needed between BeginTable() and EndTable(), those buffers are shared (1 per level of stacked table). // - Accessing those requires chasing an extra pointer so for very frequently used data we leave them in the main table structure. // - We also leave out of this structure data that tend to be particularly useful for debugging/metrics. -struct ImGuiTableTempData +// sizeof() ~ 112 bytes. +struct IMGUI_API ImGuiTableTempData { int TableIndex; // Index in g.Tables.Buf[] pool float LastTimeActive; // Last timestamp this structure was used @@ -2322,7 +2714,7 @@ struct ImGuiTableTempData float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable() int HostBackupItemWidthStackSize;//Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable() - IMGUI_API ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; } + ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; } }; // sizeof() ~ 12 @@ -2382,19 +2774,27 @@ namespace ImGui IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window); IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window); IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy); + IMGUI_API bool IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent); IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below); IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0); IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0); IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size); + IMGUI_API void SetWindowHiddendAndSkipItemsForCurrentFrame(ImGuiWindow* window); + inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); } + inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); } + inline ImVec2 WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p) { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); } // Windows: Display Order and Focus Order - IMGUI_API void FocusWindow(ImGuiWindow* window); - IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window); + IMGUI_API void FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags = 0); + IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window, ImGuiViewport* filter_viewport, ImGuiFocusRequestFlags flags); IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window); + IMGUI_API void BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* above_window); + IMGUI_API int FindWindowDisplayIndex(ImGuiWindow* window); + IMGUI_API ImGuiWindow* FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* window); // Fonts, drawing IMGUI_API void SetCurrentFont(ImFont* font); @@ -2404,10 +2804,11 @@ namespace ImGui IMGUI_API ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport); // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents. // Init - IMGUI_API void Initialize(ImGuiContext* context); - IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext(). + IMGUI_API void Initialize(); + IMGUI_API void Shutdown(); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext(). // NewFrame + IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs); IMGUI_API void UpdateHoveredWindowAndCaptureFlags(); IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window); IMGUI_API void UpdateMouseMovingWindowNewFrame(); @@ -2418,17 +2819,28 @@ namespace ImGui IMGUI_API void RemoveContextHook(ImGuiContext* context, ImGuiID hook_to_remove); IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type); + // Viewports + IMGUI_API void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport); + // Settings IMGUI_API void MarkIniSettingsDirty(); IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window); IMGUI_API void ClearIniSettings(); - IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name); - IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); - IMGUI_API ImGuiWindowSettings* FindOrCreateWindowSettings(const char* name); + IMGUI_API void AddSettingsHandler(const ImGuiSettingsHandler* handler); + IMGUI_API void RemoveSettingsHandler(const char* type_name); IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); + // Settings - Windows + IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name); + IMGUI_API ImGuiWindowSettings* FindWindowSettingsByID(ImGuiID id); + IMGUI_API ImGuiWindowSettings* FindWindowSettingsByWindow(ImGuiWindow* window); + IMGUI_API void ClearWindowSettings(const char* name); + + // Localization + IMGUI_API void LocalizeRegisterEntries(const ImGuiLocEntry* entries, int count); + inline const char* LocalizeGetMsg(ImGuiLocKey key) { ImGuiContext& g = *GImGui; const char* msg = g.LocalizationTable[key]; return msg ? msg : "*Missing Text*"; } + // Scrolling - IMGUI_API void SetNextWindowScroll(const ImVec2& scroll); // Use -1.0f on one axis to leave as-is IMGUI_API void SetScrollX(ImGuiWindow* window, float scroll_x); IMGUI_API void SetScrollY(ImGuiWindow* window, float scroll_y); IMGUI_API void SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio); @@ -2443,7 +2855,6 @@ namespace ImGui //#endif // Basic Accessors - inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.LastItemData.ID; } // Get ID of last item (~~ often same ImGui::GetID(label) beforehand) inline ImGuiItemStatusFlags GetItemStatusFlags(){ ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; } inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; } inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } @@ -2457,14 +2868,16 @@ namespace ImGui IMGUI_API void MarkItemEdited(ImGuiID id); // Mark data associated to given item as "edited", used by IsItemDeactivatedAfterEdit() function. IMGUI_API void PushOverrideID(ImGuiID id); // Push given value as-is at the top of the ID stack (whereas PushID combines old and new hashes) IMGUI_API ImGuiID GetIDWithSeed(const char* str_id_begin, const char* str_id_end, ImGuiID seed); + IMGUI_API ImGuiID GetIDWithSeed(int n, ImGuiID seed); // Basic Helpers for widget code IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f); - IMGUI_API void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f); + inline void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f) { ItemSize(bb.GetSize(), text_baseline_y); } // FIXME: This is a misleading API since we expect CursorPos to be bb.Min. IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0); - IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); - IMGUI_API void ItemInputable(ImGuiWindow* window, ImGuiID id); + IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags); + IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0); IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id); + IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API void PushMultiItemsWidths(int components, float width_full); @@ -2472,20 +2885,10 @@ namespace ImGui IMGUI_API ImVec2 GetContentRegionMaxAbs(); IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); - // Parameter stacks + // Parameter stacks (shared) IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); - -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - // Currently refactoring focus/nav/tabbing system - // If you have old/custom copy-and-pasted widgets that used FocusableItemRegister(): - // (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)' - // (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' - // (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedTabbing) != 0 || g.NavActivateInputId == id' (WIP) - // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText() - inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd() - inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem -#endif + IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx); // Logging/Capture IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. @@ -2501,9 +2904,11 @@ namespace ImGui IMGUI_API void ClosePopupsExceptModals(); IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); - IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags); + IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags); IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window); IMGUI_API ImGuiWindow* GetTopMostPopupModal(); + IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal(); + IMGUI_API ImGuiWindow* FindBlockingModal(ImGuiWindow* window); IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window); IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy); @@ -2523,41 +2928,118 @@ namespace ImGui IMGUI_API bool NavMoveRequestButNoResultYet(); IMGUI_API void NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags); - IMGUI_API void NavMoveRequestResolveWithLastItem(); + IMGUI_API void NavMoveRequestResolveWithLastItem(ImGuiNavItemData* result); IMGUI_API void NavMoveRequestCancel(); IMGUI_API void NavMoveRequestApplyResult(); IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); - IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); - IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); - IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); - IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. + IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis); + IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX(); + IMGUI_API void SetNavWindow(ImGuiWindow* window); IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel); - // Focus Scope (WIP) - // This is generally used to identify a selection set (multiple of which may be in the same window), as selection - // patterns generally need to react (e.g. clear selection) when landing on an item of the set. - IMGUI_API void PushFocusScope(ImGuiID id); - IMGUI_API void PopFocusScope(); - inline ImGuiID GetFocusedFocusScope() { ImGuiContext& g = *GImGui; return g.NavFocusScopeId; } // Focus scope which is actually active - inline ImGuiID GetFocusScope() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.NavFocusScopeIdCurrent; } // Focus scope we are outputting into, set by PushFocusScope() + // Focus/Activation + // This should be part of a larger set of API: FocusItem(offset = -1), FocusItemByID(id), ActivateItem(offset = -1), ActivateItemByID(id) etc. which are + // much harder to design and implement than expected. I have a couple of private branches on this matter but it's not simple. For now implementing the easy ones. + IMGUI_API void FocusItem(); // Focus last item (no selection/activation). + IMGUI_API void ActivateItemByID(ImGuiID id); // Activate an item by ID (button, checkbox, tree node etc.). Activation is queued and processed on the next frame when the item is encountered again. // Inputs // FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions. - IMGUI_API void SetItemUsingMouseWheel(); - IMGUI_API void SetActiveIdUsingNavAndKeys(); - inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } - inline bool IsActiveIdUsingNavInput(ImGuiNavInput input) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavInputMask & (1 << input)) != 0; } - inline bool IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; IM_ASSERT(key < 64); return (g.ActiveIdUsingKeyInputMask & ((ImU64)1 << key)) != 0; } + inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; } + inline bool IsNamedKeyOrModKey(ImGuiKey key) { return (key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END) || key == ImGuiMod_Ctrl || key == ImGuiMod_Shift || key == ImGuiMod_Alt || key == ImGuiMod_Super || key == ImGuiMod_Shortcut; } + inline bool IsLegacyKey(ImGuiKey key) { return key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_LegacyNativeKey_END; } + inline bool IsKeyboardKey(ImGuiKey key) { return key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END; } + inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; } + inline bool IsMouseKey(ImGuiKey key) { return key >= ImGuiKey_Mouse_BEGIN && key < ImGuiKey_Mouse_END; } + inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; } + inline ImGuiKeyChord ConvertShortcutMod(ImGuiKeyChord key_chord) { ImGuiContext& g = *GImGui; IM_ASSERT_PARANOID(key_chord & ImGuiMod_Shortcut); return (key_chord & ~ImGuiMod_Shortcut) | (g.IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl); } + inline ImGuiKey ConvertSingleModFlagToKey(ImGuiContext* ctx, ImGuiKey key) + { + ImGuiContext& g = *ctx; + if (key == ImGuiMod_Ctrl) return ImGuiKey_ReservedForModCtrl; + if (key == ImGuiMod_Shift) return ImGuiKey_ReservedForModShift; + if (key == ImGuiMod_Alt) return ImGuiKey_ReservedForModAlt; + if (key == ImGuiMod_Super) return ImGuiKey_ReservedForModSuper; + if (key == ImGuiMod_Shortcut) return (g.IO.ConfigMacOSXBehaviors ? ImGuiKey_ReservedForModSuper : ImGuiKey_ReservedForModCtrl); + return key; + } + + IMGUI_API ImGuiKeyData* GetKeyData(ImGuiContext* ctx, ImGuiKey key); + inline ImGuiKeyData* GetKeyData(ImGuiKey key) { ImGuiContext& g = *GImGui; return GetKeyData(&g, key); } + IMGUI_API void GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size); + inline ImGuiKey MouseButtonToKey(ImGuiMouseButton button) { IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); return (ImGuiKey)(ImGuiKey_MouseLeft + button); } IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f); - inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { ImGuiContext& g = *GImGui; const int key_index = g.IO.KeyMap[key]; return (key_index >= 0) ? IsKeyPressed(key_index, repeat) : false; } - inline bool IsNavInputDown(ImGuiNavInput n) { ImGuiContext& g = *GImGui; return g.IO.NavInputs[n] > 0.0f; } - inline bool IsNavInputTest(ImGuiNavInput n, ImGuiInputReadMode rm) { return (GetNavInputAmount(n, rm) > 0.0f); } - IMGUI_API ImGuiKeyModFlags GetMergedKeyModFlags(); + IMGUI_API ImVec2 GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down); + IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis); + IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); + IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate); + IMGUI_API void SetActiveIdUsingAllKeyboardKeys(); + inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } + + // [EXPERIMENTAL] Low-Level: Key/Input Ownership + // - The idea is that instead of "eating" a given input, we can link to an owner id. + // - Ownership is most often claimed as a result of reacting to a press/down event (but occasionally may be claimed ahead). + // - Input queries can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID. + // - Legacy input queries (without specifying an owner or _Any or _None) are equivalent to using ImGuiKeyOwner_Any (== 0). + // - Input ownership is automatically released on the frame after a key is released. Therefore: + // - for ownership registration happening as a result of a down/press event, the SetKeyOwner() call may be done once (common case). + // - for ownership registration happening ahead of a down/press event, the SetKeyOwner() call needs to be made every frame (happens if e.g. claiming ownership on hover). + // - SetItemKeyOwner() is a shortcut for common simple case. A custom widget will probably want to call SetKeyOwner() multiple times directly based on its interaction state. + // - This is marked experimental because not all widgets are fully honoring the Set/Test idioms. We will need to move forward step by step. + // Please open a GitHub Issue to submit your usage scenario or if there's a use case you need solved. + IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key); + IMGUI_API void SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); + IMGUI_API void SetKeyOwnersForKeyChord(ImGuiKeyChord key, ImGuiID owner_id, ImGuiInputFlags flags = 0); + IMGUI_API void SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags = 0); // Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'. + IMGUI_API bool TestKeyOwner(ImGuiKey key, ImGuiID owner_id); // Test that key is either not owned, either owned by 'owner_id' + inline ImGuiKeyOwnerData* GetKeyOwnerData(ImGuiContext* ctx, ImGuiKey key) { if (key & ImGuiMod_Mask_) key = ConvertSingleModFlagToKey(ctx, key); IM_ASSERT(IsNamedKey(key)); return &ctx->KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; } + + // [EXPERIMENTAL] High-Level: Input Access functions w/ support for Key/Input Ownership + // - Important: legacy IsKeyPressed(ImGuiKey, bool repeat=true) _DEFAULTS_ to repeat, new IsKeyPressed() requires _EXPLICIT_ ImGuiInputFlags_Repeat flag. + // - Expected to be later promoted to public API, the prototypes are designed to replace existing ones (since owner_id can default to Any == 0) + // - Specifying a value for 'ImGuiID owner' will test that EITHER the key is NOT owned (UNLESS locked), EITHER the key is owned by 'owner'. + // Legacy functions use ImGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease. + // - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API. + IMGUI_API bool IsKeyDown(ImGuiKey key, ImGuiID owner_id); + IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat. + IMGUI_API bool IsKeyReleased(ImGuiKey key, ImGuiID owner_id); + IMGUI_API bool IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id); + IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0); + IMGUI_API bool IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id); + + // [EXPERIMENTAL] Shortcut Routing + // - ImGuiKeyChord = a ImGuiKey optionally OR-red with ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super. + // ImGuiKey_C (accepted by functions taking ImGuiKey or ImGuiKeyChord) + // ImGuiKey_C | ImGuiMod_Ctrl (accepted by functions taking ImGuiKeyChord) + // ONLY ImGuiMod_XXX values are legal to 'OR' with an ImGuiKey. You CANNOT 'OR' two ImGuiKey values. + // - When using one of the routing flags (e.g. ImGuiInputFlags_RouteFocused): routes requested ahead of time given a chord (key + modifiers) and a routing policy. + // - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame. + // - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route. + // - Multiple read sites may use the same owner id and will all get the granted route. + // - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location. + IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); + IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); + IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id); + IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord); + + // [EXPERIMENTAL] Focus Scope + // This is generally used to identify a unique input location (for e.g. a selection set) + // There is one per window (automatically set in Begin), but: + // - Selection patterns generally need to react (e.g. clear a selection) when landing on one item of the set. + // So in order to identify a set multiple lists in same window may each need a focus scope. + // If you imagine an hypothetical BeginSelectionGroup()/EndSelectionGroup() api, it would likely call PushFocusScope()/EndFocusScope() + // - Shortcut routing also use focus scope as a default location identifier if an owner is not provided. + // We don't use the ID Stack for this as it is common to want them separate. + IMGUI_API void PushFocusScope(ImGuiID id); + IMGUI_API void PopFocusScope(); + inline ImGuiID GetCurrentFocusScope() { ImGuiContext& g = *GImGui; return g.CurrentFocusScopeId; } // Focus scope we are outputting into, set by PushFocusScope() // Drag and Drop + IMGUI_API bool IsDragDropActive(); IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); IMGUI_API void ClearDragDrop(); IMGUI_API bool IsDragDropPayloadBeingAccepted(); + IMGUI_API void RenderDragDropTargetRect(const ImRect& bb); // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API) IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect); @@ -2592,7 +3074,10 @@ namespace ImGui IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table); IMGUI_API void TableDrawBorders(ImGuiTable* table); IMGUI_API void TableDrawContextMenu(ImGuiTable* table); + IMGUI_API bool TableBeginContextMenuPopup(ImGuiTable* table); IMGUI_API void TableMergeDrawChannels(ImGuiTable* table); + inline ImGuiTableInstanceData* TableGetInstanceData(ImGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; } + inline ImGuiID TableGetInstanceID(ImGuiTable* table, int instance_no) { return TableGetInstanceData(table, instance_no)->TableInstanceID; } IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table); IMGUI_API void TableSortSpecsBuild(ImGuiTable* table); IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column); @@ -2604,7 +3089,7 @@ namespace ImGui IMGUI_API void TableEndCell(ImGuiTable* table); IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n); IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n); - IMGUI_API ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0); + IMGUI_API ImGuiID TableGetColumnResizeID(ImGuiTable* table, int column_n, int instance_no = 0); IMGUI_API float TableGetMaxColumnWidth(const ImGuiTable* table, int column_n); IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n); IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table); @@ -2618,20 +3103,27 @@ namespace ImGui IMGUI_API void TableSaveSettings(ImGuiTable* table); IMGUI_API void TableResetSettings(ImGuiTable* table); IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table); - IMGUI_API void TableSettingsInstallHandler(ImGuiContext* context); + IMGUI_API void TableSettingsAddSettingsHandler(); IMGUI_API ImGuiTableSettings* TableSettingsCreate(ImGuiID id, int columns_count); IMGUI_API ImGuiTableSettings* TableSettingsFindByID(ImGuiID id); // Tab Bars + inline ImGuiTabBar* GetCurrentTabBar() { ImGuiContext& g = *GImGui; return g.CurrentTabBar; } IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags); IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id); + IMGUI_API ImGuiTabItem* TabBarFindTabByOrder(ImGuiTabBar* tab_bar, int order); + IMGUI_API ImGuiTabItem* TabBarGetCurrentTab(ImGuiTabBar* tab_bar); + inline int TabBarGetTabOrder(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) { return tab_bar->Tabs.index_from_ptr(tab); } + IMGUI_API const char* TabBarGetTabName(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); - IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int offset); - IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, ImVec2 mouse_pos); + IMGUI_API void TabBarQueueFocus(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); + IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, int offset); + IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos); IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar); - IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags); - IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button); + IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window); + IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker); + IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window); IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col); IMGUI_API void TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped); @@ -2648,47 +3140,45 @@ namespace ImGui IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0); IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. + IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow); // Render helpers (those functions don't access any ImGui state!) IMGUI_API void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale = 1.0f); IMGUI_API void RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col); IMGUI_API void RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz); - IMGUI_API void RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow); IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col); IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); - IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding); - -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - // [1.71: 2019/06/07: Updating prototypes of some of the internal functions. Leaving those for reference for a short while] - inline void RenderArrow(ImVec2 pos, ImGuiDir dir, float scale=1.0f) { ImGuiWindow* window = GetCurrentWindow(); RenderArrow(window->DrawList, pos, GetColorU32(ImGuiCol_Text), dir, scale); } - inline void RenderBullet(ImVec2 pos) { ImGuiWindow* window = GetCurrentWindow(); RenderBullet(window->DrawList, pos, GetColorU32(ImGuiCol_Text)); } -#endif + IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, const ImRect& outer, const ImRect& inner, ImU32 col, float rounding); // Widgets IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); + IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0); + IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags = 0); + IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags, float thickness = 1.0f); + IMGUI_API void SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_width); + IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value); + IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value); + + // Widgets: Window Decorations IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos); IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos); - IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0); IMGUI_API void Scrollbar(ImGuiAxis axis); - IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float avail_v, float contents_v, ImDrawFlags flags); - IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col); + IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 avail_v, ImS64 contents_v, ImDrawFlags flags); IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners IMGUI_API ImGuiID GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir); - IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags); - IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value); - IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value); // Widgets low-level behaviors IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb); - IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f); + IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f, ImU32 bg_col = 0); IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); - IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextItemOpen() data, if any. May return true when logging IMGUI_API void TreePushOverrideID(ImGuiID id); + IMGUI_API void TreeNodeSetOpen(ImGuiID id, bool open); + IMGUI_API bool TreeNodeUpdateNextOpen(ImGuiID id, ImGuiTreeNodeFlags flags); // Return open state. Consume previous SetNextItemOpen() data, if any. May return true when logging. // Template functions are instantiated in imgui_widgets.cpp for a finite number of types. // To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link to existing instances and silence Clang warnings (see #2036). @@ -2697,23 +3187,24 @@ namespace ImGui template IMGUI_API T ScaleValueFromRatioT(ImGuiDataType data_type, float t, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size); template IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags); template IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb); - template IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v); + template IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v); template IMGUI_API bool CheckboxFlagsT(const char* label, T* flags, T flags_value); // Data type helpers IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type); IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format); IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2); - IMGUI_API bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* p_data, const char* format); + IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format); IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2); IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max); // InputText IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); + IMGUI_API void InputTextDeactivateHook(ImGuiID id); IMGUI_API bool TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags); IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL); inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); } - inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active + inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active // Color IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); @@ -2721,7 +3212,7 @@ namespace ImGui IMGUI_API void ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags flags); // Plot - IMGUI_API int PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size); + IMGUI_API int PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, const ImVec2& size_arg); // Shade functions (write over already created vertices) IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); @@ -2732,28 +3223,56 @@ namespace ImGui IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window); IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window); + // Debug Log + IMGUI_API void DebugLog(const char* fmt, ...) IM_FMTARGS(1); + IMGUI_API void DebugLogV(const char* fmt, va_list args) IM_FMTLIST(1); + // Debug Tools IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL); IMGUI_API void ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL); + IMGUI_API void ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); + IMGUI_API void DebugLocateItem(ImGuiID target_id); // Call sparingly: only 1 at the same time! + IMGUI_API void DebugLocateItemOnHover(ImGuiID target_id); // Only call on reaction to a mouse Hover: because only 1 at the same time! + IMGUI_API void DebugLocateItemResolveWithLastItem(); inline void DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, col); } inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; } - IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); IMGUI_API void DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end); IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns); IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, const ImDrawList* draw_list, const char* label); IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb); IMGUI_API void DebugNodeFont(ImFont* font); + IMGUI_API void DebugNodeFontGlyph(ImFont* font, const ImFontGlyph* glyph); IMGUI_API void DebugNodeStorage(ImGuiStorage* storage, const char* label); IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label); IMGUI_API void DebugNodeTable(ImGuiTable* table); IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings); + IMGUI_API void DebugNodeInputTextState(ImGuiInputTextState* state); IMGUI_API void DebugNodeWindow(ImGuiWindow* window, const char* label); IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings); IMGUI_API void DebugNodeWindowsList(ImVector* windows, const char* label); + IMGUI_API void DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int windows_size, ImGuiWindow* parent_in_begin_stack); IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport); + IMGUI_API void DebugRenderKeyboardPreview(ImDrawList* draw_list); IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb); + // Obsolete functions +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89 + inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89 + + // Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets that used FocusableItemRegister(): + // (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)' + // (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' + // (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedTabbing) != 0 || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))' (WIP) + // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText() + inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd() + inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem +#endif +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity! +#endif + } // namespace ImGui @@ -2768,7 +3287,9 @@ struct ImFontBuilderIO }; // Helper for font builder +#ifdef IMGUI_ENABLE_STB_TRUETYPE IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype(); +#endif IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque); @@ -2783,16 +3304,18 @@ IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table //----------------------------------------------------------------------------- #ifdef IMGUI_ENABLE_TEST_ENGINE -extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id); +extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, ImGuiID id, const ImRect& bb, const ImGuiLastItemData* item_data); // item_data may be NULL extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags); extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...); extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiID id); -#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemAdd(&g, _BB, _ID) // Register item bounding box -#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional) -#define IMGUI_TEST_ENGINE_LOG(_FMT,...) if (g.TestEngineHookItems) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log +// In IMGUI_VERSION_NUM >= 18934: changed IMGUI_TEST_ENGINE_ITEM_ADD(bb,id) to IMGUI_TEST_ENGINE_ITEM_ADD(id,bb,item_data); +#define IMGUI_TEST_ENGINE_ITEM_ADD(_ID,_BB,_ITEM_DATA) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemAdd(&g, _ID, _BB, _ITEM_DATA) // Register item bounding box +#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional) +#define IMGUI_TEST_ENGINE_LOG(_FMT,...) if (g.TestEngineHookItems) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log #else -#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)0) +#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0) +#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g) #endif //----------------------------------------------------------------------------- diff --git a/Externals/imgui/imgui_tables.cpp b/Externals/imgui/imgui_tables.cpp index 56056ae39e..d3967a5ff9 100644 --- a/Externals/imgui/imgui_tables.cpp +++ b/Externals/imgui/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.85 +// dear imgui, v1.89.7 // (tables and columns code) /* @@ -24,7 +24,7 @@ Index of this file: */ // Navigating this file: -// - In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. // - With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. //----------------------------------------------------------------------------- @@ -80,20 +80,20 @@ Index of this file: // - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge. // - outer_size.x > 0.0f -> Set Fixed width. // Y with ScrollX/ScrollY disabled: we output table directly in current window -// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful is parent window can vertically scroll. +// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful if parent window can vertically scroll. // - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set) // - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set) // Y with ScrollX/ScrollY enabled: using a child window for scrolling -// - outer_size.y < 0.0f -> Bottom-align. Not meaningful is parent window can vertically scroll. +// - outer_size.y < 0.0f -> Bottom-align. Not meaningful if parent window can vertically scroll. // - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window. // - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis. //----------------------------------------------------------------------------- // Outer size is also affected by the NoHostExtendX/NoHostExtendY flags. -// Important to that note how the two flags have slightly different behaviors! +// Important to note how the two flags have slightly different behaviors! // - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used. // - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY is disabled. Data below the limit will be clipped and not visible. // In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height. -// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable) +// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not useful and not easily noticeable). //----------------------------------------------------------------------------- // About 'inner_width': // With ScrollX disabled: @@ -112,15 +112,16 @@ Index of this file: //----------------------------------------------------------------------------- // COLUMNS SIZING POLICIES +// (Reference: ImGuiTableFlags_SizingXXX flags and ImGuiTableColumnFlags_WidthXXX flags) //----------------------------------------------------------------------------- // About overriding column sizing policy and width/weight with TableSetupColumn(): -// We use a default parameter of 'init_width_or_weight == -1'. +// We use a default parameter of -1 for 'init_width'/'init_weight'. // - with ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic // - with ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom // - with ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f // - with ImGuiTableColumnFlags_WidthStretch, init_weight > 0 (explicit) --> weight is custom // Widths are specified _without_ CellPadding. If you specify a width of 100.0f, the column will be cover (100.0f + Padding * 2.0f) -// and you can fit a 100.0f wide item in it without clipping and with full padding. +// and you can fit a 100.0f wide item in it without clipping and with padding honored. //----------------------------------------------------------------------------- // About default sizing policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag) // - with Table policy ImGuiTableFlags_SizingFixedFit --> default Column policy is ImGuiTableColumnFlags_WidthFixed, default Width is equal to contents width @@ -134,10 +135,10 @@ Index of this file: // - using mixed policies with ScrollX does not make much sense, as using Stretch columns with ScrollX does not make much sense in the first place! // that is, unless 'inner_width' is passed to BeginTable() to explicitly provide a total width to layout columns in. // - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the width of the maximum contents. -// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths. +// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weights/widths. //----------------------------------------------------------------------------- // About using column width: -// If a column is manual resizable or has a width specified with TableSetupColumn(): +// If a column is manually resizable or has a width specified with TableSetupColumn(): // - you may use GetContentRegionAvail().x to query the width available in a given column. // - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width. // If the column is not resizable and has no width specified with TableSetupColumn(): @@ -151,7 +152,7 @@ Index of this file: // TABLES CLIPPING/CULLING //----------------------------------------------------------------------------- // About clipping/culling of Rows in Tables: -// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows. +// - For large numbers of rows, it is recommended you use ImGuiListClipper to submit only visible rows. // ImGuiListClipper is reliant on the fact that rows are of equal height. // See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper. // - Note that auto-resizing columns don't play well with using the clipper. @@ -168,7 +169,7 @@ Index of this file: // - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.). // // [A] [B] [C] -// TableNextColumn(): true false false -> [userland] when TableNextColumn() / TableSetColumnIndex() return false, user can skip submitting items but only if the column doesn't contribute to row height. +// TableNextColumn(): true false false -> [userland] when TableNextColumn() / TableSetColumnIndex() returns false, user can skip submitting items but only if the column doesn't contribute to row height. // SkipItems: false false true -> [internal] when SkipItems is true, most widgets will early out if submitted, resulting is no layout output. // ClipRect: normal zero-width zero-width -> [internal] when ClipRect is zero, ItemAdd() will return false and most widgets will early out mid-way. // ImDrawList output: normal dummy dummy -> [internal] when using the dummy channel, ImDrawList submissions (if any) will be wasted (because cliprect is zero-width anyway). @@ -188,12 +189,12 @@ Index of this file: #define _CRT_SECURE_NO_WARNINGS #endif -#include "imgui.h" -#ifndef IMGUI_DISABLE - #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS #endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE #include "imgui_internal.h" // System includes @@ -315,11 +316,11 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG return false; // Sanity checks - IM_ASSERT(columns_count > 0 && columns_count <= IMGUI_TABLE_MAX_COLUMNS && "Only 1..64 columns allowed!"); + IM_ASSERT(columns_count > 0 && columns_count < IMGUI_TABLE_MAX_COLUMNS); if (flags & ImGuiTableFlags_ScrollX) IM_ASSERT(inner_width >= 0.0f); - // If an outer size is specified ahead we will be able to early out when not visible. Exact clipping rules may evolve. + // If an outer size is specified ahead we will be able to early out when not visible. Exact clipping criteria may evolve. const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0; const ImVec2 avail_size = GetContentRegionAvail(); ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f); @@ -332,18 +333,13 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // Acquire storage for the table ImGuiTable* table = g.Tables.GetOrAddByKey(id); - const int instance_no = (table->LastFrameActive != g.FrameCount) ? 0 : table->InstanceCurrent + 1; - const ImGuiID instance_id = id + instance_no; const ImGuiTableFlags table_last_flags = table->Flags; - if (instance_no > 0) - IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID"); // Acquire temporary buffers const int table_idx = g.Tables.GetIndex(table); - g.CurrentTableStackIdx++; - if (g.CurrentTableStackIdx + 1 > g.TablesTempDataStack.Size) - g.TablesTempDataStack.resize(g.CurrentTableStackIdx + 1, ImGuiTableTempData()); - ImGuiTableTempData* temp_data = table->TempData = &g.TablesTempDataStack[g.CurrentTableStackIdx]; + if (++g.TablesTempDataStacked > g.TablesTempData.Size) + g.TablesTempData.resize(g.TablesTempDataStacked, ImGuiTableTempData()); + ImGuiTableTempData* temp_data = table->TempData = &g.TablesTempData[g.TablesTempDataStacked - 1]; temp_data->TableIndex = table_idx; table->DrawSplitter = &table->TempData->DrawSplitter; table->DrawSplitter->Clear(); @@ -353,9 +349,9 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG flags = TableFixFlags(flags, outer_window); // Initialize + const int instance_no = (table->LastFrameActive != g.FrameCount) ? 0 : table->InstanceCurrent + 1; table->ID = id; table->Flags = flags; - table->InstanceCurrent = (ImS16)instance_no; table->LastFrameActive = g.FrameCount; table->OuterWindow = table->InnerWindow = outer_window; table->ColumnsCount = columns_count; @@ -363,6 +359,23 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG table->InnerWidth = inner_width; temp_data->UserOuterSize = outer_size; + // Instance data (for instance 0, TableID == TableInstanceID) + ImGuiID instance_id; + table->InstanceCurrent = (ImS16)instance_no; + if (instance_no > 0) + { + IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID"); + if (table->InstanceDataExtra.Size < instance_no) + table->InstanceDataExtra.push_back(ImGuiTableInstanceData()); + instance_id = GetIDWithSeed(instance_no, GetIDWithSeed("##Instances", NULL, id)); // Push "##Instances" followed by (int)instance_no in ID stack. + } + else + { + instance_id = id; + } + ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); + table_instance->TableInstanceID = instance_id; + // When not using a child window, WorkRect.Max will grow as we append contents. if (use_child_window) { @@ -394,6 +407,14 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG table->OuterRect = table->InnerWindow->Rect(); table->InnerRect = table->InnerWindow->InnerRect; IM_ASSERT(table->InnerWindow->WindowPadding.x == 0.0f && table->InnerWindow->WindowPadding.y == 0.0f && table->InnerWindow->WindowBorderSize == 0.0f); + + // When using multiple instances, ensure they have the same amount of horizontal decorations (aka vertical scrollbar) so stretched columns can be aligned) + if (instance_no == 0) + { + table->HasScrollbarYPrev = table->HasScrollbarYCurr; + table->HasScrollbarYCurr = false; + } + table->HasScrollbarYCurr |= (table->InnerWindow->ScrollMax.y > 0.0f); } else { @@ -403,7 +424,9 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG } // Push a standardized ID for both child-using and not-child-using tables - PushOverrideID(instance_id); + PushOverrideID(id); + if (instance_no > 0) + PushOverrideID(instance_id); // FIXME: Somehow this is not resolved by stack-tool, even tho GetIDWithSeed() submitted the symbol. // Backup a copy of host window members we will modify ImGuiWindow* inner_window = table->InnerWindow; @@ -455,12 +478,13 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG table->IsUnfrozenRows = true; table->DeclColumnsCount = 0; - // Using opaque colors facilitate overlapping elements of the grid + // Using opaque colors facilitate overlapping lines of the grid, otherwise we'd need to improve TableDrawBorders() table->BorderColorStrong = GetColorU32(ImGuiCol_TableBorderStrong); table->BorderColorLight = GetColorU32(ImGuiCol_TableBorderLight); // Make table current g.CurrentTable = table; + outer_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX(); outer_window->DC.CurrentTableIdx = table_idx; if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. inner_window->DC.CurrentTableIdx = table_idx; @@ -468,7 +492,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0) table->IsResetDisplayOrderRequest = true; - // Mark as used + // Mark as used to avoid GC if (table_idx >= g.TablesLastTimeActive.Size) g.TablesLastTimeActive.resize(table_idx + 1, -1.0f); g.TablesLastTimeActive[table_idx] = (float)g.Time; @@ -538,7 +562,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG if (table->RefScale != 0.0f && table->RefScale != new_ref_scale_unit) { const float scale_factor = new_ref_scale_unit / table->RefScale; - //IMGUI_DEBUG_LOG("[table] %08X RefScaleUnit %.3f -> %.3f, scaling width by %.3f\n", table->ID, table->RefScaleUnit, new_ref_scale_unit, scale_factor); + //IMGUI_DEBUG_PRINT("[table] %08X RefScaleUnit %.3f -> %.3f, scaling width by %.3f\n", table->ID, table->RefScaleUnit, new_ref_scale_unit, scale_factor); for (int n = 0; n < columns_count; n++) table->Columns[n].WidthRequest = table->Columns[n].WidthRequest * scale_factor; } @@ -561,34 +585,40 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG } // For reference, the average total _allocation count_ for a table is: -// + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables) +// + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables[]) // + 1 (for table->RawData allocated below) // + 1 (for table->ColumnsNames, if names are used) -// Shared allocations per number of nested tables +// Shared allocations for the maximum number of simultaneously nested tables (generally a very small number) // + 1 (for table->Splitter._Channels) // + 2 * active_channels_count (for ImDrawCmd and ImDrawIdx buffers inside channels) -// Where active_channels_count is variable but often == columns_count or columns_count + 1, see TableSetupDrawChannels() for details. +// Where active_channels_count is variable but often == columns_count or == columns_count + 1, see TableSetupDrawChannels() for details. // Unused channels don't perform their +2 allocations. void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count) { // Allocate single buffer for our arrays - ImSpanAllocator<3> span_allocator; + const int columns_bit_array_size = (int)ImBitArrayGetStorageSizeInBytes(columns_count); + ImSpanAllocator<6> span_allocator; span_allocator.Reserve(0, columns_count * sizeof(ImGuiTableColumn)); span_allocator.Reserve(1, columns_count * sizeof(ImGuiTableColumnIdx)); span_allocator.Reserve(2, columns_count * sizeof(ImGuiTableCellData), 4); + for (int n = 3; n < 6; n++) + span_allocator.Reserve(n, columns_bit_array_size); table->RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes()); memset(table->RawData, 0, span_allocator.GetArenaSizeInBytes()); span_allocator.SetArenaBasePtr(table->RawData); span_allocator.GetSpan(0, &table->Columns); span_allocator.GetSpan(1, &table->DisplayOrderToIndex); span_allocator.GetSpan(2, &table->RowCellData); + table->EnabledMaskByDisplayOrder = (ImU32*)span_allocator.GetSpanPtrBegin(3); + table->EnabledMaskByIndex = (ImU32*)span_allocator.GetSpanPtrBegin(4); + table->VisibleMaskByIndex = (ImU32*)span_allocator.GetSpanPtrBegin(5); } // Apply queued resizing/reordering/hiding requests void ImGui::TableBeginApplyRequests(ImGuiTable* table) { // Handle resizing request - // (We process this at the first TableBegin of the frame) + // (We process this in the TableBegin() of the first instance of each table) // FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling? if (table->InstanceCurrent == 0) { @@ -633,8 +663,7 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table) table->Columns[table->DisplayOrderToIndex[order_n]].DisplayOrder -= (ImGuiTableColumnIdx)reorder_dir; IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir); - // Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[], - // rebuild the later from the former. + // Display order is stored in both columns->IndexDisplayOrder and table->DisplayOrder[]. Rebuild later from the former. for (int column_n = 0; column_n < table->ColumnsCount; column_n++) table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n; table->ReorderColumnDir = 0; @@ -708,8 +737,8 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I } } -// Layout columns for the frame. This is in essence the followup to BeginTable(). -// Runs on the first call to TableNextRow(), to give a chance for TableSetupColumn() to be called first. +// Layout columns for the frame. This is in essence the followup to BeginTable() and this is our largest function. +// Runs on the first call to TableNextRow(), to give a chance for TableSetupColumn() and other TableSetupXXXXX() functions to be called first. // FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for _WidthAuto columns. // Increase feedback side-effect with widgets relying on WorkRect.Max.x... Maybe provide a default distribution for _WidthAuto columns? void ImGui::TableUpdateLayout(ImGuiTable* table) @@ -720,8 +749,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_); table->IsDefaultDisplayOrder = true; table->ColumnsEnabledCount = 0; - table->EnabledMaskByIndex = 0x00; - table->EnabledMaskByDisplayOrder = 0x00; + ImBitArrayClearAllBits(table->EnabledMaskByIndex, table->ColumnsCount); + ImBitArrayClearAllBits(table->EnabledMaskByDisplayOrder, table->ColumnsCount); table->LeftMostEnabledColumn = -1; table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE @@ -786,8 +815,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) else table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n; column->IndexWithinEnabledSet = table->ColumnsEnabledCount++; - table->EnabledMaskByIndex |= (ImU64)1 << column_n; - table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder; + ImBitArraySetBit(table->EnabledMaskByIndex, column_n); + ImBitArraySetBit(table->EnabledMaskByDisplayOrder, column->DisplayOrder); prev_visible_column_idx = column_n; IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder); @@ -830,12 +859,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) table->IsSettingsDirty = true; // [Part 3] Fix column flags and record a few extra information. - float sum_width_requests = 0.0f; // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns but including spacing/padding. - float stretch_sum_weights = 0.0f; // Sum of all weights for stretch columns. + float sum_width_requests = 0.0f; // Sum of all width for fixed and auto-resize columns, excluding width contributed by Stretch columns but including spacing/padding. + float stretch_sum_weights = 0.0f; // Sum of all weights for stretch columns. table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1; for (int column_n = 0; column_n < table->ColumnsCount; column_n++) { - if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n))) + if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n)) continue; ImGuiTableColumn* column = &table->Columns[column_n]; @@ -851,7 +880,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!) if (column->AutoFitQueue != 0x00) column->WidthRequest = width_auto; - else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n))) + else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && column->IsRequestOutput) column->WidthRequest = width_auto; // FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets @@ -887,17 +916,19 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) sum_width_requests += table->CellPaddingX * 2.0f; } table->ColumnsEnabledFixedCount = (ImGuiTableColumnIdx)count_fixed; + table->ColumnsStretchSumWeights = stretch_sum_weights; // [Part 4] Apply final widths based on requested widths const ImRect work_rect = table->WorkRect; const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); - const float width_avail = ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth(); + const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synched tables with mismatching scrollbar state (#5920) + const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed); const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests; float width_remaining_for_stretched_columns = width_avail_for_stretched_columns; table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount; for (int column_n = 0; column_n < table->ColumnsCount; column_n++) { - if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n))) + if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n)) continue; ImGuiTableColumn* column = &table->Columns[column_n]; @@ -924,7 +955,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths)) for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--) { - if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) + if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) continue; ImGuiTableColumn* column = &table->Columns[table->DisplayOrderToIndex[order_n]]; if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch)) @@ -934,10 +965,19 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) width_remaining_for_stretched_columns -= 1.0f; } + // Determine if table is hovered which will be used to flag columns as hovered. + // - In principle we'd like to use the equivalent of IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + // but because our item is partially submitted at this point we use ItemHoverable() and a workaround (temporarily + // clear ActiveId, which is equivalent to the change provided by _AllowWhenBLockedByActiveItem). + // - This allows columns to be marked as hovered when e.g. clicking a button inside the column, or using drag and drop. + ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); table->HoveredColumnBody = -1; table->HoveredColumnBorder = -1; - const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table->LastOuterHeight)); - const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0); + const ImRect mouse_hit_rect(table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.Max.x, ImMax(table->OuterRect.Max.y, table->OuterRect.Min.y + table_instance->LastOuterHeight)); + const ImGuiID backup_active_id = g.ActiveId; + g.ActiveId = 0; + const bool is_hovering_table = ItemHoverable(mouse_hit_rect, 0, ImGuiItemFlags_None); + g.ActiveId = backup_active_id; // [Part 6] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column // Process columns in their visible orders as we are comparing the visible order and adjusting host_clip_rect while looping. @@ -946,14 +986,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1; ImRect host_clip_rect = table->InnerClipRect; //host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2; - table->VisibleMaskByIndex = 0x00; - table->RequestOutputMaskByIndex = 0x00; + ImBitArrayClearAllBits(table->VisibleMaskByIndex, table->ColumnsCount); for (int order_n = 0; order_n < table->ColumnsCount; order_n++) { const int column_n = table->DisplayOrderToIndex[order_n]; ImGuiTableColumn* column = &table->Columns[column_n]; - column->NavLayerCurrent = (ImS8)((table->FreezeRowsCount > 0 || column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); + column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen if (offset_x_frozen && table->FreezeColumnsCount == visible_n) { @@ -964,7 +1003,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // Clear status flags column->Flags &= ~ImGuiTableColumnFlags_StatusMask_; - if ((table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n)) == 0) + if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) { // Hidden column: clear a few fields and we are done with it for the remainder of the function. // We set a zero-width clip rect but set Min.y/Max.y properly to not interfere with the clipper. @@ -1017,12 +1056,10 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y); const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY; if (is_visible) - table->VisibleMaskByIndex |= ((ImU64)1 << column_n); + ImBitArraySetBit(table->VisibleMaskByIndex, column_n); // Mark column as requesting output from user. Note that fixed + non-resizable sets are auto-fitting at all times and therefore always request output. column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0; - if (column->IsRequestOutput) - table->RequestOutputMaskByIndex |= ((ImU64)1 << column_n); // Mark column as SkipItems (ignoring all items/layout) column->IsSkipItems = !column->IsEnabled || table->HostSkipItems; @@ -1097,30 +1134,29 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // [Part 10] Hit testing on borders if (table->Flags & ImGuiTableFlags_Resizable) TableUpdateBorders(table); - table->LastFirstRowHeight = 0.0f; + table_instance->LastFirstRowHeight = 0.0f; table->IsLayoutLocked = true; table->IsUsingHeaders = false; // [Part 11] Context menu - if (table->IsContextPopupOpen && table->InstanceCurrent == table->InstanceInteracted) + if (TableBeginContextMenuPopup(table)) { - const ImGuiID context_menu_id = ImHashStr("##ContextMenu", 0, table->ID); - if (BeginPopupEx(context_menu_id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings)) - { - TableDrawContextMenu(table); - EndPopup(); - } - else - { - table->IsContextPopupOpen = false; - } + TableDrawContextMenu(table); + EndPopup(); } - // [Part 13] Sanitize and build sort specs before we have a change to use them for display. + // [Part 12] Sanitize and build sort specs before we have a chance to use them for display. // This path will only be exercised when sort specs are modified before header rows (e.g. init or visibility change) if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable)) TableSortSpecsBuild(table); + // [Part 13] Setup inner window decoration size (for scrolling / nav tracking to properly take account of frozen rows/columns) + if (table->FreezeColumnsRequest > 0) + table->InnerWindow->DecoInnerSizeX1 = table->Columns[table->DisplayOrderToIndex[table->FreezeColumnsRequest - 1]].MaxX - table->OuterRect.Min.x; + if (table->FreezeRowsRequest > 0) + table->InnerWindow->DecoInnerSizeY1 = table_instance->LastFrozenHeight; + table_instance->LastFrozenHeight = 0.0f; + // Initial state ImGuiWindow* inner_window = table->InnerWindow; if (table->Flags & ImGuiTableFlags_NoClip) @@ -1130,9 +1166,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) } // Process hit-testing on resizing borders. Actual size change will be applied in EndTable() -// - Set table->HoveredColumnBorder with a short delay/timer to reduce feedback noise -// - Submit ahead of table contents and header, use ImGuiButtonFlags_AllowItemOverlap to prioritize widgets -// overlapping the same area. +// - Set table->HoveredColumnBorder with a short delay/timer to reduce visual feedback noise. void ImGui::TableUpdateBorders(ImGuiTable* table) { ImGuiContext& g = *GImGui; @@ -1142,14 +1176,15 @@ void ImGui::TableUpdateBorders(ImGuiTable* table) // use the final height from last frame. Because this is only affecting _interaction_ with columns, it is not // really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height). // Actual columns highlight/render will be performed in EndTable() and not be affected. + ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS; const float hit_y1 = table->OuterRect.Min.y; - const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table->LastOuterHeight); - const float hit_y2_head = hit_y1 + table->LastFirstRowHeight; + const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight); + const float hit_y2_head = hit_y1 + table_instance->LastFirstRowHeight; for (int order_n = 0; order_n < table->ColumnsCount; order_n++) { - if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) + if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) continue; const int column_n = table->DisplayOrderToIndex[order_n]; @@ -1167,11 +1202,11 @@ void ImGui::TableUpdateBorders(ImGuiTable* table) ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent); ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit); + ItemAdd(hit_rect, column_id, NULL, ImGuiItemFlags_NoNav); //GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100)); - KeepAliveID(column_id); bool hovered = false, held = false; - bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus); + bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus); if (pressed && IsMouseDoubleClicked(0)) { TableSetColumnWidthAutoSingle(table, column_n); @@ -1224,6 +1259,7 @@ void ImGui::EndTable() TableOpenContextMenu((int)table->HoveredColumnBody); // Finalize table height + ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); inner_window->DC.PrevLineSize = temp_data->HostBackupPrevLineSize; inner_window->DC.CurrLineSize = temp_data->HostBackupCurrLineSize; inner_window->DC.CursorMaxPos = temp_data->HostBackupCursorMaxPos; @@ -1234,7 +1270,7 @@ void ImGui::EndTable() else if (!(flags & ImGuiTableFlags_NoHostExtendY)) table->OuterRect.Max.y = table->InnerRect.Max.y = ImMax(table->OuterRect.Max.y, inner_content_max_y); // Patch OuterRect/InnerRect height table->WorkRect.Max.y = ImMax(table->WorkRect.Max.y, table->OuterRect.Max.y); - table->LastOuterHeight = table->OuterRect.GetHeight(); + table_instance->LastOuterHeight = table->OuterRect.GetHeight(); // Setup inner scrolling range // FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y, @@ -1280,17 +1316,23 @@ void ImGui::EndTable() splitter->Merge(inner_window->DrawList); // Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable() - const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); - table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount; + float auto_fit_width_for_fixed = 0.0f; + float auto_fit_width_for_stretched = 0.0f; + float auto_fit_width_for_stretched_min = 0.0f; for (int column_n = 0; column_n < table->ColumnsCount; column_n++) - if (table->EnabledMaskByIndex & ((ImU64)1 << column_n)) + if (IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n)) { ImGuiTableColumn* column = &table->Columns[column_n]; - if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) - table->ColumnsAutoFitWidth += column->WidthRequest; + float column_width_request = ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) ? column->WidthRequest : TableGetColumnWidthAuto(table, column); + if (column->Flags & ImGuiTableColumnFlags_WidthFixed) + auto_fit_width_for_fixed += column_width_request; else - table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, column); + auto_fit_width_for_stretched += column_width_request; + if ((column->Flags & ImGuiTableColumnFlags_WidthStretch) && (column->Flags & ImGuiTableColumnFlags_NoResize) != 0) + auto_fit_width_for_stretched_min = ImMax(auto_fit_width_for_stretched_min, column_width_request / (column->StretchWeight / table->ColumnsStretchSumWeights)); } + const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); + table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount + auto_fit_width_for_fixed + ImMax(auto_fit_width_for_stretched, auto_fit_width_for_stretched_min); // Update scroll if ((table->Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window) @@ -1318,8 +1360,10 @@ void ImGui::EndTable() } // Pop from id stack - IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table->ID + table->InstanceCurrent, "Mismatching PushID/PopID!"); + IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table_instance->TableInstanceID, "Mismatching PushID/PopID!"); IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= temp_data->HostBackupItemWidthStackSize, "Too many PopItemWidth!"); + if (table->InstanceCurrent > 0) + PopID(); PopID(); // Restore window data that we modified @@ -1382,9 +1426,8 @@ void ImGui::EndTable() // Clear or restore current table, if any IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table); - IM_ASSERT(g.CurrentTableStackIdx >= 0); - g.CurrentTableStackIdx--; - temp_data = g.CurrentTableStackIdx >= 0 ? &g.TablesTempDataStack[g.CurrentTableStackIdx] : NULL; + IM_ASSERT(g.TablesTempDataStacked > 0); + temp_data = (--g.TablesTempDataStacked > 0) ? &g.TablesTempData[g.TablesTempDataStacked - 1] : NULL; g.CurrentTable = temp_data ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL; if (g.CurrentTable) { @@ -1392,6 +1435,7 @@ void ImGui::EndTable() g.CurrentTable->DrawSplitter = &temp_data->DrawSplitter; } outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1; + NavUpdateCurrentWindowIsScrollPushableX(); } // See "COLUMN SIZING POLICIES" comments at the top of this file @@ -1571,30 +1615,33 @@ ImGuiTableColumnFlags ImGui::TableGetColumnFlags(int column_n) // Return the cell rectangle based on currently known height. // - Important: we generally don't know our row height until the end of the row, so Max.y will be incorrect in many situations. -// The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it. +// The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it, or in TableEndRow() when we locked that height. // - Important: if ImGuiTableFlags_PadOuterX is set but ImGuiTableFlags_PadInnerX is not set, the outer-most left and right // columns report a small offset so their CellBgRect can extend up to the outer border. +// FIXME: But the rendering code in TableEndRow() nullifies that with clamping required for scrolling. ImRect ImGui::TableGetCellBgRect(const ImGuiTable* table, int column_n) { const ImGuiTableColumn* column = &table->Columns[column_n]; float x1 = column->MinX; float x2 = column->MaxX; - if (column->PrevEnabledColumn == -1) - x1 -= table->CellSpacingX1; - if (column->NextEnabledColumn == -1) - x2 += table->CellSpacingX2; + //if (column->PrevEnabledColumn == -1) + // x1 -= table->OuterPaddingX; + //if (column->NextEnabledColumn == -1) + // x2 += table->OuterPaddingX; + x1 = ImMax(x1, table->WorkRect.Min.x); + x2 = ImMin(x2, table->WorkRect.Max.x); return ImRect(x1, table->RowPosY1, x2, table->RowPosY2); } // Return the resizing ID for the right-side of the given column. -ImGuiID ImGui::TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no) +ImGuiID ImGui::TableGetColumnResizeID(ImGuiTable* table, int column_n, int instance_no) { IM_ASSERT(column_n >= 0 && column_n < table->ColumnsCount); - ImGuiID id = table->ID + 1 + (instance_no * table->ColumnsCount) + column_n; - return id; + ImGuiID instance_id = TableGetInstanceID(table, instance_no); + return instance_id + 1 + column_n; // FIXME: #6140: still not ideal } -// Return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered. +// Return -1 when table is not hovered. return columns_count if hovering the unused space at the right of the right-most visible column. int ImGui::TableGetHoveredColumn() { ImGuiContext& g = *GImGui; @@ -1622,7 +1669,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n return; if (column_n == -1) column_n = table->CurrentColumn; - if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0) + if (!IM_BITARRAY_TESTBIT(table->VisibleMaskByIndex, column_n)) return; if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n) table->RowCellDataCurrent++; @@ -1712,6 +1759,8 @@ void ImGui::TableBeginRow(ImGuiTable* table) table->RowTextBaseline = 0.0f; table->RowIndentOffsetX = window->DC.Indent.x - table->HostIndentX; // Lock indent window->DC.PrevLineTextBaseOffset = 0.0f; + window->DC.CurrLineSize = ImVec2(0.0f, 0.0f); + window->DC.IsSameLine = window->DC.IsSetPos = false; window->DC.CursorMaxPos.y = next_y1; // Making the header BG color non-transparent will allow us to overlay it multiple times when handling smooth dragging. @@ -1748,7 +1797,7 @@ void ImGui::TableEndRow(ImGuiTable* table) const bool unfreeze_rows_actual = (table->CurrentRow + 1 == table->FreezeRowsCount); const bool unfreeze_rows_request = (table->CurrentRow + 1 == table->FreezeRowsRequest); if (table->CurrentRow == 0) - table->LastFirstRowHeight = bg_y2 - bg_y1; + TableGetInstanceData(table, table->InstanceCurrent)->LastFirstRowHeight = bg_y2 - bg_y1; const bool is_visible = (bg_y2 >= table->InnerClipRect.Min.y && bg_y1 <= table->InnerClipRect.Max.y); if (is_visible) @@ -1799,10 +1848,12 @@ void ImGui::TableEndRow(ImGuiTable* table) ImGuiTableCellData* cell_data_end = &table->RowCellData[table->RowCellDataCurrent]; for (ImGuiTableCellData* cell_data = &table->RowCellData[0]; cell_data <= cell_data_end; cell_data++) { + // As we render the BG here we need to clip things (for layout we would not) + // FIXME: This cancels the OuterPadding addition done by TableGetCellBgRect(), need to keep it while rendering correctly while scrolling. const ImGuiTableColumn* column = &table->Columns[cell_data->Column]; ImRect cell_bg_rect = TableGetCellBgRect(table, cell_data->Column); cell_bg_rect.ClipWith(table->BgClipRect); - cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped + cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX); window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); } @@ -1822,17 +1873,15 @@ void ImGui::TableEndRow(ImGuiTable* table) // get the new cursor position. if (unfreeze_rows_request) for (int column_n = 0; column_n < table->ColumnsCount; column_n++) - { - ImGuiTableColumn* column = &table->Columns[column_n]; - column->NavLayerCurrent = (ImS8)((column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); - } + table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main; if (unfreeze_rows_actual) { IM_ASSERT(table->IsUnfrozenRows == false); + const float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y); table->IsUnfrozenRows = true; + TableGetInstanceData(table, table->InstanceCurrent)->LastFrozenHeight = y0 - table->OuterRect.Min.y; // BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect - float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y); table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y); table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y; table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen; @@ -1895,7 +1944,7 @@ bool ImGui::TableSetColumnIndex(int column_n) // Return whether the column is visible. User may choose to skip submitting items based on this return value, // however they shouldn't skip submitting for columns that may have the tallest contribution to row height. - return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0; + return table->Columns[column_n].IsRequestOutput; } // [Public] Append into the next column, wrap and create a new row when already on last column @@ -1920,8 +1969,7 @@ bool ImGui::TableNextColumn() // Return whether the column is visible. User may choose to skip submitting items based on this return value, // however they shouldn't skip submitting for columns that may have the tallest contribution to row height. - int column_n = table->CurrentColumn; - return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0; + return table->Columns[table->CurrentColumn].IsRequestOutput; } @@ -1930,6 +1978,7 @@ bool ImGui::TableNextColumn() // FIXME-TABLE FIXME-OPT: Could probably shortcut some things for non-active or clipped columns. void ImGui::TableBeginCell(ImGuiTable* table, int column_n) { + ImGuiContext& g = *GImGui; ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiWindow* window = table->InnerWindow; table->CurrentColumn = column_n; @@ -1951,14 +2000,9 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n) window->WorkRect.Max.x = column->WorkMaxX; window->DC.ItemWidth = column->ItemWidth; - // To allow ImGuiListClipper to function we propagate our row height - if (!column->IsEnabled) - window->DC.CursorPos.y = ImMax(window->DC.CursorPos.y, table->RowPosY2); - window->SkipItems = column->IsSkipItems; if (column->IsSkipItems) { - ImGuiContext& g = *GImGui; g.LastItemData.ID = 0; g.LastItemData.StatusFlags = 0; } @@ -1977,7 +2021,6 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n) } // Logging - ImGuiContext& g = *GImGui; if (g.LogEnabled && !column->IsSkipItems) { LogRenderedText(&window->DC.CursorPos, "|"); @@ -1991,6 +2034,9 @@ void ImGui::TableEndCell(ImGuiTable* table) ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; ImGuiWindow* window = table->InnerWindow; + if (window->DC.IsSetPos) + ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); + // Report maximum position so we can infer content size per column. float* p_max_pos_x; if (table->RowFlags & ImGuiTableRowFlags_Headers) @@ -1998,7 +2044,8 @@ void ImGui::TableEndCell(ImGuiTable* table) else p_max_pos_x = table->IsUnfrozenRows ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen; *p_max_pos_x = ImMax(*p_max_pos_x, window->DC.CursorMaxPos.x); - table->RowPosY2 = ImMax(table->RowPosY2, window->DC.CursorMaxPos.y + table->CellPaddingY); + if (column->IsEnabled) + table->RowPosY2 = ImMax(table->RowPosY2, window->DC.CursorMaxPos.y + table->CellPaddingY); column->ItemWidth = window->DC.ItemWidth; // Propagate text baseline for the entire row @@ -2085,7 +2132,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width) if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width) return; - //IMGUI_DEBUG_LOG("TableSetColumnWidth(%d, %.1f->%.1f)\n", column_0_idx, column_0->WidthGiven, column_0_width); + //IMGUI_DEBUG_PRINT("TableSetColumnWidth(%d, %.1f->%.1f)\n", column_0_idx, column_0->WidthGiven, column_0_width); ImGuiTableColumn* column_1 = (column_0->NextEnabledColumn != -1) ? &table->Columns[column_0->NextEnabledColumn] : NULL; // In this surprisingly not simple because of how we support mixing Fixed and multiple Stretch columns. @@ -2093,7 +2140,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width) // - All stretch: easy. // - One or more fixed + one stretch: easy. // - One or more fixed + more than one stretch: tricky. - // Qt when manual resize is enabled only support a single _trailing_ stretch column. + // Qt when manual resize is enabled only supports a single _trailing_ stretch column, we support more cases here. // When forwarding resize from Wn| to Fn+1| we need to be considerate of the _NoResize flag on Fn+1. // FIXME-TABLE: Find a way to rewrite all of this so interactions feel more consistent for the user. @@ -2176,7 +2223,7 @@ void ImGui::TableUpdateColumnsWeightFromWidth(ImGuiTable* table) { IM_ASSERT(table->LeftMostStretchedColumn != -1 && table->RightMostStretchedColumn != -1); - // Measure existing quantity + // Measure existing quantities float visible_weight = 0.0f; float visible_width = 0.0f; for (int column_n = 0; column_n < table->ColumnsCount; column_n++) @@ -2258,7 +2305,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table) const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1; const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsEnabledCount; const int channels_for_bg = 1 + 1 * freeze_row_multiplier; - const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || table->VisibleMaskByIndex != table->EnabledMaskByIndex) ? +1 : 0; + const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || (memcmp(table->VisibleMaskByIndex, table->EnabledMaskByIndex, ImBitArrayGetStorageSizeInBytes(table->ColumnsCount)) != 0)) ? +1 : 0; const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy; table->DrawSplitter->Split(table->InnerWindow->DrawList, channels_total); table->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1); @@ -2332,19 +2379,26 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table) // Track which groups we are going to attempt to merge, and which channels goes into each group. struct MergeGroup { - ImRect ClipRect; - int ChannelsCount; - ImBitArray ChannelsMask; - - MergeGroup() { ChannelsCount = 0; } + ImRect ClipRect; + int ChannelsCount = 0; + ImBitArrayPtr ChannelsMask = NULL; }; int merge_group_mask = 0x00; MergeGroup merge_groups[4]; + // Use a reusable temp buffer for the merge masks as they are dynamically sized. + const int max_draw_channels = (4 + table->ColumnsCount * 2); + const int size_for_masks_bitarrays_one = (int)ImBitArrayGetStorageSizeInBytes(max_draw_channels); + g.TempBuffer.reserve(size_for_masks_bitarrays_one * 5); + memset(g.TempBuffer.Data, 0, size_for_masks_bitarrays_one * 5); + for (int n = 0; n < IM_ARRAYSIZE(merge_groups); n++) + merge_groups[n].ChannelsMask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * n)); + ImBitArrayPtr remaining_mask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * 4)); + // 1. Scan channels and take note of those which can be merged for (int column_n = 0; column_n < table->ColumnsCount; column_n++) { - if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0) + if (!IM_BITARRAY_TESTBIT(table->VisibleMaskByIndex, column_n)) continue; ImGuiTableColumn* column = &table->Columns[column_n]; @@ -2355,7 +2409,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table) // Don't attempt to merge if there are multiple draw calls within the column ImDrawChannel* src_channel = &splitter->_Channels[channel_no]; - if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0) + if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0 && src_channel->_CmdBuffer.back().UserCallback == NULL) // Equivalent of PopUnusedDrawCmd() src_channel->_CmdBuffer.pop_back(); if (src_channel->_CmdBuffer.Size != 1) continue; @@ -2376,11 +2430,11 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table) } const int merge_group_n = (has_freeze_h && column_n < table->FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2); - IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS); + IM_ASSERT(channel_no < max_draw_channels); MergeGroup* merge_group = &merge_groups[merge_group_n]; if (merge_group->ChannelsCount == 0) merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX); - merge_group->ChannelsMask.SetBit(channel_no); + ImBitArraySetBit(merge_group->ChannelsMask, channel_no); merge_group->ChannelsCount++; merge_group->ClipRect.Add(src_channel->_CmdBuffer[0].ClipRect); merge_group_mask |= (1 << merge_group_n); @@ -2416,9 +2470,8 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table) const int LEADING_DRAW_CHANNELS = 2; g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data; - ImBitArray remaining_mask; // We need 132-bit of storage - remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count); - remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen); + ImBitArraySetBitRange(remaining_mask, LEADING_DRAW_CHANNELS, splitter->_Count); + ImBitArrayClearBit(remaining_mask, table->Bg2DrawChannelUnfrozen); IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN); int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS); //ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect; @@ -2445,20 +2498,18 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table) merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x); if ((merge_group_n & 2) != 0 && (table->Flags & ImGuiTableFlags_NoHostExtendY) == 0) merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y); -#if 0 - GetOverlayDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, 0, 1.0f); - GetOverlayDrawList()->AddLine(merge_group->ClipRect.Min, merge_clip_rect.Min, IM_COL32(255, 100, 0, 200)); - GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200)); -#endif + //GetForegroundDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, 0, 1.0f); // [DEBUG] + //GetForegroundDrawList()->AddLine(merge_group->ClipRect.Min, merge_clip_rect.Min, IM_COL32(255, 100, 0, 200)); + //GetForegroundDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200)); remaining_count -= merge_group->ChannelsCount; - for (int n = 0; n < IM_ARRAYSIZE(remaining_mask.Storage); n++) - remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n]; + for (int n = 0; n < (size_for_masks_bitarrays_one >> 2); n++) + remaining_mask[n] &= ~merge_group->ChannelsMask[n]; for (int n = 0; n < splitter->_Count && merge_channels_count != 0; n++) { // Copy + overwrite new clip rect - if (!merge_group->ChannelsMask.TestBit(n)) + if (!IM_BITARRAY_TESTBIT(merge_group->ChannelsMask, n)) continue; - merge_group->ChannelsMask.ClearBit(n); + IM_BITARRAY_CLEARBIT(merge_group->ChannelsMask, n); merge_channels_count--; ImDrawChannel* channel = &splitter->_Channels[n]; @@ -2476,7 +2527,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table) // Append unmergeable channels that we didn't reorder at the end of the list for (int n = 0; n < splitter->_Count && remaining_count != 0; n++) { - if (!remaining_mask.TestBit(n)) + if (!IM_BITARRAY_TESTBIT(remaining_mask, n)) continue; ImDrawChannel* channel = &splitter->_Channels[n]; memcpy(dst_tmp++, channel, sizeof(ImDrawChannel)); @@ -2499,15 +2550,16 @@ void ImGui::TableDrawBorders(ImGuiTable* table) inner_drawlist->PushClipRect(table->Bg0ClipRectForDrawCmd.Min, table->Bg0ClipRectForDrawCmd.Max, false); // Draw inner border and resizing feedback + ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); const float border_size = TABLE_BORDER_SIZE; const float draw_y1 = table->InnerRect.Min.y; const float draw_y2_body = table->InnerRect.Max.y; - const float draw_y2_head = table->IsUsingHeaders ? ImMin(table->InnerRect.Max.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table->LastFirstRowHeight) : draw_y1; + const float draw_y2_head = table->IsUsingHeaders ? ImMin(table->InnerRect.Max.y, (table->FreezeRowsCount >= 1 ? table->InnerRect.Min.y : table->WorkRect.Min.y) + table_instance->LastFirstRowHeight) : draw_y1; if (table->Flags & ImGuiTableFlags_BordersInnerV) { for (int order_n = 0; order_n < table->ColumnsCount; order_n++) { - if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n))) + if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) continue; const int column_n = table->DisplayOrderToIndex[order_n]; @@ -2612,7 +2664,6 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs() TableUpdateLayout(table); TableSortSpecsBuild(table); - return &table->SortSpecs; } @@ -2731,7 +2782,7 @@ void ImGui::TableSortSpecsSanitize(ImGuiTable* table) } } - // Fallback default sort order (if no column had the ImGuiTableColumnFlags_DefaultSort flag) + // Fallback default sort order (if no column with the ImGuiTableColumnFlags_DefaultSort flag) if (sort_order_count == 0 && !(table->Flags & ImGuiTableFlags_SortTristate)) for (int column_n = 0; column_n < table->ColumnsCount; column_n++) { @@ -2835,10 +2886,9 @@ void ImGui::TableHeadersRow() continue; // Push an id to allow unnamed labels (generally accidental, but let's behave nicely with them) - // - in your own code you may omit the PushID/PopID all-together, provided you know they won't collide - // - table->InstanceCurrent is only >0 when we use multiple BeginTable/EndTable calls with same identifier. + // In your own code you may omit the PushID/PopID all-together, provided you know they won't collide. const char* name = (TableGetColumnFlags(column_n) & ImGuiTableColumnFlags_NoHeaderLabel) ? "" : TableGetColumnName(column_n); - PushID(table->InstanceCurrent * table->ColumnsCount + column_n); + PushID(column_n); TableHeader(name); PopID(); } @@ -2909,11 +2959,9 @@ void ImGui::TableHeader(const char* label) //GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] //GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] - // Using AllowItemOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items. + // Using AllowOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items. bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowItemOverlap); - if (g.ActiveId != id) - SetItemAllowOverlap(); + bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowOverlap); if (held || hovered || selected) { const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); @@ -2953,7 +3001,7 @@ void ImGui::TableHeader(const char* label) } // Sort order arrow - const float ellipsis_max = cell_r.Max.x - w_arrow - w_sort_text; + const float ellipsis_max = ImMax(cell_r.Max.x - w_arrow - w_sort_text, label_pos.x); if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort)) { if (column->SortOrder != -1) @@ -2984,8 +3032,8 @@ void ImGui::TableHeader(const char* label) RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, label_end, &label_size); const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x); - if (text_clipped && hovered && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay) - SetTooltip("%.*s", (int)(label_end - label), label); + if (text_clipped && hovered && g.ActiveId == 0) + SetItemTooltip("%.*s", (int)(label_end - label), label); // We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden if (IsMouseReleased(1) && IsItemHovered()) @@ -3019,6 +3067,17 @@ void ImGui::TableOpenContextMenu(int column_n) } } +bool ImGui::TableBeginContextMenuPopup(ImGuiTable* table) +{ + if (!table->IsContextPopupOpen || table->InstanceCurrent != table->InstanceInteracted) + return false; + const ImGuiID context_menu_id = ImHashStr("##ContextMenu", 0, table->ID); + if (BeginPopupEx(context_menu_id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings)) + return true; + table->IsContextPopupOpen = false; + return false; +} + // Output context menu into current window (generally a popup) // FIXME-TABLE: Ideally this should be writable by the user. Full programmatic access to that data? void ImGui::TableDrawContextMenu(ImGuiTable* table) @@ -3038,15 +3097,15 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table) if (column != NULL) { const bool can_resize = !(column->Flags & ImGuiTableColumnFlags_NoResize) && column->IsEnabled; - if (MenuItem("Size column to fit###SizeOne", NULL, false, can_resize)) + if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableSizeOne), NULL, false, can_resize)) // "###SizeOne" TableSetColumnWidthAutoSingle(table, column_n); } const char* size_all_desc; if (table->ColumnsEnabledFixedCount == table->ColumnsEnabledCount && (table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame) - size_all_desc = "Size all columns to fit###SizeAll"; // All fixed + size_all_desc = LocalizeGetMsg(ImGuiLocKey_TableSizeAllFit); // "###SizeAll" All fixed else - size_all_desc = "Size all columns to default###SizeAll"; // All stretch or mixed + size_all_desc = LocalizeGetMsg(ImGuiLocKey_TableSizeAllDefault); // "###SizeAll" All stretch or mixed if (MenuItem(size_all_desc, NULL)) TableSetColumnWidthAutoAll(table); want_separator = true; @@ -3055,7 +3114,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table) // Ordering if (table->Flags & ImGuiTableFlags_Reorderable) { - if (MenuItem("Reset order", NULL, false, !table->IsDefaultDisplayOrder)) + if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetOrder), NULL, false, !table->IsDefaultDisplayOrder)) table->IsResetDisplayOrderRequest = true; want_separator = true; } @@ -3412,21 +3471,20 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle if (!save_column) continue; buf->appendf("Column %-2d", column_n); - if (column->UserID != 0) buf->appendf(" UserID=%08X", column->UserID); - if (save_size && column->IsStretch) buf->appendf(" Weight=%.4f", column->WidthOrWeight); - if (save_size && !column->IsStretch) buf->appendf(" Width=%d", (int)column->WidthOrWeight); - if (save_visible) buf->appendf(" Visible=%d", column->IsEnabled); - if (save_order) buf->appendf(" Order=%d", column->DisplayOrder); - if (save_sort && column->SortOrder != -1) buf->appendf(" Sort=%d%c", column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? 'v' : '^'); + if (column->UserID != 0) { buf->appendf(" UserID=%08X", column->UserID); } + if (save_size && column->IsStretch) { buf->appendf(" Weight=%.4f", column->WidthOrWeight); } + if (save_size && !column->IsStretch) { buf->appendf(" Width=%d", (int)column->WidthOrWeight); } + if (save_visible) { buf->appendf(" Visible=%d", column->IsEnabled); } + if (save_order) { buf->appendf(" Order=%d", column->DisplayOrder); } + if (save_sort && column->SortOrder != -1) { buf->appendf(" Sort=%d%c", column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? 'v' : '^'); } buf->append("\n"); } buf->append("\n"); } } -void ImGui::TableSettingsInstallHandler(ImGuiContext* context) +void ImGui::TableSettingsAddSettingsHandler() { - ImGuiContext& g = *context; ImGuiSettingsHandler ini_handler; ini_handler.TypeName = "Table"; ini_handler.TypeHash = ImHashStr("Table"); @@ -3435,7 +3493,7 @@ void ImGui::TableSettingsInstallHandler(ImGuiContext* context) ini_handler.ReadLineFn = TableSettingsHandler_ReadLine; ini_handler.ApplyAllFn = TableSettingsHandler_ApplyAll; ini_handler.WriteAllFn = TableSettingsHandler_WriteAll; - g.SettingsHandlers.push_back(ini_handler); + AddSettingsHandler(&ini_handler); } //------------------------------------------------------------------------- @@ -3449,7 +3507,7 @@ void ImGui::TableSettingsInstallHandler(ImGuiContext* context) // Remove Table (currently only used by TestEngine) void ImGui::TableRemove(ImGuiTable* table) { - //IMGUI_DEBUG_LOG("TableRemove() id=0x%08X\n", table->ID); + //IMGUI_DEBUG_PRINT("TableRemove() id=0x%08X\n", table->ID); ImGuiContext& g = *GImGui; int table_idx = g.Tables.GetIndex(table); //memset(table->RawData.Data, 0, table->RawData.size_in_bytes()); @@ -3461,12 +3519,12 @@ void ImGui::TableRemove(ImGuiTable* table) // Free up/compact internal Table buffers for when it gets unused void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table) { - //IMGUI_DEBUG_LOG("TableGcCompactTransientBuffers() id=0x%08X\n", table->ID); + //IMGUI_DEBUG_PRINT("TableGcCompactTransientBuffers() id=0x%08X\n", table->ID); ImGuiContext& g = *GImGui; IM_ASSERT(table->MemoryCompacted == false); table->SortSpecs.Specs = NULL; table->SortSpecsMulti.clear(); - table->IsSortSpecsDirty = true; // FIXME: shouldn't have to leak into user performing a sort + table->IsSortSpecsDirty = true; // FIXME: In theory shouldn't have to leak into user performing a sort on resume. table->ColumnsNames.clear(); table->MemoryCompacted = true; for (int n = 0; n < table->ColumnsCount; n++) @@ -3505,7 +3563,7 @@ void ImGui::TableGcCompactSettings() // - DebugNodeTable() [Internal] //------------------------------------------------------------------------- -#ifndef IMGUI_DISABLE_METRICS_WINDOW +#ifndef IMGUI_DISABLE_DEBUG_TOOLS static const char* DebugNodeTableGetSizingPolicyDesc(ImGuiTableFlags sizing_policy) { @@ -3519,13 +3577,9 @@ static const char* DebugNodeTableGetSizingPolicyDesc(ImGuiTableFlags sizing_poli void ImGui::DebugNodeTable(ImGuiTable* table) { - char buf[512]; - char* p = buf; - const char* buf_end = buf + IM_ARRAYSIZE(buf); - const bool is_active = (table->LastFrameActive >= ImGui::GetFrameCount() - 2); // Note that fully clipped early out scrolling tables will appear as inactive here. - ImFormatString(p, buf_end - p, "Table 0x%08X (%d columns, in '%s')%s", table->ID, table->ColumnsCount, table->OuterWindow->Name, is_active ? "" : " *Inactive*"); + const bool is_active = (table->LastFrameActive >= GetFrameCount() - 2); // Note that fully clipped early out scrolling tables will appear as inactive here. if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } - bool open = TreeNode(table, "%s", buf); + bool open = TreeNode(table, "Table 0x%08X (%d columns, in '%s')%s", table->ID, table->ColumnsCount, table->OuterWindow->Name, is_active ? "" : " *Inactive*"); if (!is_active) { PopStyleColor(); } if (IsItemHovered()) GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255)); @@ -3533,6 +3587,8 @@ void ImGui::DebugNodeTable(ImGuiTable* table) GetForegroundDrawList()->AddRect(GetItemRectMin(), GetItemRectMax(), IM_COL32(255, 255, 0, 255)); if (!open) return; + if (table->InstanceCurrent > 0) + Text("** %d instances of same table! Some data below will refer to last instance.", table->InstanceCurrent + 1); bool clear_settings = SmallButton("Clear settings"); BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f) Sizing: '%s'", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight(), DebugNodeTableGetSizingPolicyDesc(table->Flags)); BulletText("ColumnsGivenWidth: %.1f, ColumnsAutoFitWidth: %.1f, InnerWidth: %.1f%s", table->ColumnsGivenWidth, table->ColumnsAutoFitWidth, table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : ""); @@ -3548,6 +3604,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table) { ImGuiTableColumn* column = &table->Columns[n]; const char* name = TableGetColumnName(table, n); + char buf[512]; ImFormatString(buf, IM_ARRAYSIZE(buf), "Column %d order %d '%s': offset %+.2f to %+.2f%s\n" "Enabled: %d, VisibleX/Y: %d/%d, RequestOutput: %d, SkipItems: %d, DrawChannels: %d,%d\n" @@ -3597,7 +3654,7 @@ void ImGui::DebugNodeTableSettings(ImGuiTableSettings* settings) TreePop(); } -#else // #ifndef IMGUI_DISABLE_METRICS_WINDOW +#else // #ifndef IMGUI_DISABLE_DEBUG_TOOLS void ImGui::DebugNodeTable(ImGuiTable*) {} void ImGui::DebugNodeTableSettings(ImGuiTableSettings*) {} @@ -3836,6 +3893,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiOldColumnFl columns->Count = columns_count; columns->Flags = flags; window->DC.CurrentColumns = columns; + window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX(); columns->HostCursorPosY = window->DC.CursorPos.y; columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x; @@ -3937,6 +3995,7 @@ void ImGui::NextColumn() { // New row/line: column 0 honor IndentX. window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f); + window->DC.IsSameLine = false; columns->LineMinY = columns->LineMaxY; } window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); @@ -3988,8 +4047,7 @@ void ImGui::EndColumns() const ImGuiID column_id = columns->ID + ImGuiID(n); const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH; const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2)); - KeepAliveID(column_id); - if (IsClippedEx(column_hit_rect, column_id)) // FIXME: Can be removed or replaced with a lower-level test + if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav)) continue; bool hovered = false, held = false; @@ -4026,6 +4084,7 @@ void ImGui::EndColumns() window->DC.CurrentColumns = NULL; window->DC.ColumnsOffset.x = 0.0f; window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); + NavUpdateCurrentWindowIsScrollPushableX(); } void ImGui::Columns(int columns_count, const char* id, bool border) diff --git a/Externals/imgui/imgui_widgets.cpp b/Externals/imgui/imgui_widgets.cpp index 7da069b6be..431324470f 100644 --- a/Externals/imgui/imgui_widgets.cpp +++ b/Externals/imgui/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.85 +// dear imgui, v1.89.7 // (widgets code) /* @@ -32,16 +32,15 @@ Index of this file: #define _CRT_SECURE_NO_WARNINGS #endif -#include "imgui.h" -#ifndef IMGUI_DISABLE - #ifndef IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS #endif + +#include "imgui.h" +#ifndef IMGUI_DISABLE #include "imgui_internal.h" // System includes -#include // toupper #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier #include // intptr_t #else @@ -82,6 +81,7 @@ Index of this file: #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead +#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated #endif //------------------------------------------------------------------------- @@ -126,7 +126,7 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1); // For InputTextEx() static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); -static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); +static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); //------------------------------------------------------------------------- // [SECTION] Widgets: Text, etc. @@ -166,7 +166,21 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); const float wrap_pos_x = window->DC.TextWrapPos; const bool wrap_enabled = (wrap_pos_x >= 0.0f); - if (text_end - text > 2000 && !wrap_enabled) + if (text_end - text <= 2000 || wrap_enabled) + { + // Common case + const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; + const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); + + ImRect bb(text_pos, text_pos + text_size); + ItemSize(text_size, 0.0f); + if (!ItemAdd(bb, 0)) + return; + + // Render (we don't hide text after ## in this end-user function) + RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); + } + else { // Long text! // Perform manual coarse clipping to optimize for long multi-line text @@ -239,19 +253,6 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags) ItemSize(text_size, 0.0f); ItemAdd(bb, 0); } - else - { - const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; - const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); - - ImRect bb(text_pos, text_pos + text_size); - ItemSize(text_size, 0.0f); - if (!ItemAdd(bb, 0)) - return; - - // Render (we don't hide text after ## in this end-user function) - RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); - } } void ImGui::TextUnformatted(const char* text, const char* text_end) @@ -273,10 +274,9 @@ void ImGui::TextV(const char* fmt, va_list args) if (window->SkipItems) return; - // FIXME-OPT: Handle the %s shortcut? - ImGuiContext& g = *GImGui; - const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - TextEx(g.TempBuffer, text_end, ImGuiTextFlags_NoWidthForLargeClippedText); + const char* text, *text_end; + ImFormatStringToTempBufferV(&text, &text_end, fmt, args); + TextEx(text, text_end, ImGuiTextFlags_NoWidthForLargeClippedText); } void ImGui::TextColored(const ImVec4& col, const char* fmt, ...) @@ -290,10 +290,7 @@ void ImGui::TextColored(const ImVec4& col, const char* fmt, ...) void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args) { PushStyleColor(ImGuiCol_Text, col); - if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) - TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting - else - TextV(fmt, args); + TextV(fmt, args); PopStyleColor(); } @@ -309,10 +306,7 @@ void ImGui::TextDisabledV(const char* fmt, va_list args) { ImGuiContext& g = *GImGui; PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) - TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting - else - TextV(fmt, args); + TextV(fmt, args); PopStyleColor(); } @@ -327,13 +321,10 @@ void ImGui::TextWrapped(const char* fmt, ...) void ImGui::TextWrappedV(const char* fmt, va_list args) { ImGuiContext& g = *GImGui; - bool need_backup = (g.CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set + const bool need_backup = (g.CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position if one is already set if (need_backup) PushTextWrapPos(0.0f); - if (fmt[0] == '%' && fmt[1] == 's' && fmt[2] == 0) - TextEx(va_arg(args, const char*), NULL, ImGuiTextFlags_NoWidthForLargeClippedText); // Skip formatting - else - TextV(fmt, args); + TextV(fmt, args); if (need_backup) PopTextWrapPos(); } @@ -357,8 +348,8 @@ void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) const ImGuiStyle& style = g.Style; const float w = CalcItemWidth(); - const char* value_text_begin = &g.TempBuffer[0]; - const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + const char* value_text_begin, *value_text_end; + ImFormatStringToTempBufferV(&value_text_begin, &value_text_end, fmt, args); const ImVec2 value_size = CalcTextSize(value_text_begin, value_text_end, false); const ImVec2 label_size = CalcTextSize(label, NULL, true); @@ -393,8 +384,8 @@ void ImGui::BulletTextV(const char* fmt, va_list args) ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const char* text_begin = g.TempBuffer; - const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + const char* text_begin, *text_end; + ImFormatStringToTempBufferV(&text_begin, &text_end, fmt, args); const ImVec2 label_size = CalcTextSize(text_begin, text_end, false); const ImVec2 total_size = ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x * 2) : 0.0f), label_size.y); // Empty text doesn't add padding ImVec2 pos = window->DC.CursorPos; @@ -501,22 +492,27 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0) flags |= ImGuiButtonFlags_PressedOnDefault_; + // Default behavior inherited from item flags + // Note that _both_ ButtonFlags and ItemFlags are valid sources, so copy one into the item_flags and only check that. + ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags); + if (flags & ImGuiButtonFlags_AllowOverlap) + item_flags |= ImGuiItemflags_AllowOverlap; + if (flags & ImGuiButtonFlags_Repeat) + item_flags |= ImGuiItemFlags_ButtonRepeat; + ImGuiWindow* backup_hovered_window = g.HoveredWindow; const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window; if (flatten_hovered_children) g.HoveredWindow = window; #ifdef IMGUI_ENABLE_TEST_ENGINE + // Alternate registration spot, for when caller didn't use ItemAdd() if (id != 0 && g.LastItemData.ID != id) - IMGUI_TEST_ENGINE_ITEM_ADD(bb, id); + IMGUI_TEST_ENGINE_ITEM_ADD(id, bb, NULL); #endif bool pressed = false; - bool hovered = ItemHoverable(bb, id); - - // Drag source doesn't report as hovered - if (hovered && g.DragDropActive && g.DragDropPayload.SourceId == id && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoDisableHover)) - hovered = false; + bool hovered = ItemHoverable(bb, id, item_flags); // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) @@ -535,27 +531,29 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if (flatten_hovered_children) g.HoveredWindow = backup_hovered_window; - // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. - if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) - hovered = false; - // Mouse handling + const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id; if (hovered) { + // Poll mouse buttons + // - 'mouse_button_clicked' is generally carried into ActiveIdMouseButton when setting ActiveId. + // - Technically we only need some values in one code path, but since this is gated by hovered test this is fine. + int mouse_button_clicked = -1; + int mouse_button_released = -1; + for (int button = 0; button < 3; button++) + if (flags & (ImGuiButtonFlags_MouseButtonLeft << button)) // Handle ImGuiButtonFlags_MouseButtonRight and ImGuiButtonFlags_MouseButtonMiddle here. + { + if (IsMouseClicked(button, test_owner_id) && mouse_button_clicked == -1) { mouse_button_clicked = button; } + if (IsMouseReleased(button, test_owner_id) && mouse_button_released == -1) { mouse_button_released = button; } + } + + // Process initial action if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) { - // Poll buttons - int mouse_button_clicked = -1; - int mouse_button_released = -1; - if ((flags & ImGuiButtonFlags_MouseButtonLeft) && g.IO.MouseClicked[0]) { mouse_button_clicked = 0; } - else if ((flags & ImGuiButtonFlags_MouseButtonRight) && g.IO.MouseClicked[1]) { mouse_button_clicked = 1; } - else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && g.IO.MouseClicked[2]) { mouse_button_clicked = 2; } - if ((flags & ImGuiButtonFlags_MouseButtonLeft) && g.IO.MouseReleased[0]) { mouse_button_released = 0; } - else if ((flags & ImGuiButtonFlags_MouseButtonRight) && g.IO.MouseReleased[1]) { mouse_button_released = 1; } - else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && g.IO.MouseReleased[2]) { mouse_button_released = 2; } - if (mouse_button_clicked != -1 && g.ActiveId != id) { + if (!(flags & ImGuiButtonFlags_NoSetKeyOwner)) + SetKeyOwner(MouseButtonToKey(mouse_button_clicked), id); if (flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere)) { SetActiveID(id, window); @@ -564,7 +562,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool SetFocusID(id, window); FocusWindow(window); } - if ((flags & ImGuiButtonFlags_PressedOnClick) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[mouse_button_clicked])) + if ((flags & ImGuiButtonFlags_PressedOnClick) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseClickedCount[mouse_button_clicked] == 2)) { pressed = true; if (flags & ImGuiButtonFlags_NoHoldingActiveId) @@ -577,21 +575,23 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool FocusWindow(window); } } - if ((flags & ImGuiButtonFlags_PressedOnRelease) && mouse_button_released != -1) + if (flags & ImGuiButtonFlags_PressedOnRelease) { - // Repeat mode trumps on release behavior - const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; - if (!has_repeated_at_least_once) - pressed = true; - if (!(flags & ImGuiButtonFlags_NoNavFocus)) - SetFocusID(id, window); - ClearActiveID(); + if (mouse_button_released != -1) + { + const bool has_repeated_at_least_once = (item_flags & ImGuiItemFlags_ButtonRepeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior + if (!has_repeated_at_least_once) + pressed = true; + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + SetFocusID(id, window); + ClearActiveID(); + } } // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above). // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. - if (g.ActiveId == id && (flags & ImGuiButtonFlags_Repeat)) - if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, true)) + if (g.ActiveId == id && (item_flags & ImGuiItemFlags_ButtonRepeat)) + if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, test_owner_id, ImGuiInputFlags_Repeat)) pressed = true; } @@ -607,13 +607,22 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if (g.NavActivateDownId == id) { bool nav_activated_by_code = (g.NavActivateId == id); - bool nav_activated_by_inputs = IsNavInputTest(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiInputReadMode_Repeat : ImGuiInputReadMode_Pressed); + bool nav_activated_by_inputs = (g.NavActivatePressedId == id); + if (!nav_activated_by_inputs && (item_flags & ImGuiItemFlags_ButtonRepeat)) + { + // Avoid pressing multiple keys from triggering excessive amount of repeat events + const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space); + const ImGuiKeyData* key2 = GetKeyData(ImGuiKey_Enter); + const ImGuiKeyData* key3 = GetKeyData(ImGuiKey_NavGamepadActivate); + const float t1 = ImMax(ImMax(key1->DownDuration, key2->DownDuration), key3->DownDuration); + nav_activated_by_inputs = CalcTypematicRepeatAmount(t1 - g.IO.DeltaTime, t1, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0; + } if (nav_activated_by_code || nav_activated_by_inputs) { // Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button. pressed = true; SetActiveID(id, window); - g.ActiveIdSource = ImGuiInputSource_Nav; + g.ActiveIdSource = g.NavInputSource; if (!(flags & ImGuiButtonFlags_NoNavFocus)) SetFocusID(id, window); } @@ -629,8 +638,12 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; const int mouse_button = g.ActiveIdMouseButton; - IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT); - if (g.IO.MouseDown[mouse_button]) + if (mouse_button == -1) + { + // Fallback for the rare situation were g.ActiveId was set programmatically or from another widget (e.g. #6304). + ClearActiveID(); + } + else if (IsMouseDown(mouse_button, test_owner_id)) { held = true; } @@ -641,9 +654,10 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if ((release_in || release_anywhere) && !g.DragDropActive) { // Report as pressed when releasing the mouse (this is the most common path) - bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDownWasDoubleClick[mouse_button]; - bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps - if (!is_double_click_release && !is_repeating_already) + bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseReleased[mouse_button] && g.IO.MouseClickedLastCount[mouse_button] == 2; + bool is_repeating_already = (item_flags & ImGuiItemFlags_ButtonRepeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps + bool is_button_avail_or_owned = TestKeyOwner(MouseButtonToKey(mouse_button), test_owner_id); + if (!is_double_click_release && !is_repeating_already && is_button_avail_or_owned) pressed = true; } ClearActiveID(); @@ -651,7 +665,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool if (!(flags & ImGuiButtonFlags_NoNavFocus)) g.NavDisableHighlight = true; } - else if (g.ActiveIdSource == ImGuiInputSource_Nav) + else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad) { // When activated using Nav, we hold on the ActiveID until activation button is released if (g.NavActivateDownId != id) @@ -688,9 +702,6 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags if (!ItemAdd(bb, id)) return false; - if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat) - flags |= ImGuiButtonFlags_Repeat; - bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); @@ -731,6 +742,7 @@ bool ImGui::SmallButton(const char* label) // Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id) bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiButtonFlags flags) { + ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; @@ -748,16 +760,17 @@ bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg, ImGuiBut bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags); return pressed; } bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiButtonFlags flags) { + ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; - ImGuiContext& g = *GImGui; const ImGuiID id = window->GetID(str_id); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); const float default_size = GetFrameHeight(); @@ -765,9 +778,6 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu if (!ItemAdd(bb, id)) return false; - if (g.LastItemData.InFlags & ImGuiItemFlags_ButtonRepeat) - flags |= ImGuiButtonFlags_Repeat; - bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); @@ -778,6 +788,7 @@ bool ImGui::ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size, ImGuiBu RenderFrame(bb.Min, bb.Max, bg_col, true, g.Style.FrameRounding); RenderArrow(window->DrawList, bb.Min + ImVec2(ImMax(0.0f, (size.x - g.FontSize) * 0.5f), ImMax(0.0f, (size.y - g.FontSize) * 0.5f)), text_col, dir); + IMGUI_TEST_ENGINE_ITEM_INFO(id, str_id, g.LastItemData.StatusFlags); return pressed; } @@ -815,7 +826,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos) ImU32 col = GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered); ImVec2 center = bb.GetCenter(); if (hovered) - window->DrawList->AddCircleFilled(center, ImMax(2.0f, g.FontSize * 0.5f + 1.0f), col, 12); + window->DrawList->AddCircleFilled(center, ImMax(2.0f, g.FontSize * 0.5f + 1.0f), col); float cross_extent = g.FontSize * 0.5f * 0.7071f - 1.0f; ImU32 cross_col = GetColorU32(ImGuiCol_Text); @@ -839,9 +850,8 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos) // Render ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); ImU32 text_col = GetColorU32(ImGuiCol_Text); - ImVec2 center = bb.GetCenter(); if (hovered || held) - window->DrawList->AddCircleFilled(center/*+ ImVec2(0.0f, -0.5f)*/, g.FontSize * 0.5f + 1.0f, bg_col, 12); + window->DrawList->AddCircleFilled(bb.GetCenter()/*+ ImVec2(0.0f, -0.5f)*/, g.FontSize * 0.5f + 1.0f, bg_col); RenderArrow(window->DrawList, bb.Min + g.Style.FramePadding, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); // Switch to moving the window after mouse is moved beyond the initial drag threshold @@ -853,7 +863,7 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos) ImGuiID ImGui::GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis) { - return window->GetIDNoKeepAlive(axis == ImGuiAxis_X ? "#SCROLLX" : "#SCROLLY"); + return window->GetID(axis == ImGuiAxis_X ? "#SCROLLX" : "#SCROLLY"); } // Return scrollbar rectangle, must only be called for corresponding axis if window->ScrollbarX/Y is set. @@ -874,9 +884,7 @@ void ImGui::Scrollbar(ImGuiAxis axis) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - const ImGuiID id = GetWindowScrollbarID(window, axis); - KeepAliveID(id); // Calculate scrollbar bounding box ImRect bb = GetWindowScrollbarRect(window, axis); @@ -896,7 +904,9 @@ void ImGui::Scrollbar(ImGuiAxis axis) } float size_avail = window->InnerRect.Max[axis] - window->InnerRect.Min[axis]; float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f; - ScrollbarEx(bb, id, axis, &window->Scroll[axis], size_avail, size_contents, rounding_corners); + ImS64 scroll = (ImS64)window->Scroll[axis]; + ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_avail, (ImS64)size_contents, rounding_corners); + window->Scroll[axis] = (float)scroll; } // Vertical/Horizontal scrollbar @@ -905,7 +915,7 @@ void ImGui::Scrollbar(ImGuiAxis axis) // - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar // - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal. // Still, the code should probably be made simpler.. -bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float size_avail_v, float size_contents_v, ImDrawFlags flags) +bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_avail_v, ImS64 size_contents_v, ImDrawFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -936,22 +946,23 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount) // But we maintain a minimum size in pixel to allow for the user to still aim inside. IM_ASSERT(ImMax(size_contents_v, size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. - const float win_size_v = ImMax(ImMax(size_contents_v, size_avail_v), 1.0f); - const float grab_h_pixels = ImClamp(scrollbar_size_v * (size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v); + const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_avail_v), (ImS64)1); + const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_avail_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v); const float grab_h_norm = grab_h_pixels / scrollbar_size_v; // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). bool held = false; bool hovered = false; + ItemAdd(bb_frame, id, NULL, ImGuiItemFlags_NoNav); ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus); - float scroll_max = ImMax(1.0f, size_contents_v - size_avail_v); - float scroll_ratio = ImSaturate(*p_scroll_v / scroll_max); + const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v); + float scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max); float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Grab position in normalized space if (held && allow_interaction && grab_h_norm < 1.0f) { - float scrollbar_pos_v = bb.Min[axis]; - float mouse_pos_v = g.IO.MousePos[axis]; + const float scrollbar_pos_v = bb.Min[axis]; + const float mouse_pos_v = g.IO.MousePos[axis]; // Click position in scrollbar normalized space (0.0f->1.0f) const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); @@ -971,10 +982,10 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, floa // Apply scroll (p_scroll_v will generally point on one member of window->Scroll) // It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm)); - *p_scroll_v = IM_ROUND(scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v)); + *p_scroll_v = (ImS64)(scroll_v_norm * scroll_max); // Update values for rendering - scroll_ratio = ImSaturate(*p_scroll_v / scroll_max); + scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max); grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Update distance to grab now that we have seeked and saturated @@ -1022,20 +1033,21 @@ void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& // ImageButton() is flawed as 'id' is always derived from 'texture_id' (see #2464 #1390) // We provide this internal helper to write your own variant while we figure out how to redesign the public ImageButton() API. -bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col) +bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2); + const ImVec2 padding = g.Style.FramePadding; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2.0f); ItemSize(bb); if (!ItemAdd(bb, id)) return false; bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held); + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); // Render const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); @@ -1048,9 +1060,21 @@ bool ImGui::ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size return pressed; } -// frame_padding < 0: uses FramePadding from style (default) -// frame_padding = 0: no framing -// frame_padding > 0: set framing size +bool ImGui::ImageButton(const char* str_id, ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; + + return ImageButtonEx(window->GetID(str_id), user_texture_id, size, uv0, uv1, bg_col, tint_col); +} + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +// Legacy API obsoleted in 1.89. Two differences with new ImageButton() +// - new ImageButton() requires an explicit 'const char* str_id' Old ImageButton() used opaque imTextureId (created issue with: multiple buttons with same image, transient texture id values, opaque computation of ID) +// - new ImageButton() always use style.FramePadding Old ImageButton() had an override argument. +// If you need to change padding with new ImageButton() you can use PushStyleVar(ImGuiStyleVar_FramePadding, value), consistent with other Button functions. bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col) { ImGuiContext& g = *GImGui; @@ -1063,9 +1087,14 @@ bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const I const ImGuiID id = window->GetID("#image"); PopID(); - const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : g.Style.FramePadding; - return ImageButtonEx(id, user_texture_id, size, uv0, uv1, padding, bg_col, tint_col); + if (frame_padding >= 0) + PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2((float)frame_padding, (float)frame_padding)); + bool ret = ImageButtonEx(id, user_texture_id, size, uv0, uv1, bg_col, tint_col); + if (frame_padding >= 0) + PopStyleVar(); + return ret; } +#endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS bool ImGui::Checkbox(const char* label, bool* v) { @@ -1133,10 +1162,8 @@ bool ImGui::CheckboxFlagsT(const char* label, T* flags, T flags_value) if (!all_on && any_on) { ImGuiContext& g = *GImGui; - ImGuiItemFlags backup_item_flags = g.CurrentItemFlags; - g.CurrentItemFlags |= ImGuiItemFlags_MixedValue; + g.NextItemData.ItemFlags |= ImGuiItemFlags_MixedValue; pressed = Checkbox(label, &all_on); - g.CurrentItemFlags = backup_item_flags; } else { @@ -1203,17 +1230,18 @@ bool ImGui::RadioButton(const char* label, bool active) MarkItemEdited(id); RenderNavHighlight(total_bb, id); - window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16); + const int num_segment = window->DrawList->_CalcCircleAutoSegmentCount(radius); + window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), num_segment); if (active) { const float pad = ImMax(1.0f, IM_FLOOR(square_sz / 6.0f)); - window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark), 16); + window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark)); } if (style.FrameBorderSize > 0.0f) { - window->DrawList->AddCircle(center + ImVec2(1, 1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); - window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); + window->DrawList->AddCircle(center + ImVec2(1, 1), radius, GetColorU32(ImGuiCol_BorderShadow), num_segment, style.FrameBorderSize); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), num_segment, style.FrameBorderSize); } ImVec2 label_pos = ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y); @@ -1280,7 +1308,7 @@ void ImGui::Bullet() ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const float line_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + g.Style.FramePadding.y * 2), g.FontSize); + const float line_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), g.FontSize); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height)); ItemSize(bb); if (!ItemAdd(bb, 0)) @@ -1336,6 +1364,7 @@ void ImGui::NewLine() ImGuiContext& g = *GImGui; const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.IsSameLine = false; if (window->DC.CurrLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. ItemSize(ImVec2(0, 0)); else @@ -1355,7 +1384,9 @@ void ImGui::AlignTextToFramePadding() } // Horizontal/vertical separating line -void ImGui::SeparatorEx(ImGuiSeparatorFlags flags) +// FIXME: Surprisingly, this seemingly trivial widget is a victim of many different legacy/tricky layout issues. +// Note how thickness == 1.0f is handled specifically as not moving CursorPos by 'thickness', but other values are. +void ImGui::SeparatorEx(ImGuiSeparatorFlags flags, float thickness) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -1363,21 +1394,20 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags) ImGuiContext& g = *GImGui; IM_ASSERT(ImIsPowerOfTwo(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))); // Check that only 1 option is selected + IM_ASSERT(thickness > 0.0f); - float thickness_draw = 1.0f; - float thickness_layout = 0.0f; if (flags & ImGuiSeparatorFlags_Vertical) { - // Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout. + // Vertical separator, for menu bars (use current line height). float y1 = window->DC.CursorPos.y; float y2 = window->DC.CursorPos.y + window->DC.CurrLineSize.y; - const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + thickness_draw, y2)); - ItemSize(ImVec2(thickness_layout, 0.0f)); + const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + thickness, y2)); + ItemSize(ImVec2(thickness, 0.0f)); if (!ItemAdd(bb, 0)) return; // Draw - window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator)); if (g.LogEnabled) LogText(" |"); } @@ -1391,18 +1421,30 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags) if (g.GroupStack.Size > 0 && g.GroupStack.back().WindowID == window->ID) x1 += window->DC.Indent.x; + // FIXME-WORKRECT: In theory we should simply be using WorkRect.Min.x/Max.x everywhere but it isn't aesthetically what we want, + // need to introduce a variant of WorkRect for that purpose. (#4787) + if (ImGuiTable* table = g.CurrentTable) + { + x1 = table->Columns[table->CurrentColumn].MinX; + x2 = table->Columns[table->CurrentColumn].MaxX; + } + + // Before Tables API happened, we relied on Separator() to span all columns of a Columns() set. + // We currently don't need to provide the same feature for tables because tables naturally have border features. ImGuiOldColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL; if (columns) PushColumnsBackground(); // We don't provide our width to the layout so that it doesn't get feed back into AutoFit - const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness_draw)); - ItemSize(ImVec2(0.0f, thickness_layout)); - const bool item_visible = ItemAdd(bb, 0); - if (item_visible) + // FIXME: This prevents ->CursorMaxPos based bounding box evaluation from working (e.g. TableEndCell) + const float thickness_for_layout = (thickness == 1.0f) ? 0.0f : thickness; // FIXME: See 1.70/1.71 Separator() change: makes legacy 1-px separator not affect layout yet. Should change. + const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness)); + ItemSize(ImVec2(0.0f, thickness_for_layout)); + + if (ItemAdd(bb, 0)) { // Draw - window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator)); + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator)); if (g.LogEnabled) LogRenderedText(&bb.Min, "--------------------------------\n"); @@ -1422,33 +1464,101 @@ void ImGui::Separator() if (window->SkipItems) return; - // Those flags should eventually be overridable by the user + // Those flags should eventually be configurable by the user + // FIXME: We cannot g.Style.SeparatorTextBorderSize for thickness as it relates to SeparatorText() which is a decorated separator, not defaulting to 1.0f. ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; - flags |= ImGuiSeparatorFlags_SpanAllColumns; - SeparatorEx(flags); + flags |= ImGuiSeparatorFlags_SpanAllColumns; // NB: this only applies to legacy Columns() api as they relied on Separator() a lot. + SeparatorEx(flags, 1.0f); +} + +void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_w) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiStyle& style = g.Style; + + const ImVec2 label_size = CalcTextSize(label, label_end, false); + const ImVec2 pos = window->DC.CursorPos; + const ImVec2 padding = style.SeparatorTextPadding; + + const float separator_thickness = style.SeparatorTextBorderSize; + const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness)); + const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y)); + const float text_baseline_y = ImFloor((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImFloor((style.SeparatorTextSize - label_size.y) * 0.5f)); + ItemSize(min_size, text_baseline_y); + if (!ItemAdd(bb, id)) + return; + + const float sep1_x1 = pos.x; + const float sep2_x2 = bb.Max.x; + const float seps_y = ImFloor((bb.Min.y + bb.Max.y) * 0.5f + 0.99999f); + + const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f); + const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN + + // This allows using SameLine() to position something in the 'extra_w' + window->DC.CursorPosPrevLine.x = label_pos.x + label_size.x; + + const ImU32 separator_col = GetColorU32(ImGuiCol_Separator); + if (label_size.x > 0.0f) + { + const float sep1_x2 = label_pos.x - style.ItemSpacing.x; + const float sep2_x1 = label_pos.x + label_size.x + extra_w + style.ItemSpacing.x; + if (sep1_x2 > sep1_x1 && separator_thickness > 0.0f) + window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep1_x2, seps_y), separator_col, separator_thickness); + if (sep2_x2 > sep2_x1 && separator_thickness > 0.0f) + window->DrawList->AddLine(ImVec2(sep2_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness); + if (g.LogEnabled) + LogSetNextTextDecoration("---", NULL); + RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, bb.Max.x, label, label_end, &label_size); + } + else + { + if (g.LogEnabled) + LogText("---"); + if (separator_thickness > 0.0f) + window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness); + } +} + +void ImGui::SeparatorText(const char* label) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + + // The SeparatorText() vs SeparatorTextEx() distinction is designed to be considerate that we may want: + // - allow separator-text to be draggable items (would require a stable ID + a noticeable highlight) + // - this high-level entry point to allow formatting? (which in turns may require ID separate from formatted string) + // - because of this we probably can't turn 'const char* label' into 'const char* fmt, ...' + // Otherwise, we can decide that users wanting to drag this would layout a dedicated drag-item, + // and then we can turn this into a format function. + SeparatorTextEx(0, label, FindRenderedTextEnd(label), 0.0f); } // Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise. -bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay) +bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay, ImU32 bg_col) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - const ImGuiItemFlags item_flags_backup = g.CurrentItemFlags; - g.CurrentItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus; - bool item_add = ItemAdd(bb, id); - g.CurrentItemFlags = item_flags_backup; - if (!item_add) + if (!ItemAdd(bb, id, NULL, ImGuiItemFlags_NoNav)) return false; + // FIXME: AFAIK the only leftover reason for passing ImGuiButtonFlags_AllowOverlap here is + // to allow caller of SplitterBehavior() to call SetItemAllowOverlap() after the item. + // Nowadays we would instead want to use SetNextItemAllowOverlap() before the item. + ImGuiButtonFlags button_flags = ImGuiButtonFlags_FlattenChildren; +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + button_flags |= ImGuiButtonFlags_AllowOverlap; +#endif + bool hovered, held; ImRect bb_interact = bb; bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); - ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); + ButtonBehavior(bb_interact, id, &hovered, &held, button_flags); if (hovered) g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; // for IsItemHovered(), because bb_interact is larger than bb - if (g.ActiveId != id) - SetItemAllowOverlap(); if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay)) SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW); @@ -1481,7 +1591,9 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float } } - // Render + // Render at new position + if (bg_col & IM_COL32_A_MASK) + window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, bg_col, 0.0f); const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : (hovered && g.HoveredIdTimer >= hover_visibility_delay) ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, 0.0f); @@ -1522,7 +1634,7 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc width_excess -= width_to_remove_per_item * count_same_width; } - // Round width and redistribute remainder left-to-right (could make it an option of the function?) + // Round width and redistribute remainder // Ensure that e.g. the right-most tab of a shrunk tab-bar always reaches exactly at the same distance from the right-most edge of the tab bar separator. width_excess = 0.0f; for (int n = 0; n < count; n++) @@ -1531,10 +1643,13 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc width_excess += items[n].Width - width_rounded; items[n].Width = width_rounded; } - if (width_excess > 0.0f) - for (int n = 0; n < count; n++) - if (items[n].Index < (int)(width_excess + 0.01f)) - items[n].Width += 1.0f; + while (width_excess > 0.0f) + for (int n = 0; n < count && width_excess > 0.0f; n++) + { + float width_to_add = ImMin(items[n].InitialWidth - items[n].Width, 1.0f); + items[n].Width += width_to_add; + width_excess -= width_to_add; + } } //------------------------------------------------------------------------- @@ -1656,7 +1771,12 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags if (flags & ImGuiComboFlags_HeightRegular) popup_max_height_in_items = 8; else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4; else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20; - SetNextWindowSizeConstraints(ImVec2(w, 0.0f), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); + ImVec2 constraint_min(0.0f, 0.0f), constraint_max(FLT_MAX, FLT_MAX); + if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.x <= 0.0f) // Don't apply constraints if user specified a size + constraint_min.x = w; + if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) == 0 || g.NextWindowData.SizeVal.y <= 0.0f) + constraint_max.y = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); + SetNextWindowSizeConstraints(constraint_min, constraint_max); } // This is essentially a specialized version of BeginPopupEx() @@ -1704,10 +1824,10 @@ bool ImGui::BeginComboPreview() ImGuiWindow* window = g.CurrentWindow; ImGuiComboPreviewData* preview_data = &g.ComboPreviewData; - if (window->SkipItems || !window->ClipRect.Overlaps(g.LastItemData.Rect)) // FIXME: Because we don't have a ImGuiItemStatusFlags_Visible flag to test last ItemAdd() result + if (window->SkipItems || !(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible)) return false; IM_ASSERT(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag? - if (!window->ClipRect.Contains(preview_data->PreviewRect)) // Narrower test (optional) + if (!window->ClipRect.Overlaps(preview_data->PreviewRect)) // Narrower test (optional) return false; // FIXME: This could be contained in a PushWorkRect() api @@ -1719,6 +1839,7 @@ bool ImGui::BeginComboPreview() window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding; window->DC.CursorMaxPos = window->DC.CursorPos; window->DC.LayoutType = ImGuiLayoutType_Horizontal; + window->DC.IsSameLine = false; PushClipRect(preview_data->PreviewRect.Min, preview_data->PreviewRect.Max, true); return true; @@ -1744,6 +1865,7 @@ void ImGui::EndComboPreview() window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine; window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset; window->DC.LayoutType = preview_data->BackupLayout; + window->DC.IsSameLine = false; preview_data->PreviewRect = ImRect(); } @@ -1804,7 +1926,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi const char* item_text; if (!items_getter(data, i, &item_text)) item_text = "*Unknown item*"; - if (Selectable(item_text, item_selected)) + if (Selectable(item_text, item_selected) && *current_item != i) { value_changed = true; *current_item = i; @@ -1846,11 +1968,11 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa //------------------------------------------------------------------------- // [SECTION] Data Type and Data Formatting Helpers [Internal] //------------------------------------------------------------------------- -// - PatchFormatStringFloatToInt() // - DataTypeGetInfo() // - DataTypeFormatString() // - DataTypeApplyOp() // - DataTypeApplyOpFromText() +// - DataTypeCompare() // - DataTypeClamp() // - GetMinimumStepAtDecimalPrecision // - RoundScalarWithFormat<>() @@ -1876,30 +1998,6 @@ static const ImGuiDataTypeInfo GDataTypeInfo[] = }; IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT); -// FIXME-LEGACY: Prior to 1.61 our DragInt() function internally used floats and because of this the compile-time default value for format was "%.0f". -// Even though we changed the compile-time default, we expect users to have carried %f around, which would break the display of DragInt() calls. -// To honor backward compatibility we are rewriting the format string, unless IMGUI_DISABLE_OBSOLETE_FUNCTIONS is enabled. What could possibly go wrong?! -static const char* PatchFormatStringFloatToInt(const char* fmt) -{ - if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '0' && fmt[3] == 'f' && fmt[4] == 0) // Fast legacy path for "%.0f" which is expected to be the most common case. - return "%d"; - const char* fmt_start = ImParseFormatFindStart(fmt); // Find % (if any, and ignore %%) - const char* fmt_end = ImParseFormatFindEnd(fmt_start); // Find end of format specifier, which itself is an exercise of confidence/recklessness (because snprintf is dependent on libc or user). - if (fmt_end > fmt_start && fmt_end[-1] == 'f') - { -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - if (fmt_start == fmt && fmt_end[0] == 0) - return "%d"; - ImGuiContext& g = *GImGui; - ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%.*s%%d%s", (int)(fmt_start - fmt), fmt, fmt_end); // Honor leading and trailing decorations, but lose alignment/precision. - return g.TempBuffer; -#else - IM_ASSERT(0 && "DragInt(): Invalid format string!"); // Old versions used a default parameter of "%.0f", please replace with e.g. "%d" -#endif - } - return fmt; -} - const ImGuiDataTypeInfo* ImGui::DataTypeGetInfo(ImGuiDataType data_type) { IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); @@ -1981,24 +2079,10 @@ void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const // User can input math operators (e.g. +100) to edit a numerical values. // NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess.. -bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* p_data, const char* format) +bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format) { while (ImCharIsBlankA(*buf)) buf++; - - // We don't support '-' op because it would conflict with inputing negative value. - // Instead you can use +-100 to subtract from an existing value - char op = buf[0]; - if (op == '+' || op == '*' || op == '/') - { - buf++; - while (ImCharIsBlankA(*buf)) - buf++; - } - else - { - op = 0; - } if (!buf[0]) return false; @@ -2007,66 +2091,21 @@ bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_b ImGuiDataTypeTempStorage data_backup; memcpy(&data_backup, p_data, type_info->Size); - if (format == NULL) + // Sanitize format + // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf + // - In theory could treat empty format as using default, but this would only cover rare/bizarre case of using InputScalar() + integer + format string without %. + char format_sanitized[32]; + if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) format = type_info->ScanFmt; - - // FIXME-LEGACY: The aim is to remove those operators and write a proper expression evaluator at some point.. - int arg1i = 0; - if (data_type == ImGuiDataType_S32) - { - int* v = (int*)p_data; - int arg0i = *v; - float arg1f = 0.0f; - if (op && sscanf(initial_value_buf, format, &arg0i) < 1) - return false; - // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision - if (op == '+') { if (sscanf(buf, "%d", &arg1i)) *v = (int)(arg0i + arg1i); } // Add (use "+-" to subtract) - else if (op == '*') { if (sscanf(buf, "%f", &arg1f)) *v = (int)(arg0i * arg1f); } // Multiply - else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (int)(arg0i / arg1f); } // Divide - else { if (sscanf(buf, format, &arg1i) == 1) *v = arg1i; } // Assign constant - } - else if (data_type == ImGuiDataType_Float) - { - // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in - format = "%f"; - float* v = (float*)p_data; - float arg0f = *v, arg1f = 0.0f; - if (op && sscanf(initial_value_buf, format, &arg0f) < 1) - return false; - if (sscanf(buf, format, &arg1f) < 1) - return false; - if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) - else if (op == '*') { *v = arg0f * arg1f; } // Multiply - else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide - else { *v = arg1f; } // Assign constant - } - else if (data_type == ImGuiDataType_Double) - { - format = "%lf"; // scanf differentiate float/double unlike printf which forces everything to double because of ellipsis - double* v = (double*)p_data; - double arg0f = *v, arg1f = 0.0; - if (op && sscanf(initial_value_buf, format, &arg0f) < 1) - return false; - if (sscanf(buf, format, &arg1f) < 1) - return false; - if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) - else if (op == '*') { *v = arg0f * arg1f; } // Multiply - else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide - else { *v = arg1f; } // Assign constant - } - else if (data_type == ImGuiDataType_U32 || data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64) - { - // All other types assign constant - // We don't bother handling support for legacy operators since they are a little too crappy. Instead we will later implement a proper expression evaluator in the future. - if (sscanf(buf, format, p_data) < 1) - return false; - } else + format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_ARRAYSIZE(format_sanitized)); + + // Small types need a 32-bit buffer to receive the result from scanf() + int v32 = 0; + if (sscanf(buf, format, type_info->Size >= 4 ? p_data : &v32) < 1) + return false; + if (type_info->Size < 4) { - // Small types need a 32-bit buffer to receive the result from scanf() - int v32; - if (sscanf(buf, format, &v32) < 1) - return false; if (data_type == ImGuiDataType_S8) *(ImS8*)p_data = (ImS8)ImClamp(v32, (int)IM_S8_MIN, (int)IM_S8_MAX); else if (data_type == ImGuiDataType_U8) @@ -2148,45 +2187,17 @@ static float GetMinimumStepAtDecimalPrecision(int decimal_precision) } template -static const char* ImAtoi(const char* src, TYPE* output) -{ - int negative = 0; - if (*src == '-') { negative = 1; src++; } - if (*src == '+') { src++; } - TYPE v = 0; - while (*src >= '0' && *src <= '9') - v = (v * 10) + (*src++ - '0'); - *output = negative ? -v : v; - return src; -} - -// Sanitize format -// - Zero terminate so extra characters after format (e.g. "%f123") don't confuse atof/atoi -// - stb_sprintf.h supports several new modifiers which format numbers in a way that also makes them incompatible atof/atoi. -static void SanitizeFormatString(const char* fmt, char* fmt_out, size_t fmt_out_size) -{ - IM_UNUSED(fmt_out_size); - const char* fmt_end = ImParseFormatFindEnd(fmt); - IM_ASSERT((size_t)(fmt_end - fmt + 1) < fmt_out_size); // Format is too long, let us know if this happens to you! - while (fmt < fmt_end) - { - char c = *(fmt++); - if (c != '\'' && c != '$' && c != '_') // Custom flags provided by stb_sprintf.h. POSIX 2008 also supports '. - *(fmt_out++) = c; - } - *fmt_out = 0; // Zero-terminate -} - -template TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, TYPE v) { + IM_UNUSED(data_type); + IM_ASSERT(data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double); const char* fmt_start = ImParseFormatFindStart(format); if (fmt_start[0] != '%' || fmt_start[1] == '%') // Don't apply if the value is not visible in the format string return v; // Sanitize format char fmt_sanitized[32]; - SanitizeFormatString(fmt_start, fmt_sanitized, IM_ARRAYSIZE(fmt_sanitized)); + ImParseFormatSanitizeForPrinting(fmt_start, fmt_sanitized, IM_ARRAYSIZE(fmt_sanitized)); fmt_start = fmt_sanitized; // Format value with our rounding, and read back @@ -2195,10 +2206,8 @@ TYPE ImGui::RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, const char* p = v_str; while (*p == ' ') p++; - if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) - v = (TYPE)ImAtof(p); - else - ImAtoi(p, (SIGNEDTYPE*)&v); + v = (TYPE)ImAtof(p); + return v; } @@ -2245,10 +2254,13 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const if (g.IO.KeyShift) adjust_delta *= 10.0f; } - else if (g.ActiveIdSource == ImGuiInputSource_Nav) + else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad) { const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; - adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f)[axis]; + const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow); + const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast); + const float tweak_factor = tweak_slow ? 1.0f / 1.0f : tweak_fast ? 10.0f : 1.0f; + adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor; v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); } adjust_delta *= v_speed; @@ -2302,8 +2314,8 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const } // Round to user desired precision based on format string - if (!(flags & ImGuiSliderFlags_NoRoundToFormat)) - v_cur = RoundScalarWithFormatT(format, data_type, v_cur); + if (is_floating_point && !(flags & ImGuiSliderFlags_NoRoundToFormat)) + v_cur = RoundScalarWithFormatT(format, data_type, v_cur); // Preserve remainder after rounding has been applied. This also allow slow tweaking of values. g.DragCurrentAccumDirty = false; @@ -2346,9 +2358,10 @@ bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v ImGuiContext& g = *GImGui; if (g.ActiveId == id) { + // Those are the things we can do easily outside the DragBehaviorT<> template, saves code generation. if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0]) ClearActiveID(); - else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) + else if ((g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad) && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) ClearActiveID(); } if (g.ActiveId != id) @@ -2399,36 +2412,38 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, // Default format string when passing NULL if (format == NULL) format = DataTypeGetInfo(data_type)->PrintFmt; - else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.) - format = PatchFormatStringFloatToInt(format); - // Tabbing or CTRL-clicking on Drag turns it into an InputText - const bool hovered = ItemHoverable(frame_bb, id); + const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags); bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); if (!temp_input_is_active) { + // Tabbing or CTRL-clicking on Drag turns it into an InputText const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; - const bool clicked = (hovered && g.IO.MouseClicked[0]); - const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]); - if (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id) + const bool clicked = hovered && IsMouseClicked(0, id); + const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id)); + const bool make_active = (input_requested_by_tabbing || clicked || double_clicked || g.NavActivateId == id); + if (make_active && (clicked || double_clicked)) + SetKeyOwner(ImGuiKey_MouseLeft, id); + if (make_active && temp_input_allowed) + if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))) + temp_input_is_active = true; + + // (Optional) simple click (without moving) turns Drag into an InputText + if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active) + if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) + { + g.NavActivateId = id; + g.NavActivateFlags = ImGuiActivateFlags_PreferInput; + temp_input_is_active = true; + } + + if (make_active && !temp_input_is_active) { SetActiveID(id, window); SetFocusID(id, window); FocusWindow(window); g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); - if (temp_input_allowed) - if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id) - temp_input_is_active = true; } - - // Experimental: simple click (without moving) turns Drag into an InputText - if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active) - if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) - { - g.NavActivateId = g.NavActivateInputId = id; - g.NavActivateFlags = ImGuiActivateFlags_PreferInput; - temp_input_is_active = true; - } } if (temp_input_is_active) @@ -2458,7 +2473,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, if (label_size.x > 0.0f) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | (temp_input_allowed ? ImGuiItemStatusFlags_Inputable : 0)); return value_changed; } @@ -2604,35 +2619,6 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_ return value_changed; } -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - -// Obsolete versions with power parameter. See https://github.com/ocornut/imgui/issues/3361 for details. -bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, float v_speed, const void* p_min, const void* p_max, const char* format, float power) -{ - ImGuiSliderFlags drag_flags = ImGuiSliderFlags_None; - if (power != 1.0f) - { - IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); - IM_ASSERT(p_min != NULL && p_max != NULL); // When using a power curve the drag needs to have known bounds - drag_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths - } - return DragScalar(label, data_type, p_data, v_speed, p_min, p_max, format, drag_flags); -} - -bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed, const void* p_min, const void* p_max, const char* format, float power) -{ - ImGuiSliderFlags drag_flags = ImGuiSliderFlags_None; - if (power != 1.0f) - { - IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); - IM_ASSERT(p_min != NULL && p_max != NULL); // When using a power curve the drag needs to have known bounds - drag_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths - } - return DragScalarN(label, data_type, p_data, components, v_speed, p_min, p_max, format, drag_flags); -} - -#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS - //------------------------------------------------------------------------- // [SECTION] Widgets: SliderScalar, SliderFloat, SliderInt, etc. //------------------------------------------------------------------------- @@ -2683,7 +2669,6 @@ float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, T v_max_fudged = -logarithmic_zero_epsilon; float result; - if (v_clamped <= v_min_fudged) result = 0.0f; // Workaround for values that are in-range but below our fudge else if (v_clamped >= v_max_fudged) @@ -2707,91 +2692,81 @@ float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, T return flipped ? (1.0f - result) : result; } - - // Linear slider - return (float)((FLOATTYPE)(SIGNEDTYPE)(v_clamped - v_min) / (FLOATTYPE)(SIGNEDTYPE)(v_max - v_min)); + else + { + // Linear slider + return (float)((FLOATTYPE)(SIGNEDTYPE)(v_clamped - v_min) / (FLOATTYPE)(SIGNEDTYPE)(v_max - v_min)); + } } // Convert a parametric position on a slider into a value v in the output space (the logical opposite of ScaleRatioFromValueT) template TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, TYPE v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_halfsize) { - if (v_min == v_max) + // We special-case the extents because otherwise our logarithmic fudging can lead to "mathematically correct" + // but non-intuitive behaviors like a fully-left slider not actually reaching the minimum value. Also generally simpler. + if (t <= 0.0f || v_min == v_max) return v_min; - const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); + if (t >= 1.0f) + return v_max; - TYPE result; + TYPE result = (TYPE)0; if (is_logarithmic) { - // We special-case the extents because otherwise our fudging can lead to "mathematically correct" but non-intuitive behaviors like a fully-left slider not actually reaching the minimum value - if (t <= 0.0f) - result = v_min; - else if (t >= 1.0f) - result = v_max; - else + // Fudge min/max to avoid getting silly results close to zero + FLOATTYPE v_min_fudged = (ImAbs((FLOATTYPE)v_min) < logarithmic_zero_epsilon) ? ((v_min < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_min; + FLOATTYPE v_max_fudged = (ImAbs((FLOATTYPE)v_max) < logarithmic_zero_epsilon) ? ((v_max < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_max; + + const bool flipped = v_max < v_min; // Check if range is "backwards" + if (flipped) + ImSwap(v_min_fudged, v_max_fudged); + + // Awkward special case - we need ranges of the form (-100 .. 0) to convert to (-100 .. -epsilon), not (-100 .. epsilon) + if ((v_max == 0.0f) && (v_min < 0.0f)) + v_max_fudged = -logarithmic_zero_epsilon; + + float t_with_flip = flipped ? (1.0f - t) : t; // t, but flipped if necessary to account for us flipping the range + + if ((v_min * v_max) < 0.0f) // Range crosses zero, so we have to do this in two parts { - bool flipped = v_max < v_min; // Check if range is "backwards" - - // Fudge min/max to avoid getting silly results close to zero - FLOATTYPE v_min_fudged = (ImAbs((FLOATTYPE)v_min) < logarithmic_zero_epsilon) ? ((v_min < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_min; - FLOATTYPE v_max_fudged = (ImAbs((FLOATTYPE)v_max) < logarithmic_zero_epsilon) ? ((v_max < 0.0f) ? -logarithmic_zero_epsilon : logarithmic_zero_epsilon) : (FLOATTYPE)v_max; - - if (flipped) - ImSwap(v_min_fudged, v_max_fudged); - - // Awkward special case - we need ranges of the form (-100 .. 0) to convert to (-100 .. -epsilon), not (-100 .. epsilon) - if ((v_max == 0.0f) && (v_min < 0.0f)) - v_max_fudged = -logarithmic_zero_epsilon; - - float t_with_flip = flipped ? (1.0f - t) : t; // t, but flipped if necessary to account for us flipping the range - - if ((v_min * v_max) < 0.0f) // Range crosses zero, so we have to do this in two parts - { - float zero_point_center = (-(float)ImMin(v_min, v_max)) / ImAbs((float)v_max - (float)v_min); // The zero point in parametric space - float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize; - float zero_point_snap_R = zero_point_center + zero_deadzone_halfsize; - if (t_with_flip >= zero_point_snap_L && t_with_flip <= zero_point_snap_R) - result = (TYPE)0.0f; // Special case to make getting exactly zero possible (the epsilon prevents it otherwise) - else if (t_with_flip < zero_point_center) - result = (TYPE)-(logarithmic_zero_epsilon * ImPow(-v_min_fudged / logarithmic_zero_epsilon, (FLOATTYPE)(1.0f - (t_with_flip / zero_point_snap_L)))); - else - result = (TYPE)(logarithmic_zero_epsilon * ImPow(v_max_fudged / logarithmic_zero_epsilon, (FLOATTYPE)((t_with_flip - zero_point_snap_R) / (1.0f - zero_point_snap_R)))); - } - else if ((v_min < 0.0f) || (v_max < 0.0f)) // Entirely negative slider - result = (TYPE)-(-v_max_fudged * ImPow(-v_min_fudged / -v_max_fudged, (FLOATTYPE)(1.0f - t_with_flip))); + float zero_point_center = (-(float)ImMin(v_min, v_max)) / ImAbs((float)v_max - (float)v_min); // The zero point in parametric space + float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize; + float zero_point_snap_R = zero_point_center + zero_deadzone_halfsize; + if (t_with_flip >= zero_point_snap_L && t_with_flip <= zero_point_snap_R) + result = (TYPE)0.0f; // Special case to make getting exactly zero possible (the epsilon prevents it otherwise) + else if (t_with_flip < zero_point_center) + result = (TYPE)-(logarithmic_zero_epsilon * ImPow(-v_min_fudged / logarithmic_zero_epsilon, (FLOATTYPE)(1.0f - (t_with_flip / zero_point_snap_L)))); else - result = (TYPE)(v_min_fudged * ImPow(v_max_fudged / v_min_fudged, (FLOATTYPE)t_with_flip)); + result = (TYPE)(logarithmic_zero_epsilon * ImPow(v_max_fudged / logarithmic_zero_epsilon, (FLOATTYPE)((t_with_flip - zero_point_snap_R) / (1.0f - zero_point_snap_R)))); } + else if ((v_min < 0.0f) || (v_max < 0.0f)) // Entirely negative slider + result = (TYPE)-(-v_max_fudged * ImPow(-v_min_fudged / -v_max_fudged, (FLOATTYPE)(1.0f - t_with_flip))); + else + result = (TYPE)(v_min_fudged * ImPow(v_max_fudged / v_min_fudged, (FLOATTYPE)t_with_flip)); } else { // Linear slider + const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); if (is_floating_point) { result = ImLerp(v_min, v_max, t); } - else + else if (t < 1.0) { // - For integer values we want the clicking position to match the grab box so we round above // This code is carefully tuned to work with large values (e.g. high ranges of U64) while preserving this property.. // - Not doing a *1.0 multiply at the end of a range as it tends to be lossy. While absolute aiming at a large s64/u64 // range is going to be imprecise anyway, with this check we at least make the edge values matches expected limits. - if (t < 1.0) - { - FLOATTYPE v_new_off_f = (SIGNEDTYPE)(v_max - v_min) * t; - result = (TYPE)((SIGNEDTYPE)v_min + (SIGNEDTYPE)(v_new_off_f + (FLOATTYPE)(v_min > v_max ? -0.5 : 0.5))); - } - else - { - result = v_max; - } + FLOATTYPE v_new_off_f = (SIGNEDTYPE)(v_max - v_min) * t; + result = (TYPE)((SIGNEDTYPE)v_min + (SIGNEDTYPE)(v_new_off_f + (FLOATTYPE)(v_min > v_max ? -0.5 : 0.5))); } } return result; } -// FIXME: Move more of the code into SliderBehavior() +// FIXME: Try to move more of the code into shared SliderBehavior() template bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb) { @@ -2801,13 +2776,14 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ const ImGuiAxis axis = (flags & ImGuiSliderFlags_Vertical) ? ImGuiAxis_Y : ImGuiAxis_X; const bool is_logarithmic = (flags & ImGuiSliderFlags_Logarithmic) != 0; const bool is_floating_point = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); + const SIGNEDTYPE v_range = (v_min < v_max ? v_max - v_min : v_min - v_max); - const float grab_padding = 2.0f; + // Calculate bounds + const float grab_padding = 2.0f; // FIXME: Should be part of style. const float slider_sz = (bb.Max[axis] - bb.Min[axis]) - grab_padding * 2.0f; float grab_sz = style.GrabMinSize; - SIGNEDTYPE v_range = (v_min < v_max ? v_max - v_min : v_min - v_max); - if (!is_floating_point && v_range >= 0) // v_range < 0 may happen on integer overflows - grab_sz = ImMax((float)(slider_sz / (v_range + 1)), style.GrabMinSize); // For integer sliders: if possible have the grab size represent 1 unit + if (!is_floating_point && v_range >= 0) // v_range < 0 may happen on integer overflows + grab_sz = ImMax((float)(slider_sz / (v_range + 1)), style.GrabMinSize); // For integer sliders: if possible have the grab size represent 1 unit grab_sz = ImMin(grab_sz, slider_sz); const float slider_usable_sz = slider_sz - grab_sz; const float slider_usable_pos_min = bb.Min[axis] + grab_padding + grab_sz * 0.5f; @@ -2838,13 +2814,23 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ else { const float mouse_abs_pos = g.IO.MousePos[axis]; - clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f; + if (g.ActiveIdIsJustActivated) + { + float grab_t = ScaleRatioFromValueT(data_type, *v, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); + if (axis == ImGuiAxis_Y) + grab_t = 1.0f - grab_t; + const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); + const bool clicked_around_grab = (mouse_abs_pos >= grab_pos - grab_sz * 0.5f - 1.0f) && (mouse_abs_pos <= grab_pos + grab_sz * 0.5f + 1.0f); // No harm being extra generous here. + g.SliderGrabClickOffset = (clicked_around_grab && is_floating_point) ? mouse_abs_pos - grab_pos : 0.0f; + } + if (slider_usable_sz > 0.0f) + clicked_t = ImSaturate((mouse_abs_pos - g.SliderGrabClickOffset - slider_usable_pos_min) / slider_usable_sz); if (axis == ImGuiAxis_Y) clicked_t = 1.0f - clicked_t; set_new_value = true; } } - else if (g.ActiveIdSource == ImGuiInputSource_Nav) + else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad) { if (g.ActiveIdIsJustActivated) { @@ -2852,25 +2838,26 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ g.SliderCurrentAccumDirty = false; } - const ImVec2 input_delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 0.0f, 0.0f); - float input_delta = (axis == ImGuiAxis_X) ? input_delta2.x : -input_delta2.y; + float input_delta = (axis == ImGuiAxis_X) ? GetNavTweakPressedAmount(axis) : -GetNavTweakPressedAmount(axis); if (input_delta != 0.0f) { + const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow); + const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast); const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; if (decimal_precision > 0) { input_delta /= 100.0f; // Gamepad/keyboard tweak speeds in % of slider bounds - if (IsNavInputDown(ImGuiNavInput_TweakSlow)) + if (tweak_slow) input_delta /= 10.0f; } else { - if ((v_range >= -100.0f && v_range <= 100.0f) || IsNavInputDown(ImGuiNavInput_TweakSlow)) + if ((v_range >= -100.0f && v_range <= 100.0f) || tweak_slow) input_delta = ((input_delta < 0.0f) ? -1.0f : +1.0f) / (float)v_range; // Gamepad/keyboard tweak speeds in integer steps else input_delta /= 100.0f; } - if (IsNavInputDown(ImGuiNavInput_TweakFast)) + if (tweak_fast) input_delta *= 10.0f; g.SliderCurrentAccum += input_delta; @@ -2899,8 +2886,8 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ // Calculate what our "new" clicked_t will be, and thus how far we actually moved the slider, and subtract this from the accumulator TYPE v_new = ScaleValueFromRatioT(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); - if (!(flags & ImGuiSliderFlags_NoRoundToFormat)) - v_new = RoundScalarWithFormatT(format, data_type, v_new); + if (is_floating_point && !(flags & ImGuiSliderFlags_NoRoundToFormat)) + v_new = RoundScalarWithFormatT(format, data_type, v_new); float new_clicked_t = ScaleRatioFromValueT(data_type, v_new, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); if (delta > 0) @@ -2918,8 +2905,8 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ TYPE v_new = ScaleValueFromRatioT(data_type, clicked_t, v_min, v_max, is_logarithmic, logarithmic_zero_epsilon, zero_deadzone_halfsize); // Round to user desired precision based on format string - if (!(flags & ImGuiSliderFlags_NoRoundToFormat)) - v_new = RoundScalarWithFormatT(format, data_type, v_new); + if (is_floating_point && !(flags & ImGuiSliderFlags_NoRoundToFormat)) + v_new = RoundScalarWithFormatT(format, data_type, v_new); // Apply result if (*v != v_new) @@ -2958,6 +2945,7 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type // Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert. IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flag! Has the 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead."); + // Those are the things we can do easily outside the SliderBehaviorT<> template, saves code generation. ImGuiContext& g = *GImGui; if ((g.LastItemData.InFlags & ImGuiItemFlags_ReadOnly) || (flags & ImGuiSliderFlags_ReadOnly)) return false; @@ -3017,24 +3005,27 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat // Default format string when passing NULL if (format == NULL) format = DataTypeGetInfo(data_type)->PrintFmt; - else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.) - format = PatchFormatStringFloatToInt(format); - // Tabbing or CTRL-clicking on Slider turns it into an input box - const bool hovered = ItemHoverable(frame_bb, id); + const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags); bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id); if (!temp_input_is_active) { + // Tabbing or CTRL-clicking on Slider turns it into an input box const bool input_requested_by_tabbing = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; - const bool clicked = (hovered && g.IO.MouseClicked[0]); - if (input_requested_by_tabbing || clicked || g.NavActivateId == id || g.NavActivateInputId == id) + const bool clicked = hovered && IsMouseClicked(0, id); + const bool make_active = (input_requested_by_tabbing || clicked || g.NavActivateId == id); + if (make_active && clicked) + SetKeyOwner(ImGuiKey_MouseLeft, id); + if (make_active && temp_input_allowed) + if (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput))) + temp_input_is_active = true; + + if (make_active && !temp_input_is_active) { SetActiveID(id, window); SetFocusID(id, window); FocusWindow(window); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); - if (temp_input_allowed && (input_requested_by_tabbing || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id)) - temp_input_is_active = true; } } @@ -3070,7 +3061,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat if (label_size.x > 0.0f) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | (temp_input_allowed ? ImGuiItemStatusFlags_Inputable : 0)); return value_changed; } @@ -3181,12 +3172,13 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d // Default format string when passing NULL if (format == NULL) format = DataTypeGetInfo(data_type)->PrintFmt; - else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.) - format = PatchFormatStringFloatToInt(format); - const bool hovered = ItemHoverable(frame_bb, id); - if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavActivateInputId == id) + const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags); + const bool clicked = hovered && IsMouseClicked(0, id); + if (clicked || g.NavActivateId == id) { + if (clicked) + SetKeyOwner(ImGuiKey_MouseLeft, id); SetActiveID(id, window); SetFocusID(id, window); FocusWindow(window); @@ -3229,39 +3221,14 @@ bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, return VSliderScalar(label, size, ImGuiDataType_S32, v, &v_min, &v_max, format, flags); } -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - -// Obsolete versions with power parameter. See https://github.com/ocornut/imgui/issues/3361 for details. -bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format, float power) -{ - ImGuiSliderFlags slider_flags = ImGuiSliderFlags_None; - if (power != 1.0f) - { - IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); - slider_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths - } - return SliderScalar(label, data_type, p_data, p_min, p_max, format, slider_flags); -} - -bool ImGui::SliderScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* v_min, const void* v_max, const char* format, float power) -{ - ImGuiSliderFlags slider_flags = ImGuiSliderFlags_None; - if (power != 1.0f) - { - IM_ASSERT(power == 1.0f && "Call function with ImGuiSliderFlags_Logarithmic flags instead of using the old 'float power' function!"); - slider_flags |= ImGuiSliderFlags_Logarithmic; // Fallback for non-asserting paths - } - return SliderScalarN(label, data_type, v, components, v_min, v_max, format, slider_flags); -} - -#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS - //------------------------------------------------------------------------- // [SECTION] Widgets: InputScalar, InputFloat, InputInt, etc. //------------------------------------------------------------------------- // - ImParseFormatFindStart() [Internal] // - ImParseFormatFindEnd() [Internal] // - ImParseFormatTrimDecorations() [Internal] +// - ImParseFormatSanitizeForPrinting() [Internal] +// - ImParseFormatSanitizeForScanning() [Internal] // - ImParseFormatPrecision() [Internal] // - TempInputTextScalar() [Internal] // - InputScalar() @@ -3309,7 +3276,7 @@ const char* ImParseFormatFindEnd(const char* fmt) } // Extract the format out of a format string with leading or trailing decorations -// fmt = "blah blah" -> return fmt +// fmt = "blah blah" -> return "" // fmt = "%.3f" -> return fmt // fmt = "hello %.3f" -> return fmt + 6 // fmt = "%.3f hello" -> return buf written with "%.3f" @@ -3317,7 +3284,7 @@ const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, size_t buf_ { const char* fmt_start = ImParseFormatFindStart(fmt); if (fmt_start[0] != '%') - return fmt; + return ""; const char* fmt_end = ImParseFormatFindEnd(fmt_start); if (fmt_end[0] == 0) // If we only have leading decoration, we don't need to copy the data. return fmt_start; @@ -3325,6 +3292,57 @@ const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, size_t buf_ return buf; } +// Sanitize format +// - Zero terminate so extra characters after format (e.g. "%f123") don't confuse atof/atoi +// - stb_sprintf.h supports several new modifiers which format numbers in a way that also makes them incompatible atof/atoi. +void ImParseFormatSanitizeForPrinting(const char* fmt_in, char* fmt_out, size_t fmt_out_size) +{ + const char* fmt_end = ImParseFormatFindEnd(fmt_in); + IM_UNUSED(fmt_out_size); + IM_ASSERT((size_t)(fmt_end - fmt_in + 1) < fmt_out_size); // Format is too long, let us know if this happens to you! + while (fmt_in < fmt_end) + { + char c = *fmt_in++; + if (c != '\'' && c != '$' && c != '_') // Custom flags provided by stb_sprintf.h. POSIX 2008 also supports '. + *(fmt_out++) = c; + } + *fmt_out = 0; // Zero-terminate +} + +// - For scanning we need to remove all width and precision fields and flags "%+3.7f" -> "%f". BUT don't strip types like "%I64d" which includes digits. ! "%07I64d" -> "%I64d" +const char* ImParseFormatSanitizeForScanning(const char* fmt_in, char* fmt_out, size_t fmt_out_size) +{ + const char* fmt_end = ImParseFormatFindEnd(fmt_in); + const char* fmt_out_begin = fmt_out; + IM_UNUSED(fmt_out_size); + IM_ASSERT((size_t)(fmt_end - fmt_in + 1) < fmt_out_size); // Format is too long, let us know if this happens to you! + bool has_type = false; + while (fmt_in < fmt_end) + { + char c = *fmt_in++; + if (!has_type && ((c >= '0' && c <= '9') || c == '.' || c == '+' || c == '#')) + continue; + has_type |= ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); // Stop skipping digits + if (c != '\'' && c != '$' && c != '_') // Custom flags provided by stb_sprintf.h. POSIX 2008 also supports '. + *(fmt_out++) = c; + } + *fmt_out = 0; // Zero-terminate + return fmt_out_begin; +} + +template +static const char* ImAtoi(const char* src, TYPE* output) +{ + int negative = 0; + if (*src == '-') { negative = 1; src++; } + if (*src == '+') { src++; } + TYPE v = 0; + while (*src >= '0' && *src <= '9') + v = (v * 10) + (*src++ - '0'); + *output = negative ? -v : v; + return src; +} + // Parse display precision back from the display format string // FIXME: This is still used by some navigation code path to infer a minimum tweak step, but we should aim to rework widgets so it isn't needed. int ImParseFormatPrecision(const char* fmt, int default_precision) @@ -3371,31 +3389,43 @@ bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* return value_changed; } +static inline ImGuiInputTextFlags InputScalar_DefaultCharsFilter(ImGuiDataType data_type, const char* format) +{ + if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) + return ImGuiInputTextFlags_CharsScientific; + const char format_last_char = format[0] ? format[strlen(format) - 1] : 0; + return (format_last_char == 'x' || format_last_char == 'X') ? ImGuiInputTextFlags_CharsHexadecimal : ImGuiInputTextFlags_CharsDecimal; +} + // Note that Drag/Slider functions are only forwarding the min/max values clamping values if the ImGuiSliderFlags_AlwaysClamp flag is set! // This is intended: this way we allow CTRL+Click manual input to set a value out of bounds, for maximum flexibility. // However this may not be ideal for all uses, as some user code may break on out of bound values. bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min, const void* p_clamp_max) { - ImGuiContext& g = *GImGui; - + // FIXME: May need to clarify display behavior if format doesn't contain %. + // "%d" -> "%d" / "There are %d items" -> "%d" / "items" -> "%d" (fallback). Also see #6405 + const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); char fmt_buf[32]; char data_buf[32]; format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf)); + if (format[0] == 0) + format = type_info->PrintFmt; DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format); ImStrTrimBlanks(data_buf); ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited; - flags |= ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal); + flags |= InputScalar_DefaultCharsFilter(data_type, format); + bool value_changed = false; if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags)) { // Backup old value - size_t data_type_size = DataTypeGetInfo(data_type)->Size; + size_t data_type_size = type_info->Size; ImGuiDataTypeTempStorage data_backup; memcpy(&data_backup, p_data, data_type_size); // Apply new value (or operations) then clamp - DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialTextA.Data, data_type, p_data, NULL); + DataTypeApplyFromText(data_buf, data_type, p_data, format); if (p_clamp_min || p_clamp_max) { if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0) @@ -3428,13 +3458,18 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data char buf[64]; DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); - bool value_changed = false; - if ((flags & (ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0) - flags |= ImGuiInputTextFlags_CharsDecimal; - flags |= ImGuiInputTextFlags_AutoSelectAll; - flags |= ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string. + // Testing ActiveId as a minor optimization as filtering is not needed until active + if (g.ActiveId == 0 && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0) + flags |= InputScalar_DefaultCharsFilter(data_type, format); + flags |= ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string. - if (p_step != NULL) + bool value_changed = false; + if (p_step == NULL) + { + if (InputText(label, buf, IM_ARRAYSIZE(buf), flags)) + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + } + else { const float button_size = GetFrameHeight(); @@ -3442,7 +3477,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data PushID(label); SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2)); if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view - value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialTextA.Data, data_type, p_data, format); + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable); // Step buttons const ImVec2 backup_frame_padding = style.FramePadding; @@ -3476,11 +3512,6 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data PopID(); EndGroup(); } - else - { - if (InputText(label, buf, IM_ARRAYSIZE(buf), flags)) - value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialTextA.Data, data_type, p_data, format); - } if (value_changed) MarkItemEdited(g.LastItemData.ID); @@ -3577,7 +3608,11 @@ bool ImGui::InputDouble(const char* label, double* v, double step, double step_f // - InputText() // - InputTextWithHint() // - InputTextMultiline() +// - InputTextGetCharInfo() [Internal] +// - InputTextReindexLines() [Internal] +// - InputTextReindexLinesRange() [Internal] // - InputTextEx() [Internal] +// - DebugNodeInputTextState() [Internal] //------------------------------------------------------------------------- bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) @@ -3593,7 +3628,7 @@ bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, co bool ImGui::InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) { - IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() + IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() or InputTextEx() manually if you need multi-line + hint. return InputTextEx(label, hint, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data); } @@ -3611,9 +3646,9 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** return line_count; } -static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line) +static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *ctx; ImFont* font = g.Font; const float line_height = g.FontSize; const float scale = line_height / font->FontSize; @@ -3662,14 +3697,14 @@ namespace ImStb static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->CurLenW; } static ImWchar STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { return obj->TextW[idx]; } -static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *GImGui; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); } +static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); } static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x200000 ? 0 : key; } static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx) { const ImWchar* text = obj->TextW.Data; const ImWchar* text_remaining = NULL; - const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true); + const ImVec2 size = InputTextCalcTextSizeW(obj->Ctx, text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true); r->x0 = 0.0f; r->x1 = size.x; r->baseline_y_delta = size.y; @@ -3678,17 +3713,39 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* ob r->num_chars = (int)(text_remaining - (text + line_start_idx)); } -// When ImGuiInputTextFlags_Password is set, we don't want actions such as CTRL+Arrow to leak the fact that underlying data are blanks or separators. -static bool is_separator(unsigned int c) { return ImCharIsBlankW(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } -static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx) { if (obj->Flags & ImGuiInputTextFlags_Password) return 0; return idx > 0 ? (is_separator(obj->TextW[idx - 1]) && !is_separator(obj->TextW[idx]) ) : 1; } +static bool is_separator(unsigned int c) +{ + return c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|' || c=='\n' || c=='\r' || c=='.' || c=='!'; +} + +static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx) +{ + // When ImGuiInputTextFlags_Password is set, we don't want actions such as CTRL+Arrow to leak the fact that underlying data are blanks or separators. + if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0) + return 0; + + bool prev_white = ImCharIsBlankW(obj->TextW[idx - 1]); + bool prev_separ = is_separator(obj->TextW[idx - 1]); + bool curr_white = ImCharIsBlankW(obj->TextW[idx]); + bool curr_separ = is_separator(obj->TextW[idx]); + return ((prev_white || prev_separ) && !(curr_separ || curr_white)) || (curr_separ && !prev_separ); +} +static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx) +{ + if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0) + return 0; + + bool prev_white = ImCharIsBlankW(obj->TextW[idx]); + bool prev_separ = is_separator(obj->TextW[idx]); + bool curr_white = ImCharIsBlankW(obj->TextW[idx - 1]); + bool curr_separ = is_separator(obj->TextW[idx - 1]); + return ((prev_white) && !(curr_separ || curr_white)) || (curr_separ && !prev_separ); +} static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } -#ifdef __APPLE__ // FIXME: Move setting to IO structure -static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx) { if (obj->Flags & ImGuiInputTextFlags_Password) return 0; return idx > 0 ? (!is_separator(obj->TextW[idx - 1]) && is_separator(obj->TextW[idx]) ) : 1; } -static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } -#else -static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } -#endif -#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h +static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } +static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } +static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx) { ImGuiContext& g = *obj->Ctx; if (g.IO.ConfigMacOSXBehaviors) return STB_TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx); else return STB_TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx); } +#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h #define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n) @@ -3767,11 +3824,12 @@ static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* st { stb_text_makeundo_replace(str, state, 0, str->CurLenW, text_len); ImStb::STB_TEXTEDIT_DELETECHARS(str, 0, str->CurLenW); + state->cursor = state->select_start = state->select_end = 0; if (text_len <= 0) return; if (ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len)) { - state->cursor = text_len; + state->cursor = state->select_start = state->select_end = text_len; state->has_preferred_x = 0; return; } @@ -3815,6 +3873,10 @@ void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count) void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end) { + // Accept null ranges + if (new_text == new_text_end) + return; + const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0; const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); if (new_text_len + BufTextLen >= BufSize) @@ -3823,7 +3885,7 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons return; // Contrary to STB_TEXTEDIT_INSERTCHARS() this is working in the UTF8 buffer, hence the mildly similar code (until we remove the U16 buffer altogether!) - ImGuiContext& g = *GImGui; + ImGuiContext& g = *Ctx; ImGuiInputTextState* edit_state = &g.InputTextState; IM_ASSERT(edit_state->ID != 0 && g.ActiveId == edit_state->ID); IM_ASSERT(Buf == edit_state->TextA.Data); @@ -3856,7 +3918,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f if (c < 0x20) { bool pass = false; - pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); + pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); // Note that an Enter KEY will emit \r and be ignored (we poll for KEY in InputText() code) pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput)); if (!pass) return false; @@ -3881,14 +3943,22 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f // Generic named filters if (apply_named_filters && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))) { - // The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf. + // The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf to use e.g. ',' instead of '.'. // The standard mandate that programs starts in the "C" locale where the decimal point is '.'. // We don't really intend to provide widespread support for it, but out of empathy for people stuck with using odd API, we support the bare minimum aka overriding the decimal point. // Change the default decimal_point with: // ImGui::GetCurrentContext()->PlatformLocaleDecimalPoint = *localeconv()->decimal_point; + // Users of non-default decimal point (in particular ',') may be affected by word-selection logic (is_word_boundary_from_right/is_word_boundary_from_left) functions. ImGuiContext& g = *GImGui; const unsigned c_decimal_point = (unsigned int)g.PlatformLocaleDecimalPoint; + // Full-width -> half-width conversion for numeric fields (https://en.wikipedia.org/wiki/Halfwidth_and_Fullwidth_Forms_(Unicode_block) + // While this is mostly convenient, this has the side-effect for uninformed users accidentally inputting full-width characters that they may + // scratch their head as to why it works in numerical fields vs in generic text fields it would require support in the font. + if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsScientific | ImGuiInputTextFlags_CharsHexadecimal)) + if (c >= 0xFF01 && c <= 0xFF5E) + c = c - 0xFF01 + 0x21; + // Allow 0-9 . - + * / if (flags & ImGuiInputTextFlags_CharsDecimal) if (!(c >= '0' && c <= '9') && (c != c_decimal_point) && (c != '-') && (c != '+') && (c != '*') && (c != '/')) @@ -3907,18 +3977,21 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f // Turn a-z into A-Z if (flags & ImGuiInputTextFlags_CharsUppercase) if (c >= 'a' && c <= 'z') - *p_char = (c += (unsigned int)('A' - 'a')); + c += (unsigned int)('A' - 'a'); if (flags & ImGuiInputTextFlags_CharsNoBlank) if (ImCharIsBlankW(c)) return false; + + *p_char = c; } // Custom callback filter if (flags & ImGuiInputTextFlags_CallbackCharFilter) { + ImGuiContext& g = *GImGui; ImGuiInputTextCallbackData callback_data; - memset(&callback_data, 0, sizeof(ImGuiInputTextCallbackData)); + callback_data.Ctx = &g; callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter; callback_data.EventChar = (ImWchar)c; callback_data.Flags = flags; @@ -3933,6 +4006,64 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f return true; } +// Find the shortest single replacement we can make to get the new text from the old text. +// Important: needs to be run before TextW is rewritten with the new characters because calling STB_TEXTEDIT_GETCHAR() at the end. +// FIXME: Ideally we should transition toward (1) making InsertChars()/DeleteChars() update undo-stack (2) discourage (and keep reconcile) or obsolete (and remove reconcile) accessing buffer directly. +static void InputTextReconcileUndoStateAfterUserCallback(ImGuiInputTextState* state, const char* new_buf_a, int new_length_a) +{ + ImGuiContext& g = *GImGui; + const ImWchar* old_buf = state->TextW.Data; + const int old_length = state->CurLenW; + const int new_length = ImTextCountCharsFromUtf8(new_buf_a, new_buf_a + new_length_a); + g.TempBuffer.reserve_discard((new_length + 1) * sizeof(ImWchar)); + ImWchar* new_buf = (ImWchar*)(void*)g.TempBuffer.Data; + ImTextStrFromUtf8(new_buf, new_length + 1, new_buf_a, new_buf_a + new_length_a); + + const int shorter_length = ImMin(old_length, new_length); + int first_diff; + for (first_diff = 0; first_diff < shorter_length; first_diff++) + if (old_buf[first_diff] != new_buf[first_diff]) + break; + if (first_diff == old_length && first_diff == new_length) + return; + + int old_last_diff = old_length - 1; + int new_last_diff = new_length - 1; + for (; old_last_diff >= first_diff && new_last_diff >= first_diff; old_last_diff--, new_last_diff--) + if (old_buf[old_last_diff] != new_buf[new_last_diff]) + break; + + const int insert_len = new_last_diff - first_diff + 1; + const int delete_len = old_last_diff - first_diff + 1; + if (insert_len > 0 || delete_len > 0) + if (STB_TEXTEDIT_CHARTYPE* p = stb_text_createundo(&state->Stb.undostate, first_diff, delete_len, insert_len)) + for (int i = 0; i < delete_len; i++) + p[i] = ImStb::STB_TEXTEDIT_GETCHAR(state, first_diff + i); +} + +// As InputText() retain textual data and we currently provide a path for user to not retain it (via local variables) +// we need some form of hook to reapply data back to user buffer on deactivation frame. (#4714) +// It would be more desirable that we discourage users from taking advantage of the "user not retaining data" trick, +// but that more likely be attractive when we do have _NoLiveEdit flag available. +void ImGui::InputTextDeactivateHook(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + ImGuiInputTextState* state = &g.InputTextState; + if (id == 0 || state->ID != id) + return; + g.InputTextDeactivatedState.ID = state->ID; + if (state->Flags & ImGuiInputTextFlags_ReadOnly) + { + g.InputTextDeactivatedState.TextA.resize(0); // In theory this data won't be used, but clear to be neat. + } + else + { + IM_ASSERT(state->TextA.Data != 0); + g.InputTextDeactivatedState.TextA.resize(state->CurLenA + 1); + memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->CurLenA + 1); + } +} + // Edit a string of text // - buf_size account for the zero-terminator, so a buf_size of 6 can hold "Hello" but not "Hello!". // This is so we can easily call InputText() on static arrays using ARRAYSIZE() and to match @@ -3964,7 +4095,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (is_resizable) IM_ASSERT(callback != NULL); // Must provide a callback if you set the ImGuiInputTextFlags_CallbackResize flag! - if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope, + if (is_multiline) // Open group before calling GetID() because groups tracks id created within their scope (including the scrollbar) BeginGroup(); const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); @@ -3977,6 +4108,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ ImGuiWindow* draw_window = window; ImVec2 inner_size = frame_size; ImGuiItemStatusFlags item_status_flags = 0; + ImGuiLastItemData item_data_backup; if (is_multiline) { ImVec2 backup_pos = window->DC.CursorPos; @@ -3987,6 +4119,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ return false; } item_status_flags = g.LastItemData.StatusFlags; + item_data_backup = g.LastItemData; window->DC.CursorPos = backup_pos; // We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug. @@ -3994,8 +4127,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); + PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Ensure no clip rect so mouse hover can reach FramePadding edges bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove); - PopStyleVar(2); + PopStyleVar(3); PopStyleColor(); if (!child_visible) { @@ -4017,7 +4151,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ return false; item_status_flags = g.LastItemData.StatusFlags; } - const bool hovered = ItemHoverable(frame_bb, id); + const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags); if (hovered) g.MouseCursor = ImGuiMouseCursor_TextInput; @@ -4025,7 +4159,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ ImGuiInputTextState* state = GetInputTextState(id); const bool input_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; - const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard)); + const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateId == id) && ((g.NavActivateFlags & ImGuiActivateFlags_PreferInput) || (g.NavInputSource == ImGuiInputSource_Keyboard))); const bool user_clicked = hovered && io.MouseClicked[0]; const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y); @@ -4035,7 +4169,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX; - const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); + const bool init_changed_specs = (state != NULL && state->Stb.single_line != !is_multiline); // state != NULL means its our state. const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav || input_requested_by_tabbing); const bool init_state = (init_make_active || user_scroll_active); if ((init_state && g.ActiveId != id) || init_changed_specs) @@ -4044,23 +4178,30 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ state = &g.InputTextState; state->CursorAnimReset(); + // Backup state of deactivating item so they'll have a chance to do a write to output buffer on the same frame they report IsItemDeactivatedAfterEdit (#4714) + InputTextDeactivateHook(state->ID); + // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) // From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode) const int buf_len = (int)strlen(buf); state->InitialTextA.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string. memcpy(state->InitialTextA.Data, buf, buf_len + 1); + // Preserve cursor position and undo/redo stack if we come back to same widget + // FIXME: Since we reworked this on 2022/06, may want to differenciate recycle_cursor vs recycle_undostate? + bool recycle_state = (state->ID == id && !init_changed_specs); + if (recycle_state && (state->CurLenA != buf_len || (state->TextAIsValid && strncmp(state->TextA.Data, buf, buf_len) != 0))) + recycle_state = false; + // Start edition const char* buf_end = NULL; + state->ID = id; state->TextW.resize(buf_size + 1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data is always pointing to at least an empty string. state->TextA.resize(0); state->TextAIsValid = false; // TextA is not valid yet (we will display buf until then) state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, buf_size, buf, NULL, &buf_end); state->CurLenA = (int)(buf_end - buf); // We can't get the result from ImStrncpy() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. - // Preserve cursor position and undo/redo stack if we come back to same widget - // FIXME: For non-readonly widgets we might be able to require that TextAIsValid && TextA == buf ? (untested) and discard undo stack if user buffer has changed. - const bool recycle_state = (state->ID == id && !init_changed_specs); if (recycle_state) { // Recycle existing cursor/selection/undo stack but clamp position @@ -4069,7 +4210,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } else { - state->ID = id; state->ScrollX = 0.0f; stb_textedit_initialize_state(&state->Stb, !is_multiline); } @@ -4088,24 +4228,33 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ state->Stb.insert_mode = 1; // stb field name is indeed incorrect (see #2863) } + const bool is_osx = io.ConfigMacOSXBehaviors; if (g.ActiveId != id && init_make_active) { IM_ASSERT(state && state->ID == id); SetActiveID(id, window); SetFocusID(id, window); FocusWindow(window); - - // Declare our inputs - IM_ASSERT(ImGuiNavInput_COUNT < 32); + } + if (g.ActiveId == id) + { + // Declare some inputs, the other are registered and polled via Shortcut() routing system. + if (user_clicked) + SetKeyOwner(ImGuiKey_MouseLeft, id); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory)) g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); - g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel); - g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Home) | ((ImU64)1 << ImGuiKey_End); + SetKeyOwner(ImGuiKey_Home, id); + SetKeyOwner(ImGuiKey_End, id); if (is_multiline) - g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_PageUp) | ((ImU64)1 << ImGuiKey_PageDown); - if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character. - g.ActiveIdUsingKeyInputMask |= ((ImU64)1 << ImGuiKey_Tab); + { + SetKeyOwner(ImGuiKey_PageUp, id); + SetKeyOwner(ImGuiKey_PageDown, id); + } + if (is_osx) + SetKeyOwner(ImGuiMod_Alt, id); + if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character. + SetShortcutRouting(ImGuiKey_Tab, id); } // We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function) @@ -4117,10 +4266,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ clear_active_id = true; // Lock the decision of whether we are going to take the path displaying the cursor or selection - const bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active); + bool render_cursor = (g.ActiveId == id) || (state && user_scroll_active); bool render_selection = state && (state->HasSelection() || select_all) && (RENDER_SELECTION_WHEN_INACTIVE || render_cursor); bool value_changed = false; - bool enter_pressed = false; + bool validated = false; // When read-only we always use the live data passed to the function // FIXME-OPT: Because our selection/cursor code currently needs the wide text we need to convert it when active, which is not ideal :( @@ -4163,35 +4312,63 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ state->Edited = false; state->BufCapacityA = buf_size; state->Flags = flags; - state->UserCallback = callback; - state->UserCallbackData = callback_user_data; // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. // Down the line we should have a cleaner library-wide concept of Selected vs Active. g.ActiveIdAllowOverlap = !io.MouseDown[0]; - g.WantTextInputNextFrame = 1; // Edit in progress const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + state->ScrollX; const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y) : (g.FontSize * 0.5f)); - const bool is_osx = io.ConfigMacOSXBehaviors; - if (select_all || (hovered && !is_osx && io.MouseDoubleClicked[0])) + if (select_all) { state->SelectAll(); state->SelectedAllMouseLock = true; } - else if (hovered && is_osx && io.MouseDoubleClicked[0]) + else if (hovered && io.MouseClickedCount[0] >= 2 && !io.KeyShift) { - // Double-click select a word only, OS X style (by simulating keystrokes) - state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); - state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); + stb_textedit_click(state, &state->Stb, mouse_x, mouse_y); + const int multiclick_count = (io.MouseClickedCount[0] - 2); + if ((multiclick_count % 2) == 0) + { + // Double-click: Select word + // We always use the "Mac" word advance for double-click select vs CTRL+Right which use the platform dependent variant: + // FIXME: There are likely many ways to improve this behavior, but there's no "right" behavior (depends on use-case, software, OS) + const bool is_bol = (state->Stb.cursor == 0) || ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor - 1) == '\n'; + if (STB_TEXT_HAS_SELECTION(&state->Stb) || !is_bol) + state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); + //state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); + if (!STB_TEXT_HAS_SELECTION(&state->Stb)) + ImStb::stb_textedit_prep_selection_at_cursor(&state->Stb); + state->Stb.cursor = ImStb::STB_TEXTEDIT_MOVEWORDRIGHT_MAC(state, state->Stb.cursor); + state->Stb.select_end = state->Stb.cursor; + ImStb::stb_textedit_clamp(state, &state->Stb); + } + else + { + // Triple-click: Select line + const bool is_eol = ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb.cursor) == '\n'; + state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART); + state->OnKeyPressed(STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT); + state->OnKeyPressed(STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT); + if (!is_eol && is_multiline) + { + ImSwap(state->Stb.select_start, state->Stb.select_end); + state->Stb.cursor = state->Stb.select_end; + } + state->CursorFollow = false; + } + state->CursorAnimReset(); } else if (io.MouseClicked[0] && !state->SelectedAllMouseLock) { if (hovered) { - stb_textedit_click(state, &state->Stb, mouse_x, mouse_y); + if (io.KeyShift) + stb_textedit_drag(state, &state->Stb, mouse_x, mouse_y); + else + stb_textedit_click(state, &state->Stb, mouse_x, mouse_y); state->CursorAnimReset(); } } @@ -4204,19 +4381,18 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (state->SelectedAllMouseLock && !io.MouseDown[0]) state->SelectedAllMouseLock = false; - // It is ill-defined whether the backend needs to send a \t character when pressing the TAB keys. - // Win32 and GLFW naturally do it but not SDL. - const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper); - if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !ignore_char_inputs && !io.KeyShift && !is_readonly) - if (!io.InputQueueCharacters.contains('\t')) - { - unsigned int c = '\t'; // Insert TAB - if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) - state->OnKeyPressed((int)c); - } + // We expect backends to emit a Tab key but some also emit a Tab character which we ignore (#2467, #1336) + // (For Tab and Enter: Win32/SFML/Allegro are sending both keys and chars, GLFW and SDL are only sending keys. For Space they all send all threes) + if ((flags & ImGuiInputTextFlags_AllowTabInput) && Shortcut(ImGuiKey_Tab, id) && !is_readonly) + { + unsigned int c = '\t'; // Insert TAB + if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) + state->OnKeyPressed((int)c); + } // Process regular text input (before we check for Return because using some IME will effectively send a Return?) // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters. + const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper); if (io.InputQueueCharacters.Size > 0) { if (!ignore_char_inputs && !is_readonly && !input_requested_by_nav) @@ -4224,7 +4400,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { // Insert character if they pass filtering unsigned int c = (unsigned int)io.InputQueueCharacters[n]; - if (c == '\t' && io.KeyShift) + if (c == '\t') // Skip Tab, see above. continue; if (InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) state->OnKeyPressed((int)c); @@ -4236,45 +4412,54 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } // Process other shortcuts/key-presses - bool cancel_edit = false; + bool revert_edit = false; if (g.ActiveId == id && !g.ActiveIdIsJustActivated && !clear_active_id) { IM_ASSERT(state != NULL); - IM_ASSERT(io.KeyMods == GetMergedKeyModFlags() && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); // We rarely do this check, but if anything let's do it here. const int row_count_per_page = ImMax((int)((inner_size.y - style.FramePadding.y) / g.FontSize), 1); state->Stb.row_count_per_page = row_count_per_page; const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_osx = io.ConfigMacOSXBehaviors; - const bool is_osx_shift_shortcut = is_osx && (io.KeyMods == (ImGuiKeyModFlags_Super | ImGuiKeyModFlags_Shift)); const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End - const bool is_ctrl_key_only = (io.KeyMods == ImGuiKeyModFlags_Ctrl); - const bool is_shift_key_only = (io.KeyMods == ImGuiKeyModFlags_Shift); - const bool is_shortcut_key = g.IO.ConfigMacOSXBehaviors ? (io.KeyMods == ImGuiKeyModFlags_Super) : (io.KeyMods == ImGuiKeyModFlags_Ctrl); - const bool is_cut = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); - const bool is_copy = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || state->HasSelection()); - const bool is_paste = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_readonly; - const bool is_undo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Z)) && !is_readonly && is_undoable); - const bool is_redo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressedMap(ImGuiKey_Z))) && !is_readonly && is_undoable; + // Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText) + // Otherwise we could simply assume that we own the keys as we are active. + const ImGuiInputFlags f_repeat = ImGuiInputFlags_Repeat; + const bool is_cut = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_X, id, f_repeat) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, id, f_repeat)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); + const bool is_copy = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_C, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, id)) && !is_password && (!is_multiline || state->HasSelection()); + const bool is_paste = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_V, id, f_repeat) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, id, f_repeat)) && !is_readonly; + const bool is_undo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Z, id, f_repeat)) && !is_readonly && is_undoable; + const bool is_redo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Y, id, f_repeat) || (is_osx && Shortcut(ImGuiMod_Shortcut | ImGuiMod_Shift | ImGuiKey_Z, id, f_repeat))) && !is_readonly && is_undoable; + const bool is_select_all = Shortcut(ImGuiMod_Shortcut | ImGuiKey_A, id); // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful. - const bool is_validate_enter = IsKeyPressedMap(ImGuiKey_Enter) || IsKeyPressedMap(ImGuiKey_KeyPadEnter); - const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed) && !IsKeyPressedMap(ImGuiKey_Space)) || IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed); - const bool is_cancel = IsKeyPressedMap(ImGuiKey_Escape) || IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed); + const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; + const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter, true) || IsKeyPressed(ImGuiKey_KeypadEnter, true); + const bool is_gamepad_validate = nav_gamepad_active && (IsKeyPressed(ImGuiKey_NavGamepadActivate, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false)); + const bool is_cancel = Shortcut(ImGuiKey_Escape, id, f_repeat) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, id, f_repeat)); - if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontSize; } - else if (IsKeyPressedMap(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontSize; } - else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Backspace) && !is_readonly) + // FIXME: Should use more Shortcut() and reduce IsKeyPressed()+SetKeyOwner(), but requires modifiers combination to be taken account of. + if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } + else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } + else if (IsKeyPressed(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } + else if (IsKeyPressed(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } + else if (IsKeyPressed(ImGuiKey_PageUp) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGUP | k_mask); scroll_y -= row_count_per_page * g.FontSize; } + else if (IsKeyPressed(ImGuiKey_PageDown) && is_multiline) { state->OnKeyPressed(STB_TEXTEDIT_K_PGDOWN | k_mask); scroll_y += row_count_per_page * g.FontSize; } + else if (IsKeyPressed(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } + else if (IsKeyPressed(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } + else if (IsKeyPressed(ImGuiKey_Delete) && !is_readonly && !is_cut) + { + if (!state->HasSelection()) + { + // OSX doesn't seem to have Super+Delete to delete until end-of-line, so we don't emulate that (as opposed to Super+Backspace) + if (is_wordmove_key_down) + state->OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); + } + state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); + } + else if (IsKeyPressed(ImGuiKey_Backspace) && !is_readonly) { if (!state->HasSelection()) { @@ -4285,12 +4470,17 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } - else if (is_validate_enter) + else if (is_enter_pressed || is_gamepad_validate) { + // Determine if we turn Enter into a \n character bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; - if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) + if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) { - enter_pressed = clear_active_id = true; + validated = true; + if (io.ConfigInputTextEnterKeepActive && !is_multiline) + state->SelectAll(); // No need to scroll + else + clear_active_id = true; } else if (!is_readonly) { @@ -4299,21 +4489,32 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ state->OnKeyPressed((int)c); } } - else if (is_validate_nav) - { - IM_ASSERT(!is_validate_enter); - enter_pressed = clear_active_id = true; - } else if (is_cancel) { - clear_active_id = cancel_edit = true; + if (flags & ImGuiInputTextFlags_EscapeClearsAll) + { + if (state->CurLenA > 0) + { + revert_edit = true; + } + else + { + render_cursor = render_selection = false; + clear_active_id = true; + } + } + else + { + clear_active_id = revert_edit = true; + render_cursor = render_selection = false; + } } else if (is_undo || is_redo) { state->OnKeyPressed(is_undo ? STB_TEXTEDIT_K_UNDO : STB_TEXTEDIT_K_REDO); state->ClearSelection(); } - else if (is_shortcut_key && IsKeyPressedMap(ImGuiKey_A)) + else if (is_select_all) { state->SelectAll(); state->CursorFollow = true; @@ -4347,12 +4548,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const int clipboard_len = (int)strlen(clipboard); ImWchar* clipboard_filtered = (ImWchar*)IM_ALLOC((clipboard_len + 1) * sizeof(ImWchar)); int clipboard_filtered_len = 0; - for (const char* s = clipboard; *s; ) + for (const char* s = clipboard; *s != 0; ) { unsigned int c; s += ImTextCharFromUtf8(&c, s, NULL); - if (c == 0) - break; if (!InputTextFilterCharacter(&c, flags, callback, callback_user_data, ImGuiInputSource_Clipboard)) continue; clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; @@ -4372,19 +4571,29 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } // Process callbacks and apply result back to user's buffer. + const char* apply_new_text = NULL; + int apply_new_text_length = 0; if (g.ActiveId == id) { IM_ASSERT(state != NULL); - const char* apply_new_text = NULL; - int apply_new_text_length = 0; - if (cancel_edit) + if (revert_edit && !is_readonly) { - // Restore initial value. Only return true if restoring to the initial value changes the current buffer contents. - if (!is_readonly && strcmp(buf, state->InitialTextA.Data) != 0) + if (flags & ImGuiInputTextFlags_EscapeClearsAll) { + // Clear input + apply_new_text = ""; + apply_new_text_length = 0; + value_changed |= (buf[0] != 0); + STB_TEXTEDIT_CHARTYPE empty_string; + stb_textedit_replace(state, &state->Stb, &empty_string, 0); + } + else if (strcmp(buf, state->InitialTextA.Data) != 0) + { + // Restore initial value. Only return true if restoring to the initial value changes the current buffer contents. // Push records into the undo stack so we can CTRL+Z the revert operation itself apply_new_text = state->InitialTextA.Data; apply_new_text_length = state->InitialTextA.Size - 1; + value_changed = true; ImVector w_text; if (apply_new_text_length > 0) { @@ -4395,22 +4604,24 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } } + // Apply ASCII value + if (!is_readonly) + { + state->TextAIsValid = true; + state->TextA.resize(state->TextW.Size * 4 + 1); + ImTextStrToUtf8(state->TextA.Data, state->TextA.Size, state->TextW.Data, NULL); + } + // When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame. // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. // This also allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage (please note that if you use this property along ImGuiInputTextFlags_CallbackResize you can end up with your temporary string object unnecessarily allocating once a frame, either store your string data, either if you don't then don't use ImGuiInputTextFlags_CallbackResize). - bool apply_edit_back_to_user_buffer = !cancel_edit || (enter_pressed && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); + const bool apply_edit_back_to_user_buffer = !revert_edit || (validated && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); if (apply_edit_back_to_user_buffer) { // Apply new value immediately - copy modified buffer back // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer // FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect. // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks. - if (!is_readonly) - { - state->TextAIsValid = true; - state->TextA.resize(state->TextW.Size * 4 + 1); - ImTextStrToUtf8(state->TextA.Data, state->TextA.Size, state->TextW.Data, NULL); - } // User callback if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_CallbackAlways)) != 0) @@ -4419,18 +4630,18 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. ImGuiInputTextFlags event_flag = 0; - ImGuiKey event_key = ImGuiKey_COUNT; - if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab)) + ImGuiKey event_key = ImGuiKey_None; + if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && Shortcut(ImGuiKey_Tab, id)) { event_flag = ImGuiInputTextFlags_CallbackCompletion; event_key = ImGuiKey_Tab; } - else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow)) + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressed(ImGuiKey_UpArrow)) { event_flag = ImGuiInputTextFlags_CallbackHistory; event_key = ImGuiKey_UpArrow; } - else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow)) + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressed(ImGuiKey_DownArrow)) { event_flag = ImGuiInputTextFlags_CallbackHistory; event_key = ImGuiKey_DownArrow; @@ -4447,13 +4658,14 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (event_flag) { ImGuiInputTextCallbackData callback_data; - memset(&callback_data, 0, sizeof(ImGuiInputTextCallbackData)); + callback_data.Ctx = &g; callback_data.EventFlag = event_flag; callback_data.Flags = flags; callback_data.UserData = callback_user_data; + char* callback_buf = is_readonly ? buf : state->TextA.Data; callback_data.EventKey = event_key; - callback_data.Buf = state->TextA.Data; + callback_data.Buf = callback_buf; callback_data.BufTextLen = state->CurLenA; callback_data.BufSize = state->BufCapacityA; callback_data.BufDirty = false; @@ -4468,7 +4680,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ callback(&callback_data); // Read back what user may have modified - IM_ASSERT(callback_data.Buf == state->TextA.Data); // Invalid to modify those fields + callback_buf = is_readonly ? buf : state->TextA.Data; // Pointer may have been invalidated by a resize callback + IM_ASSERT(callback_data.Buf == callback_buf); // Invalid to modify those fields IM_ASSERT(callback_data.BufSize == state->BufCapacityA); IM_ASSERT(callback_data.Flags == flags); const bool buf_dirty = callback_data.BufDirty; @@ -4477,9 +4690,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb.select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb.select_start : ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); } if (buf_dirty) { + IM_ASSERT((flags & ImGuiInputTextFlags_ReadOnly) == 0); IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! + InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ? if (callback_data.BufTextLen > backup_current_text_length && is_resizable) - state->TextW.resize(state->TextW.Size + (callback_data.BufTextLen - backup_current_text_length)); + state->TextW.resize(state->TextW.Size + (callback_data.BufTextLen - backup_current_text_length)); // Worse case scenario resize state->CurLenW = ImTextStrFromUtf8(state->TextW.Data, state->TextW.Size, callback_data.Buf, NULL); state->CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() state->CursorAnimReset(); @@ -4492,47 +4707,59 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { apply_new_text = state->TextA.Data; apply_new_text_length = state->CurLenA; + value_changed = true; } } + } - // Copy result to user buffer - if (apply_new_text) + // Handle reapplying final data on deactivation (see InputTextDeactivateHook() for details) + if (g.InputTextDeactivatedState.ID == id) + { + if (g.ActiveId != id && IsItemDeactivatedAfterEdit() && !is_readonly) { - // We cannot test for 'backup_current_text_length != apply_new_text_length' here because we have no guarantee that the size - // of our owned buffer matches the size of the string object held by the user, and by design we allow InputText() to be used - // without any storage on user's side. - IM_ASSERT(apply_new_text_length >= 0); - if (is_resizable) - { - ImGuiInputTextCallbackData callback_data; - callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize; - callback_data.Flags = flags; - callback_data.Buf = buf; - callback_data.BufTextLen = apply_new_text_length; - callback_data.BufSize = ImMax(buf_size, apply_new_text_length + 1); - callback_data.UserData = callback_user_data; - callback(&callback_data); - buf = callback_data.Buf; - buf_size = callback_data.BufSize; - apply_new_text_length = ImMin(callback_data.BufTextLen, buf_size - 1); - IM_ASSERT(apply_new_text_length <= buf_size); - } - //IMGUI_DEBUG_LOG("InputText(\"%s\"): apply_new_text length %d\n", label, apply_new_text_length); - - // If the underlying buffer resize was denied or not carried to the next frame, apply_new_text_length+1 may be >= buf_size. - ImStrncpy(buf, apply_new_text, ImMin(apply_new_text_length + 1, buf_size)); - value_changed = true; + apply_new_text = g.InputTextDeactivatedState.TextA.Data; + apply_new_text_length = g.InputTextDeactivatedState.TextA.Size - 1; + value_changed |= (strcmp(g.InputTextDeactivatedState.TextA.Data, buf) != 0); + //IMGUI_DEBUG_LOG("InputText(): apply Deactivated data for 0x%08X: \"%.*s\".\n", id, apply_new_text_length, apply_new_text); } + g.InputTextDeactivatedState.ID = 0; + } - // Clear temporary user storage - state->Flags = ImGuiInputTextFlags_None; - state->UserCallback = NULL; - state->UserCallbackData = NULL; + // Copy result to user buffer. This can currently only happen when (g.ActiveId == id) + if (apply_new_text != NULL) + { + // We cannot test for 'backup_current_text_length != apply_new_text_length' here because we have no guarantee that the size + // of our owned buffer matches the size of the string object held by the user, and by design we allow InputText() to be used + // without any storage on user's side. + IM_ASSERT(apply_new_text_length >= 0); + if (is_resizable) + { + ImGuiInputTextCallbackData callback_data; + callback_data.Ctx = &g; + callback_data.EventFlag = ImGuiInputTextFlags_CallbackResize; + callback_data.Flags = flags; + callback_data.Buf = buf; + callback_data.BufTextLen = apply_new_text_length; + callback_data.BufSize = ImMax(buf_size, apply_new_text_length + 1); + callback_data.UserData = callback_user_data; + callback(&callback_data); + buf = callback_data.Buf; + buf_size = callback_data.BufSize; + apply_new_text_length = ImMin(callback_data.BufTextLen, buf_size - 1); + IM_ASSERT(apply_new_text_length <= buf_size); + } + //IMGUI_DEBUG_PRINT("InputText(\"%s\"): apply_new_text length %d\n", label, apply_new_text_length); + + // If the underlying buffer resize was denied or not carried to the next frame, apply_new_text_length+1 may be >= buf_size. + ImStrncpy(buf, apply_new_text, ImMin(apply_new_text_length + 1, buf_size)); } // Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value) - if (clear_active_id && g.ActiveId == id) + // Otherwise request text input ahead for next frame. + if (g.ActiveId == id && clear_active_id) ClearActiveID(); + else if (g.ActiveId == id) + g.WantTextInputNextFrame = 1; // Render frame if (!is_multiline) @@ -4612,11 +4839,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ searches_result_line_no[1] = line_count; // Calculate 2d position by finding the beginning of the line and measuring distance - cursor_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x; + cursor_offset.x = InputTextCalcTextSizeW(&g, ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x; cursor_offset.y = searches_result_line_no[0] * g.FontSize; if (searches_result_line_no[1] >= 0) { - select_start_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x; + select_start_offset.x = InputTextCalcTextSizeW(&g, ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x; select_start_offset.y = searches_result_line_no[1] * g.FontSize; } @@ -4649,7 +4876,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Test if cursor is vertically visible if (cursor_offset.y - g.FontSize < scroll_y) scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); - else if (cursor_offset.y - inner_size.y >= scroll_y) + else if (cursor_offset.y - (inner_size.y - style.FramePadding.y * 2.0f) >= scroll_y) scroll_y = cursor_offset.y - inner_size.y + style.FramePadding.y * 2.0f; const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f); scroll_y = ImClamp(scroll_y, 0.0f, scroll_max_y); @@ -4685,7 +4912,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ } else { - ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true); + ImVec2 rect_size = InputTextCalcTextSizeW(&g, p, text_selected_end, &p, NULL, true); if (rect_size.x <= 0.0f) rect_size.x = IM_FLOOR(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn)); rect.ClipWith(clip_rect); @@ -4716,7 +4943,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) if (!is_readonly) - g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_screen_pos.y - g.FontSize); + { + g.PlatformImeData.WantVisible = true; + g.PlatformImeData.InputPos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_screen_pos.y - g.FontSize); + g.PlatformImeData.InputLineHeight = g.FontSize; + } } } else @@ -4741,9 +4972,21 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (is_multiline) { + // For focus requests to work on our multiline we need to ensure our child ItemAdd() call specifies the ImGuiItemFlags_Inputable (ref issue #4761)... Dummy(ImVec2(text_size.x, text_size.y + style.FramePadding.y)); + g.NextItemData.ItemFlags |= ImGuiItemFlags_Inputable | ImGuiItemFlags_NoTabStop; EndChild(); + item_data_backup.StatusFlags |= (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredWindow); + + // ...and then we need to undo the group overriding last item data, which gets a bit messy as EndGroup() tries to forward scrollbar being active... + // FIXME: This quite messy/tricky, should attempt to get rid of the child window. EndGroup(); + if (g.LastItemData.ID == 0) + { + g.LastItemData.ID = id; + g.LastItemData.InFlags = item_data_backup.InFlags; + g.LastItemData.StatusFlags = item_data_backup.StatusFlags; + } } // Log as text @@ -4759,13 +5002,49 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (value_changed && !(flags & ImGuiInputTextFlags_NoMarkEdited)) MarkItemEdited(id); - IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); + IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable); if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0) - return enter_pressed; + return validated; else return value_changed; } +void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state) +{ +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + ImGuiContext& g = *GImGui; + ImStb::STB_TexteditState* stb_state = &state->Stb; + ImStb::StbUndoState* undo_state = &stb_state->undostate; + Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId); + DebugLocateItemOnHover(state->ID); + Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenW, state->CurLenA, stb_state->cursor, stb_state->select_start, stb_state->select_end); + Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x); + Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point); + if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state + { + PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + for (int n = 0; n < STB_TEXTEDIT_UNDOSTATECOUNT; n++) + { + ImStb::StbUndoRecord* undo_rec = &undo_state->undo_rec[n]; + const char undo_rec_type = (n < undo_state->undo_point) ? 'u' : (n >= undo_state->redo_point) ? 'r' : ' '; + if (undo_rec_type == ' ') + BeginDisabled(); + char buf[64] = ""; + if (undo_rec_type != ' ' && undo_rec->char_storage != -1) + ImTextStrToUtf8(buf, IM_ARRAYSIZE(buf), undo_state->undo_char + undo_rec->char_storage, undo_state->undo_char + undo_rec->char_storage + undo_rec->insert_length); + Text("%c [%02d] where %03d, insert %03d, delete %03d, char_storage %03d \"%s\"", + undo_rec_type, n, undo_rec->where, undo_rec->insert_length, undo_rec->delete_length, undo_rec->char_storage, buf); + if (undo_rec_type == ' ') + EndDisabled(); + } + PopStyleVar(); + } + EndChild(); +#else + IM_UNUSED(state); +#endif +} + //------------------------------------------------------------------------- // [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc. //------------------------------------------------------------------------- @@ -4786,28 +5065,32 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } +static void ColorEditRestoreH(const float* col, float* H) +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.ColorEditCurrentID != 0); + if (g.ColorEditSavedID != g.ColorEditCurrentID || g.ColorEditSavedColor != ImGui::ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0))) + return; + *H = g.ColorEditSavedHue; +} + // ColorEdit supports RGB and HSV inputs. In case of RGB input resulting color may have undefined hue and/or saturation. // Since widget displays both RGB and HSV values we must preserve hue and saturation to prevent these values resetting. static void ColorEditRestoreHS(const float* col, float* H, float* S, float* V) { - // This check is optional. Suppose we have two color widgets side by side, both widgets display different colors, but both colors have hue and/or saturation undefined. - // With color check: hue/saturation is preserved in one widget. Editing color in one widget would reset hue/saturation in another one. - // Without color check: common hue/saturation would be displayed in all widgets that have hue/saturation undefined. - // g.ColorEditLastColor is stored as ImU32 RGB value: this essentially gives us color equality check with reduced precision. - // Tiny external color changes would not be detected and this check would still pass. This is OK, since we only restore hue/saturation _only_ if they are undefined, - // therefore this change flipping hue/saturation from undefined to a very tiny value would still be represented in color picker. ImGuiContext& g = *GImGui; - if (g.ColorEditLastColor != ImGui::ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0))) + IM_ASSERT(g.ColorEditCurrentID != 0); + if (g.ColorEditSavedID != g.ColorEditCurrentID || g.ColorEditSavedColor != ImGui::ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0))) return; // When S == 0, H is undefined. // When H == 1 it wraps around to 0. - if (*S == 0.0f || (*H == 0.0f && g.ColorEditLastHue == 1)) - *H = g.ColorEditLastHue; + if (*S == 0.0f || (*H == 0.0f && g.ColorEditSavedHue == 1)) + *H = g.ColorEditSavedHue; // When V == 0, S is undefined. if (*V == 0.0f) - *S = g.ColorEditLastSat; + *S = g.ColorEditSavedSat; } // Edit colors components (each component in 0.0f..1.0f range). @@ -4830,6 +5113,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag BeginGroup(); PushID(label); + const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0); + if (set_current_color_edit_id) + g.ColorEditCurrentID = window->IDStack.back(); // If we're not showing any slider there's no point in doing any HSV conversions const ImGuiColorEditFlags flags_untouched = flags; @@ -4863,7 +5149,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); else if ((flags & ImGuiColorEditFlags_InputRGB) && (flags & ImGuiColorEditFlags_DisplayHSV)) { - // Hue is lost when converting from greyscale rgb (saturation=0). Restore it. + // Hue is lost when converting from grayscale rgb (saturation=0). Restore it. ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); ColorEditRestoreHS(col, &f[0], &f[1], &f[2]); } @@ -4915,7 +5201,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); } if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); } } else if ((flags & ImGuiColorEditFlags_DisplayHex) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) @@ -4943,7 +5229,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag IM_UNUSED(r); // Fixes C6031: Return value ignored: 'sscanf'. } if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); } ImGuiWindow* picker_active_window = NULL; @@ -4960,32 +5246,37 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag // Store current color and open a picker g.ColorPickerRef = col_v4; OpenPopup("picker"); - SetNextWindowPos(g.LastItemData.Rect.GetBL() + ImVec2(-1, style.ItemSpacing.y)); + SetNextWindowPos(g.LastItemData.Rect.GetBL() + ImVec2(0.0f, style.ItemSpacing.y)); } } if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); if (BeginPopup("picker")) { - picker_active_window = g.CurrentWindow; - if (label != label_display_end) + if (g.CurrentWindow->BeginCount == 1) { - TextEx(label, label_display_end); - Spacing(); + picker_active_window = g.CurrentWindow; + if (label != label_display_end) + { + TextEx(label, label_display_end); + Spacing(); + } + ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar; + ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags_DisplayMask_ | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; + SetNextItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? + value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); } - ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar; - ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags_DisplayMask_ | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; - SetNextItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? - value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); EndPopup(); } } if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) { - const float text_offset_x = (flags & ImGuiColorEditFlags_NoInputs) ? w_button : w_full + style.ItemInnerSpacing.x; - window->DC.CursorPos = ImVec2(pos.x + text_offset_x, pos.y + style.FramePadding.y); + // Position not necessarily next to last submitted button (e.g. if style.ColorButtonPosition == ImGuiDir_Left), + // but we need to use SameLine() to setup baseline correctly. Might want to refactor SameLine() to simplify this. + SameLine(0.0f, style.ItemInnerSpacing.x); + window->DC.CursorPos.x = pos.x + ((flags & ImGuiColorEditFlags_NoInputs) ? w_button : w_full + style.ItemInnerSpacing.x); TextEx(label, label_display_end); } @@ -4997,10 +5288,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag f[n] = i[n] / 255.0f; if ((flags & ImGuiColorEditFlags_DisplayHSV) && (flags & ImGuiColorEditFlags_InputRGB)) { - g.ColorEditLastHue = f[0]; - g.ColorEditLastSat = f[1]; + g.ColorEditSavedHue = f[0]; + g.ColorEditSavedSat = f[1]; ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); - g.ColorEditLastColor = ColorConvertFloat4ToU32(ImVec4(f[0], f[1], f[2], 0)); + g.ColorEditSavedID = g.ColorEditCurrentID; + g.ColorEditSavedColor = ColorConvertFloat4ToU32(ImVec4(f[0], f[1], f[2], 0)); } if ((flags & ImGuiColorEditFlags_DisplayRGB) && (flags & ImGuiColorEditFlags_InputHSV)) ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); @@ -5012,6 +5304,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag col[3] = f[3]; } + if (set_current_color_edit_id) + g.ColorEditCurrentID = 0; PopID(); EndGroup(); @@ -5022,7 +5316,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag bool accepted_drag_drop = false; if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) { - memcpy((float*)col, payload->Data, sizeof(float) * 3); // Preserve alpha if any //-V512 + memcpy((float*)col, payload->Data, sizeof(float) * 3); // Preserve alpha if any //-V512 //-V1086 value_changed = accepted_drag_drop = true; } if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) @@ -5041,7 +5335,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag if (picker_active_window && g.ActiveId != 0 && g.ActiveIdWindow == picker_active_window) g.LastItemData.ID = g.ActiveId; - if (value_changed) + if (value_changed && g.LastItemData.ID != 0) // In case of ID collision, the second EndGroup() won't catch g.ActiveId MarkItemEdited(g.LastItemData.ID); return value_changed; @@ -5085,6 +5379,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl g.NextItemData.ClearFlags(); PushID(label); + const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0); + if (set_current_color_edit_id) + g.ColorEditCurrentID = window->IDStack.back(); BeginGroup(); if (!(flags & ImGuiColorEditFlags_NoSidePreview)) @@ -5133,7 +5430,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float R = col[0], G = col[1], B = col[2]; if (flags & ImGuiColorEditFlags_InputRGB) { - // Hue is lost when converting from greyscale rgb (saturation=0). Restore it. + // Hue is lost when converting from grayscale rgb (saturation=0). Restore it. ColorConvertRGBtoHSV(R, G, B, H, S, V); ColorEditRestoreHS(col, &H, &S, &V); } @@ -5178,7 +5475,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl } } if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); } else if (flags & ImGuiColorEditFlags_PickerHueBar) { @@ -5188,14 +5485,11 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl { S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1)); V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1)); - - // Greatly reduces hue jitter and reset to 0 when hue == 255 and color is rapidly modified using SV square. - if (g.ColorEditLastColor == ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0))) - H = g.ColorEditLastHue; + ColorEditRestoreH(col, &H); // Greatly reduces hue jitter and reset to 0 when hue == 255 and color is rapidly modified using SV square. value_changed = value_changed_sv = true; } if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); + OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight); // Hue bar logic SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); @@ -5266,9 +5560,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (flags & ImGuiColorEditFlags_InputRGB) { ColorConvertHSVtoRGB(H, S, V, col[0], col[1], col[2]); - g.ColorEditLastHue = H; - g.ColorEditLastSat = S; - g.ColorEditLastColor = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0)); + g.ColorEditSavedHue = H; + g.ColorEditSavedSat = S; + g.ColorEditSavedID = g.ColorEditCurrentID; + g.ColorEditSavedColor = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0)); } else if (flags & ImGuiColorEditFlags_InputHSV) { @@ -5370,7 +5665,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl float sin_hue_angle = ImSin(H * 2.0f * IM_PI); ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f); float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f; - int hue_cursor_segments = ImClamp((int)(hue_cursor_rad / 1.4f), 9, 32); + int hue_cursor_segments = draw_list->_CalcCircleAutoSegmentCount(hue_cursor_rad); // Lock segment count so the +1 one matches others. draw_list->AddCircleFilled(hue_cursor_pos, hue_cursor_rad, hue_color32, hue_cursor_segments); draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad + 1, col_midgrey, hue_cursor_segments); draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad, col_white, hue_cursor_segments); @@ -5380,13 +5675,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle); ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle); ImVec2 uv_white = GetFontTexUvWhitePixel(); - draw_list->PrimReserve(6, 6); + draw_list->PrimReserve(3, 3); draw_list->PrimVtx(tra, uv_white, hue_color32); - draw_list->PrimVtx(trb, uv_white, hue_color32); - draw_list->PrimVtx(trc, uv_white, col_white); - draw_list->PrimVtx(tra, uv_white, 0); draw_list->PrimVtx(trb, uv_white, col_black); - draw_list->PrimVtx(trc, uv_white, 0); + draw_list->PrimVtx(trc, uv_white, col_white); draw_list->AddTriangle(tra, trb, trc, col_midgrey, 1.5f); sv_cursor_pos = ImLerp(ImLerp(trc, tra, ImSaturate(S)), trb, ImSaturate(1 - V)); } @@ -5409,9 +5701,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f; - draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, user_col32_striped_of_alpha, 12); - draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad + 1, col_midgrey, 12); - draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad, col_white, 12); + int sv_cursor_segments = draw_list->_CalcCircleAutoSegmentCount(sv_cursor_rad); // Lock segment count so the +1 one matches others. + draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, user_col32_striped_of_alpha, sv_cursor_segments); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad + 1, col_midgrey, sv_cursor_segments); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad, col_white, sv_cursor_segments); // Render alpha bar if (alpha_bar) @@ -5429,9 +5722,11 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (value_changed && memcmp(backup_initial_col, col, components * sizeof(float)) == 0) value_changed = false; - if (value_changed) + if (value_changed && g.LastItemData.ID != 0) // In case of ID collision, the second EndGroup() won't catch g.ActiveId MarkItemEdited(g.LastItemData.ID); + if (set_current_color_edit_id) + g.ColorEditCurrentID = 0; PopID(); return value_changed; @@ -5441,7 +5736,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // FIXME: May want to display/ignore the alpha component in the color display? Yet show it in the tooltip. // 'desc_id' is not called 'label' because we don't display it next to the button, but only in the tooltip. // Note that 'col' may be encoded in HSV if ImGuiColorEditFlags_InputHSV is set. -bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, ImVec2 size) +bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, const ImVec2& size_arg) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -5449,11 +5744,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl ImGuiContext& g = *GImGui; const ImGuiID id = window->GetID(desc_id); - float default_size = GetFrameHeight(); - if (size.x == 0.0f) - size.x = default_size; - if (size.y == 0.0f) - size.y = default_size; + const float default_size = GetFrameHeight(); + const ImVec2 size(size_arg.x == 0.0f ? default_size : size_arg.x, size_arg.y == 0.0f ? default_size : size_arg.y); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); ItemSize(bb, (size.y >= default_size) ? g.Style.FramePadding.y : 0.0f); if (!ItemAdd(bb, id)) @@ -5518,7 +5810,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl } // Tooltip - if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) + if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered && IsItemHovered(ImGuiHoveredFlags_ForTooltip)) ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); return pressed; @@ -5548,7 +5840,8 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags { ImGuiContext& g = *GImGui; - BeginTooltipEx(0, ImGuiTooltipFlags_OverridePreviousTooltip); + if (!BeginTooltipEx(ImGuiTooltipFlags_OverridePrevious, ImGuiWindowFlags_None)) + return; const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; if (text_end > text) { @@ -5751,9 +6044,9 @@ bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char if (window->SkipItems) return false; - ImGuiContext& g = *GImGui; - const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end); + const char* label, *label_end; + ImFormatStringToTempBufferV(&label, &label_end, fmt, args); + return TreeNodeBehavior(window->GetID(str_id), flags, label, label_end); } bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) @@ -5762,12 +6055,19 @@ bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char if (window->SkipItems) return false; - ImGuiContext& g = *GImGui; - const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end); + const char* label, *label_end; + ImFormatStringToTempBufferV(&label, &label_end, fmt, args); + return TreeNodeBehavior(window->GetID(ptr_id), flags, label, label_end); } -bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) +void ImGui::TreeNodeSetOpen(ImGuiID id, bool open) +{ + ImGuiContext& g = *GImGui; + ImGuiStorage* storage = g.CurrentWindow->DC.StateStorage; + storage->SetInt(id, open ? 1 : 0); +} + +bool ImGui::TreeNodeUpdateNextOpen(ImGuiID id, ImGuiTreeNodeFlags flags) { if (flags & ImGuiTreeNodeFlags_Leaf) return true; @@ -5783,7 +6083,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) if (g.NextItemData.OpenCond & ImGuiCond_Always) { is_open = g.NextItemData.OpenVal; - storage->SetInt(id, is_open); + TreeNodeSetOpen(id, is_open); } else { @@ -5792,7 +6092,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) if (stored_value == -1) { is_open = g.NextItemData.OpenVal; - storage->SetInt(id, is_open); + TreeNodeSetOpen(id, is_open); } else { @@ -5858,7 +6158,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop(). // This is currently only support 32 level deep and we are fine with (1 << Depth) overflowing into a zero. const bool is_leaf = (flags & ImGuiTreeNodeFlags_Leaf) != 0; - bool is_open = TreeNodeBehaviorIsOpen(id, flags); + bool is_open = TreeNodeUpdateNextOpen(id, flags); if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavLeftJumpsBackHere) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) window->DC.TreeJumpToParentOnPopMask |= (1 << window->DC.TreeDepth); @@ -5875,8 +6175,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l } ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None; - if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) - button_flags |= ImGuiButtonFlags_AllowItemOverlap; + if ((flags & ImGuiTreeNodeFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap)) + button_flags |= ImGuiButtonFlags_AllowOverlap; if (!is_leaf) button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; @@ -5919,7 +6219,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l toggled = true; if (flags & ImGuiTreeNodeFlags_OpenOnArrow) toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job - if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0]) + if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseClickedCount[0] == 2) toggled = true; } else if (pressed && g.DragDropHoldJustPressedId == id) @@ -5932,11 +6232,13 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if (g.NavId == id && g.NavMoveDir == ImGuiDir_Left && is_open) { toggled = true; + NavClearPreferredPosForAxis(ImGuiAxis_X); NavMoveRequestCancel(); } if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? { toggled = true; + NavClearPreferredPosForAxis(ImGuiAxis_X); NavMoveRequestCancel(); } @@ -5947,8 +6249,6 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledOpen; } } - if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) - SetItemAllowOverlap(); // In this branch, TreeNodeBehavior() cannot toggle the selection so this will never trigger. if (selected != was_selected) //-V547 @@ -5966,9 +6266,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if (flags & ImGuiTreeNodeFlags_Bullet) RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.60f, text_pos.y + g.FontSize * 0.5f), text_col); else if (!is_leaf) - RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); + RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 1.0f); else // Leaf without bullet, left-adjusted text - text_pos.x -= text_offset_x; + text_pos.x -= text_offset_x -padding.x; if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton) frame_bb.Max.x -= g.FontSize + style.FramePadding.x; @@ -5988,7 +6288,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if (flags & ImGuiTreeNodeFlags_Bullet) RenderBullet(window->DrawList, ImVec2(text_pos.x - text_offset_x * 0.5f, text_pos.y + g.FontSize * 0.5f), text_col); else if (!is_leaf) - RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); + RenderArrow(window->DrawList, ImVec2(text_pos.x - text_offset_x + padding.x, text_pos.y + g.FontSize * 0.15f), text_col, is_open ? ((flags & ImGuiTreeNodeFlags_UpsideDownArrow) ? ImGuiDir_Up : ImGuiDir_Down) : ImGuiDir_Right, 0.70f); if (g.LogEnabled) LogSetNextTextDecoration(">", NULL); RenderText(text_pos, label, label_end, false); @@ -6092,7 +6392,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl ImGuiID id = window->GetID(label); flags |= ImGuiTreeNodeFlags_CollapsingHeader; if (p_visible) - flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton; + flags |= ImGuiTreeNodeFlags_AllowOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton; bool is_open = TreeNodeBehavior(id, flags, label); if (p_visible != NULL) { @@ -6121,7 +6421,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFl // Tip: pass a non-visible label (e.g. "##hello") then you can use the space to draw other text or image. // But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID or use ##unique_id. -// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowItemOverlap are also frequently used flags. +// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowOverlap are also frequently used flags. // FIXME: Selectable() with (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported. bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) { @@ -6201,10 +6501,11 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl // We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries ImGuiButtonFlags button_flags = 0; if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; } + if (flags & ImGuiSelectableFlags_NoSetKeyOwner) { button_flags |= ImGuiButtonFlags_NoSetKeyOwner; } if (flags & ImGuiSelectableFlags_SelectOnClick) { button_flags |= ImGuiButtonFlags_PressedOnClick; } if (flags & ImGuiSelectableFlags_SelectOnRelease) { button_flags |= ImGuiButtonFlags_PressedOnRelease; } if (flags & ImGuiSelectableFlags_AllowDoubleClick) { button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; } - if (flags & ImGuiSelectableFlags_AllowItemOverlap) { button_flags |= ImGuiButtonFlags_AllowItemOverlap; } + if ((flags & ImGuiSelectableFlags_AllowOverlap) || (g.LastItemData.InFlags & ImGuiItemflags_AllowOverlap)) { button_flags |= ImGuiButtonFlags_AllowOverlap; } const bool was_selected = selected; bool hovered, held; @@ -6217,7 +6518,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl // - (1) it would require focus scope to be set, need exposing PushFocusScope() or equivalent (e.g. BeginSelection() calling PushFocusScope()) // - (2) usage will fail with clipped items // The multi-select API aim to fix those issues, e.g. may be replaced with a BeginSelection() API. - if ((flags & ImGuiSelectableFlags_SelectOnNav) && g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == window->DC.NavFocusScopeIdCurrent) + if ((flags & ImGuiSelectableFlags_SelectOnNav) && g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == g.CurrentFocusScopeId) if (g.NavJustMovedToId == id) selected = pressed = true; @@ -6226,23 +6527,18 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl { if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent) { - SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, ImRect(bb.Min - window->Pos, bb.Max - window->Pos)); // (bb == NavRect) + SetNavID(id, window->DC.NavLayerCurrent, g.CurrentFocusScopeId, WindowRectAbsToRel(window, bb)); // (bb == NavRect) g.NavDisableHighlight = true; } } if (pressed) MarkItemEdited(id); - if (flags & ImGuiSelectableFlags_AllowItemOverlap) - SetItemAllowOverlap(); - // In this branch, Selectable() cannot toggle the selection so this will never trigger. if (selected != was_selected) //-V547 g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection; // Render - if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld)) - hovered = true; if (hovered || selected) { const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); @@ -6327,20 +6623,6 @@ bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg) return true; } -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -// OBSOLETED in 1.81 (from February 2021) -bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items) -{ - // If height_in_items == -1, default height is maximum 7. - ImGuiContext& g = *GImGui; - float height_in_items_f = (height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f; - ImVec2 size; - size.x = 0.0f; - size.y = GetTextLineHeightWithSpacing() * height_in_items_f + g.Style.FramePadding.y * 2.0f; - return BeginListBox(label, size); -} -#endif - void ImGui::EndListBox() { ImGuiContext& g = *GImGui; @@ -6417,7 +6699,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v // - others https://github.com/ocornut/imgui/wiki/Useful-Extensions //------------------------------------------------------------------------- -int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size) +int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, const ImVec2& size_arg) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -6428,10 +6710,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get const ImGuiID id = window->GetID(label); const ImVec2 label_size = CalcTextSize(label, NULL, true); - if (frame_size.x == 0.0f) - frame_size.x = CalcItemWidth(); - if (frame_size.y == 0.0f) - frame_size.y = label_size.y + (style.FramePadding.y * 2); + const ImVec2 frame_size = CalcItemSize(size_arg, CalcItemWidth(), label_size.y + style.FramePadding.y * 2.0f); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); @@ -6439,7 +6718,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get ItemSize(total_bb, style.FramePadding.y); if (!ItemAdd(total_bb, 0, &frame_bb)) return -1; - const bool hovered = ItemHoverable(frame_bb, id); + const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags); // Determine scale from values if not specified if (scale_min == FLT_MAX || scale_max == FLT_MAX) @@ -6691,6 +6970,7 @@ bool ImGui::BeginMenuBar() // We overwrite CursorMaxPos because BeginGroup sets it to CursorPos (essentially the .EmitItem hack in EndMenuBar() would need something analogous here, maybe a BeginGroupEx() with flags). window->DC.CursorPos = window->DC.CursorMaxPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y); window->DC.LayoutType = ImGuiLayoutType_Horizontal; + window->DC.IsSameLine = false; window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; window->DC.MenuBarAppending = true; AlignTextToFramePadding(); @@ -6716,7 +6996,7 @@ void ImGui::EndMenuBar() // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering) const ImGuiNavLayer layer = ImGuiNavLayer_Menu; - IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check + IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check (FIXME: Seems unnecessary) FocusWindow(window); SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]); g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. @@ -6734,6 +7014,7 @@ void ImGui::EndMenuBar() g.GroupStack.back().EmitItem = false; EndGroup(); // Restore position on layer 0 window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.IsSameLine = false; window->DC.NavLayerCurrent = ImGuiNavLayer_Main; window->DC.MenuBarAppending = false; } @@ -6805,11 +7086,35 @@ void ImGui::EndMainMenuBar() // FIXME: With this strategy we won't be able to restore a NULL focus. ImGuiContext& g = *GImGui; if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest) - FocusTopMostWindowUnderOne(g.NavWindow, NULL); + FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild); End(); } +static bool IsRootOfOpenMenuSet() +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if ((g.OpenPopupStack.Size <= g.BeginPopupStack.Size) || (window->Flags & ImGuiWindowFlags_ChildMenu)) + return false; + + // Initially we used 'upper_popup->OpenParentId == window->IDStack.back()' to differentiate multiple menu sets from each others + // (e.g. inside menu bar vs loose menu items) based on parent ID. + // This would however prevent the use of e.g. PushID() user code submitting menus. + // Previously this worked between popup and a first child menu because the first child menu always had the _ChildWindow flag, + // making hovering on parent popup possible while first child menu was focused - but this was generally a bug with other side effects. + // Instead we don't treat Popup specifically (in order to consistently support menu features in them), maybe the first child menu of a Popup + // doesn't have the _ChildWindow flag, and we rely on this IsRootOfOpenMenuSet() check to allow hovering between root window/popup and first child menu. + // In the end, lack of ID check made it so we could no longer differentiate between separate menu sets. To compensate for that, we at least check parent window nav layer. + // This fixes the most common case of menu opening on hover when moving between window content and menu bar. Multiple different menu sets in same nav layer would still + // open on hover, but that should be a lesser problem, because if such menus are close in proximity in window content then it won't feel weird and if they are far apart + // it likely won't be a problem anyone runs into. + const ImGuiPopupData* upper_popup = &g.OpenPopupStack[g.BeginPopupStack.Size]; + if (window->DC.NavLayerCurrent != upper_popup->ParentNavLayer) + return false; + return upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu) && ImGui::IsWindowChildOf(upper_popup->Window, window, true); +} + bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) { ImGuiWindow* window = GetCurrentWindow(); @@ -6822,9 +7127,10 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None); // Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu) - ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus; - if (window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) - flags |= ImGuiWindowFlags_ChildWindow; + // The first menu in a hierarchy isn't so hovering doesn't get across (otherwise e.g. resizing borders with ImGuiButtonFlags_FlattenChildren would react), but top-most BeginMenu() will bypass that limitation. + ImGuiWindowFlags window_flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus; + if (window->Flags & ImGuiWindowFlags_ChildMenu) + window_flags |= ImGuiWindowFlags_ChildWindow; // If a menu with same the ID was already submitted, we will append to it, matching the behavior of Begin(). // We are relying on a O(N) search - so O(N log N) over the frame - which seems like the most efficient for the expected small amount of BeginMenu() calls per frame. @@ -6832,7 +7138,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) if (g.MenusIdSubmittedThisFrame.contains(id)) { if (menu_is_open) - menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) else g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values return menu_is_open; @@ -6842,11 +7148,12 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) g.MenusIdSubmittedThisFrame.push_back(id); ImVec2 label_size = CalcTextSize(label, NULL, true); - bool pressed; - bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].OpenParentId == window->IDStack.back()); - ImGuiWindow* backed_nav_window = g.NavWindow; + + // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent without always being a Child window) + // This is only done for items for the menu set and not the full parent window. + const bool menuset_is_open = IsRootOfOpenMenuSet(); if (menuset_is_open) - g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) + PushItemFlag(ImGuiItemFlags_NoWindowHoverableCheck, true); // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu, // However the final position is going to be different! It is chosen by FindBestWindowPosForPopup(). @@ -6856,6 +7163,10 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) if (!enabled) BeginDisabled(); const ImGuiMenuColumns* offsets = &window->DC.MenuColumns; + bool pressed; + + // We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another. + const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { // Menu inside an horizontal menu bar @@ -6866,7 +7177,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); float w = label_size.x; ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); - pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups, ImVec2(w, 0.0f)); + pressed = Selectable("", menu_is_open, selectable_flags, ImVec2(w, label_size.y)); RenderText(text_pos, label); PopStyleVar(); window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). @@ -6882,7 +7193,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); - pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); + pressed = Selectable("", menu_is_open, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y)); RenderText(text_pos, label); if (icon_w > 0.0f) RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon); @@ -6891,9 +7202,9 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) if (!enabled) EndDisabled(); - const bool hovered = (g.HoveredId == id) && enabled; + const bool hovered = (g.HoveredId == id) && enabled && !g.NavDisableMouseHover; if (menuset_is_open) - g.NavWindow = backed_nav_window; + PopItemFlag(); bool want_open = false; bool want_close = false; @@ -6901,29 +7212,37 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) { // Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. - bool moving_toward_other_child_menu = false; - ImGuiWindow* child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? g.OpenPopupStack[g.BeginPopupStack.Size].Window : NULL; - if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar)) + bool moving_toward_child_menu = false; + ImGuiPopupData* child_popup = (g.BeginPopupStack.Size < g.OpenPopupStack.Size) ? &g.OpenPopupStack[g.BeginPopupStack.Size] : NULL; // Popup candidate (testing below) + ImGuiWindow* child_menu_window = (child_popup && child_popup->Window && child_popup->Window->ParentWindow == window) ? child_popup->Window : NULL; + if (g.HoveredWindow == window && child_menu_window != NULL) { float ref_unit = g.FontSize; // FIXME-DPI + float child_dir = (window->Pos.x < child_menu_window->Pos.x) ? 1.0f : -1.0f; ImRect next_window_rect = child_menu_window->Rect(); ImVec2 ta = (g.IO.MousePos - g.IO.MouseDelta); - ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); - ImVec2 tc = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); + ImVec2 tb = (child_dir > 0.0f) ? next_window_rect.GetTL() : next_window_rect.GetTR(); + ImVec2 tc = (child_dir > 0.0f) ? next_window_rect.GetBL() : next_window_rect.GetBR(); float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, ref_unit * 0.5f, ref_unit * 2.5f); // add a bit of extra slack. - ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues (FIXME: ??) - tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -ref_unit * 8.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? + ta.x += child_dir * -0.5f; + tb.x += child_dir * ref_unit; + tc.x += child_dir * ref_unit; + tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -ref_unit * 8.0f); // triangle has maximum height to limit the slope and the bias toward large sub-menus tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +ref_unit * 8.0f); - moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); - //GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_toward_other_child_menu ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG] + moving_toward_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); + //GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_toward_child_menu ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG] } - if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu) + + // The 'HovereWindow == window' check creates an inconsistency (e.g. moving away from menu slowly tends to hit same window, whereas moving away fast does not) + // But we also need to not close the top-menu menu when moving over void. Perhaps we should extend the triangle check to a larger polygon. + // (Remember to test this on BeginPopup("A")->BeginMenu("B") sequence which behaves slightly differently as B isn't a Child of A and hovering isn't shared.) + if (menu_is_open && !hovered && g.HoveredWindow == window && !moving_toward_child_menu && !g.NavDisableMouseHover) want_close = true; // Open if (!menu_is_open && pressed) // Click/activate to open want_open = true; - else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open + else if (!menu_is_open && hovered && !moving_toward_child_menu) // Hover to open want_open = true; if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open { @@ -6958,21 +7277,32 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0)); PopID(); - if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size) + if (want_open && !menu_is_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size) { - // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame. + // Don't reopen/recycle same menu level in the same frame, first close the other menu and yield for a frame. OpenPopup(label); - return false; } - - menu_is_open |= want_open; - if (want_open) + else if (want_open) + { + menu_is_open = true; OpenPopup(label); + } if (menu_is_open) { - SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: this is super misleading! The value will serve as reference for FindBestWindowPosForPopup(), not actual pos. - menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + ImGuiLastItemData last_item_in_parent = g.LastItemData; + SetNextWindowPos(popup_pos, ImGuiCond_Always); // Note: misleading: the value will serve as reference for FindBestWindowPosForPopup(), not actual pos. + PushStyleVar(ImGuiStyleVar_ChildRounding, style.PopupRounding); // First level will use _PopupRounding, subsequent will use _ChildRounding + menu_is_open = BeginPopupEx(id, window_flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + PopStyleVar(); + if (menu_is_open) + { + // Restore LastItemData so IsItemXXXX functions can work after BeginMenu()/EndMenu() + // (This fixes using IsItemClicked() and IsItemHovered(), but IsItemHovered() also relies on its support for ImGuiItemFlags_NoWindowHoverableCheck) + g.LastItemData = last_item_in_parent; + if (g.HoveredWindow == window) + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow; + } } else { @@ -6989,17 +7319,18 @@ bool ImGui::BeginMenu(const char* label, bool enabled) void ImGui::EndMenu() { - // Nav: When a left move request _within our child menu_ failed, close ourselves (the _parent_ menu). - // A menu doesn't close itself because EndMenuBar() wants the catch the last Left<>Right inputs. - // However, it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction. + // Nav: When a left move request our menu failed, close ourselves. ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) - if (g.NavWindow && (g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow == window) - { - ClosePopupToLevel(g.BeginPopupStack.Size, true); - NavMoveRequestCancel(); - } + IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginMenu()/EndMenu() calls + ImGuiWindow* parent_window = window->ParentWindow; // Should always be != NULL is we passed assert. + if (window->BeginCount == window->BeginCountPreviousFrame) + if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet()) + if (g.NavWindow && (g.NavWindow->RootWindowForNav == window) && parent_window->DC.LayoutType == ImGuiLayoutType_Vertical) + { + ClosePopupToLevel(g.BeginPopupStack.Size - 1, true); + NavMoveRequestCancel(); + } EndPopup(); } @@ -7015,13 +7346,20 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut ImVec2 pos = window->DC.CursorPos; ImVec2 label_size = CalcTextSize(label, NULL, true); + // See BeginMenuEx() for comments about this. + const bool menuset_is_open = IsRootOfOpenMenuSet(); + if (menuset_is_open) + PushItemFlag(ImGuiItemFlags_NoWindowHoverableCheck, true); + // We've been using the equivalent of ImGuiSelectableFlags_SetNavIdOnHover on all Selectable() since early Nav system days (commit 43ee5d73), // but I am unsure whether this should be kept at all. For now moved it to be an opt-in feature used by menus only. bool pressed; PushID(label); if (!enabled) BeginDisabled(); - const ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover; + + // We use ImGuiSelectableFlags_NoSetKeyOwner to allow down on one menu item, move, up on another. + const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_NoSetKeyOwner | ImGuiSelectableFlags_SetNavIdOnHover; const ImGuiMenuColumns* offsets = &window->DC.MenuColumns; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { @@ -7031,9 +7369,10 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset); PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); - pressed = Selectable("", selected, flags, ImVec2(w, 0.0f)); + pressed = Selectable("", selected, selectable_flags, ImVec2(w, 0.0f)); PopStyleVar(); - RenderText(text_pos, label); + if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) + RenderText(text_pos, label); window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). } else @@ -7046,23 +7385,28 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut float checkmark_w = IM_FLOOR(g.FontSize * 1.20f); float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); - pressed = Selectable("", false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); - RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label); - if (icon_w > 0.0f) - RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon); - if (shortcut_w > 0.0f) + pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, label_size.y)); + if (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) { - PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); - RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false); - PopStyleColor(); + RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label); + if (icon_w > 0.0f) + RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon); + if (shortcut_w > 0.0f) + { + PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(offsets->OffsetShortcut + stretch_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f); } - if (selected) - RenderCheckMark(window->DrawList, pos + ImVec2(offsets->OffsetMark + stretch_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(ImGuiCol_Text), g.FontSize * 0.866f); } IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0)); if (!enabled) EndDisabled(); PopID(); + if (menuset_is_open) + PopItemFlag(); return pressed; } @@ -7093,11 +7437,17 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected, // - TabBarCalcTabID() [Internal] // - TabBarCalcMaxTabWidth() [Internal] // - TabBarFindTabById() [Internal] +// - TabBarFindTabByOrder() [Internal] +// - TabBarGetCurrentTab() [Internal] +// - TabBarGetTabName() [Internal] // - TabBarRemoveTab() [Internal] // - TabBarCloseTab() [Internal] // - TabBarScrollClamp() [Internal] // - TabBarScrollToTab() [Internal] -// - TabBarQueueChangeTabOrder() [Internal] +// - TabBarQueueFocus() [Internal] +// - TabBarQueueReorder() [Internal] +// - TabBarProcessReorderFromMousePos() [Internal] +// - TabBarProcessReorder() [Internal] // - TabBarScrollingButtons() [Internal] // - TabBarTabListPopupButton() [Internal] //------------------------------------------------------------------------- @@ -7114,7 +7464,7 @@ struct ImGuiTabBarSection namespace ImGui { static void TabBarLayout(ImGuiTabBar* tab_bar); - static ImU32 TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label); + static ImU32 TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window); static float TabBarCalcMaxTabWidth(); static float TabBarScrollClamp(ImGuiTabBar* tab_bar, float scrolling); static void TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiID tab_id, ImGuiTabBarSection* sections); @@ -7205,8 +7555,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG // Ensure correct ordering when toggling ImGuiTabBarFlags_Reorderable flag, or when a new tab was added while being not reorderable if ((flags & ImGuiTabBarFlags_Reorderable) != (tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (tab_bar->TabsAddedNew && !(flags & ImGuiTabBarFlags_Reorderable))) - if (tab_bar->Tabs.Size > 1) - ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerByBeginOrder); + ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerByBeginOrder); tab_bar->TabsAddedNew = false; // Flags @@ -7223,6 +7572,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG tab_bar->ItemSpacingY = g.Style.ItemSpacing.y; tab_bar->FramePadding = g.Style.FramePadding; tab_bar->TabsActiveCount = 0; + tab_bar->LastTabItemIdx = -1; tab_bar->BeginCount = 1; // Set cursor pos in a way which only be used in the off-chance the user erroneously submits item before BeginTabItem(): items will overlap @@ -7271,6 +7621,7 @@ void ImGui::EndTabBar() if (tab_bar->BeginCount > 1) window->DC.CursorPos = tab_bar->BackupCursorPos; + tab_bar->LastTabItemIdx = -1; if ((tab_bar->Flags & ImGuiTabBarFlags_DockNode) == 0) PopID(); @@ -7278,6 +7629,12 @@ void ImGui::EndTabBar() g.CurrentTabBar = g.CurrentTabBarStack.empty() ? NULL : GetTabBarFromTabBarRef(g.CurrentTabBarStack.back()); } +// Scrolling happens only in the central section (leading/trailing sections are not scrolling) +static float TabBarCalcScrollableWidth(ImGuiTabBar* tab_bar, ImGuiTabBarSection* sections) +{ + return tab_bar->BarRect.GetWidth() - sections[0].Width - sections[2].Width - sections[1].Spacing; +} + // This is called only once a frame before by the first call to ItemTab() // The reason we're not calling it in BeginTabBar() is to leave a chance to the user to call the SetTabItemClosed() functions. static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) @@ -7380,9 +7737,9 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) // Refresh tab width immediately, otherwise changes of style e.g. style.FramePadding.x would noticeably lag in the tab bar. // Additionally, when using TabBarAddTab() to manipulate tab bar order we occasionally insert new tabs that don't have a width yet, // and we cannot wait for the next BeginTabItem() call. We cannot compute this width within TabBarAddTab() because font size depends on the active window. - const char* tab_name = tab_bar->GetTabName(tab); - const bool has_close_button = (tab->Flags & ImGuiTabItemFlags_NoCloseButton) ? false : true; - tab->ContentWidth = TabItemCalcSize(tab_name, has_close_button).x; + const char* tab_name = TabBarGetTabName(tab_bar, tab); + const bool has_close_button_or_unsaved_marker = (tab->Flags & ImGuiTabItemFlags_NoCloseButton) == 0 || (tab->Flags & ImGuiTabItemFlags_UnsavedDocument); + tab->ContentWidth = (tab->RequestedWidth >= 0.0f) ? tab->RequestedWidth : TabItemCalcSize(tab_name, has_close_button_or_unsaved_marker).x; int section_n = TabItemGetSectionIdx(tab); ImGuiTabBarSection* section = §ions[section_n]; @@ -7391,12 +7748,10 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) // Store data so we can build an array sorted by width if we need to shrink tabs down IM_MSVC_WARNING_SUPPRESS(6385); - int shrink_buffer_index = shrink_buffer_indexes[section_n]++; - g.ShrinkWidthBuffer[shrink_buffer_index].Index = tab_n; - g.ShrinkWidthBuffer[shrink_buffer_index].Width = tab->ContentWidth; - - IM_ASSERT(tab->ContentWidth > 0.0f); - tab->Width = tab->ContentWidth; + ImGuiShrinkWidthItem* shrink_width_item = &g.ShrinkWidthBuffer[shrink_buffer_indexes[section_n]++]; + shrink_width_item->Index = tab_n; + shrink_width_item->Width = shrink_width_item->InitialWidth = tab->ContentWidth; + tab->Width = ImMax(tab->ContentWidth, 1.0f); } // Compute total ideal width (used for e.g. auto-resizing a window) @@ -7426,7 +7781,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) width_excess = (section_0_w + section_2_w) - tab_bar->BarRect.GetWidth(); // Excess used to shrink leading/trailing section // With ImGuiTabBarFlags_FittingPolicyScroll policy, we will only shrink leading/trailing if the central section is not visible anymore - if (width_excess > 0.0f && ((tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown) || !central_section_is_visible)) + if (width_excess >= 1.0f && ((tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown) || !central_section_is_visible)) { int shrink_data_count = (central_section_is_visible ? sections[1].TabCount : sections[0].TabCount + sections[2].TabCount); int shrink_data_offset = (central_section_is_visible ? sections[0].TabCount + sections[2].TabCount : 0); @@ -7440,6 +7795,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) if (shrinked_width < 0.0f) continue; + shrinked_width = ImMax(1.0f, shrinked_width); int section_n = TabItemGetSectionIdx(tab); sections[section_n].Width -= (tab->Width - shrinked_width); tab->Width = shrinked_width; @@ -7460,6 +7816,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) { ImGuiTabItem* tab = &tab_bar->Tabs[section_tab_index + tab_n]; tab->Offset = tab_offset; + tab->NameOffset = -1; tab_offset += tab->Width + (tab_n < section->TabCount - 1 ? g.Style.ItemInnerSpacing.x : 0.0f); } tab_bar->WidthAllTabs += ImMax(section->Width + section->Spacing, 0.0f); @@ -7467,6 +7824,9 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) section_tab_index += section->TabCount; } + // Clear name buffers + tab_bar->TabsNames.Buf.resize(0); + // If we have lost the selected tab, select the next most recently active one if (found_selected_tab_id == false) tab_bar->SelectedTabId = 0; @@ -7477,9 +7837,23 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) tab_bar->VisibleTabId = tab_bar->SelectedTabId; tab_bar->VisibleTabWasSubmitted = false; - // Update scrolling + // Apply request requests if (scroll_to_tab_id != 0) TabBarScrollToTab(tab_bar, scroll_to_tab_id, sections); + else if ((tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) && IsMouseHoveringRect(tab_bar->BarRect.Min, tab_bar->BarRect.Max, true) && IsWindowContentHoverable(g.CurrentWindow)) + { + const float wheel = g.IO.MouseWheelRequestAxisSwap ? g.IO.MouseWheel : g.IO.MouseWheelH; + const ImGuiKey wheel_key = g.IO.MouseWheelRequestAxisSwap ? ImGuiKey_MouseWheelY : ImGuiKey_MouseWheelX; + if (TestKeyOwner(wheel_key, tab_bar->ID) && wheel != 0.0f) + { + const float scroll_step = wheel * TabBarCalcScrollableWidth(tab_bar, sections) / 3.0f; + tab_bar->ScrollingTargetDistToVisibility = 0.0f; + tab_bar->ScrollingTarget = TabBarScrollClamp(tab_bar, tab_bar->ScrollingTarget - scroll_step); + } + SetKeyOwner(wheel_key, tab_bar->ID); + } + + // Update scrolling tab_bar->ScrollingAnim = TabBarScrollClamp(tab_bar, tab_bar->ScrollingAnim); tab_bar->ScrollingTarget = TabBarScrollClamp(tab_bar, tab_bar->ScrollingTarget); if (tab_bar->ScrollingAnim != tab_bar->ScrollingTarget) @@ -7498,10 +7872,6 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) tab_bar->ScrollingRectMinX = tab_bar->BarRect.Min.x + sections[0].Width + sections[0].Spacing; tab_bar->ScrollingRectMaxX = tab_bar->BarRect.Max.x - sections[2].Width - sections[1].Spacing; - // Clear name buffers - if ((tab_bar->Flags & ImGuiTabBarFlags_DockNode) == 0) - tab_bar->TabsNames.Buf.resize(0); - // Actual layout in host window (we don't do it in BeginTabBar() so as not to waste an extra frame) ImGuiWindow* window = g.CurrentWindow; window->DC.CursorPos = tab_bar->BarRect.Min; @@ -7509,9 +7879,11 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, tab_bar->BarRect.Min.x + tab_bar->WidthAllTabsIdeal); } -// Dockables uses Name/ID in the global namespace. Non-dockable items use the ID stack. -static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label) +// Dockable windows uses Name/ID in the global namespace. Non-dockable items use the ID stack. +static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window) { + IM_ASSERT(docked_window == NULL); // master branch only + IM_UNUSED(docked_window); if (tab_bar->Flags & ImGuiTabBarFlags_DockNode) { ImGuiID id = ImHashStr(label); @@ -7540,7 +7912,30 @@ ImGuiTabItem* ImGui::TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id) return NULL; } -// The *TabId fields be already set by the docking system _before_ the actual TabItem was created, so we clear them regardless. +// Order = visible order, not submission order! (which is tab->BeginOrder) +ImGuiTabItem* ImGui::TabBarFindTabByOrder(ImGuiTabBar* tab_bar, int order) +{ + if (order < 0 || order >= tab_bar->Tabs.Size) + return NULL; + return &tab_bar->Tabs[order]; +} + +ImGuiTabItem* ImGui::TabBarGetCurrentTab(ImGuiTabBar* tab_bar) +{ + if (tab_bar->LastTabItemIdx <= 0 || tab_bar->LastTabItemIdx >= tab_bar->Tabs.Size) + return NULL; + return &tab_bar->Tabs[tab_bar->LastTabItemIdx]; +} + +const char* ImGui::TabBarGetTabName(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) +{ + if (tab->NameOffset == -1) + return "N/A"; + IM_ASSERT(tab->NameOffset < tab_bar->TabsNames.Buf.Size); + return tab_bar->TabsNames.Buf.Data + tab->NameOffset; +} + +// The *TabId fields are already set by the docking system _before_ the actual TabItem was created, so we clear them regardless. void ImGui::TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id) { if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id)) @@ -7553,7 +7948,9 @@ void ImGui::TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id) // Called on manual closure attempt void ImGui::TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) { - IM_ASSERT(!(tab->Flags & ImGuiTabItemFlags_Button)); + if (tab->Flags & ImGuiTabItemFlags_Button) + return; // A button appended with TabItemButton(). + if (!(tab->Flags & ImGuiTabItemFlags_UnsavedDocument)) { // This will remove a frame of lag for selecting another tab on closure. @@ -7569,7 +7966,7 @@ void ImGui::TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) { // Actually select before expecting closure attempt (on an UnsavedDocument tab user is expect to e.g. show a popup) if (tab_bar->VisibleTabId != tab->ID) - tab_bar->NextSelectedTabId = tab->ID; + TabBarQueueFocus(tab_bar, tab); } } @@ -7590,11 +7987,10 @@ static void ImGui::TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiID tab_id, ImGui ImGuiContext& g = *GImGui; float margin = g.FontSize * 1.0f; // When to scroll to make Tab N+1 visible always make a bit of N visible to suggest more scrolling area (since we don't have a scrollbar) - int order = tab_bar->GetTabOrder(tab); + int order = TabBarGetTabOrder(tab_bar, tab); // Scrolling happens only in the central section (leading/trailing sections are not scrolling) - // FIXME: This is all confusing. - float scrollable_width = tab_bar->BarRect.GetWidth() - sections[0].Width - sections[2].Width - sections[1].Spacing; + float scrollable_width = TabBarCalcScrollableWidth(tab_bar, sections); // We make all tabs positions all relative Sections[0].Width to make code simpler float tab_x1 = tab->Offset - sections[0].Width + (order > sections[0].TabCount - 1 ? -margin : 0.0f); @@ -7614,7 +8010,12 @@ static void ImGui::TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiID tab_id, ImGui } } -void ImGui::TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int offset) +void ImGui::TabBarQueueFocus(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) +{ + tab_bar->NextSelectedTabId = tab->ID; +} + +void ImGui::TabBarQueueReorder(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, int offset) { IM_ASSERT(offset != 0); IM_ASSERT(tab_bar->ReorderRequestTabId == 0); @@ -7622,7 +8023,7 @@ void ImGui::TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, in tab_bar->ReorderRequestOffset = (ImS16)offset; } -void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* src_tab, ImVec2 mouse_pos) +void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* src_tab, ImVec2 mouse_pos) { ImGuiContext& g = *GImGui; IM_ASSERT(tab_bar->ReorderRequestTabId == 0); @@ -7665,7 +8066,7 @@ bool ImGui::TabBarProcessReorder(ImGuiTabBar* tab_bar) return false; //IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_Reorderable); // <- this may happen when using debug tools - int tab2_order = tab_bar->GetTabOrder(tab1) + tab_bar->ReorderRequestOffset; + int tab2_order = TabBarGetTabOrder(tab_bar, tab1) + tab_bar->ReorderRequestOffset; if (tab2_order < 0 || tab2_order >= tab_bar->Tabs.Size) return false; @@ -7725,7 +8126,7 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar) if (select_dir != 0) if (ImGuiTabItem* tab_item = TabBarFindTabByID(tab_bar, tab_bar->SelectedTabId)) { - int selected_order = tab_bar->GetTabOrder(tab_item); + int selected_order = TabBarGetTabOrder(tab_bar, tab_item); int target_order = selected_order + select_dir; // Skip tab item buttons until another tab item is found or end is reached @@ -7777,7 +8178,7 @@ static ImGuiTabItem* ImGui::TabBarTabListPopupButton(ImGuiTabBar* tab_bar) if (tab->Flags & ImGuiTabItemFlags_Button) continue; - const char* tab_name = tab_bar->GetTabName(tab); + const char* tab_name = TabBarGetTabName(tab_bar, tab); if (Selectable(tab_name, tab_bar->SelectedTabId == tab->ID)) tab_to_select = tab; } @@ -7816,7 +8217,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f } IM_ASSERT(!(flags & ImGuiTabItemFlags_Button)); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead! - bool ret = TabItemEx(tab_bar, label, p_open, flags); + bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL); if (ret && !(flags & ImGuiTabItemFlags_NoPushId)) { ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx]; @@ -7857,29 +8258,32 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags) IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!"); return false; } - return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder); + return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL); } -bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags) +bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window) { // Layout whole tab bar if not already done - if (tab_bar->WantLayout) - TabBarLayout(tab_bar); - ImGuiContext& g = *GImGui; + if (tab_bar->WantLayout) + { + ImGuiNextItemData backup_next_item_data = g.NextItemData; + TabBarLayout(tab_bar); + g.NextItemData = backup_next_item_data; + } ImGuiWindow* window = g.CurrentWindow; if (window->SkipItems) return false; const ImGuiStyle& style = g.Style; - const ImGuiID id = TabBarCalcTabID(tab_bar, label); + const ImGuiID id = TabBarCalcTabID(tab_bar, label, docked_window); // If the user called us with *p_open == false, we early out and don't render. // We make a call to ItemAdd() so that attempts to use a contextual popup menu with an implicit ID won't use an older ID. IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags); if (p_open && !*p_open) { - ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus); + ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav); return false; } @@ -7892,9 +8296,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, else if (p_open == NULL) flags |= ImGuiTabItemFlags_NoCloseButton; - // Calculate tab contents size - ImVec2 size = TabItemCalcSize(label, p_open != NULL); - // Acquire tab data ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, id); bool tab_is_new = false; @@ -7903,33 +8304,48 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, tab_bar->Tabs.push_back(ImGuiTabItem()); tab = &tab_bar->Tabs.back(); tab->ID = id; - tab->Width = size.x; - tab_bar->TabsAddedNew = true; - tab_is_new = true; + tab_bar->TabsAddedNew = tab_is_new = true; } tab_bar->LastTabItemIdx = (ImS16)tab_bar->Tabs.index_from_ptr(tab); + + // Calculate tab contents size + ImVec2 size = TabItemCalcSize(label, (p_open != NULL) || (flags & ImGuiTabItemFlags_UnsavedDocument)); + tab->RequestedWidth = -1.0f; + if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth) + size.x = tab->RequestedWidth = g.NextItemData.Width; + if (tab_is_new) + tab->Width = ImMax(1.0f, size.x); tab->ContentWidth = size.x; tab->BeginOrder = tab_bar->TabsActiveCount++; const bool tab_bar_appearing = (tab_bar->PrevFrameVisible + 1 < g.FrameCount); const bool tab_bar_focused = (tab_bar->Flags & ImGuiTabBarFlags_IsFocused) != 0; const bool tab_appearing = (tab->LastFrameVisible + 1 < g.FrameCount); + const bool tab_just_unsaved = (flags & ImGuiTabItemFlags_UnsavedDocument) && !(tab->Flags & ImGuiTabItemFlags_UnsavedDocument); const bool is_tab_button = (flags & ImGuiTabItemFlags_Button) != 0; tab->LastFrameVisible = g.FrameCount; tab->Flags = flags; - // Append name with zero-terminator - tab->NameOffset = (ImS32)tab_bar->TabsNames.size(); - tab_bar->TabsNames.append(label, label + strlen(label) + 1); + // Append name _WITH_ the zero-terminator + if (docked_window != NULL) + { + IM_ASSERT(docked_window == NULL); // master branch only + } + else + { + tab->NameOffset = (ImS32)tab_bar->TabsNames.size(); + tab_bar->TabsNames.append(label, label + strlen(label) + 1); + } // Update selected tab - if (tab_appearing && (tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs) && tab_bar->NextSelectedTabId == 0) - if (!tab_bar_appearing || tab_bar->SelectedTabId == 0) - if (!is_tab_button) - tab_bar->NextSelectedTabId = id; // New tabs gets activated - if ((flags & ImGuiTabItemFlags_SetSelected) && (tab_bar->SelectedTabId != id)) // SetSelected can only be passed on explicit tab bar - if (!is_tab_button) - tab_bar->NextSelectedTabId = id; + if (!is_tab_button) + { + if (tab_appearing && (tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs) && tab_bar->NextSelectedTabId == 0) + if (!tab_bar_appearing || tab_bar->SelectedTabId == 0) + TabBarQueueFocus(tab_bar, tab); // New tabs gets activated + if ((flags & ImGuiTabItemFlags_SetSelected) && (tab_bar->SelectedTabId != id)) // _SetSelected can only be passed on explicit tab bar + TabBarQueueFocus(tab_bar, tab); + } // Lock visibility // (Note: tab_contents_visible != tab_selected... because CTRL+TAB operations may preview some tabs without selecting them!) @@ -7946,7 +8362,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, // and then gets submitted again, the tabs will have 'tab_appearing=true' but 'tab_is_new=false'. if (tab_appearing && (!tab_bar_appearing || tab_is_new)) { - ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus); + ItemAdd(ImRect(), id, NULL, ImGuiItemFlags_NoNav); if (is_tab_button) return false; return tab_contents_visible; @@ -7986,17 +8402,14 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, } // Click to Select a tab - ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowItemOverlap); + // Allow the close button to overlap + ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap); if (g.DragDropActive) button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; bool hovered, held; bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags); if (pressed && !is_tab_button) - tab_bar->NextSelectedTabId = id; - - // Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs to be hovered) - if (g.ActiveId != id) - SetItemAllowOverlap(); + TabBarQueueFocus(tab_bar, tab); // Drag and drop: re-order tabs if (held && !tab_appearing && IsMouseDragging(0)) @@ -8033,9 +8446,8 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, // Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget. const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup); - if (hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1))) - if (!is_tab_button) - tab_bar->NextSelectedTabId = id; + if (hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button) + TabBarQueueFocus(tab_bar, tab); if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton) flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton; @@ -8044,7 +8456,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, id) : 0; bool just_closed; bool text_clipped; - TabItemLabelAndCloseButton(display_draw_list, bb, flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped); + TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped); if (just_closed && p_open != NULL) { *p_open = false; @@ -8061,9 +8473,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, // (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores) // FIXME: This is a mess. // FIXME: We may want disabled tab to still display the tooltip? - if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay && IsItemHovered()) + if (text_clipped && g.HoveredId == id && !held) if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip)) - SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label); + SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label); IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected if (is_tab_button) @@ -8081,24 +8493,30 @@ void ImGui::SetTabItemClosed(const char* label) if (is_within_manual_tab_bar) { ImGuiTabBar* tab_bar = g.CurrentTabBar; - ImGuiID tab_id = TabBarCalcTabID(tab_bar, label); + ImGuiID tab_id = TabBarCalcTabID(tab_bar, label, NULL); if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id)) tab->WantClose = true; // Will be processed by next call to TabBarLayout() } } -ImVec2 ImGui::TabItemCalcSize(const char* label, bool has_close_button) +ImVec2 ImGui::TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker) { ImGuiContext& g = *GImGui; ImVec2 label_size = CalcTextSize(label, NULL, true); ImVec2 size = ImVec2(label_size.x + g.Style.FramePadding.x, label_size.y + g.Style.FramePadding.y * 2.0f); - if (has_close_button) + if (has_close_button_or_unsaved_marker) size.x += g.Style.FramePadding.x + (g.Style.ItemInnerSpacing.x + g.FontSize); // We use Y intentionally to fit the close button circle. else size.x += g.Style.FramePadding.x + 1.0f; return ImVec2(ImMin(size.x, TabBarCalcMaxTabWidth()), size.y); } +ImVec2 ImGui::TabItemCalcSize(ImGuiWindow*) +{ + IM_ASSERT(0); // This function exists to facilitate merge with 'docking' branch. + return ImVec2(0.0f, 0.0f); +} + void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col) { // While rendering tabs, we trim 1 pixel off the top of our bounding box so they can fit within a regular frame height while looking "detached" from it. diff --git a/Externals/imgui/imstb_rectpack.h b/Externals/imgui/imstb_rectpack.h index 3958952162..f6917e7a6e 100644 --- a/Externals/imgui/imstb_rectpack.h +++ b/Externals/imgui/imstb_rectpack.h @@ -1,15 +1,19 @@ // [DEAR IMGUI] -// This is a slightly modified version of stb_rect_pack.h 1.00. -// Those changes would need to be pushed into nothings/stb: -// - Added STBRP__CDECL +// This is a slightly modified version of stb_rect_pack.h 1.01. // Grep for [DEAR IMGUI] to find the changes. - -// stb_rect_pack.h - v1.00 - public domain - rectangle packing +// +// stb_rect_pack.h - v1.01 - public domain - rectangle packing // Sean Barrett 2014 // // Useful for e.g. packing rectangular textures into an atlas. // Does not do rotation. // +// Before #including, +// +// #define STB_RECT_PACK_IMPLEMENTATION +// +// in the file that you want to have the implementation. +// // Not necessarily the awesomest packing method, but better than // the totally naive one in stb_truetype (which is primarily what // this is meant to replace). @@ -41,6 +45,7 @@ // // Version history: // +// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section // 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles // 0.99 (2019-02-07) warning fixes // 0.11 (2017-03-03) return packing success/fail result @@ -81,11 +86,10 @@ typedef struct stbrp_context stbrp_context; typedef struct stbrp_node stbrp_node; typedef struct stbrp_rect stbrp_rect; -#ifdef STBRP_LARGE_RECTS typedef int stbrp_coord; -#else -typedef unsigned short stbrp_coord; -#endif + +#define STBRP__MAXVAL 0x7fffffff +// Mostly for internal use, but this is the maximum supported coordinate value. STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); // Assign packed locations to rectangles. The rectangles are of type @@ -213,10 +217,9 @@ struct stbrp_context #define STBRP_ASSERT assert #endif -// [DEAR IMGUI] Added STBRP__CDECL #ifdef _MSC_VER #define STBRP__NOTUSED(v) (void)(v) -#define STBRP__CDECL __cdecl +#define STBRP__CDECL __cdecl #else #define STBRP__NOTUSED(v) (void)sizeof(v) #define STBRP__CDECL @@ -262,9 +265,6 @@ STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_ou STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) { int i; -#ifndef STBRP_LARGE_RECTS - STBRP_ASSERT(width <= 0xffff && height <= 0xffff); -#endif for (i=0; i < num_nodes-1; ++i) nodes[i].next = &nodes[i+1]; @@ -283,11 +283,7 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, context->extra[0].y = 0; context->extra[0].next = &context->extra[1]; context->extra[1].x = (stbrp_coord) width; -#ifdef STBRP_LARGE_RECTS context->extra[1].y = (1<<30); -#else - context->extra[1].y = 65535; -#endif context->extra[1].next = NULL; } @@ -433,7 +429,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt if (y <= best_y) { if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { best_x = xpos; - STBRP_ASSERT(y <= best_y); + //STBRP_ASSERT(y <= best_y); [DEAR IMGUI] best_y = y; best_waste = waste; best = prev; @@ -529,7 +525,6 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i return res; } -// [DEAR IMGUI] Added STBRP__CDECL static int STBRP__CDECL rect_height_compare(const void *a, const void *b) { const stbrp_rect *p = (const stbrp_rect *) a; @@ -541,7 +536,6 @@ static int STBRP__CDECL rect_height_compare(const void *a, const void *b) return (p->w > q->w) ? -1 : (p->w < q->w); } -// [DEAR IMGUI] Added STBRP__CDECL static int STBRP__CDECL rect_original_order(const void *a, const void *b) { const stbrp_rect *p = (const stbrp_rect *) a; @@ -549,12 +543,6 @@ static int STBRP__CDECL rect_original_order(const void *a, const void *b) return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); } -#ifdef STBRP_LARGE_RECTS -#define STBRP__MAXVAL 0xffffffff -#else -#define STBRP__MAXVAL 0xffff -#endif - STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) { int i, all_rects_packed = 1; diff --git a/Externals/imgui/imstb_textedit.h b/Externals/imgui/imstb_textedit.h index 2c635b27d0..a8a823110b 100644 --- a/Externals/imgui/imstb_textedit.h +++ b/Externals/imgui/imstb_textedit.h @@ -1,10 +1,11 @@ // [DEAR IMGUI] -// This is a slightly modified version of stb_textedit.h 1.13. +// This is a slightly modified version of stb_textedit.h 1.14. // Those changes would need to be pushed into nothings/stb: // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) +// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000) // Grep for [DEAR IMGUI] to find the changes. -// stb_textedit.h - v1.13 - public domain - Sean Barrett +// stb_textedit.h - v1.14 - public domain - Sean Barrett // Development of this library was sponsored by RAD Game Tools // // This C header file implements the guts of a multi-line text-editing @@ -35,6 +36,7 @@ // // VERSION HISTORY // +// 1.14 (2021-07-11) page up/down, various fixes // 1.13 (2019-02-07) fix bug in undo size management // 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash // 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield @@ -58,6 +60,7 @@ // Ulf Winklemann: move-by-word in 1.1 // Fabian Giesen: secondary key inputs in 1.5 // Martins Mozeiko: STB_TEXTEDIT_memmove in 1.6 +// Louis Schnellbach: page up/down in 1.14 // // Bugfixes: // Scott Graham @@ -93,8 +96,8 @@ // moderate sizes. The undo system does no memory allocations, so // it grows STB_TexteditState by the worst-case storage which is (in bytes): // -// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATE_COUNT -// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHAR_COUNT +// [4 + 3 * sizeof(STB_TEXTEDIT_POSITIONTYPE)] * STB_TEXTEDIT_UNDOSTATECOUNT +// + sizeof(STB_TEXTEDIT_CHARTYPE) * STB_TEXTEDIT_UNDOCHARCOUNT // // // Implementation mode: @@ -522,29 +525,14 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s int z = STB_TEXTEDIT_STRINGLEN(str); int i=0, first; - if (n == z) { - // if it's at the end, then find the last line -- simpler than trying to - // explicitly handle this case in the regular code - if (single_line) { - STB_TEXTEDIT_LAYOUTROW(&r, str, 0); - find->y = 0; - find->first_char = 0; - find->length = z; - find->height = r.ymax - r.ymin; - find->x = r.x1; - } else { - find->y = 0; - find->x = 0; - find->height = 1; - while (i < z) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - prev_start = i; - i += r.num_chars; - } - find->first_char = i; - find->length = 0; - find->prev_first = prev_start; - } + if (n == z && single_line) { + // special case if it's at the end (may not be needed?) + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + find->y = 0; + find->first_char = 0; + find->length = z; + find->height = r.ymax - r.ymin; + find->x = r.x1; return; } @@ -555,9 +543,13 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s STB_TEXTEDIT_LAYOUTROW(&r, str, i); if (n < i + r.num_chars) break; + if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line + break; // [DEAR IMGUI] prev_start = i; i += r.num_chars; find->y += r.baseline_y_delta; + if (i == z) // [DEAR IMGUI] + break; // [DEAR IMGUI] } find->first_char = first = i; @@ -716,10 +708,6 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta state->has_preferred_x = 0; return 1; } - // [DEAR IMGUI] - //// remove the undo since we didn't actually insert the characters - //if (state->undostate.undo_point) - // --state->undostate.undo_point; // note: paste failure will leave deleted selection, may be restored with an undo (see https://github.com/nothings/stb/issues/734 for details) return 0; } diff --git a/Externals/imgui/imstb_truetype.h b/Externals/imgui/imstb_truetype.h index 48c2026176..35c827e6b9 100644 --- a/Externals/imgui/imstb_truetype.h +++ b/Externals/imgui/imstb_truetype.h @@ -1,10 +1,19 @@ // [DEAR IMGUI] -// This is a slightly modified version of stb_truetype.h 1.20. +// This is a slightly modified version of stb_truetype.h 1.26. // Mostly fixing for compiler and static analyzer warnings. // Grep for [DEAR IMGUI] to find the changes. -// stb_truetype.h - v1.20 - public domain -// authored from 2009-2016 by Sean Barrett / RAD Game Tools +// stb_truetype.h - v1.26 - public domain +// authored from 2009-2021 by Sean Barrett / RAD Game Tools +// +// ======================================================================= +// +// NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES +// +// This library does no range checking of the offsets found in the file, +// meaning an attacker can use it to read arbitrary memory. +// +// ======================================================================= // // This library processes TrueType files: // parse files @@ -37,11 +46,11 @@ // Daniel Ribeiro Maciel // // Bug/warning reports/fixes: -// "Zer" on mollyrocket Fabian "ryg" Giesen -// Cass Everitt Martins Mozeiko -// stoiko (Haemimont Games) Cap Petschulat -// Brian Hook Omar Cornut -// Walter van Niftrik github:aloucks +// "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe +// Cass Everitt Martins Mozeiko github:aloucks +// stoiko (Haemimont Games) Cap Petschulat github:oyvindjam +// Brian Hook Omar Cornut github:vassvik +// Walter van Niftrik Ryan Griege // David Gow Peter LaValle // David Given Sergey Popov // Ivan-Assen Ivanov Giumo X. Clanjor @@ -49,11 +58,17 @@ // Johan Duparc Thomas Fields // Hou Qiming Derek Vinyard // Rob Loach Cort Stratton -// Kenney Phillis Jr. github:oyvindjam -// Brian Costabile github:vassvik +// Kenney Phillis Jr. Brian Costabile +// Ken Voskuil (kaesve) // // VERSION HISTORY // +// 1.26 (2021-08-28) fix broken rasterizer +// 1.25 (2021-07-11) many fixes +// 1.24 (2020-02-05) fix warning +// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) +// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined +// 1.21 (2019-02-25) fix warning // 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod // 1.18 (2018-01-29) add missing function @@ -248,19 +263,6 @@ // recommend it. // // -// SOURCE STATISTICS (based on v0.6c, 2050 LOC) -// -// Documentation & header file 520 LOC \___ 660 LOC documentation -// Sample code 140 LOC / -// Truetype parsing 620 LOC ---- 620 LOC TrueType -// Software rasterization 240 LOC \. -// Curve tessellation 120 LOC \__ 550 LOC Bitmap creation -// Bitmap management 100 LOC / -// Baked bitmap interface 70 LOC / -// Font name matching & access 150 LOC ---- 150 -// C runtime library abstraction 60 LOC ---- 60 -// -// // PERFORMANCE MEASUREMENTS FOR 1.06: // // 32-bit 64-bit @@ -275,8 +277,8 @@ //// SAMPLE PROGRAMS //// // -// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless -// +// Incomplete text-in-3d-api example, which draws quads properly aligned to be lossless. +// See "tests/truetype_demo_win32.c" for a complete version. #if 0 #define STB_TRUETYPE_IMPLEMENTATION // force following include to generate implementation #include "stb_truetype.h" @@ -302,6 +304,8 @@ void my_stbtt_initfont(void) void my_stbtt_print(float x, float y, char *text) { // assume orthographic projection with units = screen pixels, origin at top left + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, ftex); glBegin(GL_QUADS); @@ -309,10 +313,10 @@ void my_stbtt_print(float x, float y, char *text) if (*text >= 32 && *text < 128) { stbtt_aligned_quad q; stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);//1=opengl & d3d10+,0=d3d9 - glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y0); - glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y0); - glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y1); - glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y1); + glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0); + glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0); + glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1); + glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1); } ++text; } @@ -719,7 +723,7 @@ struct stbtt_fontinfo int numGlyphs; // number of glyphs, needed for range checking - int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf + int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf int index_map; // a cmap mapping for our chosen character encoding int indexToLocFormat; // format needed to map from glyph index to glyph @@ -802,6 +806,18 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); // as above, but takes one or more glyph indices for greater efficiency +typedef struct stbtt_kerningentry +{ + int glyph1; // use stbtt_FindGlyphIndex + int glyph2; + int advance; +} stbtt_kerningentry; + +STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info); +STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length); +// Retrieves a complete list of all of the kerning pairs provided by the font +// stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write. +// The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1) ////////////////////////////////////////////////////////////////////////////// // @@ -846,6 +862,12 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); // frees the data allocated above +STBTT_DEF unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl); +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg); +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg); +// fills svg with the character's SVG data. +// returns data size or 0 if SVG not found. + ////////////////////////////////////////////////////////////////////////////// // // BITMAP RENDERING @@ -1347,6 +1369,22 @@ static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) return stbtt__cff_get_index(&cff); } +// since most people won't use this, find this table the first time it's needed +static int stbtt__get_svg(stbtt_fontinfo *info) +{ + stbtt_uint32 t; + if (info->svg < 0) { + t = stbtt__find_table(info->data, info->fontstart, "SVG "); + if (t) { + stbtt_uint32 offset = ttULONG(info->data + t + 2); + info->svg = t + offset; + } else { + info->svg = 0; + } + } + return info->svg; +} + static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) { stbtt_uint32 cmap, t; @@ -1426,6 +1464,8 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in else info->numGlyphs = 0xffff; + info->svg = -1; + // find a cmap encoding table we understand *now* to avoid searching // later. (todo: could make this installable) // the same regardless of glyph. @@ -1509,12 +1549,12 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep search += 2; { - stbtt_uint16 offset, start; + stbtt_uint16 offset, start, last; stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1); - STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); - if (unicode_codepoint < start) + last = ttUSHORT(data + endCount + 2*item); + if (unicode_codepoint < start || unicode_codepoint > last) return 0; offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); @@ -1774,7 +1814,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s } } num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); - } else if (numberOfContours == -1) { + } else if (numberOfContours < 0) { // Compound shapes. int more = 1; stbtt_uint8 *comp = data + g + 10; @@ -1841,7 +1881,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s if (comp_verts) STBTT_free(comp_verts, info->userdata); return 0; } - if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); //-V595 + if (num_vertices > 0 && vertices) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); if (vertices) STBTT_free(vertices, info->userdata); vertices = tmp; @@ -1851,9 +1891,6 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s // More components ? more = flags & (1<<5); } - } else if (numberOfContours < 0) { - // @TODO other compound variations? - STBTT_assert(0); } else { // numberOfCounters == 0, do nothing } @@ -1971,7 +2008,7 @@ static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int gly start = end; } } - if (fdselector == -1) stbtt__new_buf(NULL, 0); + if (fdselector == -1) return stbtt__new_buf(NULL, 0); // [DEAR IMGUI] fixed, see #6007 and nothings/stb#1422 return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); } @@ -2107,7 +2144,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); has_subrs = 1; } - // fallthrough + // FALLTHROUGH case 0x1D: // callgsubr if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); v = (int) s[--sp]; @@ -2212,7 +2249,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st } break; default: - if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) //-V560 + if (b0 != 255 && b0 != 28 && b0 < 32) return STBTT__CSERR("reserved operator"); // push immediate @@ -2282,7 +2319,49 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde } } -static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +STBTT_DEF int stbtt_GetKerningTableLength(const stbtt_fontinfo *info) +{ + stbtt_uint8 *data = info->data + info->kern; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + return ttUSHORT(data+10); +} + +STBTT_DEF int stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry* table, int table_length) +{ + stbtt_uint8 *data = info->data + info->kern; + int k, length; + + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format + return 0; + + length = ttUSHORT(data+10); + if (table_length < length) + length = table_length; + + for (k = 0; k < length; k++) + { + table[k].glyph1 = ttUSHORT(data+18+(k*6)); + table[k].glyph2 = ttUSHORT(data+20+(k*6)); + table[k].advance = ttSHORT(data+22+(k*6)); + } + + return length; +} + +static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { stbtt_uint8 *data = info->data + info->kern; stbtt_uint32 needle, straw; @@ -2312,245 +2391,225 @@ static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph return 0; } -static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) +static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) { - stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); - switch(coverageFormat) { - case 1: { - stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); + stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); + switch (coverageFormat) { + case 1: { + stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); - // Binary search. - stbtt_int32 l=0, r=glyphCount-1, m; - int straw, needle=glyph; - while (l <= r) { - stbtt_uint8 *glyphArray = coverageTable + 4; - stbtt_uint16 glyphID; - m = (l + r) >> 1; - glyphID = ttUSHORT(glyphArray + 2 * m); - straw = glyphID; - if (needle < straw) - r = m - 1; - else if (needle > straw) - l = m + 1; - else { - return m; - } + // Binary search. + stbtt_int32 l=0, r=glyphCount-1, m; + int straw, needle=glyph; + while (l <= r) { + stbtt_uint8 *glyphArray = coverageTable + 4; + stbtt_uint16 glyphID; + m = (l + r) >> 1; + glyphID = ttUSHORT(glyphArray + 2 * m); + straw = glyphID; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + return m; } - } break; + } + break; + } - case 2: { - stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); - stbtt_uint8 *rangeArray = coverageTable + 4; + case 2: { + stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); + stbtt_uint8 *rangeArray = coverageTable + 4; - // Binary search. - stbtt_int32 l=0, r=rangeCount-1, m; - int strawStart, strawEnd, needle=glyph; - while (l <= r) { - stbtt_uint8 *rangeRecord; - m = (l + r) >> 1; - rangeRecord = rangeArray + 6 * m; - strawStart = ttUSHORT(rangeRecord); - strawEnd = ttUSHORT(rangeRecord + 2); - if (needle < strawStart) - r = m - 1; - else if (needle > strawEnd) - l = m + 1; - else { - stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); - return startCoverageIndex + glyph - strawStart; - } + // Binary search. + stbtt_int32 l=0, r=rangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = ttUSHORT(rangeRecord); + strawEnd = ttUSHORT(rangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else { + stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); + return startCoverageIndex + glyph - strawStart; } - } break; + } + break; + } - default: { - // There are no other cases. - STBTT_assert(0); - } break; - } + default: return -1; // unsupported + } - return -1; + return -1; } static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) { - stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); - switch(classDefFormat) - { - case 1: { - stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); - stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); - stbtt_uint8 *classDef1ValueArray = classDefTable + 6; + stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); + switch (classDefFormat) + { + case 1: { + stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); + stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); + stbtt_uint8 *classDef1ValueArray = classDefTable + 6; - if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) - return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); + if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); + break; + } - // [DEAR IMGUI] Commented to fix static analyzer warning - //classDefTable = classDef1ValueArray + 2 * glyphCount; - } break; + case 2: { + stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); + stbtt_uint8 *classRangeRecords = classDefTable + 4; - case 2: { - stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); - stbtt_uint8 *classRangeRecords = classDefTable + 4; + // Binary search. + stbtt_int32 l=0, r=classRangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = ttUSHORT(classRangeRecord); + strawEnd = ttUSHORT(classRangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + return (stbtt_int32)ttUSHORT(classRangeRecord + 4); + } + break; + } - // Binary search. - stbtt_int32 l=0, r=classRangeCount-1, m; - int strawStart, strawEnd, needle=glyph; - while (l <= r) { - stbtt_uint8 *classRangeRecord; - m = (l + r) >> 1; - classRangeRecord = classRangeRecords + 6 * m; - strawStart = ttUSHORT(classRangeRecord); - strawEnd = ttUSHORT(classRangeRecord + 2); - if (needle < strawStart) - r = m - 1; - else if (needle > strawEnd) - l = m + 1; - else - return (stbtt_int32)ttUSHORT(classRangeRecord + 4); - } + default: + return -1; // Unsupported definition type, return an error. + } - // [DEAR IMGUI] Commented to fix static analyzer warning - //classDefTable = classRangeRecords + 6 * classRangeCount; - } break; - - default: { - // There are no other cases. - STBTT_assert(0); - } break; - } - - return -1; + // "All glyphs not assigned to a class fall into class 0". (OpenType spec) + return 0; } // Define to STBTT_assert(x) if you want to break on unimplemented formats. #define STBTT_GPOS_TODO_assert(x) -static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { - stbtt_uint16 lookupListOffset; - stbtt_uint8 *lookupList; - stbtt_uint16 lookupCount; - stbtt_uint8 *data; - stbtt_int32 i; + stbtt_uint16 lookupListOffset; + stbtt_uint8 *lookupList; + stbtt_uint16 lookupCount; + stbtt_uint8 *data; + stbtt_int32 i, sti; - if (!info->gpos) return 0; + if (!info->gpos) return 0; - data = info->data + info->gpos; + data = info->data + info->gpos; - if (ttUSHORT(data+0) != 1) return 0; // Major version 1 - if (ttUSHORT(data+2) != 0) return 0; // Minor version 0 + if (ttUSHORT(data+0) != 1) return 0; // Major version 1 + if (ttUSHORT(data+2) != 0) return 0; // Minor version 0 - lookupListOffset = ttUSHORT(data+8); - lookupList = data + lookupListOffset; - lookupCount = ttUSHORT(lookupList); + lookupListOffset = ttUSHORT(data+8); + lookupList = data + lookupListOffset; + lookupCount = ttUSHORT(lookupList); - for (i=0; i= pairSetCount) return 0; - // Binary search. - while (l <= r) { - stbtt_uint16 secondGlyph; - stbtt_uint8 *pairValue; - m = (l + r) >> 1; - pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; - secondGlyph = ttUSHORT(pairValue); - straw = secondGlyph; - if (needle < straw) - r = m - 1; - else if (needle > straw) - l = m + 1; - else { - stbtt_int16 xAdvance = ttSHORT(pairValue + 2); - return xAdvance; - } - } - } break; + needle=glyph2; + r=pairValueCount-1; + l=0; - case 2: { - stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); - stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + // Binary search. + while (l <= r) { + stbtt_uint16 secondGlyph; + stbtt_uint8 *pairValue; + m = (l + r) >> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = ttUSHORT(pairValue); + straw = secondGlyph; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + stbtt_int16 xAdvance = ttSHORT(pairValue + 2); + return xAdvance; + } + } + } else + return 0; + break; + } - stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); - stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); - int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); - int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); + case 2: { + stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + if (valueFormat1 == 4 && valueFormat2 == 0) { // Support more formats? + stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); + stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); + int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); + int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); - stbtt_uint16 class1Count = ttUSHORT(table + 12); - stbtt_uint16 class2Count = ttUSHORT(table + 14); - STBTT_assert(glyph1class < class1Count); - STBTT_assert(glyph2class < class2Count); + stbtt_uint16 class1Count = ttUSHORT(table + 12); + stbtt_uint16 class2Count = ttUSHORT(table + 14); + stbtt_uint8 *class1Records, *class2Records; + stbtt_int16 xAdvance; - // TODO: Support more formats. - STBTT_GPOS_TODO_assert(valueFormat1 == 4); - if (valueFormat1 != 4) return 0; - STBTT_GPOS_TODO_assert(valueFormat2 == 0); - if (valueFormat2 != 0) return 0; + if (glyph1class < 0 || glyph1class >= class1Count) return 0; // malformed + if (glyph2class < 0 || glyph2class >= class2Count) return 0; // malformed - if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) { - stbtt_uint8 *class1Records = table + 16; - stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); - stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); - return xAdvance; - } - } break; - - default: { - // There are no other cases. - STBTT_assert(0); - break; - } // [DEAR IMGUI] removed ; - } - } - break; - } // [DEAR IMGUI] removed ; + class1Records = table + 16; + class2Records = class1Records + 2 * (glyph1class * class2Count); + xAdvance = ttSHORT(class2Records + 2 * glyph2class); + return xAdvance; + } else + return 0; + break; + } default: - // TODO: Implement other stuff. - break; - } - } + return 0; // Unsupported position format + } + } + } - return 0; + return 0; } STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) @@ -2559,8 +2618,7 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int if (info->gpos) xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); - - if (info->kern) + else if (info->kern) xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); return xAdvance; @@ -2621,6 +2679,45 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) STBTT_free(v, info->userdata); } +STBTT_DEF stbtt_uint8 *stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) +{ + int i; + stbtt_uint8 *data = info->data; + stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *) info); + + int numEntries = ttUSHORT(svg_doc_list); + stbtt_uint8 *svg_docs = svg_doc_list + 2; + + for(i=0; i= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2))) + return svg_doc; + } + return 0; +} + +STBTT_DEF int stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg) +{ + stbtt_uint8 *data = info->data; + stbtt_uint8 *svg_doc; + + if (info->svg == 0) + return 0; + + svg_doc = stbtt_FindSVGDoc(info, gl); + if (svg_doc != NULL) { + *svg = (char *) data + info->svg + ttULONG(svg_doc + 4); + return ttULONG(svg_doc + 8); + } else { + return 0; + } +} + +STBTT_DEF int stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg) +{ + return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg); +} + ////////////////////////////////////////////////////////////////////////////// // // antialiasing software rasterizer @@ -2970,6 +3067,23 @@ static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edg } } +static float stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width) +{ + STBTT_assert(top_width >= 0); + STBTT_assert(bottom_width >= 0); + return (top_width + bottom_width) / 2.0f * height; +} + +static float stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1) +{ + return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0); +} + +static float stbtt__sized_triangle_area(float height, float width) +{ + return height * width / 2; +} + static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) { float y_bottom = y_top+1; @@ -3024,13 +3138,13 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, float height; // simple case, only spans one pixel int x = (int) x_top; - height = sy1 - sy0; + height = (sy1 - sy0) * e->direction; STBTT_assert(x >= 0 && x < len); - scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height; - scanline_fill[x] += e->direction * height; // everything right of this pixel is filled + scanline[x] += stbtt__position_trapezoid_area(height, x_top, x+1.0f, x_bottom, x+1.0f); + scanline_fill[x] += height; // everything right of this pixel is filled } else { int x,x1,x2; - float y_crossing, step, sign, area; + float y_crossing, y_final, step, sign, area; // covers 2+ pixels if (x_top > x_bottom) { // flip scanline vertically; signed area is the same @@ -3042,32 +3156,83 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, dx = -dx; dy = -dy; t = x0, x0 = xb, xb = t; - // [DEAR IMGUI] Fix static analyzer warning - (void)dx; // [ImGui: fix static analyzer warning] } + STBTT_assert(dy >= 0); + STBTT_assert(dx >= 0); x1 = (int) x_top; x2 = (int) x_bottom; // compute intersection with y axis at x1+1 - y_crossing = (x1+1 - x0) * dy + y_top; + y_crossing = y_top + dy * (x1+1 - x0); + + // compute intersection with y axis at x2 + y_final = y_top + dy * (x2 - x0); + + // x1 x_top x2 x_bottom + // y_top +------|-----+------------+------------+--------|---+------------+ + // | | | | | | + // | | | | | | + // sy0 | Txxxxx|............|............|............|............| + // y_crossing | *xxxxx.......|............|............|............| + // | | xxxxx..|............|............|............| + // | | /- xx*xxxx........|............|............| + // | | dy < | xxxxxx..|............|............| + // y_final | | \- | xx*xxx.........|............| + // sy1 | | | | xxxxxB...|............| + // | | | | | | + // | | | | | | + // y_bottom +------------+------------+------------+------------+------------+ + // + // goal is to measure the area covered by '.' in each pixel + + // if x2 is right at the right edge of x1, y_crossing can blow up, github #1057 + // @TODO: maybe test against sy1 rather than y_bottom? + if (y_crossing > y_bottom) + y_crossing = y_bottom; sign = e->direction; - // area of the rectangle covered from y0..y_crossing - area = sign * (y_crossing-sy0); - // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) - scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2); - step = sign * dy; + // area of the rectangle covered from sy0..y_crossing + area = sign * (y_crossing-sy0); + + // area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing) + scanline[x1] += stbtt__sized_triangle_area(area, x1+1 - x_top); + + // check if final y_crossing is blown up; no test case for this + if (y_final > y_bottom) { + int denom = (x2 - (x1+1)); + y_final = y_bottom; + if (denom != 0) { // [DEAR IMGUI] Avoid div by zero (https://github.com/nothings/stb/issues/1316) + dy = (y_final - y_crossing ) / denom; // if denom=0, y_final = y_crossing, so y_final <= y_bottom + } + } + + // in second pixel, area covered by line segment found in first pixel + // is always a rectangle 1 wide * the height of that line segment; this + // is exactly what the variable 'area' stores. it also gets a contribution + // from the line segment within it. the THIRD pixel will get the first + // pixel's rectangle contribution, the second pixel's rectangle contribution, + // and its own contribution. the 'own contribution' is the same in every pixel except + // the leftmost and rightmost, a trapezoid that slides down in each pixel. + // the second pixel's contribution to the third pixel will be the + // rectangle 1 wide times the height change in the second pixel, which is dy. + + step = sign * dy * 1; // dy is dy/dx, change in y for every 1 change in x, + // which multiplied by 1-pixel-width is how much pixel area changes for each step in x + // so the area advances by 'step' every time + for (x = x1+1; x < x2; ++x) { - scanline[x] += area + step/2; + scanline[x] += area + step/2; // area of trapezoid is 1*step/2 area += step; } - y_crossing += dy * (x2 - (x1+1)); + STBTT_assert(STBTT_fabs(area) <= 1.01f); // accumulated error from area += step unless we round step down + STBTT_assert(sy1 > y_final-0.01f); - STBTT_assert(STBTT_fabs(area) <= 1.01f); - - scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing); + // area covered in the last pixel is the rectangle from all the pixels to the left, + // plus the trapezoid filled by the line segment in this pixel all the way to the right edge + scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1-y_final, (float) x2, x2+1.0f, x_bottom, x2+1.0f); + // the rest of the line is filled based on the total height of the line segment in this pixel scanline_fill[x2] += sign * (sy1-sy0); } } else { @@ -3075,6 +3240,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, // clipping logic. since this does not match the intended use // of this library, we use a different, very slow brute // force implementation + // note though that this does happen some of the time because + // x_top and x_bottom can be extrapolated at the top & bottom of + // the shape and actually lie outside the bounding box int x; for (x=0; x < len; ++x) { // cases: @@ -3989,6 +4157,7 @@ static float stbtt__oversample_shift(int oversample) STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { int i,j,k; + int missing_glyph_added = 0; k=0; for (i=0; i < num_ranges; ++i) { @@ -4000,7 +4169,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb int x0,y0,x1,y1; int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; int glyph = stbtt_FindGlyphIndex(info, codepoint); - if (glyph == 0 && spc->skip_missing) { + if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) { rects[k].w = rects[k].h = 0; } else { stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, @@ -4010,6 +4179,8 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb &x0,&y0,&x1,&y1); rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); + if (glyph == 0) + missing_glyph_added = 1; } ++k; } @@ -4044,7 +4215,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info // rects array must be big enough to accommodate all characters in the given ranges STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { - int i,j,k, return_value = 1; + int i,j,k, missing_glyph = -1, return_value = 1; // save current values int old_h_over = spc->h_oversample; @@ -4109,6 +4280,13 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const bc->yoff = (float) y0 * recip_v + sub_y; bc->xoff2 = (x0 + r->w) * recip_h + sub_x; bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + + if (glyph == 0) + missing_glyph = j; + } else if (spc->skip_missing) { + return_value = 0; + } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) { + ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph]; } else { return_value = 0; // if any fail, report failure } @@ -4132,7 +4310,7 @@ STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { stbtt_fontinfo info; - int i,j,n, return_value; // [DEAR IMGUI] removed = 1 + int i, j, n, return_value; // [DEAR IMGUI] removed = 1; //stbrp_context *context = (stbrp_context *) spc->pack_info; stbrp_rect *rects; @@ -4301,15 +4479,14 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex float y_frac; int winding = 0; - orig[0] = x; - //orig[1] = y; // [DEAR IMGUI] commented double assignment - // make sure y never passes through a vertex of the shape y_frac = (float) STBTT_fmod(y, 1.0f); if (y_frac < 0.01f) y += 0.01f; else if (y_frac > 0.99f) y -= 0.01f; + + orig[0] = x; orig[1] = y; // test a ray from (-infinity,y) to (x,y) @@ -4371,35 +4548,35 @@ static float stbtt__cuberoot( float x ) return (float) STBTT_pow( x,1.0f/3.0f); } -// x^3 + c*x^2 + b*x + a = 0 +// x^3 + a*x^2 + b*x + c = 0 static int stbtt__solve_cubic(float a, float b, float c, float* r) { - float s = -a / 3; - float p = b - a*a / 3; - float q = a * (2*a*a - 9*b) / 27 + c; + float s = -a / 3; + float p = b - a*a / 3; + float q = a * (2*a*a - 9*b) / 27 + c; float p3 = p*p*p; - float d = q*q + 4*p3 / 27; - if (d >= 0) { - float z = (float) STBTT_sqrt(d); - float u = (-q + z) / 2; - float v = (-q - z) / 2; - u = stbtt__cuberoot(u); - v = stbtt__cuberoot(v); - r[0] = s + u + v; - return 1; - } else { - float u = (float) STBTT_sqrt(-p/3); - float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative - float m = (float) STBTT_cos(v); + float d = q*q + 4*p3 / 27; + if (d >= 0) { + float z = (float) STBTT_sqrt(d); + float u = (-q + z) / 2; + float v = (-q - z) / 2; + u = stbtt__cuberoot(u); + v = stbtt__cuberoot(v); + r[0] = s + u + v; + return 1; + } else { + float u = (float) STBTT_sqrt(-p/3); + float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative + float m = (float) STBTT_cos(v); float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f; - r[0] = s + u * 2 * m; - r[1] = s - u * (m + n); - r[2] = s - u * (m - n); + r[0] = s + u * 2 * m; + r[1] = s - u * (m + n); + r[2] = s - u * (m - n); //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe? //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); - return 3; + return 3; } } @@ -4410,12 +4587,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc int w,h; unsigned char *data; - // if one scale is 0, use same scale for both - if (scale_x == 0) scale_x = scale_y; - if (scale_y == 0) { - if (scale_x == 0) return NULL; // if both scales are 0, return NULL - scale_y = scale_x; - } + if (scale == 0) return NULL; stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); @@ -4481,18 +4653,17 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc for (i=0; i < num_verts; ++i) { float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; - // check against every point here rather than inside line/curve primitives -- @TODO: wrong if multiple 'moves' in a row produce a garbage point, and given culling, probably more efficient to do within line/curve - float dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); - if (dist2 < min_dist*min_dist) - min_dist = (float) STBTT_sqrt(dist2); - - if (verts[i].type == STBTT_vline) { + if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) { float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y; + float dist,dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); + if (dist2 < min_dist*min_dist) + min_dist = (float) STBTT_sqrt(dist2); + // coarse culling against bbox //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) - float dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i]; + dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i]; STBTT_assert(i != 0); if (dist < min_dist) { // check position along line @@ -4519,7 +4690,8 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc float ax = x1-x0, ay = y1-y0; float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; float mx = x0 - sx, my = y0 - sy; - float res[3],px,py,t,it; + float res[3] = {0.f,0.f,0.f}; + float px,py,t,it,dist2; float a_inv = precompute[i]; if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula float a = 3*(ax*bx + ay*by); @@ -4546,6 +4718,10 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc float d = (mx*ax+my*ay) * a_inv; num = stbtt__solve_cubic(b, c, d, res); } + dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); + if (dist2 < min_dist*min_dist) + min_dist = (float) STBTT_sqrt(dist2); + if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { t = res[0], it = 1.0f - t; px = it*it*x0 + 2*t*it*x1 + t*t*x2; @@ -4805,6 +4981,12 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const // FULL VERSION HISTORY // +// 1.25 (2021-07-11) many fixes +// 1.24 (2020-02-05) fix warning +// 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) +// 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined +// 1.21 (2019-02-25) fix warning +// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() // 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod // 1.18 (2018-01-29) add missing function // 1.17 (2017-07-23) make more arguments const; doc fix diff --git a/Externals/implot/implot b/Externals/implot/implot index d875123534..cc5e1daa5c 160000 --- a/Externals/implot/implot +++ b/Externals/implot/implot @@ -1 +1 @@ -Subproject commit d87512353495e7760e7fda7566a05beef7627d8f +Subproject commit cc5e1daa5c7f2335a9460ae79c829011dc5cef2d diff --git a/Source/Core/VideoCommon/OnScreenUI.cpp b/Source/Core/VideoCommon/OnScreenUI.cpp index 50e191a7ae..1919149629 100644 --- a/Source/Core/VideoCommon/OnScreenUI.cpp +++ b/Source/Core/VideoCommon/OnScreenUI.cpp @@ -356,35 +356,37 @@ void OnScreenUI::SetScale(float backbuffer_scale) } void OnScreenUI::SetKeyMap(const DolphinKeyMap& key_map) { - // Right now this is a 1:1 mapping. But might not be true later static constexpr DolphinKeyMap dolphin_to_imgui_map = { ImGuiKey_Tab, ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow, ImGuiKey_PageUp, ImGuiKey_PageDown, ImGuiKey_Home, ImGuiKey_End, ImGuiKey_Insert, ImGuiKey_Delete, ImGuiKey_Backspace, - ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_KeyPadEnter, + ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_KeypadEnter, ImGuiKey_A, ImGuiKey_C, ImGuiKey_V, ImGuiKey_X, ImGuiKey_Y, ImGuiKey_Z, }; - static_assert(dolphin_to_imgui_map.size() == ImGuiKey_COUNT); // Fail if ImGui adds keys auto lock = GetImGuiLock(); if (!ImGui::GetCurrentContext()) return; + m_dolphin_to_imgui_map.clear(); for (int dolphin_key = 0; dolphin_key <= static_cast(DolphinKey::Z); dolphin_key++) { - int imgui_key = dolphin_to_imgui_map[DolphinKey(dolphin_key)]; + const int imgui_key = dolphin_to_imgui_map[DolphinKey(dolphin_key)]; if (imgui_key >= 0) - ImGui::GetIO().KeyMap[imgui_key] = (key_map[DolphinKey(dolphin_key)] & 0x1FF); + { + const int mapped_key = key_map[DolphinKey(dolphin_key)]; + m_dolphin_to_imgui_map[mapped_key & 0x1FF] = imgui_key; + } } } void OnScreenUI::SetKey(u32 key, bool is_down, const char* chars) { auto lock = GetImGuiLock(); - if (key < std::size(ImGui::GetIO().KeysDown)) - ImGui::GetIO().KeysDown[key] = is_down; + if (auto iter = m_dolphin_to_imgui_map.find(key); iter != m_dolphin_to_imgui_map.end()) + ImGui::GetIO().AddKeyEvent((ImGuiKey)iter->second, is_down); if (chars) ImGui::GetIO().AddInputCharactersUTF8(chars); diff --git a/Source/Core/VideoCommon/OnScreenUI.h b/Source/Core/VideoCommon/OnScreenUI.h index b94681cf66..f937027403 100644 --- a/Source/Core/VideoCommon/OnScreenUI.h +++ b/Source/Core/VideoCommon/OnScreenUI.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -65,6 +66,7 @@ private: std::unique_ptr m_imgui_vertex_format; std::vector> m_imgui_textures; std::unique_ptr m_imgui_pipeline; + std::map m_dolphin_to_imgui_map; std::mutex m_imgui_mutex; u64 m_imgui_last_frame_time = 0; From c2b495586d0b87e7dcef3d57164783045979f6d0 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Thu, 27 Jul 2023 11:59:40 -0500 Subject: [PATCH 59/99] Externals: add misc/cpp/imgui_stdlib to imgui build in order to use std::string in InputText --- Externals/imgui/imgui.vcxproj | 4 +- Externals/imgui/misc/README.txt | 23 +++++++ Externals/imgui/misc/cpp/README.txt | 13 ++++ Externals/imgui/misc/cpp/imgui_stdlib.cpp | 75 +++++++++++++++++++++++ Externals/imgui/misc/cpp/imgui_stdlib.h | 21 +++++++ 5 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 Externals/imgui/misc/README.txt create mode 100644 Externals/imgui/misc/cpp/README.txt create mode 100644 Externals/imgui/misc/cpp/imgui_stdlib.cpp create mode 100644 Externals/imgui/misc/cpp/imgui_stdlib.h diff --git a/Externals/imgui/imgui.vcxproj b/Externals/imgui/imgui.vcxproj index daeb44865d..8519368d71 100644 --- a/Externals/imgui/imgui.vcxproj +++ b/Externals/imgui/imgui.vcxproj @@ -18,7 +18,7 @@ - $(CoreDir);%(AdditionalIncludeDirectories) + .;$(CoreDir);%(AdditionalIncludeDirectories) @@ -27,6 +27,7 @@ + @@ -35,6 +36,7 @@ + diff --git a/Externals/imgui/misc/README.txt b/Externals/imgui/misc/README.txt new file mode 100644 index 0000000000..b4ce89f038 --- /dev/null +++ b/Externals/imgui/misc/README.txt @@ -0,0 +1,23 @@ + +misc/cpp/ + InputText() wrappers for C++ standard library (STL) type: std::string. + This is also an example of how you may wrap your own similar types. + +misc/debuggers/ + Helper files for popular debuggers. + With the .natvis file, types like ImVector<> will be displayed nicely in Visual Studio debugger. + +misc/fonts/ + Fonts loading/merging instructions (e.g. How to handle glyph ranges, how to merge icons fonts). + Command line tool "binary_to_compressed_c" to create compressed arrays to embed data in source code. + Suggested fonts and links. + +misc/freetype/ + Font atlas builder/rasterizer using FreeType instead of stb_truetype. + Benefit from better FreeType rasterization, in particular for small fonts. + +misc/single_file/ + Single-file header stub. + We use this to validate compiling all *.cpp files in a same compilation unit. + Users of that technique (also called "Unity builds") can generally provide this themselves, + so we don't really recommend you use this in your projects. diff --git a/Externals/imgui/misc/cpp/README.txt b/Externals/imgui/misc/cpp/README.txt new file mode 100644 index 0000000000..17f0a3cd32 --- /dev/null +++ b/Externals/imgui/misc/cpp/README.txt @@ -0,0 +1,13 @@ + +imgui_stdlib.h + imgui_stdlib.cpp + InputText() wrappers for C++ standard library (STL) type: std::string. + This is also an example of how you may wrap your own similar types. + +imgui_scoped.h + [Experimental, not currently in main repository] + Additional header file with some RAII-style wrappers for common Dear ImGui functions. + Try by merging: https://github.com/ocornut/imgui/pull/2197 + Discuss at: https://github.com/ocornut/imgui/issues/2096 + +See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki: + https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness diff --git a/Externals/imgui/misc/cpp/imgui_stdlib.cpp b/Externals/imgui/misc/cpp/imgui_stdlib.cpp new file mode 100644 index 0000000000..c9060e8860 --- /dev/null +++ b/Externals/imgui/misc/cpp/imgui_stdlib.cpp @@ -0,0 +1,75 @@ +// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) +// This is also an example of how you may wrap your own similar types. + +// Changelog: +// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string + +// See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki: +// https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness + +#include "imgui.h" +#include "imgui_stdlib.h" + +struct InputTextCallback_UserData +{ + std::string* Str; + ImGuiInputTextCallback ChainCallback; + void* ChainCallbackUserData; +}; + +static int InputTextCallback(ImGuiInputTextCallbackData* data) +{ + InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData; + if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) + { + // Resize string callback + // If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want. + std::string* str = user_data->Str; + IM_ASSERT(data->Buf == str->c_str()); + str->resize(data->BufTextLen); + data->Buf = (char*)str->c_str(); + } + else if (user_data->ChainCallback) + { + // Forward to user callback, if any + data->UserData = user_data->ChainCallbackUserData; + return user_data->ChainCallback(data); + } + return 0; +} + +bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); +} + +bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data); +} + +bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data) +{ + IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0); + flags |= ImGuiInputTextFlags_CallbackResize; + + InputTextCallback_UserData cb_user_data; + cb_user_data.Str = str; + cb_user_data.ChainCallback = callback; + cb_user_data.ChainCallbackUserData = user_data; + return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data); +} diff --git a/Externals/imgui/misc/cpp/imgui_stdlib.h b/Externals/imgui/misc/cpp/imgui_stdlib.h new file mode 100644 index 0000000000..835a808f2f --- /dev/null +++ b/Externals/imgui/misc/cpp/imgui_stdlib.h @@ -0,0 +1,21 @@ +// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.) +// This is also an example of how you may wrap your own similar types. + +// Changelog: +// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string + +// See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki: +// https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness + +#pragma once + +#include + +namespace ImGui +{ + // ImGui::InputText() with std::string + // Because text input needs dynamic resizing, we need to setup a callback to grow the capacity + IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr); + IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr); + IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr); +} From 317bb629b9f69736307c10ced12f559b0d023e87 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Tue, 13 Jun 2023 11:19:49 -0700 Subject: [PATCH 60/99] GekkoDisassembler: Remove unread variable m_flags Writes to m_flags are pointless as it's never read. --- Source/Core/Common/GekkoDisassembler.cpp | 31 ------------------------ Source/Core/Common/GekkoDisassembler.h | 1 - 2 files changed, 32 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index 59ea32f170..6ccb5cac6d 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -153,7 +153,6 @@ u32* GekkoDisassembler::m_instr = nullptr; u32* GekkoDisassembler::m_iaddr = nullptr; std::string GekkoDisassembler::m_opcode; std::string GekkoDisassembler::m_operands; -unsigned char GekkoDisassembler::m_flags = PPCF_ILLEGAL; static u32 HelperRotateMask(int r, int mb, int me) { @@ -368,8 +367,6 @@ void GekkoDisassembler::ill(u32 in) m_opcode = "(ill)"; m_operands = fmt::format("{:08x}", in); } - - m_flags |= PPCF_ILLEGAL; } // Generate immediate instruction operand. @@ -387,10 +384,6 @@ std::string GekkoDisassembler::imm(u32 in, int uimm, int type, bool hex) if (i > 0x7fff) i -= 0x10000; } - else - { - m_flags |= PPCF_UNSIGNED; - } switch (type) { @@ -454,7 +447,6 @@ void GekkoDisassembler::trapi(u32 in, unsigned char dmode) { const char* cnd = trap_condition[PPCGETD(in)]; - m_flags |= dmode; if (cnd != nullptr) { m_opcode = fmt::format("t{}{}", dmode ? 'd' : 'w', cnd); @@ -473,9 +465,6 @@ void GekkoDisassembler::cmpi(u32 in, int uimm) if (i < 2) { - if (i != 0) - m_flags |= PPCF_64; - m_opcode = fmt::format("{}i", cmpname[uimm * 2 + i]); i = (int)PPCGETCRD(in); @@ -638,7 +627,6 @@ void GekkoDisassembler::nooper(u32 in, std::string_view name, unsigned char dmod } else { - m_flags |= dmode; m_opcode = name; } } @@ -669,7 +657,6 @@ void GekkoDisassembler::rld(u32 in, std::string_view name, int i) int bsh = i ? (int)PPCGETB(in) : (int)(((in & 2) << 4) + PPCGETB(in)); int m = (int)(in & 0x7e0) >> 5; - m_flags |= PPCF_64; m_opcode = fmt::format("rld{}{}", name, (in & 1) ? "." : ""); m_operands = fmt::format("{}, {}, {}{}, {}", regnames[a], regnames[s], regsel[i], bsh, m); } @@ -680,9 +667,6 @@ void GekkoDisassembler::cmp(u32 in) if (i < 2) { - if (i != 0) - m_flags |= PPCF_64; - m_opcode = cmpname[((in & PPCIDX2MASK) ? 2 : 0) + i]; i = (int)PPCGETCRD(in); @@ -704,7 +688,6 @@ void GekkoDisassembler::trap(u32 in, unsigned char dmode) if (cnd != nullptr) { - m_flags |= dmode; m_opcode = fmt::format("t{}{}", dmode ? 'd' : 'w', cnd); m_operands = ra_rb(in); } @@ -714,7 +697,6 @@ void GekkoDisassembler::trap(u32 in, unsigned char dmode) { if (dmode) { - m_flags |= dmode; m_opcode = "td"; m_operands = "31,0,0"; } @@ -740,8 +722,6 @@ void GekkoDisassembler::dab(u32 in, std::string_view name, int mask, int smode, } else { - m_flags |= dmode; - // rA,rS,rB if (smode) in = swapda(in); @@ -762,8 +742,6 @@ void GekkoDisassembler::rrn(u32 in, std::string_view name, int smode, int chkoe, } else { - m_flags |= dmode; - // rA,rS,NB if (smode) in = swapda(in); @@ -806,7 +784,6 @@ void GekkoDisassembler::msr(u32 in, int smode) } else { - m_flags |= PPCF_SUPER; m_opcode = fmt::format("m{}sr", smode ? 't' : 'f'); if (smode) @@ -828,9 +805,6 @@ void GekkoDisassembler::mspr(u32 in, int smode) } else { - if (spr != 1 && spr != 8 && spr != 9) - m_flags |= PPCF_SUPER; - const char* x; switch (spr) { @@ -893,7 +867,6 @@ void GekkoDisassembler::mtb(u32 in) break; default: - m_flags |= PPCF_SUPER; m_operands += fmt::format(",{}", tbr); break; } @@ -908,7 +881,6 @@ void GekkoDisassembler::sradi(u32 in) int a = (int)PPCGETA(in); int bsh = (int)(((in & 2) << 4) + PPCGETB(in)); - m_flags |= PPCF_64; m_opcode = fmt::format("sradi{}", (in & 1) ? "." : ""); m_operands = fmt::format("{}, {}, {}", regnames[a], regnames[s], bsh); } @@ -919,7 +891,6 @@ void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg, unsigned c int a = (int)PPCGETA(in); int d = (u32)(in & 0xffff); - m_flags |= dmode; m_opcode = name; if (reg == 'r') @@ -937,7 +908,6 @@ void GekkoDisassembler::fdabc(u32 in, std::string_view name, int mask, unsigned { int err = 0; - m_flags |= dmode; m_opcode = fmt::format("f{}{}", name, rcsel[in & 1]); m_operands += fmt::format("f{}", PPCGETD(in)); @@ -1259,7 +1229,6 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) m_opcode.clear(); m_operands.clear(); - m_flags = 0; switch (PPCGETIDX(in)) { diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index e18fd584f9..521216afe2 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -104,6 +104,5 @@ private: static u32* m_iaddr; // Instruction.address., usually the same as instr static std::string m_opcode; // Buffer for opcode, min. 10 chars. static std::string m_operands; // Operand buffer, min. 24 chars. - static unsigned char m_flags; // Additional flags }; } // namespace Common From a732647e5a7baaadef20e9490cca2427cf085df5 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 1 Jul 2023 16:51:47 -0700 Subject: [PATCH 61/99] GekkoDisassembler: Remove unused parameter dmode from nooper function With the removal of m_flags, dmode is no longer used in nooper. --- Source/Core/Common/GekkoDisassembler.cpp | 16 ++++++++-------- Source/Core/Common/GekkoDisassembler.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index 6ccb5cac6d..063ed89fda 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -619,7 +619,7 @@ void GekkoDisassembler::crop(u32 in, std::string_view n1, std::string_view n2) } } -void GekkoDisassembler::nooper(u32 in, std::string_view name, unsigned char dmode) +void GekkoDisassembler::nooper(u32 in, std::string_view name) { if (in & (PPCDMASK | PPCAMASK | PPCBMASK | 1)) { @@ -1316,7 +1316,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 50: - nooper(in, "rfi", PPCF_SUPER); + nooper(in, "rfi"); break; case 129: @@ -1324,7 +1324,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 150: - nooper(in, "isync", 0); + nooper(in, "isync"); break; case 193: @@ -1747,7 +1747,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 370: - nooper(in, "tlbia", PPCF_SUPER); + nooper(in, "tlbia"); break; case 371: @@ -1832,7 +1832,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 498: - nooper(in, "slbia", PPCF_SUPER | PPCF_64); + nooper(in, "slbia"); break; case 512: @@ -1868,7 +1868,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 566: - nooper(in, "tlbsync", PPCF_SUPER); + nooper(in, "tlbsync"); break; case 567: @@ -1884,7 +1884,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 598: - nooper(in, "sync", PPCF_SUPER); + nooper(in, "sync"); break; case 599: @@ -1947,7 +1947,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 854: - nooper(in, "eieio", PPCF_SUPER); + nooper(in, "eieio"); break; case 918: diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index 521216afe2..5b87a1ddd2 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -66,7 +66,7 @@ private: static void bli(u32 in); static void mcrf(u32 in, std::string_view suffix); static void crop(u32 in, std::string_view n1, std::string_view n2); - static void nooper(u32 in, std::string_view name, unsigned char dmode); + static void nooper(u32 in, std::string_view name); static void rlw(u32 in, std::string_view name, int i); static void ori(u32 in, std::string_view name); static void rld(u32 in, std::string_view name, int i); From a177c8bcb169a909f742dc53329a95becf2e1028 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 1 Jul 2023 18:04:27 -0700 Subject: [PATCH 62/99] GekkoDisassembler: Remove unused parameter dmode from dab function With the removal of m_flags, dmode is no longer used in dab. --- Source/Core/Common/GekkoDisassembler.cpp | 182 +++++++++++------------ Source/Core/Common/GekkoDisassembler.h | 3 +- 2 files changed, 92 insertions(+), 93 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index 063ed89fda..b572dc767e 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -714,7 +714,7 @@ void GekkoDisassembler::trap(u32 in, unsigned char dmode) // Standard instruction: xxxx rD,rA,rB void GekkoDisassembler::dab(u32 in, std::string_view name, int mask, int smode, int chkoe, - int chkrc, unsigned char dmode) + int chkrc) { if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc)) { @@ -1180,7 +1180,7 @@ void GekkoDisassembler::ps(u32 inst) if (inst & PPCDMASK) ill(inst); else - dab(inst, "dcbz_l", 3, 0, 0, 0, 0); + dab(inst, "dcbz_l", 3, 0, 0, 0); return; } @@ -1444,89 +1444,89 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) case 8: case (PPCOE >> 1) + 8: - dab(swapab(in), "subc", 7, 0, 1, -1, 0); + dab(swapab(in), "subc", 7, 0, 1, -1); break; case 9: - dab(in, "mulhdu", 7, 0, 0, -1, PPCF_64); + dab(in, "mulhdu", 7, 0, 0, -1); break; case 10: case (PPCOE >> 1) + 10: - dab(in, "addc", 7, 0, 1, -1, 0); + dab(in, "addc", 7, 0, 1, -1); break; case 11: - dab(in, "mulhwu", 7, 0, 0, -1, 0); + dab(in, "mulhwu", 7, 0, 0, -1); break; case 19: if (in & (PPCAMASK | PPCBMASK)) ill(in); else - dab(in, "mfcr", 4, 0, 0, 0, 0); + dab(in, "mfcr", 4, 0, 0, 0); break; case 20: - dab(in, "lwarx", 7, 0, 0, 0, 0); + dab(in, "lwarx", 7, 0, 0, 0); break; case 21: - dab(in, "ldx", 7, 0, 0, 0, PPCF_64); + dab(in, "ldx", 7, 0, 0, 0); break; case 23: - dab(in, "lwzx", 7, 0, 0, 0, 0); + dab(in, "lwzx", 7, 0, 0, 0); break; case 24: - dab(in, "slw", 7, 1, 0, -1, 0); + dab(in, "slw", 7, 1, 0, -1); break; case 26: if (in & PPCBMASK) ill(in); else - dab(in, "cntlzw", 6, 1, 0, -1, 0); + dab(in, "cntlzw", 6, 1, 0, -1); break; case 27: - dab(in, "sld", 7, 1, 0, -1, PPCF_64); + dab(in, "sld", 7, 1, 0, -1); break; case 28: - dab(in, "and", 7, 1, 0, -1, 0); + dab(in, "and", 7, 1, 0, -1); break; case 40: case (PPCOE >> 1) + 40: - dab(swapab(in), "sub", 7, 0, 1, -1, 0); + dab(swapab(in), "sub", 7, 0, 1, -1); break; case 53: - dab(in, "ldux", 7, 0, 0, 0, PPCF_64); + dab(in, "ldux", 7, 0, 0, 0); break; case 54: if (in & PPCDMASK) ill(in); else - dab(in, "dcbst", 3, 0, 0, 0, 0); + dab(in, "dcbst", 3, 0, 0, 0); break; case 55: - dab(in, "lwzux", 7, 0, 0, 0, 0); + dab(in, "lwzux", 7, 0, 0, 0); break; case 58: if (in & PPCBMASK) ill(in); else - dab(in, "cntlzd", 6, 1, 0, -1, PPCF_64); + dab(in, "cntlzd", 6, 1, 0, -1); break; case 60: - dab(in, "andc", 7, 1, 0, -1, 0); + dab(in, "andc", 7, 1, 0, -1); break; case 68: @@ -1534,33 +1534,33 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 73: - dab(in, "mulhd", 7, 0, 0, -1, PPCF_64); + dab(in, "mulhd", 7, 0, 0, -1); break; case 75: - dab(in, "mulhw", 7, 0, 0, -1, 0); + dab(in, "mulhw", 7, 0, 0, -1); break; case 83: if (in & (PPCAMASK | PPCBMASK)) ill(in); else - dab(in, "mfmsr", 4, 0, 0, 0, PPCF_SUPER); + dab(in, "mfmsr", 4, 0, 0, 0); break; case 84: - dab(in, "ldarx", 7, 0, 0, 0, PPCF_64); + dab(in, "ldarx", 7, 0, 0, 0); break; case 86: if (in & PPCDMASK) ill(in); else - dab(in, "dcbf", 3, 0, 0, 0, 0); + dab(in, "dcbf", 3, 0, 0, 0); break; case 87: - dab(in, "lbzx", 7, 0, 0, 0, 0); + dab(in, "lbzx", 7, 0, 0, 0); break; case 104: @@ -1568,28 +1568,28 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCBMASK) ill(in); else - dab(in, "neg", 6, 0, 1, -1, 0); + dab(in, "neg", 6, 0, 1, -1); break; case 119: - dab(in, "lbzux", 7, 0, 0, 0, 0); + dab(in, "lbzux", 7, 0, 0, 0); break; case 124: if (PPCGETD(in) == PPCGETB(in)) - dab(in, "not", 6, 1, 0, -1, 0); + dab(in, "not", 6, 1, 0, -1); else - dab(in, "nor", 7, 1, 0, -1, 0); + dab(in, "nor", 7, 1, 0, -1); break; case 136: case (PPCOE >> 1) + 136: - dab(in, "subfe", 7, 0, 1, -1, 0); + dab(in, "subfe", 7, 0, 1, -1); break; case 138: case (PPCOE >> 1) + 138: - dab(in, "adde", 7, 0, 1, -1, 0); + dab(in, "adde", 7, 0, 1, -1); break; case 144: @@ -1600,27 +1600,27 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & (PPCAMASK | PPCBMASK)) ill(in); else - dab(in, "mtmsr", 4, 0, 0, 0, PPCF_SUPER); + dab(in, "mtmsr", 4, 0, 0, 0); break; case 149: - dab(in, "stdx", 7, 0, 0, 0, PPCF_64); + dab(in, "stdx", 7, 0, 0, 0); break; case 150: - dab(in, "stwcx.", 7, 0, 0, 1, 0); + dab(in, "stwcx.", 7, 0, 0, 1); break; case 151: - dab(in, "stwx", 7, 0, 0, 0, 0); + dab(in, "stwx", 7, 0, 0, 0); break; case 181: - dab(in, "stdux", 7, 0, 0, 0, PPCF_64); + dab(in, "stdux", 7, 0, 0, 0); break; case 183: - dab(in, "stwux", 7, 0, 0, 0, 0); + dab(in, "stwux", 7, 0, 0, 0); break; case 200: @@ -1628,7 +1628,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCBMASK) ill(in); else - dab(in, "subfze", 6, 0, 1, -1, 0); + dab(in, "subfze", 6, 0, 1, -1); break; case 202: @@ -1636,7 +1636,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCBMASK) ill(in); else - dab(in, "addze", 6, 0, 1, -1, 0); + dab(in, "addze", 6, 0, 1, -1); break; case 210: @@ -1644,11 +1644,11 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 214: - dab(in, "stdcx.", 7, 0, 0, 1, PPCF_64); + dab(in, "stdcx.", 7, 0, 0, 1); break; case 215: - dab(in, "stbx", 7, 0, 0, 0, 0); + dab(in, "stbx", 7, 0, 0, 0); break; case 232: @@ -1656,12 +1656,12 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCBMASK) ill(in); else - dab(in, "subfme", 6, 0, 1, -1, 0); + dab(in, "subfme", 6, 0, 1, -1); break; case 233: case (PPCOE >> 1) + 233: - dab(in, "mulld", 7, 0, 1, -1, PPCF_64); + dab(in, "mulld", 7, 0, 1, -1); break; case 234: @@ -1669,69 +1669,69 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCBMASK) ill(in); else - dab(in, "addme", 6, 0, 1, -1, 0); + dab(in, "addme", 6, 0, 1, -1); break; case 235: case (PPCOE >> 1) + 235: - dab(in, "mullw", 7, 0, 1, -1, 0); + dab(in, "mullw", 7, 0, 1, -1); break; case 242: if (in & PPCAMASK) ill(in); else - dab(in, "mtsrin", 5, 0, 0, 0, PPCF_SUPER); + dab(in, "mtsrin", 5, 0, 0, 0); break; case 246: if (in & PPCDMASK) ill(in); else - dab(in, "dcbtst", 3, 0, 0, 0, 0); + dab(in, "dcbtst", 3, 0, 0, 0); break; case 247: - dab(in, "stbux", 7, 0, 0, 0, 0); + dab(in, "stbux", 7, 0, 0, 0); break; case 266: case (PPCOE >> 1) + 266: - dab(in, "add", 7, 0, 1, -1, 0); + dab(in, "add", 7, 0, 1, -1); break; case 278: if (in & PPCDMASK) ill(in); else - dab(in, "dcbt", 3, 0, 0, 0, 0); + dab(in, "dcbt", 3, 0, 0, 0); break; case 279: - dab(in, "lhzx", 7, 0, 0, 0, 0); + dab(in, "lhzx", 7, 0, 0, 0); break; case 284: - dab(in, "eqv", 7, 1, 0, -1, 0); + dab(in, "eqv", 7, 1, 0, -1); break; case 306: if (in & (PPCDMASK | PPCAMASK)) ill(in); else - dab(in, "tlbie", 1, 0, 0, 0, PPCF_SUPER); + dab(in, "tlbie", 1, 0, 0, 0); break; case 310: - dab(in, "eciwx", 7, 0, 0, 0, 0); + dab(in, "eciwx", 7, 0, 0, 0); break; case 311: - dab(in, "lhzux", 7, 0, 0, 0, 0); + dab(in, "lhzux", 7, 0, 0, 0); break; case 316: - dab(in, "xor", 7, 1, 0, -1, 0); + dab(in, "xor", 7, 1, 0, -1); break; case 339: @@ -1739,11 +1739,11 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 341: - dab(in, "lwax", 7, 0, 0, 0, PPCF_64); + dab(in, "lwax", 7, 0, 0, 0); break; case 343: - dab(in, "lhax", 7, 0, 0, 0, 0); + dab(in, "lhax", 7, 0, 0, 0); break; case 370: @@ -1755,19 +1755,19 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 373: - dab(in, "lwaux", 7, 0, 0, 0, PPCF_64); + dab(in, "lwaux", 7, 0, 0, 0); break; case 375: - dab(in, "lhaux", 7, 0, 0, 0, 0); + dab(in, "lhaux", 7, 0, 0, 0); break; case 407: - dab(in, "sthx", 7, 0, 0, 0, 0); + dab(in, "sthx", 7, 0, 0, 0); break; case 412: - dab(in, "orc", 7, 1, 0, -1, 0); + dab(in, "orc", 7, 1, 0, -1); break; case 413: @@ -1778,32 +1778,32 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & (PPCDMASK | PPCAMASK)) ill(in); else - dab(in, "slbie", 1, 0, 0, 0, PPCF_SUPER | PPCF_64); + dab(in, "slbie", 1, 0, 0, 0); break; case 438: - dab(in, "ecowx", 7, 0, 0, 0, 0); + dab(in, "ecowx", 7, 0, 0, 0); break; case 439: - dab(in, "sthux", 7, 0, 0, 0, 0); + dab(in, "sthux", 7, 0, 0, 0); break; case 444: if (PPCGETD(in) == PPCGETB(in)) - dab(in, "mr", 6, 1, 0, -1, 0); + dab(in, "mr", 6, 1, 0, -1); else - dab(in, "or", 7, 1, 0, -1, 0); + dab(in, "or", 7, 1, 0, -1); break; case 457: case (PPCOE >> 1) + 457: - dab(in, "divdu", 7, 0, 1, -1, PPCF_64); + dab(in, "divdu", 7, 0, 1, -1); break; case 459: case (PPCOE >> 1) + 459: - dab(in, "divwu", 7, 0, 1, -1, 0); + dab(in, "divwu", 7, 0, 1, -1); break; case 467: @@ -1814,21 +1814,21 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCDMASK) ill(in); else - dab(in, "dcbi", 3, 0, 0, 0, 0); + dab(in, "dcbi", 3, 0, 0, 0); break; case 476: - dab(in, "nand", 7, 1, 0, -1, 0); + dab(in, "nand", 7, 1, 0, -1); break; case 489: case (PPCOE >> 1) + 489: - dab(in, "divd", 7, 0, 1, -1, PPCF_64); + dab(in, "divd", 7, 0, 1, -1); break; case 491: case (PPCOE >> 1) + 491: - dab(in, "divw", 7, 0, 1, -1, 0); + dab(in, "divw", 7, 0, 1, -1); break; case 498: @@ -1848,11 +1848,11 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 533: - dab(in, "lswx", 7, 0, 0, 0, 0); + dab(in, "lswx", 7, 0, 0, 0); break; case 534: - dab(in, "lwbrx", 7, 0, 0, 0, 0); + dab(in, "lwbrx", 7, 0, 0, 0); break; case 535: @@ -1860,11 +1860,11 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 536: - dab(in, "srw", 7, 1, 0, -1, 0); + dab(in, "srw", 7, 1, 0, -1); break; case 539: - dab(in, "srd", 7, 1, 0, -1, PPCF_64); + dab(in, "srd", 7, 1, 0, -1); break; case 566: @@ -1899,15 +1899,15 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCAMASK) ill(in); else - dab(in, "mfsrin", 5, 0, 0, 0, PPCF_SUPER); + dab(in, "mfsrin", 5, 0, 0, 0); break; case 661: - dab(in, "stswx", 7, 0, 0, 0, 0); + dab(in, "stswx", 7, 0, 0, 0); break; case 662: - dab(in, "stwbrx", 7, 0, 0, 0, 0); + dab(in, "stwbrx", 7, 0, 0, 0); break; case 663: @@ -1931,15 +1931,15 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 790: - dab(in, "lhbrx", 7, 0, 0, 0, 0); + dab(in, "lhbrx", 7, 0, 0, 0); break; case 792: - dab(in, "sraw", 7, 1, 0, -1, 0); + dab(in, "sraw", 7, 1, 0, -1); break; case 794: - dab(in, "srad", 7, 1, 0, -1, PPCF_64); + dab(in, "srad", 7, 1, 0, -1); break; case 824: @@ -1951,28 +1951,28 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 918: - dab(in, "sthbrx", 7, 0, 0, 0, 0); + dab(in, "sthbrx", 7, 0, 0, 0); break; case 922: if (in & PPCBMASK) ill(in); else - dab(in, "extsh", 6, 1, 0, -1, 0); + dab(in, "extsh", 6, 1, 0, -1); break; case 954: if (in & PPCBMASK) ill(in); else - dab(in, "extsb", 6, 1, 0, -1, 0); + dab(in, "extsb", 6, 1, 0, -1); break; case 982: if (in & PPCDMASK) ill(in); else - dab(in, "icbi", 3, 0, 0, 0, 0); + dab(in, "icbi", 3, 0, 0, 0); break; case 983: @@ -1983,14 +1983,14 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & PPCBMASK) ill(in); else - dab(in, "extsw", 6, 1, 0, -1, PPCF_64); + dab(in, "extsw", 6, 1, 0, -1); break; case 1014: if (in & PPCDMASK) ill(in); else - dab(in, "dcbz", 3, 0, 0, 0, 0); + dab(in, "dcbz", 3, 0, 0, 0); break; default: @@ -2233,7 +2233,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) if (in & (PPCAMASK | PPCBMASK)) ill(in); else - dab(in, "mffs", 4, 0, 0, -1, 0); + dab(in, "mffs", 4, 0, 0, -1); break; case 711: diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index 5b87a1ddd2..8f842b0167 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -72,8 +72,7 @@ private: static void rld(u32 in, std::string_view name, int i); static void cmp(u32 in); static void trap(u32 in, unsigned char dmode); - static void dab(u32 in, std::string_view name, int mask, int smode, int chkoe, int chkrc, - unsigned char dmode); + static void dab(u32 in, std::string_view name, int mask, int smode, int chkoe, int chkrc); static void rrn(u32 in, std::string_view name, int smode, int chkoe, int chkrc, unsigned char dmode); static void mtcr(u32 in); From b3c5021fc47dc25bf7477df89ce28cf7f217572d Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 1 Jul 2023 18:06:08 -0700 Subject: [PATCH 63/99] GekkoDisassembler: Remove unused parameter dmode from rrn function With the removal of m_flags, dmode is no longer used in rrn. --- Source/Core/Common/GekkoDisassembler.cpp | 9 ++++----- Source/Core/Common/GekkoDisassembler.h | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index b572dc767e..f068ea9628 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -733,8 +733,7 @@ void GekkoDisassembler::dab(u32 in, std::string_view name, int mask, int smode, } // Last operand is no register: xxxx rD,rA,NB -void GekkoDisassembler::rrn(u32 in, std::string_view name, int smode, int chkoe, int chkrc, - unsigned char dmode) +void GekkoDisassembler::rrn(u32 in, std::string_view name, int smode, int chkoe, int chkrc) { if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc)) { @@ -1880,7 +1879,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 597: - rrn(in, "lswi", 0, 0, 0, 0); + rrn(in, "lswi", 0, 0, 0); break; case 598: @@ -1919,7 +1918,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 725: - rrn(in, "stswi", 0, 0, 0, 0); + rrn(in, "stswi", 0, 0, 0); break; case 727: @@ -1943,7 +1942,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 824: - rrn(in, "srawi", 1, 0, -1, 0); + rrn(in, "srawi", 1, 0, -1); break; case 854: diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index 8f842b0167..9a276a4d7e 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -73,8 +73,7 @@ private: static void cmp(u32 in); static void trap(u32 in, unsigned char dmode); static void dab(u32 in, std::string_view name, int mask, int smode, int chkoe, int chkrc); - static void rrn(u32 in, std::string_view name, int smode, int chkoe, int chkrc, - unsigned char dmode); + static void rrn(u32 in, std::string_view name, int smode, int chkoe, int chkrc); static void mtcr(u32 in); static void msr(u32 in, int smode); static void mspr(u32 in, int smode); From 33dc2a9e6a63723485dec6ab2b3af6c393e5b597 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 1 Jul 2023 18:07:41 -0700 Subject: [PATCH 64/99] GekkoDisassembler: Remove unused parameter dmode from ldst function With the removal of m_flags, dmode is no longer used in ldst. --- Source/Core/Common/GekkoDisassembler.cpp | 16 ++++++++-------- Source/Core/Common/GekkoDisassembler.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index f068ea9628..59db7ca2e5 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -884,7 +884,7 @@ void GekkoDisassembler::sradi(u32 in) m_operands = fmt::format("{}, {}, {}", regnames[a], regnames[s], bsh); } -void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg, unsigned char dmode) +void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg) { int s = (int)PPCGETD(in); int a = (int)PPCGETA(in); @@ -2014,7 +2014,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) case 45: case 46: case 47: - ldst(in, ldstnames[PPCGETIDX(in) - 32], 'r', 0); + ldst(in, ldstnames[PPCGETIDX(in) - 32], 'r'); break; case 48: @@ -2025,20 +2025,20 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) case 53: case 54: case 55: - ldst(in, ldstnames[PPCGETIDX(in) - 32], 'f', 0); + ldst(in, ldstnames[PPCGETIDX(in) - 32], 'f'); break; case 58: switch (in & 3) { case 0: - ldst(in & ~3, "ld", 'r', PPCF_64); + ldst(in & ~3, "ld", 'r'); break; case 1: - ldst(in & ~3, "ldu", 'r', PPCF_64); + ldst(in & ~3, "ldu", 'r'); break; case 2: - ldst(in & ~3, "lwa", 'r', PPCF_64); + ldst(in & ~3, "lwa", 'r'); break; default: ill(in); @@ -2099,10 +2099,10 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) switch (in & 3) { case 0: - ldst(in & ~3, "std", 'r', PPCF_64); + ldst(in & ~3, "std", 'r'); break; case 1: - ldst(in & ~3, "stdu", 'r', PPCF_64); + ldst(in & ~3, "stdu", 'r'); break; default: ill(in); diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index 9a276a4d7e..bbc5c6f8e0 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -79,7 +79,7 @@ private: static void mspr(u32 in, int smode); static void mtb(u32 in); static void sradi(u32 in); - static void ldst(u32 in, std::string_view name, char reg, unsigned char dmode); + static void ldst(u32 in, std::string_view name, char reg); static void fdabc(u32 in, std::string_view name, int mask, unsigned char dmode); static void fmr(u32 in); static void fdab(u32 in, std::string_view name); From 3c6ea825c2fdef5685e35864f090c74a7006cf69 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 1 Jul 2023 18:08:22 -0700 Subject: [PATCH 65/99] GekkoDisassembler: Remove unused parameter dmode from fdabc function With the removal of m_flags, dmode is no longer used in fdabc. --- Source/Core/Common/GekkoDisassembler.cpp | 62 ++++++++++++------------ Source/Core/Common/GekkoDisassembler.h | 2 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Source/Core/Common/GekkoDisassembler.cpp b/Source/Core/Common/GekkoDisassembler.cpp index 59db7ca2e5..46905c8773 100644 --- a/Source/Core/Common/GekkoDisassembler.cpp +++ b/Source/Core/Common/GekkoDisassembler.cpp @@ -903,7 +903,7 @@ void GekkoDisassembler::ldst(u32 in, std::string_view name, char reg) } // Standard floating point instruction: xxxx fD,fA,fC,fB -void GekkoDisassembler::fdabc(u32 in, std::string_view name, int mask, unsigned char dmode) +void GekkoDisassembler::fdabc(u32 in, std::string_view name, int mask) { int err = 0; @@ -2050,43 +2050,43 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) switch (in & 0x3e) { case 36: - fdabc(in, "divs", 5, 0); + fdabc(in, "divs", 5); break; case 40: - fdabc(in, "subs", 5, 0); + fdabc(in, "subs", 5); break; case 42: - fdabc(in, "adds", 5, 0); + fdabc(in, "adds", 5); break; case 44: - fdabc(in, "sqrts", 1, 0); + fdabc(in, "sqrts", 1); break; case 48: - fdabc(in, "res", 1, 0); + fdabc(in, "res", 1); break; case 50: - fdabc(in, "muls", 6, 0); + fdabc(in, "muls", 6); break; case 56: - fdabc(in, "msubs", 7, 0); + fdabc(in, "msubs", 7); break; case 58: - fdabc(in, "madds", 7, 0); + fdabc(in, "madds", 7); break; case 60: - fdabc(in, "nmsubs", 7, 0); + fdabc(in, "nmsubs", 7); break; case 62: - fdabc(in, "nmadds", 7, 0); + fdabc(in, "nmadds", 7); break; default: @@ -2116,47 +2116,47 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) switch (in & 0x1e) { case 4: - fdabc(in, "div", 5, 0); + fdabc(in, "div", 5); break; case 8: - fdabc(in, "sub", 5, 0); + fdabc(in, "sub", 5); break; case 10: - fdabc(in, "add", 5, 0); + fdabc(in, "add", 5); break; case 12: - fdabc(in, "sqrt", 1, 0); + fdabc(in, "sqrt", 1); break; case 14: - fdabc(in, "sel", 7, 0); + fdabc(in, "sel", 7); break; case 18: - fdabc(in, "mul", 6, 0); + fdabc(in, "mul", 6); break; case 20: - fdabc(in, "rsqrte", 1, 0); + fdabc(in, "rsqrte", 1); break; case 24: - fdabc(in, "msub", 7, 0); + fdabc(in, "msub", 7); break; case 26: - fdabc(in, "madd", 7, 0); + fdabc(in, "madd", 7); break; case 28: - fdabc(in, "nmsub", 7, 0); + fdabc(in, "nmsub", 7); break; case 30: - fdabc(in, "nmadd", 7, 0); + fdabc(in, "nmadd", 7); break; default: @@ -2173,15 +2173,15 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 12: - fdabc(in, "rsp", 1, 0); + fdabc(in, "rsp", 1); break; case 14: - fdabc(in, "ctiw", 1, 0); + fdabc(in, "ctiw", 1); break; case 15: - fdabc(in, "ctiwz", 1, 0); + fdabc(in, "ctiwz", 1); break; case 32: @@ -2193,7 +2193,7 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 40: - fdabc(in, "neg", 9, 0); + fdabc(in, "neg", 9); break; case 64: @@ -2221,11 +2221,11 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 136: - fdabc(in, "nabs", 9, 0); + fdabc(in, "nabs", 9); break; case 264: - fdabc(in, "abs", 9, 0); + fdabc(in, "abs", 9); break; case 583: @@ -2248,15 +2248,15 @@ u32* GekkoDisassembler::DoDisassembly(bool big_endian) break; case 814: - fdabc(in, "fctid", 9, PPCF_64); + fdabc(in, "fctid", 9); break; case 815: - fdabc(in, "fctidz", 9, PPCF_64); + fdabc(in, "fctidz", 9); break; case 846: - fdabc(in, "fcfid", 9, PPCF_64); + fdabc(in, "fcfid", 9); break; default: diff --git a/Source/Core/Common/GekkoDisassembler.h b/Source/Core/Common/GekkoDisassembler.h index bbc5c6f8e0..a40323abf6 100644 --- a/Source/Core/Common/GekkoDisassembler.h +++ b/Source/Core/Common/GekkoDisassembler.h @@ -80,7 +80,7 @@ private: static void mtb(u32 in); static void sradi(u32 in); static void ldst(u32 in, std::string_view name, char reg); - static void fdabc(u32 in, std::string_view name, int mask, unsigned char dmode); + static void fdabc(u32 in, std::string_view name, int mask); static void fmr(u32 in); static void fdab(u32 in, std::string_view name); static void fcmp(u32 in, char c); From cd923718c329118a76e8bcf9a90b959553fbf555 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 28 Jul 2023 08:10:01 +0200 Subject: [PATCH 66/99] CommonFuncs: Add GetWin32ErrorString(). --- Source/Core/Common/CommonFuncs.cpp | 8 +++++++- Source/Core/Common/CommonFuncs.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Source/Core/Common/CommonFuncs.cpp b/Source/Core/Common/CommonFuncs.cpp index a1e93455a2..0a546428b7 100644 --- a/Source/Core/Common/CommonFuncs.cpp +++ b/Source/Core/Common/CommonFuncs.cpp @@ -52,10 +52,16 @@ std::string LastStrerrorString() // Wrapper function to get GetLastError() string. // This function might change the error code. std::string GetLastErrorString() +{ + return GetWin32ErrorString(GetLastError()); +} + +// Like GetLastErrorString() but if you have already queried the error code. +std::string GetWin32ErrorString(DWORD error_code) { char error_message[BUFFER_SIZE]; - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error_message, BUFFER_SIZE, nullptr); return std::string(error_message); } diff --git a/Source/Core/Common/CommonFuncs.h b/Source/Core/Common/CommonFuncs.h index 4dac076c04..c8e43edce9 100644 --- a/Source/Core/Common/CommonFuncs.h +++ b/Source/Core/Common/CommonFuncs.h @@ -53,6 +53,9 @@ std::string LastStrerrorString(); // This function might change the error code. std::string GetLastErrorString(); +// Like GetLastErrorString() but if you have already queried the error code. +std::string GetWin32ErrorString(unsigned long error_code); + // Obtains a full path to the specified module. std::optional GetModuleName(void* hInstance); #endif From fb9274c359d414f254da42f96323be64a5358217 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 28 Jul 2023 08:10:54 +0200 Subject: [PATCH 67/99] WiimoteReal/IOWin: Use correct error type in the default case. --- Source/Core/Core/HW/WiimoteReal/IOWin.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp index be75a204cf..f931bb10a3 100644 --- a/Source/Core/Core/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/HW/WiimoteReal/IOWin.cpp @@ -298,17 +298,8 @@ int IOWritePerWriteFile(HANDLE& dev_handle, OVERLAPPED& hid_overlap_write, // Pending is no error! break; default: - if (FAILED(error)) - { - WARN_LOG_FMT(WIIMOTE, "IOWrite[WWM_WRITE_FILE]: Error on WriteFile: {}", - Common::HRWrap(error)); - } - else - { - WARN_LOG_FMT(WIIMOTE, - "IOWrite[WWM_WRITE_FILE]: Unexpected error code from WriteFile: 0x{:08x}", - error); - } + WARN_LOG_FMT(WIIMOTE, "IOWrite[WWM_WRITE_FILE]: Error on WriteFile: {}", + Common::GetWin32ErrorString(error)); CancelIo(dev_handle); return 0; } From b5b8282ca922cf960febbdf9c5aeaa2f2f35ec4d Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 28 Jul 2023 18:45:07 +0200 Subject: [PATCH 68/99] Android: Fix SettingsActivity.onActivityResult `or` is the bitwise or operator. Fixes file pickers in the settings not saving your choice. --- .../features/settings/ui/SettingsActivity.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.kt index cae9f4e840..ccdbbe3339 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.kt @@ -181,11 +181,11 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { fragment!!.adapter!!.onFilePickerConfirmation(path!!) } - MainPresenter.REQUEST_GAME_FILE - or MainPresenter.REQUEST_SD_FILE - or MainPresenter.REQUEST_WAD_FILE - or MainPresenter.REQUEST_WII_SAVE_FILE - or MainPresenter.REQUEST_NAND_BIN_FILE -> { + MainPresenter.REQUEST_GAME_FILE, + MainPresenter.REQUEST_SD_FILE, + MainPresenter.REQUEST_WAD_FILE, + MainPresenter.REQUEST_WII_SAVE_FILE, + MainPresenter.REQUEST_NAND_BIN_FILE -> { val uri = canonicalizeIfPossible(result!!.data!!) val validExtensions: Set = if (requestCode == MainPresenter.REQUEST_GAME_FILE) FileBrowserHelper.GAME_EXTENSIONS else FileBrowserHelper.RAW_EXTENSION From dca7c67105c89b003910da70e80ed7b54325da97 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 29 Jul 2023 00:27:07 -0500 Subject: [PATCH 69/99] VideoCommon: update NetplayChatUI's chat message input to use a hidden label. This avoids an error thrown by imgui --- Source/Core/VideoCommon/NetPlayChatUI.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/NetPlayChatUI.cpp b/Source/Core/VideoCommon/NetPlayChatUI.cpp index c9db29af64..c1217d041d 100644 --- a/Source/Core/VideoCommon/NetPlayChatUI.cpp +++ b/Source/Core/VideoCommon/NetPlayChatUI.cpp @@ -57,7 +57,7 @@ void NetPlayChatUI::Display() ImGui::PushItemWidth(-50.0f * scale); - if (ImGui::InputText("", m_message_buf, IM_ARRAYSIZE(m_message_buf), + if (ImGui::InputText("##NetplayMessageBuffer", m_message_buf, IM_ARRAYSIZE(m_message_buf), ImGuiInputTextFlags_EnterReturnsTrue)) { SendMessage(); From f2b8baa82cf78f3b3bb5a58995dd31e235ca31de Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 1 Aug 2023 21:06:37 +0200 Subject: [PATCH 70/99] Translation resources sync with Transifex --- Languages/po/ar.po | 624 +++++++++++---------- Languages/po/ca.po | 624 +++++++++++---------- Languages/po/cs.po | 624 +++++++++++---------- Languages/po/da.po | 624 +++++++++++---------- Languages/po/de.po | 624 +++++++++++---------- Languages/po/dolphin-emu.pot | 624 +++++++++++---------- Languages/po/el.po | 624 +++++++++++---------- Languages/po/en.po | 624 +++++++++++---------- Languages/po/es.po | 678 ++++++++++++----------- Languages/po/fa.po | 624 +++++++++++---------- Languages/po/fi.po | 624 +++++++++++---------- Languages/po/fr.po | 680 ++++++++++++----------- Languages/po/hr.po | 624 +++++++++++---------- Languages/po/hu.po | 624 +++++++++++---------- Languages/po/it.po | 675 ++++++++++++----------- Languages/po/ja.po | 624 +++++++++++---------- Languages/po/ko.po | 624 +++++++++++---------- Languages/po/ms.po | 624 +++++++++++---------- Languages/po/nb.po | 624 +++++++++++---------- Languages/po/nl.po | 650 +++++++++++----------- Languages/po/pl.po | 624 +++++++++++---------- Languages/po/pt.po | 624 +++++++++++---------- Languages/po/pt_BR.po | 680 ++++++++++++----------- Languages/po/ro.po | 624 +++++++++++---------- Languages/po/ru.po | 624 +++++++++++---------- Languages/po/sr.po | 624 +++++++++++---------- Languages/po/sv.po | 1001 +++++++++++++++++++--------------- Languages/po/tr.po | 624 +++++++++++---------- Languages/po/zh_CN.po | 670 ++++++++++++----------- Languages/po/zh_TW.po | 624 +++++++++++---------- 30 files changed, 10117 insertions(+), 9269 deletions(-) diff --git a/Languages/po/ar.po b/Languages/po/ar.po index 7ff3cab9c6..e79a698176 100644 --- a/Languages/po/ar.po +++ b/Languages/po/ar.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: mansoor , 2013,2015-2023\n" "Language-Team: Arabic (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -326,7 +326,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&حول" @@ -347,7 +347,7 @@ msgstr "&إضافة وظيفة" msgid "&Add..." msgstr "&إضافة" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&إعدادات الصوت" @@ -355,7 +355,7 @@ msgstr "&إعدادات الصوت" msgid "&Auto Update:" msgstr "&التحديث التلقائي" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&بدء تلقائي" @@ -363,11 +363,11 @@ msgstr "&بدء تلقائي" msgid "&Borderless Window" msgstr "&نافذة بلا حدود" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&نقاط التوقف" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&تتبع اخطاء المحاكي" @@ -375,15 +375,15 @@ msgstr "&تتبع اخطاء المحاكي" msgid "&Cancel" msgstr "&إلغاء" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&مدير الأسرار" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&التحقق من التحديثات" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&مسح الرموز" @@ -391,7 +391,7 @@ msgstr "&مسح الرموز" msgid "&Clone..." msgstr "&استنساخ" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&رمز" @@ -399,7 +399,7 @@ msgstr "&رمز" msgid "&Connected" msgstr "&متصل" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&إعدادات وحدة التحكم" @@ -438,11 +438,11 @@ msgstr "&تحرير الرمز" msgid "&Edit..." msgstr "&تحرير" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&إخراج القرص" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&محاكاة" @@ -462,27 +462,27 @@ msgstr "&تصدير الحالة" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&ملف" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&الخط" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&الإطار المسبق" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "&إعدادات المظهر الحر" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&إنشاء رموز من" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub مستودع " @@ -490,15 +490,15 @@ msgstr "&GitHub مستودع " msgid "&Go to start of function" msgstr "&انتقل إلى بدء الوظيفة" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&إعدادات الرسومات" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&مساعدة" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&إعدادات مفاتيح الاختصار" @@ -518,7 +518,7 @@ msgstr "&استيراد الحالة" msgid "&Import..." msgstr "&استيراد" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -530,7 +530,7 @@ msgstr "&blr إدراج" msgid "&Interframe Blending" msgstr "&مزج الإطارات" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -538,11 +538,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&اللغة" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&تحميل الحالة" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Load Symbol Map" @@ -556,15 +556,15 @@ msgstr "&تحميل الملف إلى العنوان الحالي" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&تأمين المصغرات في القائمة" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&الذاكرة" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&فيلم" @@ -572,7 +572,7 @@ msgstr "&فيلم" msgid "&Mute" msgstr "&صامت" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&شبكة الاتصال" @@ -581,23 +581,23 @@ msgid "&No" msgstr "&لا" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&فتح" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&خيارات" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&HLE وظائف تصحيح" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&إيقاف مؤقت" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&تشغيل" @@ -605,7 +605,7 @@ msgstr "&تشغيل" msgid "&Properties" msgstr "&خصائص" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&وضع للقراءة فقط" @@ -613,7 +613,7 @@ msgstr "&وضع للقراءة فقط" msgid "&Refresh List" msgstr "&تحديث القائمة" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&تسجل" @@ -631,15 +631,15 @@ msgid "&Rename symbol" msgstr "&إعادة تسمية الرمز" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&إعادة" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&أدارة حزمة الموارد" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Save Symbol Map" @@ -647,7 +647,7 @@ msgstr "&Save Symbol Map" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -655,7 +655,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&حد السرعة" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&إيقاف " @@ -663,11 +663,11 @@ msgstr "&إيقاف " msgid "&Theme:" msgstr "&المظهر" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&المواضيع" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&أدوات" @@ -681,17 +681,17 @@ msgstr "&إلغاء تحميل القرص" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&عرض" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&مشاهدة" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&الموقع" @@ -703,11 +703,11 @@ msgstr "&معلومات عن اللعبة" msgid "&Yes" msgstr "&نعم" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' لم يتم العثور على أي أسماء رموز تم إنشاؤها" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' لم يتم العثور على المسح بحثًا عن الوظائف الشائعة بدلاً من ذلك" @@ -1148,7 +1148,7 @@ msgid "Accuracy:" msgstr "ضبط" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "الإنجازات" @@ -1322,7 +1322,7 @@ msgstr "أضف" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "عنوان" @@ -1564,15 +1564,15 @@ msgstr "التنعيم" msgid "Any Region" msgstr "أي منطقة" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "إلحاق التوقيع ل" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "إلحاق ب & ملف التوقيع الموجود" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "تطبيق ملف التوقيع" @@ -1590,7 +1590,7 @@ msgstr "تاريخ الإصدار" msgid "Apply" msgstr "تطبيق" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "تطبيق ملف التوقيع" @@ -1701,7 +1701,7 @@ msgstr "ضبط حجم الإطار تلقائيا" msgid "Auto-Hide" msgstr "إخفاء تلقائي" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "RSO الكشف التلقائي عن وحدات" @@ -1804,7 +1804,7 @@ msgstr "قيمة غير صالحة المقدمة" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "الشعار" @@ -1876,7 +1876,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "حجم الكتلة" @@ -1914,7 +1914,7 @@ msgstr "" "libusb تم تمكين وضع عبور البلوتوث ولكن تم تصميم دولفين بدون\n" "لا يمكن استخدام وضع العبور" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "التمهيد لإيقاف مؤقت" @@ -1991,7 +1991,7 @@ msgstr "خطأ محول النطاق العريض" msgid "Broadband Adapter MAC Address" msgstr "عنوان ماك لمحول النطاق العريض" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "مستعرض جلسات اللعب عبر الشبكة" @@ -2053,7 +2053,7 @@ msgstr "بواسطة: " msgid "C Stick" msgstr "C عصا" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "إنشاء ملف التوقيع" @@ -2149,7 +2149,7 @@ msgstr "لا يمكن بدء جلسة اللعب عبر الشبكة بينما #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2222,7 +2222,7 @@ msgstr "المركز و المعايرة" msgid "Change &Disc" msgstr "تغيير &القرص" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "تغيير &القرص" @@ -2287,7 +2287,7 @@ msgstr "بحث عن اسرار" msgid "Cheats Manager" msgstr "مدير الأسرار" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "NAND تحقق من" @@ -2327,11 +2327,11 @@ msgstr "اختيار ملف لفتح" msgid "Choose a file to open or create" msgstr "اختر ملفًا لفتحه أو إنشائه" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "اختيار ملف الإدخال ذي الأولوية" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "اختر ملف الإدخال الثانوي" @@ -2366,7 +2366,7 @@ msgstr "Classic Controller" msgid "Clear" msgstr "مسح" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "مسح ذاكرة التخزين المؤقت" @@ -2387,7 +2387,7 @@ msgstr "استنساخ و &تحرير الرمز" msgid "Close" msgstr "إغلاق" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "الإعدادات العامة" @@ -2434,7 +2434,7 @@ msgstr "تصحيح الألوان" msgid "Color Space" msgstr "مساحة اللون" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "دمج اثنين من ملفات التوقيع" @@ -2474,7 +2474,7 @@ msgstr "تجميع التظليل" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "نوع الضغط" @@ -2610,7 +2610,7 @@ msgstr "تأكيد تغيير الخلفية" msgid "Confirm on Stop" msgstr "تأكيد على التوقف" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2621,7 +2621,7 @@ msgstr "التأكيد" msgid "Connect" msgstr "اتصال" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "ربط لوح الميزان" @@ -2629,7 +2629,7 @@ msgstr "ربط لوح الميزان" msgid "Connect USB Keyboard" msgstr "ربط لوحة مفاتيح يو إس بي" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "%1 ربط ريموت وي" @@ -2649,7 +2649,7 @@ msgstr "ربط ريموت وي 3" msgid "Connect Wii Remote 4" msgstr "ربط ريموت وي 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "ربط ريموت وي " @@ -2783,7 +2783,7 @@ msgstr "" msgid "Convergence" msgstr "التقارب" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "التقارب" @@ -3127,7 +3127,7 @@ msgid "" "leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "المنطقة الحالية" @@ -3329,7 +3329,7 @@ msgstr "Y تخفيض" msgid "Default" msgstr "افتراضي" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "(Read Only) التكوين الافتراضي" @@ -3389,7 +3389,7 @@ msgstr "'{0}' احذف الملف الموجود" msgid "Depth" msgstr "العمق" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "نسبة العمق" @@ -3402,7 +3402,7 @@ msgstr "العمق" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "الوصف" @@ -3424,11 +3424,11 @@ msgstr "منفصل" msgid "Detect" msgstr "كشف" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "تحديد النواة المزدوجة" @@ -3503,7 +3503,7 @@ msgstr "Disable EFB VRAM Copies" msgid "Disable Emulation Speed Limit" msgstr "تعطيل محاكاة الحد الأقصى للسرعة" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Fastmem تعطيل" @@ -3511,7 +3511,7 @@ msgstr "Fastmem تعطيل" msgid "Disable Fog" msgstr "تعطيل الضباب" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Disable JIT Cache" @@ -3584,7 +3584,7 @@ msgstr "هل تسمح لشركة دولفين بالإبلاغ عن معلوما msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "هل تريد إضافة \"%1\" إلى قائمة مسارات الألعاب؟" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "هل تريد مسح قائمه أسماء الرموز ؟" @@ -3615,17 +3615,17 @@ msgstr "Dolphin FIFO Log (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin Map File (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "CSV توقيع دولفين ملف" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "دولفين توقيع الملف" @@ -3790,7 +3790,7 @@ msgstr "Dump &FakeVMEM" msgid "Dump &MRAM" msgstr "Dump &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "تفريغ الصوت" @@ -3802,7 +3802,7 @@ msgstr "تفريغ القوام الأساسي" msgid "Dump EFB Target" msgstr "EFB التفريغ المستهدف" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "تفريغ الإطارات" @@ -3880,7 +3880,7 @@ msgstr "" msgid "Dutch" msgstr "الهولندية" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "خروج" @@ -3932,7 +3932,7 @@ msgid "Edit..." msgstr "حرر" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "محرر" @@ -3999,7 +3999,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "تمت محاكاة أجهزة يو إس بي" @@ -4155,7 +4155,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4195,7 +4195,7 @@ msgid "" "only." msgstr "باستخدام 5.1 المحيطي. بعض الخلفيات فقط Dolby Pro Logic II تمكن محاكاة" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4258,7 +4258,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4346,7 +4346,7 @@ msgstr "أدخل كلمة المرور" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Enter the RSO module address:" @@ -4393,18 +4393,18 @@ msgstr "Enter the RSO module address:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4545,7 +4545,7 @@ msgstr "" msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "أوروبا" @@ -4626,7 +4626,7 @@ msgstr "اسم المتغير المتوقع" msgid "Experimental" msgstr "تجريبي" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "تصدير جميع حفظ وي" @@ -4641,7 +4641,7 @@ msgstr "فشل التصدير" msgid "Export Recording" msgstr "تصدير تسجيل" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "تصدير تسجيل" @@ -4669,7 +4669,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4697,7 +4697,7 @@ msgstr "خارجي" msgid "External Frame Buffer (XFB)" msgstr "(XFB) مخزن مؤقت للإطار الخارجي" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "NAND استخراج الشهادات من" @@ -4735,7 +4735,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO Player" @@ -4755,7 +4755,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "فشل في إضافة هذه الجلسة إلى فهرس اللعب عبر الشبكة: 1%" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Failed to append to signature file '%1'" @@ -4850,7 +4850,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "فشل تصدير ملفات الحفظ التالية:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "NAND فشل استخراج شهادات من" @@ -4880,20 +4880,20 @@ msgstr "D3D فشل في العثور على واحد أو أكثر من رموز msgid "Failed to import \"%1\"." msgstr "\"%1\" فشل الاستيراد" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "فشل استيراد ملف الحفظ. الرجاء تشغيل اللعبة مرة واحدة ، ثم المحاولة مرة أخرى" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" "فشل استيراد ملف الحفظ. يبدو أن الملف المحدد تالف أو أنه ليس حفظ وي صالحًا" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4920,7 +4920,7 @@ msgid "Failed to install pack: %1" msgstr "%1 :فشل تثبيت الحزمة" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "NAND فشل تثبيت هذا العنوان على" @@ -4932,8 +4932,8 @@ msgstr "" "Failed to listen on port %1. Is another instance of the NetPlay server " "running?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Failed to load RSO module at %1" @@ -4945,7 +4945,7 @@ msgstr "d3d11.dll فشل تحميل" msgid "Failed to load dxgi.dll" msgstr "dxgi.dll فشل تحميل" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Failed to load map file '%1'" @@ -5126,19 +5126,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Failed to save FIFO log." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Failed to save code map to path '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Failed to save signature file '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Failed to save symbol map to path '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Failed to save to signature file '%1'" @@ -5188,7 +5188,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "فشل" @@ -5234,7 +5234,7 @@ msgstr "تفاصيل الملف" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "تنسيق الملف" @@ -5248,18 +5248,18 @@ msgstr "معلومات الملف" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "اسم الملف" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "مسار الملف" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "حجم الملف" @@ -5779,7 +5779,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "معرف اللعبة" @@ -5827,7 +5827,7 @@ msgstr "" msgid "Game region does not match" msgstr "منطقة اللعبة غير متطابقة" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "إعدادات خاصه باللعبة" @@ -5898,7 +5898,7 @@ msgid "Gecko Codes" msgstr "Gecko رموز" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5924,7 +5924,7 @@ msgstr "إنشاء هوية جديد للحصائيات " msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "أسماء الرموز التي تم إنشاؤها من '%1'" @@ -6001,7 +6001,7 @@ msgstr "اليسار أخضر" msgid "Green Right" msgstr "اليمين أخضر" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "شبكة" @@ -6076,7 +6076,7 @@ msgstr "ست عشرية" msgid "Hide" msgstr "إخفاء" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "إخفاء الكل" @@ -6379,7 +6379,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "النسخة الاحتياطية BootMii NAND استيراد" @@ -6394,7 +6394,7 @@ msgstr "فشل الاستيراد" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "استيراد حفظ وي" @@ -6501,8 +6501,8 @@ msgstr "معلومات" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "المعلومات" @@ -6511,10 +6511,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "منع شاشة التوقف أثناء المحاكاة" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "إدخال" @@ -6555,7 +6555,7 @@ msgstr "(%1) تثبيت القسم" msgid "Install Update" msgstr "تثبيت التحديث" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "WAD تثبيت" @@ -6575,7 +6575,7 @@ msgstr "تعليمات" msgid "Instruction Breakpoint" msgstr "نقطة توقف التعليمات" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "التعليمات" @@ -6638,7 +6638,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Interpreter (بطيء)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Interpreter Core" @@ -6663,7 +6663,7 @@ msgstr "حزمة غير صالحة 1% مقدمة :2%" msgid "Invalid Player ID" msgstr "معرف لاعب غير صالح" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Invalid RSO module address: %1" @@ -6738,11 +6738,11 @@ msgstr "الإيطالية" msgid "Italy" msgstr "إيطاليا" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT Block Linking Off" @@ -6750,47 +6750,47 @@ msgstr "JIT Block Linking Off" msgid "JIT Blocks" msgstr "JIT Blocks" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT Branch Off" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FloatingPoint Off" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Integer Off" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LoadStore Floating Off" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LoadStore Off" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LoadStore Paired Off" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LoadStore lXz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT LoadStore lbzx Off" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LoadStore lwz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Off (JIT Core)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Paired Off" @@ -6802,11 +6802,11 @@ msgstr "JIT Recompiler for ARM64 (موصى به)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "JIT Recompiler for x86-64 (موصى به)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "JIT Register Cache Off" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" @@ -6817,7 +6817,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "اليابان" @@ -6876,7 +6876,7 @@ msgstr "كيلوبايت" msgid "Kick Player" msgstr "طرد لاعب" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "كوريا" @@ -7027,11 +7027,11 @@ msgstr "ضوء" msgid "Limit Chunked Upload Speed:" msgstr "الحد من سرعة الرفع المقسم:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "قائمة الأعمدة" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "قائمة" @@ -7047,11 +7047,11 @@ msgstr "الاستماع" msgid "Load" msgstr "تحميل" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Load &Bad Map File..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Load &Other Map File..." @@ -7063,7 +7063,7 @@ msgstr "تحميل النسيج المخصص" msgid "Load File" msgstr "تحميل الملف" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "تحميل قائمة جيم كيوب الرئيسية " @@ -7173,19 +7173,19 @@ msgstr "تحميل الحالة فتحة 8" msgid "Load State Slot 9" msgstr "تحميل الحالة فتحة 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "تحميل الحالة من ملف" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "تحميل الحالة من الفتحة المحددة" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "تحميل الحالة من فتحة" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "%1 تحميل قائمة نظام وي" @@ -7197,16 +7197,16 @@ msgstr "تحميل وكتابة بيانات حفظ المضيف" msgid "Load from Selected Slot" msgstr "التحميل من الفتحة المحددة" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "تحميل من الفتحة %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Load map file" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "%1 تحميل قائمة نظام وي" @@ -7214,7 +7214,7 @@ msgstr "%1 تحميل قائمة نظام وي" msgid "Load..." msgstr "تحميل" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "الرموز المحملة من '%1'" @@ -7253,7 +7253,7 @@ msgstr "سجل" msgid "Log Configuration" msgstr "تكوين السجل" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Log JIT Instruction Coverage" @@ -7333,7 +7333,7 @@ msgstr "العصا الرئيسية" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "المطور" @@ -7350,10 +7350,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "NAND إدارة" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "أخذ عينات النسيج يدويا" @@ -7404,7 +7405,7 @@ msgstr "نقطة توقف الذاكرة" msgid "Memory Card" msgstr "بطاقة الذاكرة" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "مدير بطاقة الذاكرة" @@ -7495,8 +7496,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "%1 تم العثور على وحدات" @@ -7504,7 +7505,7 @@ msgstr "%1 تم العثور على وحدات" msgid "Mono" msgstr "احادي" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "أحادي الظلال" @@ -7567,9 +7568,10 @@ msgstr "" msgid "N&o to All" msgstr "لا للكل" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND تحقق" @@ -7578,7 +7580,7 @@ msgstr "NAND تحقق" msgid "NKit Warning" msgstr "NKit تحذير" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7604,7 +7606,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7812,7 +7814,7 @@ msgstr "لا توجد لعبة قيد التشغيل" msgid "No game running." msgstr "لا توجد لعبة قيد التشغيل" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "لم يتم اكتشاف أية مشكلات." @@ -7874,7 +7876,7 @@ msgstr "لا شيء" msgid "North America" msgstr "أمريكا الشمالية" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "غير مجموعة" @@ -7996,7 +7998,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "وثائق على الانترنت" @@ -8004,7 +8006,7 @@ msgstr "وثائق على الانترنت" msgid "Only Show Collection" msgstr "عرض المجموعة فقط" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8012,7 +8014,7 @@ msgstr "" "إلحاق رموز فقط بالبادية:\n" "(فارغ لكل الرموز)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8029,7 +8031,7 @@ msgstr "فتح" msgid "Open &Containing Folder" msgstr "فتح موقع الملف" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "فتح مجلد المستخدم" @@ -8135,11 +8137,11 @@ msgstr "لعبة أخرى" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "تشغيل تسجيل الإدخال" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8241,7 +8243,7 @@ msgstr "مسارات" msgid "Pause" msgstr "إيقاف مؤقت" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "وقفة في نهاية الفيلم" @@ -8279,7 +8281,7 @@ msgstr "سرعة الذروة لحركات التأرجح الخارجية." msgid "Per-Pixel Lighting" msgstr "لكل بكسل إضاءة" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "تحديث النظام عبر الإنترنت" @@ -8313,7 +8315,7 @@ msgstr "مساحة العنوان الفعلي" msgid "PiB" msgstr "بيتابايت" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "debug اختر خط" @@ -8330,7 +8332,7 @@ msgid "Pitch Up" msgstr "Pitch Up" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "المنصة" @@ -8569,7 +8571,7 @@ msgstr "التقدم" msgid "Public" msgstr "عامة" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "أزالة ذاكره التخزين المؤقت لقائمة الألعاب" @@ -8627,11 +8629,11 @@ msgstr "R-قوة ضغطة" msgid "READY" msgstr "جاهز" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO Modules" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO الكشف التلقائي" @@ -8785,7 +8787,7 @@ msgid "Refreshing..." msgstr "تحديث..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "المنطقة" @@ -8886,7 +8888,7 @@ msgstr "إعادة تعيين" msgid "Reset All" msgstr "إعادة تعيين الكل" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "إعادة تعيين تجاهل معالج الذعر" @@ -9118,11 +9120,11 @@ msgstr "SSL سياق" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "حفظ الرموز" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "حفظ الحالة" @@ -9145,7 +9147,7 @@ msgstr "حفظ الكل" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "حفظ التصدير" @@ -9166,11 +9168,11 @@ msgstr "حفظ اللعبة" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "حفظ الاستيراد" @@ -9232,23 +9234,23 @@ msgstr "حفظ الحالة فتحة 8" msgid "Save State Slot 9" msgstr "حفظ الحالة فتحة 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "حفظ الحالة في ملف" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "حفظ الحالة إلى الفتحة الأقدم" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "حفظ الحالة إلى الفتحة المحددة" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "حفظ الحالة إلى فتحة" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Save Symbol Map &As..." @@ -9268,11 +9270,11 @@ msgstr "حفظ كإعداد مسبق" msgid "Save as..." msgstr "حفظ بأسم" -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "حفظ ملف الإخراج المجمع بأسم" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9286,11 +9288,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Save in Same Directory as the ROM" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Save map file" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "احفظ ملف التوقيع" @@ -9298,7 +9300,7 @@ msgstr "احفظ ملف التوقيع" msgid "Save to Selected Slot" msgstr "الحفظ إلى الفتحة المحددة" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "حفظ إلى الفتحة %1 - %2" @@ -9332,7 +9334,7 @@ msgstr "لقطة للشاشة" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "بحث" @@ -9361,7 +9363,7 @@ msgstr "" "البحث غير ممكن حاليا في مساحة العنوان الافتراضية. يرجى تشغيل اللعبة قليلا " "والمحاولة مرة أخرى." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "ابحث عن تعليمات" @@ -9369,7 +9371,7 @@ msgstr "ابحث عن تعليمات" msgid "Search games..." msgstr "بحث عن الالعاب" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "تعليمات البحث" @@ -9406,7 +9408,7 @@ msgid "Select Dump Path" msgstr "تحديد مسار التفريغ" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "حدد ملف تصدير " @@ -9450,7 +9452,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "%1 - %2 حدد الفتحة" @@ -9458,7 +9460,7 @@ msgstr "%1 - %2 حدد الفتحة" msgid "Select State" msgstr "اختر الحالة" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "تحديد فتحة الحالة" @@ -9544,7 +9546,7 @@ msgstr "حدد ملف" msgid "Select a game" msgstr "اختر لعبة" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "NAND حدد عنوانًا لتثبيته إلى" @@ -9552,7 +9554,7 @@ msgstr "NAND حدد عنوانًا لتثبيته إلى" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "RSO حدد عنوان وحدة" @@ -9569,7 +9571,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "(OTP/SEEPROM dump) حدد ملف المفاتيح" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "حدد حفظ الملف" @@ -9781,11 +9783,11 @@ msgstr "" msgid "Show % Speed" msgstr "عرض السرعة" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "السجل" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "شريط الأدوات" @@ -9793,11 +9795,11 @@ msgstr "شريط الأدوات" msgid "Show Active Title in Window Title" msgstr "إظهار العنوان النشط في عنوان الإطار" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "عرض الكل" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "أستراليا" @@ -9810,7 +9812,7 @@ msgstr "عرض اللعبة الحالية على الخلاف" msgid "Show Disabled Codes First" msgstr "إظهار الرموز المعطلة أولاً" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL" @@ -9823,7 +9825,7 @@ msgstr "إظهار الرموز الممكّنة أولاً" msgid "Show FPS" msgstr "FPS عرض" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "عرض عداد الإطار" @@ -9831,15 +9833,15 @@ msgstr "عرض عداد الإطار" msgid "Show Frame Times" msgstr "عرض أوقات الإطار" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "فرنسا" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "جيم كيوب" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "ألمانيا" @@ -9851,23 +9853,23 @@ msgstr "Show Golf Mode Overlay" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "عرض مدخلات العرض" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "ايطاليا" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "اليابان" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "كوريا" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "عرض عداد التأخر" @@ -9875,7 +9877,7 @@ msgstr "عرض عداد التأخر" msgid "Show Language:" msgstr "عرض اللغة" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "تكوين السجل" @@ -9887,7 +9889,7 @@ msgstr "عرض رسائل اللعب عبر الشبكة" msgid "Show NetPlay Ping" msgstr "في اللعب عبر الشبكة Ping عرض الـ" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "هولندا" @@ -9895,7 +9897,7 @@ msgstr "هولندا" msgid "Show On-Screen Display Messages" msgstr "عرض الرسائل التي تظهر على الشاشة " -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "أوروبا" @@ -9908,19 +9910,19 @@ msgstr "عرض الكمبيوتر" msgid "Show Performance Graphs" msgstr "عرض الرسوم البيانية للأداء" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "عرض المنصات" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "عرض المناطق" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "إظهار عداد إعادة التسجيل" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "روسيا" @@ -9928,7 +9930,7 @@ msgstr "روسيا" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "اسبانيا" @@ -9940,19 +9942,19 @@ msgstr "إظهار ألوان السرعة" msgid "Show Statistics" msgstr "عرض الإحصاءات" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "عرض ساعة النظام" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "تايوان" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "امريكا" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "غير معروف" @@ -9964,15 +9966,15 @@ msgstr "" msgid "Show VPS" msgstr "VPS عرض " -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "وي" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "العالم" @@ -10081,7 +10083,7 @@ msgstr "جانبية" msgid "Sideways Wii Remote" msgstr "انحراف ريموت وي" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "قاعدة بيانات التوقيع" @@ -10327,7 +10329,7 @@ msgstr "وحدة تحكم القياسية" msgid "Start" msgstr "تشغيل" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "بدء &اللعب عبر الشبكة" @@ -10335,7 +10337,7 @@ msgstr "بدء &اللعب عبر الشبكة" msgid "Start New Cheat Search" msgstr "بدء بحث أسرار جديدة" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "بدء التسجيل" @@ -10429,7 +10431,7 @@ msgstr "3D وضع ثلاثي الأبعاد" msgid "Stereoscopic 3D Mode:" msgstr "3D وضع" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "التنظير المجسم" @@ -10451,7 +10453,7 @@ msgstr "عصا" msgid "Stop" msgstr "إيقاف" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "إيقاف تشغيل / تسجيل الإدخال" @@ -10522,8 +10524,8 @@ msgstr "مرقم" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "ناجح" @@ -10550,7 +10552,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "تم تصدير ملفات الحفظ بنجاح" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "تم استخراج الشهادات بنجاح من NAND" @@ -10562,12 +10564,12 @@ msgstr "تم استخراج الملف بنجاح." msgid "Successfully extracted system data." msgstr "استخرجت بنجاح بيانات النظام." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "تم استيراد ملف الحفظ بنجاح" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "تم بنجاح تثبيت هذا العنوان على NAND." @@ -10660,7 +10662,7 @@ msgstr "اسم الرمز" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "رموز" @@ -10680,7 +10682,7 @@ msgstr "مزامنة ريموت وي الحقيقية و اقترانها" msgid "Synchronize GPU thread" msgstr "Synchronize GPU thread" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10711,7 +10713,7 @@ msgstr "جارٍ مزامنة حفظ البيانات" msgid "System Language:" msgstr "لغة النظام" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "الإدخال" @@ -10724,7 +10726,7 @@ msgstr "TAS أدوات" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "العلامات" @@ -10742,7 +10744,7 @@ msgstr "" msgid "Taiwan" msgstr "تايوان" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "لقطة للشاشة" @@ -10824,7 +10826,7 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "أقسام نادرة مفقودة." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -10832,7 +10834,7 @@ msgstr "" "NAND لا يمكن إصلاح\n" "يوصى بعمل نسخة احتياطية من بياناتك الحالية والبدء من جديد" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND تم اصلاح" @@ -11123,6 +11125,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "\"%1\" تحتوي بطاقة الذاكرة المستهدفة بالفعل على ملف" @@ -11155,6 +11163,12 @@ msgstr "قسم التحديث مفقود" msgid "The update partition is not at its normal position." msgstr "قسم التحديث ليس في وضعه الطبيعي" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "لا يحتوي القسم {0} على نظام ملفات صالح" @@ -11183,7 +11197,7 @@ msgstr "لا يوجد شيء للتراجع !" msgid "There was an issue adding a shortcut to the desktop" msgstr "حدثت مشكلة أثناء إضافة اختصار إلى سطح المكتب" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11407,13 +11421,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr " أضاف هذه القيمة إلى قيمة تقارب المنصوص عليها في ضبط الرسومات." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "يتم ضرب هذه القيمة مع عمق المنصوص عليها في ضبط الرسومات." @@ -11471,7 +11485,7 @@ msgstr "انتهت مهله" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "العنوان" @@ -11485,7 +11499,7 @@ msgstr "إلى" msgid "To:" msgstr "إلى" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "ملء الشاشة" @@ -11733,7 +11747,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "RSO تعذر الكشف التلقائي عن وحدة" @@ -11800,11 +11814,11 @@ msgstr "غير مضغوطة GC/Wii صورة (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "التراجع عن تحميل الحالة" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "التراجع عن حفظ الحالة" @@ -11825,7 +11839,7 @@ msgstr "" "NAND إلى إزالة الإصدار المثبت حاليًا من هذا العنوان من\n" "دون حذف بيانات الحفظ الخاصة به. استمر؟" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "امريكا" @@ -12078,7 +12092,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "استخدام منطقة عازلة بعمق واحد لكلتا العينين. هناك حاجة لعدد قليل من الألعاب ." @@ -12117,7 +12131,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "تكوين المستخدم" @@ -12314,7 +12328,7 @@ msgstr "رفع مستوى الصوت" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "(*.wad) ملفات" @@ -12425,7 +12439,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "تحذير" @@ -12610,11 +12624,11 @@ msgstr "وي و ريموت وي" msgid "Wii data is not public yet" msgstr "بيانات وي ليست عامة بعد" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "ملفات حفظ وي (*.bin);;كل الملفات (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "WiiTools Signature MEGA File" @@ -12840,6 +12854,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12876,7 +12896,7 @@ msgstr "محاذاة" msgid "any value" msgstr "اي قيمة" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "تلقائي" @@ -12909,7 +12929,7 @@ msgstr "" msgid "errno" msgstr "تخطئ" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "إكمال زائف " @@ -12953,7 +12973,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "لا شيء" diff --git a/Languages/po/ca.po b/Languages/po/ca.po index 001d23e9bf..3043a0a7f2 100644 --- a/Languages/po/ca.po +++ b/Languages/po/ca.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Puniasterus , 2013-2016,2021-2023\n" "Language-Team: Catalan (http://app.transifex.com/delroth/dolphin-emu/" @@ -332,7 +332,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Sobre" @@ -353,7 +353,7 @@ msgstr "" msgid "&Add..." msgstr "&Afegir..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Paràmetres d'àudio" @@ -361,7 +361,7 @@ msgstr "&Paràmetres d'àudio" msgid "&Auto Update:" msgstr "&Actualització automàtica:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Inici automàtic" @@ -369,11 +369,11 @@ msgstr "&Inici automàtic" msgid "&Borderless Window" msgstr "&Finestra sense marges" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Punts d'interrupció" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -383,15 +383,15 @@ msgstr "" " \n" "&Cancel·lar" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Gestor de trucs" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -399,7 +399,7 @@ msgstr "" msgid "&Clone..." msgstr "&Clonar..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Codi" @@ -407,7 +407,7 @@ msgstr "&Codi" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Configuració del controlador" @@ -446,11 +446,11 @@ msgstr "&Edita codi..." msgid "&Edit..." msgstr "&Edita..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Expulsa el disc" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulació" @@ -470,27 +470,27 @@ msgstr "&Exporta una captura d'estat..." msgid "&Export as .gci..." msgstr "&Exportar com a .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fitxer" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Font..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "Avança un &fotograma" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&Repositori GitHub" @@ -498,15 +498,15 @@ msgstr "&Repositori GitHub" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Configuració de &gràfics" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Ajuda" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Configuració de &tecles d'accés" @@ -526,7 +526,7 @@ msgstr "&Importa una captura d'estat..." msgid "&Import..." msgstr "&Importar..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -538,7 +538,7 @@ msgstr "&Insertar blr" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -546,11 +546,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Idioma:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Carrega una captura d'estat..." -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -564,15 +564,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memòria" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Enregistrament" @@ -580,7 +580,7 @@ msgstr "&Enregistrament" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -589,23 +589,23 @@ msgid "&No" msgstr "&No" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Obre..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opcions" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Executar" @@ -613,7 +613,7 @@ msgstr "&Executar" msgid "&Properties" msgstr "&Propietats" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Mode de només lectura" @@ -621,7 +621,7 @@ msgstr "&Mode de només lectura" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registres" @@ -639,15 +639,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Reinicia" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -655,7 +655,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -663,7 +663,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Aturar" @@ -671,11 +671,11 @@ msgstr "&Aturar" msgid "&Theme:" msgstr "&Tema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Eines" @@ -689,17 +689,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Vista" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Veure" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Pàgina web" @@ -711,11 +711,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Sí" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1132,7 +1132,7 @@ msgid "Accuracy:" msgstr "Precisió:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1306,7 +1306,7 @@ msgstr "Afegir..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adreça" @@ -1535,15 +1535,15 @@ msgstr "Anti-Aliasing:" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1561,7 +1561,7 @@ msgstr "Data Apploader:" msgid "Apply" msgstr "Aplicar" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1668,7 +1668,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1771,7 +1771,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Pancarta" @@ -1843,7 +1843,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1879,7 +1879,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1956,7 +1956,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -2018,7 +2018,7 @@ msgstr "" msgid "C Stick" msgstr "Palanca C" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2114,7 +2114,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2185,7 +2185,7 @@ msgstr "" msgid "Change &Disc" msgstr "Canviar &Disc" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Canvia el &disc..." @@ -2247,7 +2247,7 @@ msgstr "Cerca trucs" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2285,11 +2285,11 @@ msgstr "Trieu un arxiu per obrir" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2324,7 +2324,7 @@ msgstr "" msgid "Clear" msgstr "Esborrar" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2345,7 +2345,7 @@ msgstr "" msgid "Close" msgstr "Tancar" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2392,7 +2392,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2429,7 +2429,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2565,7 +2565,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Confirmar a l'aturar" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2576,7 +2576,7 @@ msgstr "" msgid "Connect" msgstr "Connectar" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Connectar la Balance Board" @@ -2584,7 +2584,7 @@ msgstr "Connectar la Balance Board" msgid "Connect USB Keyboard" msgstr "Connectar el teclat USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2604,7 +2604,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2727,7 +2727,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Convergència:" @@ -3047,7 +3047,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3243,7 +3243,7 @@ msgstr "" msgid "Default" msgstr "Per defecte" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3303,7 +3303,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3316,7 +3316,7 @@ msgstr "Profunditat:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Descripció" @@ -3338,11 +3338,11 @@ msgstr "" msgid "Detect" msgstr "Detectar" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3417,7 +3417,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3425,7 +3425,7 @@ msgstr "" msgid "Disable Fog" msgstr "Deshabilitar boira" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3498,7 +3498,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3529,17 +3529,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3700,7 +3700,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Desa l'àudio" @@ -3712,7 +3712,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Bolcat de destinació EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Desa el vídeo" @@ -3790,7 +3790,7 @@ msgstr "" msgid "Dutch" msgstr "Holandès" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Surt" @@ -3838,7 +3838,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3905,7 +3905,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4058,7 +4058,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4098,7 +4098,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4159,7 +4159,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4244,7 +4244,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4291,18 +4291,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4441,7 +4441,7 @@ msgstr "" msgid "Euphoria" msgstr "Eufòria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4522,7 +4522,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exportar totes les partides guardades de Wii" @@ -4537,7 +4537,7 @@ msgstr "" msgid "Export Recording" msgstr "Exportar gravació" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exporta l'enregistrament..." @@ -4565,7 +4565,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4593,7 +4593,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4631,7 +4631,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Jugador FIFO" @@ -4649,7 +4649,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4743,7 +4743,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4770,18 +4770,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4808,7 +4808,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4818,8 +4818,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4831,7 +4831,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -5003,19 +5003,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5063,7 +5063,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5109,7 +5109,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5123,18 +5123,18 @@ msgstr "informació del fitxer" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Nom de l'arxiu" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Mida del fitxer" @@ -5647,7 +5647,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID del joc" @@ -5691,7 +5691,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Configuració específica de joc" @@ -5762,7 +5762,7 @@ msgid "Gecko Codes" msgstr "Codis Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5788,7 +5788,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5865,7 +5865,7 @@ msgstr "Verd Esquerra" msgid "Green Right" msgstr "Verd Dret" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5940,7 +5940,7 @@ msgstr "" msgid "Hide" msgstr "Oculta" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6214,7 +6214,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6229,7 +6229,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6334,8 +6334,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informació" @@ -6344,10 +6344,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Entrada" @@ -6388,7 +6388,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6408,7 +6408,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6471,7 +6471,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6496,7 +6496,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6572,11 +6572,11 @@ msgstr "Italià" msgid "Italy" msgstr "Itàlia" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6584,47 +6584,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6636,11 +6636,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6651,7 +6651,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japó" @@ -6710,7 +6710,7 @@ msgstr "" msgid "Kick Player" msgstr "Expulsar jugador" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Corea" @@ -6855,11 +6855,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6875,11 +6875,11 @@ msgstr "" msgid "Load" msgstr "Carregar" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6891,7 +6891,7 @@ msgstr "Carrega textures personalitzades" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -7001,19 +7001,19 @@ msgstr "Carregar ranura d'estat 8" msgid "Load State Slot 9" msgstr "Carregar estat 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Carrega des d'un fitxer" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Carrega des de la ranura" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Carrega des d'una ranura" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -7025,16 +7025,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7042,7 +7042,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7081,7 +7081,7 @@ msgstr "Registre" msgid "Log Configuration" msgstr "Configuració del registre" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7161,7 +7161,7 @@ msgstr "Palanca principal" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Fabricant" @@ -7178,10 +7178,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7232,7 +7233,7 @@ msgstr "" msgid "Memory Card" msgstr "Targeta de memòria" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7317,8 +7318,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7326,7 +7327,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7389,9 +7390,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7400,7 +7402,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7426,7 +7428,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7634,7 +7636,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7693,7 +7695,7 @@ msgstr "Cap" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Sense establir" @@ -7815,7 +7817,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Documentació en línia" @@ -7823,13 +7825,13 @@ msgstr "&Documentació en línia" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7844,7 +7846,7 @@ msgstr "Obre" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "Obre la carpeta de l'&usuari" @@ -7950,11 +7952,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Reprodueix l'enregistrament d'entrades" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8056,7 +8058,7 @@ msgstr "Camins" msgid "Pause" msgstr "Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pausa al final de l'enregistrament" @@ -8094,7 +8096,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Il·luminació per píxel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8128,7 +8130,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8145,7 +8147,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Plataforma" @@ -8376,7 +8378,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8432,11 +8434,11 @@ msgstr "R-Analògic" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8590,7 +8592,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Regió" @@ -8688,7 +8690,7 @@ msgstr "Reiniciar" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8920,11 +8922,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "&Desa l'Estat" @@ -8947,7 +8949,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8968,11 +8970,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9034,23 +9036,23 @@ msgstr "Desar Ranura d'Estat 8" msgid "Save State Slot 9" msgstr "Desar Ranura d'Estat 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9070,11 +9072,11 @@ msgstr "" msgid "Save as..." msgstr "Desar com..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9085,11 +9087,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9097,7 +9099,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9131,7 +9133,7 @@ msgstr "Captura" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Buscar" @@ -9158,7 +9160,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9166,7 +9168,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9203,7 +9205,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9247,7 +9249,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9255,7 +9257,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Tria ranura de captura" @@ -9341,7 +9343,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9349,7 +9351,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9366,7 +9368,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Seleccioni el fitxer de partida guardada" @@ -9573,11 +9575,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Mostrar &Registre" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Mostrar Barra d'&Eines" @@ -9585,11 +9587,11 @@ msgstr "Mostrar Barra d'&Eines" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Mostrar Austràlia" @@ -9602,7 +9604,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9615,7 +9617,7 @@ msgstr "" msgid "Show FPS" msgstr "Mostra FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Comptador de fotogrames" @@ -9623,15 +9625,15 @@ msgstr "Comptador de fotogrames" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Mostrar França" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Mostrar GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Mostrar Alemanya" @@ -9643,23 +9645,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Visualitza les entrades" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Mostrar Itàlia" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Mostrar Corea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Comptador de lag" @@ -9667,7 +9669,7 @@ msgstr "Comptador de lag" msgid "Show Language:" msgstr "Mostrar Idioma:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Mostrar la &Configuració del Registre" @@ -9679,7 +9681,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9687,7 +9689,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Mostrar PAL" @@ -9700,19 +9702,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Mostrar Plataformes" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Mostrar Regions" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Comptador de reenregistraments" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9720,7 +9722,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9732,19 +9734,19 @@ msgstr "" msgid "Show Statistics" msgstr "Mostrar Estadístiques" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Rellotge del sistema" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Mostrar Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Mostrar EUA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9756,15 +9758,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Mostrar Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9873,7 +9875,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10113,7 +10115,7 @@ msgstr "Controlador Estàndard" msgid "Start" msgstr "Començar" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10121,7 +10123,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Comença l'enregistrament d'entrades" @@ -10215,7 +10217,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10237,7 +10239,7 @@ msgstr "Palanca" msgid "Stop" msgstr "Atura" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Atura la reproducció/enregistrament d'entrades" @@ -10308,8 +10310,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10336,7 +10338,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10348,12 +10350,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10446,7 +10448,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10466,7 +10468,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "Sincronitzar fil de la GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10495,7 +10497,7 @@ msgstr "" msgid "System Language:" msgstr "Idioma del sistema:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Entrada TAS" @@ -10508,7 +10510,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10526,7 +10528,7 @@ msgstr "" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Captura de pantalla" @@ -10608,13 +10610,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10884,6 +10886,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10915,6 +10923,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10943,7 +10957,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11137,13 +11151,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11196,7 +11210,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Títol" @@ -11210,7 +11224,7 @@ msgstr "A" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "&Pantalla completa" @@ -11456,7 +11470,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11515,11 +11529,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Desfés la càrrega de captura" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Desfer Estat Guardat" @@ -11537,7 +11551,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11788,7 +11802,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11826,7 +11840,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -12020,7 +12034,7 @@ msgstr "Pujar el volum" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12121,7 +12135,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Advertència" @@ -12304,11 +12318,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12525,6 +12539,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12561,7 +12581,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "auto" @@ -12594,7 +12614,7 @@ msgstr "" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12638,7 +12658,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "cap" diff --git a/Languages/po/cs.po b/Languages/po/cs.po index 0f5ba90c86..9ba9d47aa7 100644 --- a/Languages/po/cs.po +++ b/Languages/po/cs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Zbyněk Schwarz , 2011-2016\n" "Language-Team: Czech (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -308,7 +308,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -329,7 +329,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Nastavení &zvuku" @@ -337,7 +337,7 @@ msgstr "Nastavení &zvuku" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -345,11 +345,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Body přerušení" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -357,15 +357,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -373,7 +373,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -381,7 +381,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Nastavení ovladače" @@ -420,11 +420,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulace" @@ -444,27 +444,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Soubor" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Postup snímkem" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "Ú&ložiště Github" @@ -472,15 +472,15 @@ msgstr "Ú&ložiště Github" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Grafická nastavení" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Nápověda" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Nastavení &klávesových zkratek" @@ -500,7 +500,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -512,7 +512,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -520,11 +520,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Nahrát Stav" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -538,15 +538,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "Pa&měť" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Video" @@ -554,7 +554,7 @@ msgstr "&Video" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -563,23 +563,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Otevřít..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "V&olby" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pauza" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Přehrát" @@ -587,7 +587,7 @@ msgstr "&Přehrát" msgid "&Properties" msgstr "&Vlastnosti" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Režim pouze pro čtení" @@ -595,7 +595,7 @@ msgstr "&Režim pouze pro čtení" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registry" @@ -613,15 +613,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Resetovat" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -629,7 +629,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -637,7 +637,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "Za&stavit" @@ -645,11 +645,11 @@ msgstr "Za&stavit" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "Nás&troje" @@ -663,17 +663,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Zobrazit" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Sledování" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Internetová stránka" @@ -685,11 +685,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1106,7 +1106,7 @@ msgid "Accuracy:" msgstr "Přesnost:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1280,7 +1280,7 @@ msgstr "Přidat..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adresa" @@ -1509,15 +1509,15 @@ msgstr "Vyhlazení okrajů" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1535,7 +1535,7 @@ msgstr "Datum zavaděče aplikace:" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1642,7 +1642,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1745,7 +1745,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Plakát" @@ -1817,7 +1817,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1853,7 +1853,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1930,7 +1930,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1992,7 +1992,7 @@ msgstr "" msgid "C Stick" msgstr "Kruhová páčka" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2088,7 +2088,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2159,7 +2159,7 @@ msgstr "" msgid "Change &Disc" msgstr "Vyměnit &disk" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Vyměnit &Disk..." @@ -2221,7 +2221,7 @@ msgstr "Hledání Cheatů" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2259,11 +2259,11 @@ msgstr "Zvolte soubor k otevření" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2298,7 +2298,7 @@ msgstr "" msgid "Clear" msgstr "Vyčistit" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2319,7 +2319,7 @@ msgstr "" msgid "Close" msgstr "Zavřít" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2366,7 +2366,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2403,7 +2403,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2539,7 +2539,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Při zastavení Potvrdit" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2550,7 +2550,7 @@ msgstr "" msgid "Connect" msgstr "Připojit" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Připojit Rola-Bola" @@ -2558,7 +2558,7 @@ msgstr "Připojit Rola-Bola" msgid "Connect USB Keyboard" msgstr "Připojit USB Klávesnici" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2578,7 +2578,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2701,7 +2701,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Sblížení:" @@ -3021,7 +3021,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3217,7 +3217,7 @@ msgstr "" msgid "Default" msgstr "Výchozí" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3277,7 +3277,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3290,7 +3290,7 @@ msgstr "Hloubka:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Popis" @@ -3312,11 +3312,11 @@ msgstr "" msgid "Detect" msgstr "Zjistit" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3391,7 +3391,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "Zakázat limit rychlosti emulace" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3399,7 +3399,7 @@ msgstr "" msgid "Disable Fog" msgstr "Zakázat Mlhu" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3472,7 +3472,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3503,17 +3503,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3674,7 +3674,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Vypsat Zvuk" @@ -3686,7 +3686,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Vypsat Cíl EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Vypsat Snímky" @@ -3764,7 +3764,7 @@ msgstr "" msgid "Dutch" msgstr "Nizozemština" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "O&dejít" @@ -3812,7 +3812,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3879,7 +3879,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4032,7 +4032,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4072,7 +4072,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4135,7 +4135,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4220,7 +4220,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4267,18 +4267,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4416,7 +4416,7 @@ msgstr "" msgid "Euphoria" msgstr "Euforie" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Evropa" @@ -4497,7 +4497,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exportovat všechny uložené hry Wii" @@ -4512,7 +4512,7 @@ msgstr "" msgid "Export Recording" msgstr "Exportovat Nahrávku" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exportovat Nahrávku..." @@ -4540,7 +4540,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4568,7 +4568,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "Externí vyrovnávací paměť snímků (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4606,7 +4606,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Přehrávač FIFO" @@ -4624,7 +4624,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4718,7 +4718,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4745,18 +4745,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4783,7 +4783,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4793,8 +4793,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4806,7 +4806,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4978,19 +4978,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5038,7 +5038,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5084,7 +5084,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5098,18 +5098,18 @@ msgstr "Informace o souboru" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Název souboru" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Velikost souboru" @@ -5622,7 +5622,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID hry" @@ -5666,7 +5666,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Nastavení Konkrétní Hry" @@ -5737,7 +5737,7 @@ msgid "Gecko Codes" msgstr "Kódy Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5763,7 +5763,7 @@ msgstr "Vytvořit novou identitu pro statistiky" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5840,7 +5840,7 @@ msgstr "Zelená vlevo" msgid "Green Right" msgstr "Zelená vpravo" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5915,7 +5915,7 @@ msgstr "" msgid "Hide" msgstr "Skrýt" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6189,7 +6189,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6204,7 +6204,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6309,8 +6309,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informace" @@ -6319,10 +6319,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Vstup" @@ -6363,7 +6363,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6383,7 +6383,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6446,7 +6446,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Převaděč (nejpomalejší)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6471,7 +6471,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6546,11 +6546,11 @@ msgstr "Italština" msgid "Italy" msgstr "Itálie" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6558,47 +6558,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6610,11 +6610,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6625,7 +6625,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japonsko" @@ -6684,7 +6684,7 @@ msgstr "" msgid "Kick Player" msgstr "Vykopnout hráče" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -6829,11 +6829,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6849,11 +6849,11 @@ msgstr "" msgid "Load" msgstr "Nahrát" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6865,7 +6865,7 @@ msgstr "Nahrát Vlastní Textury" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6975,19 +6975,19 @@ msgstr "Nahrát stav v pozici 8" msgid "Load State Slot 9" msgstr "Načíst stav v pozici 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6999,16 +6999,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7016,7 +7016,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7055,7 +7055,7 @@ msgstr "Záznam" msgid "Log Configuration" msgstr "Nastavení Záznamu" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7135,7 +7135,7 @@ msgstr "Hlavní páčka" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Tvůrce" @@ -7152,10 +7152,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7206,7 +7207,7 @@ msgstr "" msgid "Memory Card" msgstr "Paměťová karta" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7291,8 +7292,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7300,7 +7301,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskopické stíny" @@ -7363,9 +7364,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7374,7 +7376,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7400,7 +7402,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7608,7 +7610,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7668,7 +7670,7 @@ msgstr "Žádné" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Nenastaven" @@ -7790,7 +7792,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Online &dokumentace" @@ -7798,13 +7800,13 @@ msgstr "Online &dokumentace" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7819,7 +7821,7 @@ msgstr "Otevřít" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7925,11 +7927,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Spustit vstupní nahrávku..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8031,7 +8033,7 @@ msgstr "Cesty" msgid "Pause" msgstr "Pozastavit" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pozastavit na konci videa" @@ -8069,7 +8071,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Osvětlení Podle Pixelu" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8103,7 +8105,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8120,7 +8122,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Platforma" @@ -8351,7 +8353,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8407,11 +8409,11 @@ msgstr "Pravý Analog" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8565,7 +8567,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Oblast" @@ -8663,7 +8665,7 @@ msgstr "Resetovat" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8895,11 +8897,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Uložit Sta&v" @@ -8922,7 +8924,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8943,11 +8945,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9009,23 +9011,23 @@ msgstr "Uložit stav do pozice 8" msgid "Save State Slot 9" msgstr "Uložit stav do pozice 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9045,11 +9047,11 @@ msgstr "" msgid "Save as..." msgstr "Uložit jako" -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9060,11 +9062,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9072,7 +9074,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9106,7 +9108,7 @@ msgstr "SnímkObrz" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Hledat" @@ -9133,7 +9135,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9141,7 +9143,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9178,7 +9180,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9222,7 +9224,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9230,7 +9232,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Vybrat pozici stavu" @@ -9316,7 +9318,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9324,7 +9326,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9341,7 +9343,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Vyberte soubor s uloženou hrou" @@ -9550,11 +9552,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Zobrazit Záznam" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Zobrazit Panel Nás&trojů" @@ -9562,11 +9564,11 @@ msgstr "Zobrazit Panel Nás&trojů" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Zobrazit Autrálii" @@ -9579,7 +9581,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Zobrazit ELF/DOL" @@ -9592,7 +9594,7 @@ msgstr "" msgid "Show FPS" msgstr "Zobrazit Snímky za Sekundu" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Zobrazit počítadlo snímků" @@ -9600,15 +9602,15 @@ msgstr "Zobrazit počítadlo snímků" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Zobrazit Francii" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Zobrazit GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Zobrazit Německo" @@ -9620,23 +9622,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Zobrazit Obrazovku Vstupu" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Zobrazit Itálii" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Zobrazit Koreu" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Zobrazit počítadlo zpoždění" @@ -9644,7 +9646,7 @@ msgstr "Zobrazit počítadlo zpoždění" msgid "Show Language:" msgstr "Jazyk Zobrazení:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Zobrazit Nastavení &Záznamu" @@ -9656,7 +9658,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Zobrazit Nizozemí" @@ -9664,7 +9666,7 @@ msgstr "Zobrazit Nizozemí" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Zobrazit PAL" @@ -9677,19 +9679,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Zobrazit Platformy" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Zobrazit Regiony" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Zobrazit Rusko" @@ -9697,7 +9699,7 @@ msgstr "Zobrazit Rusko" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Zobrazit Španělsko" @@ -9709,19 +9711,19 @@ msgstr "" msgid "Show Statistics" msgstr "Zobrazit Statistiky" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Zobrazit Tchaj-wan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Zobrazit USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Zobrazit neznámé" @@ -9733,15 +9735,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Zobrazit WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Zobrazit Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Zobrazit svět" @@ -9850,7 +9852,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10090,7 +10092,7 @@ msgstr "Standardní Ovladač" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10098,7 +10100,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Začít nahrávat vstup" @@ -10192,7 +10194,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Režim 3D stereoskopie:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopie" @@ -10214,7 +10216,7 @@ msgstr "Páčka" msgid "Stop" msgstr "Zastavit" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10285,8 +10287,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10313,7 +10315,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10325,12 +10327,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10423,7 +10425,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10443,7 +10445,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "Synchronizovat vlákno GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10472,7 +10474,7 @@ msgstr "" msgid "System Language:" msgstr "Jazyk Systému:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS Vstup" @@ -10485,7 +10487,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10503,7 +10505,7 @@ msgstr "" msgid "Taiwan" msgstr "Tchaj-wan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Vytvořit Snímek Obrazovky" @@ -10585,13 +10587,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10861,6 +10863,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10892,6 +10900,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10920,7 +10934,7 @@ msgstr "Není co vrátit zpět!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11114,14 +11128,14 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" "Tato hodnota je přidána do hodnoty sblížení zadané v grafickém nastavení" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "Tato hodnota je vynásobena hloubkou zadanou v grafickém nastavení." @@ -11174,7 +11188,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Název" @@ -11188,7 +11202,7 @@ msgstr "Do" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11434,7 +11448,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11493,11 +11507,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Vrátit zpět Nahrání Stavu" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Vrátit zpět Uložení Stavu" @@ -11515,7 +11529,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11766,7 +11780,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "Použít jednu mezipaměť hloubky pro obě oči. Potřebné pro pár her." @@ -11804,7 +11818,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11998,7 +12012,7 @@ msgstr "Zvýšit hlasitost" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12099,7 +12113,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Varování" @@ -12282,11 +12296,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12503,6 +12517,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12539,7 +12559,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "automaticky" @@ -12572,7 +12592,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "předstírat dokončení" @@ -12616,7 +12636,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "žádné" diff --git a/Languages/po/da.po b/Languages/po/da.po index a74d1666b3..c27a3cdfd7 100644 --- a/Languages/po/da.po +++ b/Languages/po/da.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Lars Lyngby , 2020-2022\n" "Language-Team: Danish (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -327,7 +327,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Om" @@ -348,7 +348,7 @@ msgstr "&Tilføj funktion" msgid "&Add..." msgstr "&Tilføj..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Lydindstillinger" @@ -356,7 +356,7 @@ msgstr "&Lydindstillinger" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automatisk start" @@ -364,11 +364,11 @@ msgstr "&Automatisk start" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Breakpoints" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -376,15 +376,15 @@ msgstr "" msgid "&Cancel" msgstr "&Annuller" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Snydemanager" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Tjek for opdateringer..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Ryd symboler" @@ -392,7 +392,7 @@ msgstr "&Ryd symboler" msgid "&Clone..." msgstr "&Klon..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Kode" @@ -400,7 +400,7 @@ msgstr "&Kode" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Kontrollerindstillinger" @@ -439,11 +439,11 @@ msgstr "&Rediger kode..." msgid "&Edit..." msgstr "&Rediger..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Skub disk ud" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulation" @@ -463,27 +463,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fil" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Skrifttype..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Billedfremskydning" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub-repertoire" @@ -491,15 +491,15 @@ msgstr "&GitHub-repertoire" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Grafikindstillinger" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Hjælp" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Genvejstastindstillinger" @@ -519,7 +519,7 @@ msgstr "" msgid "&Import..." msgstr "&Importér..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -531,7 +531,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -539,11 +539,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Sprog:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Indlæs Tilstand" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -557,15 +557,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Hukommelse" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Film" @@ -573,7 +573,7 @@ msgstr "&Film" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -582,23 +582,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Åbn..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Indstillinger" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pause" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Afspil" @@ -606,7 +606,7 @@ msgstr "&Afspil" msgid "&Properties" msgstr "&Indstillinger" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Read-Only Tilstand" @@ -614,7 +614,7 @@ msgstr "&Read-Only Tilstand" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registre" @@ -632,15 +632,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Nulstil" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -648,7 +648,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -656,7 +656,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&Hastighedsgrænse:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Stop" @@ -664,11 +664,11 @@ msgstr "&Stop" msgid "&Theme:" msgstr "&Tema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Værktøjer" @@ -682,17 +682,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Vis" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Betragt" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Website" @@ -704,11 +704,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1139,7 +1139,7 @@ msgid "Accuracy:" msgstr "Nøjagtighed:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1313,7 +1313,7 @@ msgstr "Tilføj..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adresse" @@ -1542,15 +1542,15 @@ msgstr "Anti-Aliasing:" msgid "Any Region" msgstr "Alle regioner" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1568,7 +1568,7 @@ msgstr "Apploader Dato:" msgid "Apply" msgstr "Anvend" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1675,7 +1675,7 @@ msgstr "" msgid "Auto-Hide" msgstr "Auto-skjul" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1778,7 +1778,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1850,7 +1850,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Blokstørrelse" @@ -1888,7 +1888,7 @@ msgstr "" "Bluetooth gennemgangstilstand er aktiveret, men Dolphin blev bygget uden " "libusb. Gennemgangstilstand kan ikke bruges." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1965,7 +1965,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -2027,7 +2027,7 @@ msgstr "" msgid "C Stick" msgstr "C-Stick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2123,7 +2123,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2194,7 +2194,7 @@ msgstr "" msgid "Change &Disc" msgstr "Skift &Disk" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Skift &Disk..." @@ -2256,7 +2256,7 @@ msgstr "Snydesøgning" msgid "Cheats Manager" msgstr "Snydemanager" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Tjek NAND..." @@ -2294,11 +2294,11 @@ msgstr "Angiv en fil at åbne" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2333,7 +2333,7 @@ msgstr "Klassisk kontroller" msgid "Clear" msgstr "Ryd" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Ryd cache" @@ -2354,7 +2354,7 @@ msgstr "Klon og &Rediger kode..." msgid "Close" msgstr "Luk" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "&Konfiguration" @@ -2401,7 +2401,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2438,7 +2438,7 @@ msgstr "Kompilerer shaders" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2574,7 +2574,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Bekræft ved Stop" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2585,7 +2585,7 @@ msgstr "Bekræftelse" msgid "Connect" msgstr "Tilslut" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Forbind Balanceboard" @@ -2593,7 +2593,7 @@ msgstr "Forbind Balanceboard" msgid "Connect USB Keyboard" msgstr "Forbind USB Tastatur" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Tilslut Wii Remote %1" @@ -2613,7 +2613,7 @@ msgstr "Tilslut Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Tilslut Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Tilslut Wii Remotes" @@ -2738,7 +2738,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Konvergens:" @@ -3063,7 +3063,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3259,7 +3259,7 @@ msgstr "" msgid "Default" msgstr "Standard" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3319,7 +3319,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3332,7 +3332,7 @@ msgstr "Dybde:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Beskrivelse" @@ -3354,11 +3354,11 @@ msgstr "" msgid "Detect" msgstr "Opfang" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3433,7 +3433,7 @@ msgstr "Deaktiver EFB VRAM kopier" msgid "Disable Emulation Speed Limit" msgstr "Deaktiver begrænsning af emulationshastighed" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3441,7 +3441,7 @@ msgstr "" msgid "Disable Fog" msgstr "Deaktivér tåge" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Deaktiver JIT Cache" @@ -3514,7 +3514,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3545,17 +3545,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3716,7 +3716,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Dump Lyd" @@ -3728,7 +3728,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Drop EFB Mål" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Dump Billeder" @@ -3806,7 +3806,7 @@ msgstr "" msgid "Dutch" msgstr "Hollandsk" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "F&orlad" @@ -3854,7 +3854,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3921,7 +3921,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4074,7 +4074,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4116,7 +4116,7 @@ msgstr "" "Aktiverer Dolby Pro Logic II emulering med 5.1 surround. Kun udvalgte " "backends." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4180,7 +4180,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4265,7 +4265,7 @@ msgstr "Indtast kodeord" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4312,18 +4312,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4462,7 +4462,7 @@ msgstr "Fejl fundet i {0} ubrugte blokke i {1} partitionen." msgid "Euphoria" msgstr "Eufori" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4543,7 +4543,7 @@ msgstr "" msgid "Experimental" msgstr "Eksperimentel" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Eksporter alle Wii-saves" @@ -4558,7 +4558,7 @@ msgstr "" msgid "Export Recording" msgstr "Eksporter optagelse" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Eksporter optagelse..." @@ -4586,7 +4586,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4614,7 +4614,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "Ekstern framebuffer (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4652,7 +4652,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO-afspiller" @@ -4670,7 +4670,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4764,7 +4764,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4791,18 +4791,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4829,7 +4829,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4839,8 +4839,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4852,7 +4852,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -5024,19 +5024,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5084,7 +5084,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5130,7 +5130,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5144,18 +5144,18 @@ msgstr "Filinfo" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Filnavn" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Filstørrelse" @@ -5668,7 +5668,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Spil-id" @@ -5712,7 +5712,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Specifikke spilindstillinger" @@ -5783,7 +5783,7 @@ msgid "Gecko Codes" msgstr "Gecko-koder" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5809,7 +5809,7 @@ msgstr "Generer en ny identitet til statistik" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5886,7 +5886,7 @@ msgstr "Grøn venstre" msgid "Green Right" msgstr "Grøn højre" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5961,7 +5961,7 @@ msgstr "Heksadecimal" msgid "Hide" msgstr "Skjul" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6243,7 +6243,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6258,7 +6258,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importer Wii-save..." @@ -6363,8 +6363,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Information" @@ -6373,10 +6373,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Input" @@ -6417,7 +6417,7 @@ msgstr "" msgid "Install Update" msgstr "Installer opdatering" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Installere WAD..." @@ -6437,7 +6437,7 @@ msgstr "Instruktion" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instruktion:" @@ -6500,7 +6500,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Interpreter (langsomst)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6525,7 +6525,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6600,11 +6600,11 @@ msgstr "Italiensk" msgid "Italy" msgstr "Italien" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT blok sammenkædning slået fra" @@ -6612,47 +6612,47 @@ msgstr "JIT blok sammenkædning slået fra" msgid "JIT Blocks" msgstr "JIT blokke" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6664,11 +6664,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6679,7 +6679,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japan" @@ -6738,7 +6738,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Smid spiller ud" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -6883,11 +6883,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6903,11 +6903,11 @@ msgstr "" msgid "Load" msgstr "Indlæs" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6919,7 +6919,7 @@ msgstr "Indlæs tilpassede teksturer" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -7029,19 +7029,19 @@ msgstr "Indlæs tilstand plads 8" msgid "Load State Slot 9" msgstr "Indlæs tilstand plads 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Indlæs tilstand fra valgte plads" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Indlæs tilstand fra plads" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -7053,16 +7053,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Indlæs fra plads %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7070,7 +7070,7 @@ msgstr "" msgid "Load..." msgstr "Indlæs..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7109,7 +7109,7 @@ msgstr "Log" msgid "Log Configuration" msgstr "Konfiguration af log" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7189,7 +7189,7 @@ msgstr "Primært stik" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Udgiver" @@ -7206,10 +7206,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7260,7 +7261,7 @@ msgstr "Hukommelsesbreakpoint" msgid "Memory Card" msgstr "Hukommelseskort" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7347,8 +7348,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7356,7 +7357,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskopiske skygger" @@ -7419,9 +7420,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND tjek" @@ -7430,7 +7432,7 @@ msgstr "NAND tjek" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7456,7 +7458,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7664,7 +7666,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7725,7 +7727,7 @@ msgstr "Ingen" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Ikke sat" @@ -7847,7 +7849,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Online&dokumentation" @@ -7855,13 +7857,13 @@ msgstr "Online&dokumentation" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7876,7 +7878,7 @@ msgstr "Åbn" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7982,11 +7984,11 @@ msgstr "Andet spil..." msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Spi&l inputoptagelse..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8088,7 +8090,7 @@ msgstr "Stier" msgid "Pause" msgstr "Pause" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pause ved slutning på film" @@ -8126,7 +8128,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Per-pixel belysning" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8160,7 +8162,7 @@ msgstr "" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8177,7 +8179,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Platform" @@ -8408,7 +8410,7 @@ msgstr "" msgid "Public" msgstr "Offentlig" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8464,11 +8466,11 @@ msgstr "R-analog" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8622,7 +8624,7 @@ msgid "Refreshing..." msgstr "Genindlæser..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Region" @@ -8720,7 +8722,7 @@ msgstr "Nulstil" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8952,11 +8954,11 @@ msgstr "" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Ge&m tilstand" @@ -8979,7 +8981,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -9000,11 +9002,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9066,23 +9068,23 @@ msgstr "Gem tilstand plads 8" msgid "Save State Slot 9" msgstr "Gem tilstand plads 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Gem tilstand til ældste plads" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Gem tilstand til valgte plads" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Gem tilstand til plads" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9102,11 +9104,11 @@ msgstr "" msgid "Save as..." msgstr "Gem som..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9117,11 +9119,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9129,7 +9131,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Gem til plads %1 - %2" @@ -9163,7 +9165,7 @@ msgstr "Skærmdump" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Søg" @@ -9190,7 +9192,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9198,7 +9200,7 @@ msgstr "" msgid "Search games..." msgstr "Søg spil..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Søg instruktion" @@ -9235,7 +9237,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9279,7 +9281,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Vælg plads %1 - %2" @@ -9287,7 +9289,7 @@ msgstr "Vælg plads %1 - %2" msgid "Select State" msgstr "Vælg tilstand" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Vælg tilstand plads" @@ -9373,7 +9375,7 @@ msgstr "" msgid "Select a game" msgstr "Vælg et spil" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9381,7 +9383,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9398,7 +9400,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Vælg savefilen" @@ -9608,11 +9610,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Vis &log" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Vis &værktøjslinje" @@ -9620,11 +9622,11 @@ msgstr "Vis &værktøjslinje" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Vis Australien" @@ -9637,7 +9639,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Vis ELF/DOL" @@ -9650,7 +9652,7 @@ msgstr "" msgid "Show FPS" msgstr "Vis FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Vis billedtæller" @@ -9658,15 +9660,15 @@ msgstr "Vis billedtæller" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Vis Frankrig" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Vis GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Vis Tyskland" @@ -9678,23 +9680,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Vis input" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Vis Italien" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Vis Korea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Vis lag-tæller" @@ -9702,7 +9704,7 @@ msgstr "Vis lag-tæller" msgid "Show Language:" msgstr "Vis sprog:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Vis log&konfiguration" @@ -9714,7 +9716,7 @@ msgstr "Vis NetPlay meddelelser" msgid "Show NetPlay Ping" msgstr "Vis NetPlay ping" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Vis Holland" @@ -9722,7 +9724,7 @@ msgstr "Vis Holland" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Vis PAL" @@ -9735,19 +9737,19 @@ msgstr "Vis PC" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Vis platforme" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Vis regioner" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Vis Rusland" @@ -9755,7 +9757,7 @@ msgstr "Vis Rusland" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Vis Spanien" @@ -9767,19 +9769,19 @@ msgstr "" msgid "Show Statistics" msgstr "Vis statistikker" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Vis systemur" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Vis Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Vis USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Vis ukendte" @@ -9791,15 +9793,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Vis WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Vis Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Vis verden" @@ -9908,7 +9910,7 @@ msgstr "Sidelæns skift" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10148,7 +10150,7 @@ msgstr "Standardkontroller" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Start &NetPlay..." @@ -10156,7 +10158,7 @@ msgstr "Start &NetPlay..." msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Start med at &optage input" @@ -10250,7 +10252,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Tilstand for stereoskopisk 3D:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopi" @@ -10272,7 +10274,7 @@ msgstr "Stik" msgid "Stop" msgstr "Stop" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10343,8 +10345,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Succes" @@ -10371,7 +10373,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10383,12 +10385,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10481,7 +10483,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symboler" @@ -10501,7 +10503,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "Synkroniser GPU-tråd" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10530,7 +10532,7 @@ msgstr "" msgid "System Language:" msgstr "Systemsprog:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS-input" @@ -10543,7 +10545,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10561,7 +10563,7 @@ msgstr "" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Tag skærmbillede" @@ -10643,13 +10645,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10919,6 +10921,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10950,6 +10958,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10978,7 +10992,7 @@ msgstr "Der er intet af fortryde!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11176,13 +11190,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "Værdien tilføjes til grafikindstillingernes konvergensværdi" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "Værdien ganges med grafikindstillingernes dybdeindstilling" @@ -11235,7 +11249,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Titel" @@ -11249,7 +11263,7 @@ msgstr "Til" msgid "To:" msgstr "Til:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Aktiver &fuldskærm" @@ -11495,7 +11509,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11563,11 +11577,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Fortryd indlæsning af tilstand" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Fortræd lagring af tilstand" @@ -11585,7 +11599,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11836,7 +11850,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "Brug en enkelt dybte-buffer til begge øjne. Nødvendig til nogle spil." @@ -11874,7 +11888,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Brugerindstillinger" @@ -12068,7 +12082,7 @@ msgstr "Skru lyde op" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD-filer (*.wad)" @@ -12169,7 +12183,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Advarsel" @@ -12354,11 +12368,11 @@ msgstr "Wii og Wii Remote" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12578,6 +12592,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12614,7 +12634,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "auto" @@ -12647,7 +12667,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "falsk-udførsel" @@ -12691,7 +12711,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "ingen" diff --git a/Languages/po/de.po b/Languages/po/de.po index 16debcdf9e..1328d5ebea 100644 --- a/Languages/po/de.po +++ b/Languages/po/de.po @@ -33,7 +33,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Marc Godhusen , 2016-2022\n" "Language-Team: German (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -349,7 +349,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Über" @@ -370,7 +370,7 @@ msgstr "Funktion &hinzufügen" msgid "&Add..." msgstr "&Hinzufügen..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Audioeinstellungen" @@ -378,7 +378,7 @@ msgstr "&Audioeinstellungen" msgid "&Auto Update:" msgstr "&Automatisches Update" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automatischer Start" @@ -386,11 +386,11 @@ msgstr "&Automatischer Start" msgid "&Borderless Window" msgstr "&Randloses Fenster" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Haltepunkte" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Bug Tracker" @@ -398,15 +398,15 @@ msgstr "&Bug Tracker" msgid "&Cancel" msgstr "&Abbrechen" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Cheats-Manager" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Auf Updates prüfen..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "Symbole lös&chen" @@ -414,7 +414,7 @@ msgstr "Symbole lös&chen" msgid "&Clone..." msgstr "&Klonen..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Code" @@ -422,7 +422,7 @@ msgstr "&Code" msgid "&Connected" msgstr "&Verbunden" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Controller-Einstellungen" @@ -461,11 +461,11 @@ msgstr "Code b&earbeiten..." msgid "&Edit..." msgstr "B&earbeiten..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Disc auswerfen" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulation" @@ -485,27 +485,27 @@ msgstr "&Spielstand exportieren..." msgid "&Export as .gci..." msgstr "&Als GCI exportieren..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Datei" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "Schri&ftart..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Einzelbildwiedergabe" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "&Freies Umsehen-Einstellungen" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "Symbole erzeu&gen aus" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub-Repositorium" @@ -513,15 +513,15 @@ msgstr "&GitHub-Repositorium" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Grafikeinstellungen" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Hilfe" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Tastenkürzel-Einstellungen" @@ -541,7 +541,7 @@ msgstr "&Spielstand importieren..." msgid "&Import..." msgstr "&Importieren..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -553,7 +553,7 @@ msgstr "blr &einfügen" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -561,11 +561,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Sprache:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "Spielstand &laden" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "Symbolkarte &laden" @@ -579,15 +579,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "Widgets an Ort und Stelle &sperren" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Arbeitsspeicher" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "Fil&m" @@ -595,7 +595,7 @@ msgstr "Fil&m" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Netzwerk" @@ -604,23 +604,23 @@ msgid "&No" msgstr "&Nein" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "Ö&ffnen..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Optionen" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&HLE-Funktionen patchen" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "Pau&se" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Start" @@ -628,7 +628,7 @@ msgstr "&Start" msgid "&Properties" msgstr "&Eigenschaften" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "Nu&r-Lese-Modus" @@ -636,7 +636,7 @@ msgstr "Nu&r-Lese-Modus" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Register" @@ -654,15 +654,15 @@ msgid "&Rename symbol" msgstr "Symbol &umbenennen" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Reset" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Ressourcenpaketverwaltung" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "Symbolkarte &speichern" @@ -670,7 +670,7 @@ msgstr "Symbolkarte &speichern" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -678,7 +678,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&Geschwindigkeitsbegrenzung:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "Sto&pp" @@ -686,11 +686,11 @@ msgstr "Sto&pp" msgid "&Theme:" msgstr "&Design:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Threads" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "E&xtras" @@ -704,17 +704,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Ansicht" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Überwachungsfenster" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Webseite" @@ -726,11 +726,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Ja" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "Konnte '%1' nicht finden, es wurden keine Symbolnamen generiert" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" "'%1' konnte nicht gefunden werden, es wird stattdessen nach gemeinsamen " @@ -1178,7 +1178,7 @@ msgid "Accuracy:" msgstr "Genauigkeit:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1368,7 +1368,7 @@ msgstr "Hinzufügen..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adresse" @@ -1621,15 +1621,15 @@ msgstr "Anti-Aliasing:" msgid "Any Region" msgstr "Beliebige Region" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Signatur anfügen an" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "An &vorhandene Signaturdatei anfügen..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Signaturdatei an&wenden..." @@ -1649,7 +1649,7 @@ msgstr "Apploader Datum:" msgid "Apply" msgstr "Übernehmen" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Signaturdatei anwenden" @@ -1760,7 +1760,7 @@ msgstr "Fenstergröße automatisch anpassen" msgid "Auto-Hide" msgstr "Automatisch verbergen" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "RSO-Module automatisch erkennen?" @@ -1868,7 +1868,7 @@ msgstr "Unzulässigen Wert angegeben." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1942,7 +1942,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Blockgröße" @@ -1980,7 +1980,7 @@ msgstr "" "Bluetooth-Durchleitungsmodus ist aktiviert, aber Dolphin wurde ohne libusb " "gebaut. Durchleitungsmodus kann nicht verwendet werden." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Pausieren nach Boot" @@ -2057,7 +2057,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "&NetPlay-Sitzungen durchsuchen...." @@ -2122,7 +2122,7 @@ msgstr "" msgid "C Stick" msgstr "C-Stick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "Signatu&rdatei erstellen..." @@ -2226,7 +2226,7 @@ msgstr "Du kannst keine NetPlay-Session starten, während ein Spiel noch läuft! #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2301,7 +2301,7 @@ msgstr "Zentrieren und Kalibrieren" msgid "Change &Disc" msgstr "Disc &wechseln" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Disc &wechseln..." @@ -2374,7 +2374,7 @@ msgstr "Cheatsuche" msgid "Cheats Manager" msgstr "Cheat-Verwaltung" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "NAND prüfen..." @@ -2414,11 +2414,11 @@ msgstr "Datei zum Öffnen auswählen" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Vorrangige Eingabedatei auswählen" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Sekundäre Eingabedatei auswählen" @@ -2453,7 +2453,7 @@ msgstr "Klassischer Controller" msgid "Clear" msgstr "Leeren" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Cache leeren" @@ -2474,7 +2474,7 @@ msgstr "Code b&earbeiten und klonen..." msgid "Close" msgstr "Schließen" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Ko&nfiguration" @@ -2521,7 +2521,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "&Zwei Signaturdateien kombinieren..." @@ -2558,7 +2558,7 @@ msgstr "Kompiliere Shader" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Komprimierung" @@ -2694,7 +2694,7 @@ msgstr "Ändern des Backends bestätigen" msgid "Confirm on Stop" msgstr "Beim Beenden bestätigen" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2705,7 +2705,7 @@ msgstr "Bestätigung" msgid "Connect" msgstr "Verbinden" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Balance Bord anschließen" @@ -2713,7 +2713,7 @@ msgstr "Balance Bord anschließen" msgid "Connect USB Keyboard" msgstr "USB-Tastatur verbunden" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Wiimote %1 verbinden" @@ -2733,7 +2733,7 @@ msgstr "Wiimote 3 verbinden" msgid "Connect Wii Remote 4" msgstr "Wiimote 4 verbinden" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Wiimotes verbinden" @@ -2875,7 +2875,7 @@ msgstr "" msgid "Convergence" msgstr "Konvergenz" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Konvergenz:" @@ -3232,7 +3232,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Aktuelle Region" @@ -3432,7 +3432,7 @@ msgstr "Reduziere Y" msgid "Default" msgstr "Standard" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Standard-Einstellungen (nur lesen)" @@ -3498,7 +3498,7 @@ msgstr "Vorhandende Datei '{0}' löschen?" msgid "Depth" msgstr "Tiefe" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Tiefe in Prozent:" @@ -3511,7 +3511,7 @@ msgstr "Tiefe:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Beschreibung" @@ -3533,11 +3533,11 @@ msgstr "Gelöst" msgid "Detect" msgstr "Erkenne" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Deterministischer Doppelkern: " @@ -3612,7 +3612,7 @@ msgstr "EFB VRAM-Kopien deaktivieren" msgid "Disable Emulation Speed Limit" msgstr "Geschwindigkeitsbegrenzung ausschalten" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Fastmem deaktivieren" @@ -3620,7 +3620,7 @@ msgstr "Fastmem deaktivieren" msgid "Disable Fog" msgstr "Nebel deaktivieren" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "JIT-Zwischenspeicher deaktivieren" @@ -3711,7 +3711,7 @@ msgstr "Dolphin autorisieren, Informationen an das Entwicklerteam zu senden?" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Möchtest du \"%1\" zur Liste der Spielverzeichnisse hinzufügen?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Möchtest du die Liste der Symbolnamen löschen?" @@ -3742,17 +3742,17 @@ msgstr "Dolphin FIFO-Log (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin-Kartendatei (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Dolphin-Signatur-CSV-Datei" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Dolphin-Signaturdatei" @@ -3919,7 +3919,7 @@ msgstr "&FakeVMEM dumpen" msgid "Dump &MRAM" msgstr "&MRAM dumpen" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Audio dumpen" @@ -3931,7 +3931,7 @@ msgstr "Basistexturen dumpen" msgid "Dump EFB Target" msgstr "EFB-Target dumpen" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Frames dumpen" @@ -4012,7 +4012,7 @@ msgstr "Freigabedauer der Turbo-Taste (Frames):" msgid "Dutch" msgstr "Holländisch" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Beenden" @@ -4067,7 +4067,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Editor" @@ -4134,7 +4134,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4290,7 +4290,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4332,7 +4332,7 @@ msgstr "" "Aktiviert Dolby Pro Logic II-Emulation mit 5.1 Sorround. Wird nur von " "einigen Backends unterstützt." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4412,7 +4412,7 @@ msgstr "" "Systemen, die eine schwache CPU haben.

Im Zweifel " "deaktiviert lassen." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4499,7 +4499,7 @@ msgstr "Passwort eingeben" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Geben Sie die RSO-Moduladresse ein:" @@ -4546,18 +4546,18 @@ msgstr "Geben Sie die RSO-Moduladresse ein:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4705,7 +4705,7 @@ msgstr "" msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4786,7 +4786,7 @@ msgstr "" msgid "Experimental" msgstr "Experimentell" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Alle Wii-Spielstände exportieren" @@ -4801,7 +4801,7 @@ msgstr "" msgid "Export Recording" msgstr "Aufnahme exportieren" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Aufnahme exportieren..." @@ -4829,7 +4829,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4857,7 +4857,7 @@ msgstr "Extern" msgid "External Frame Buffer (XFB)" msgstr "Externer Bildspeicher (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Zertifikate aus NAND extrahieren" @@ -4895,7 +4895,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO-Player" @@ -4915,7 +4915,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Konnte diese Sitzung nicht zum NetPlay Index hinzufügen: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Konnte nicht an Signaturdatei '%1' anfügen." @@ -5011,7 +5011,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "Konnte folgende Spielstände nicht exportieren:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Konnte Zertifikate aus NAND nicht extrahieren" @@ -5041,14 +5041,14 @@ msgstr "Ein oder mehrere D3D-Symbole konnten nicht gefunden werden" msgid "Failed to import \"%1\"." msgstr "Konnte \"%1\" nicht importieren." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Konnte Spielstand nicht importieren. Bitte starte das Spiel einmal und " "versuche es danach erneut." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5056,7 +5056,7 @@ msgstr "" "Konnte Spielstand nicht importieren. Die gegebene Datei scheint beschädigt " "zu sein oder ist kein gültiger Wii-Spielstand." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5087,7 +5087,7 @@ msgid "Failed to install pack: %1" msgstr "Konnte Paket: %1 nicht installieren" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Konnte diesen Titel nicht in den NAND installieren." @@ -5099,8 +5099,8 @@ msgstr "" "Fehler beim Lauschen auf Port %1. Wird eine andere Instanz des NetPlay-" "Servers ausgeführt?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Konnte RSO-Modul an %1 nicht laden" @@ -5112,7 +5112,7 @@ msgstr "Fehler beim Laden der Datei d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "Fehler beim Laden der Datei dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Konnte Kartendatei '%1' nicht laden" @@ -5300,19 +5300,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Konnte FIFO-Log nicht speichern." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Konnte Codekarte nicht in Pfad '%1' speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Konnte Signaturdatei '%1' nicht speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Konnte Symbolkarte nicht in Pfad '%1' speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Konnte nicht an Signaturdatei '%1' speichern." @@ -5362,7 +5362,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Fehler" @@ -5410,7 +5410,7 @@ msgstr "Dateidetails" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Dateiformat" @@ -5424,18 +5424,18 @@ msgstr "Datei-Informationen" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Dateiname" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Dateipfad" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Dateigröße" @@ -5988,7 +5988,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Spielkennung" @@ -6034,7 +6034,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Spielspezifische Einstellungen" @@ -6105,7 +6105,7 @@ msgid "Gecko Codes" msgstr "Gecko-Codes" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6131,7 +6131,7 @@ msgstr "Neue Statistikidentität erzeugen" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Generierte Symbolnamen von '%1'" @@ -6213,7 +6213,7 @@ msgstr "Grün links" msgid "Green Right" msgstr "Grün rechts" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Tabellenansicht" @@ -6288,7 +6288,7 @@ msgstr "Hexadezimal" msgid "Hide" msgstr "Verbergen" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Alles verbergen" @@ -6617,7 +6617,7 @@ msgstr "" "Performance etwas.

Im Zweifel deaktiviert lassen." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "BootMii-NAND-Sicherung importieren..." @@ -6632,7 +6632,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Wii-Spielstand importieren..." @@ -6744,8 +6744,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Information" @@ -6754,10 +6754,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Bildschirmschoner während der Emulation sperren" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Eingabe" @@ -6798,7 +6798,7 @@ msgstr "" msgid "Install Update" msgstr "Update installieren" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "WAD installieren..." @@ -6818,7 +6818,7 @@ msgstr "Anweisung" msgid "Instruction Breakpoint" msgstr "Anweisungshaltepunkt" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Anweisung:" @@ -6883,7 +6883,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Interpreter (am langsamsten)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Interpreterkern" @@ -6908,7 +6908,7 @@ msgstr "Ungültiges Paket %1 angegeben: &2" msgid "Invalid Player ID" msgstr "Ungültige Spieler-ID" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Ungültige RSO-Moduladresse: %1" @@ -6983,11 +6983,11 @@ msgstr "Italienisch" msgid "Italy" msgstr "Italien" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT-Blockverbindung Aus" @@ -6995,47 +6995,47 @@ msgstr "JIT-Blockverbindung Aus" msgid "JIT Blocks" msgstr "JIT-Blöcke" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT Zweig Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FließKomma Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Ganzahl Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LadenSpeichern Fließkomma Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LadenSpeichern Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LadenSpeichern Gekoppelt Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LadenSpeichern lXz Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT LadenSpeichern lbzx Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LadenSpeichern lwz Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Aus (JIT-Kern)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Gekoppelt Aus" @@ -7047,11 +7047,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "JIT-Register-Cache Aus" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT-SystemRegister Aus" @@ -7065,7 +7065,7 @@ msgstr "" "niemals passieren. Melde bitte diesen Vorfall im Bug-Tracker. Dolphin wird " "jetzt beendet." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japan" @@ -7124,7 +7124,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Spieler hinauswerfen" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -7275,11 +7275,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "Uploadblock-Geschwindigkeit begrenzen:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Listen-Spalten" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Listenansicht" @@ -7295,11 +7295,11 @@ msgstr "Lauscht" msgid "Load" msgstr "Laden" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "&Ungültige Kartendatei laden..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "&Andere Kartendatei laden..." @@ -7311,7 +7311,7 @@ msgstr "Lade benutzerdefinierte Texturen" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "GameCube-Hauptmenü laden" @@ -7421,19 +7421,19 @@ msgstr "Spielstand in Slot 8 laden" msgid "Load State Slot 9" msgstr "Spielstand in Slot 9 laden" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Spielstand von Datei laden" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Spielstand vom ausgewählten Slot laden" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Spielstand von Slot laden" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Wii-Systemmenü laden %1" @@ -7445,16 +7445,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "Spielstand vom ausgewählten Slot laden" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Lade von Slot %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Kartendatei laden" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7462,7 +7462,7 @@ msgstr "" msgid "Load..." msgstr "Laden..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Geladene Symbole von '%1'" @@ -7504,7 +7504,7 @@ msgstr "Log" msgid "Log Configuration" msgstr "Protokollkonfiguration" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "JIT-Anweisungsabdeckung protokollieren" @@ -7584,7 +7584,7 @@ msgstr "Main Stick" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Hersteller" @@ -7605,10 +7605,11 @@ msgstr "" "machen, die die korrekte Nebelemulation benötigen." "

Im Zweifel deaktiviert lassen." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "NAND verwalten" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7659,7 +7660,7 @@ msgstr "Speicherhaltepunkt" msgid "Memory Card" msgstr "Speicherkarte" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Speicherkartenverwaltung" @@ -7755,8 +7756,8 @@ msgstr "" "

Benötigt in den meisten Fällen einen Reset der Emulation." "

Im Zweifel deaktiviert lassen." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7764,7 +7765,7 @@ msgstr "" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskopische Schatten" @@ -7827,9 +7828,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND-Prüfung" @@ -7838,7 +7840,7 @@ msgstr "NAND-Prüfung" msgid "NKit Warning" msgstr "NKit-Warnung" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7864,7 +7866,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8072,7 +8074,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Es wurden keine Probleme festgestellt." @@ -8137,7 +8139,7 @@ msgstr "Keine" msgid "North America" msgstr "Nordamerika" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Nicht Festgelegt" @@ -8259,7 +8261,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Online-&Dokumentation" @@ -8267,7 +8269,7 @@ msgstr "Online-&Dokumentation" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8275,7 +8277,7 @@ msgstr "" "Nur Symbole anhängen mit dem Präfix:\n" "(Leer für alle Symbole)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8292,7 +8294,7 @@ msgstr "Öffnen" msgid "Open &Containing Folder" msgstr "Über&geordneten Ordner öffnen" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -8398,11 +8400,11 @@ msgstr "Anderes Spiel..." msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Eingabeau&fzeichnung wiedergeben..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8504,7 +8506,7 @@ msgstr "Pfade" msgid "Pause" msgstr "Pause" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pause am Filmende" @@ -8542,7 +8544,7 @@ msgstr "Spitzengeschwindigkeit von nach außen gerichteten Schwenkbewegungen." msgid "Per-Pixel Lighting" msgstr "Per-Pixel Lighting" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Online-Systemaktualisierung durchführen" @@ -8576,7 +8578,7 @@ msgstr "" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Wähle eine Debug-Schriftart" @@ -8593,7 +8595,7 @@ msgid "Pitch Up" msgstr "Nicken aufwärts" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Plattform" @@ -8839,7 +8841,7 @@ msgstr "Fortschritt" msgid "Public" msgstr "Öffentlich" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Spielelisten Cache leeren" @@ -8895,11 +8897,11 @@ msgstr "R-Analog" msgid "READY" msgstr "BEREIT" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO-Module" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "Automatische RSO-Erkennung" @@ -9059,7 +9061,7 @@ msgid "Refreshing..." msgstr "Aktualisiere..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Region" @@ -9162,7 +9164,7 @@ msgstr "Zurücksetzen" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -9394,11 +9396,11 @@ msgstr "SSL-Kontext" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Code speich&ern" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "S&pielstand speichern" @@ -9421,7 +9423,7 @@ msgstr "Alle speichern" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Export speichern" @@ -9442,11 +9444,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Import speichern" @@ -9508,23 +9510,23 @@ msgstr "In Slot 8 speichern" msgid "Save State Slot 9" msgstr "In Slot 9 speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Spielstand in Datei speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Spielstand in ältesten Slot speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Spielstand im ausgewählten Slot speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Spielstand in Slot speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Symbolkarte speichern &als..." @@ -9544,11 +9546,11 @@ msgstr "" msgid "Save as..." msgstr "Speichern unter..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Kombinierte Ausgabedatei speichern als" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9562,11 +9564,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Kartendatei speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Signaturdatei speichern" @@ -9574,7 +9576,7 @@ msgstr "Signaturdatei speichern" msgid "Save to Selected Slot" msgstr "Spielstand im ausgewählten Slot speichern" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Spielstand in Slot %1 - %2 speichern" @@ -9610,7 +9612,7 @@ msgstr "ScrShot" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Suche" @@ -9637,7 +9639,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Suche nach einer Anweisung" @@ -9645,7 +9647,7 @@ msgstr "Suche nach einer Anweisung" msgid "Search games..." msgstr "Suche Spiele..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Suchanweisung" @@ -9683,7 +9685,7 @@ msgid "Select Dump Path" msgstr "Dump-Pfad auswählen" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Export-Verzeichnis auswählen" @@ -9727,7 +9729,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Slot %1 - %2 auswählen" @@ -9735,7 +9737,7 @@ msgstr "Slot %1 - %2 auswählen" msgid "Select State" msgstr "Spielstand auswählen" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Spielstand-Slot auswählen" @@ -9821,7 +9823,7 @@ msgstr "" msgid "Select a game" msgstr "Spiel auswählen" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Wähle einen Titel zum Installieren in den NAND aus." @@ -9829,7 +9831,7 @@ msgstr "Wähle einen Titel zum Installieren in den NAND aus." msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Wählen Sie die RSO-Moduladresse aus:" @@ -9846,7 +9848,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Wähle die Schlüsseldateien (OTP/SEEPROM Dump)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Wii-Spielstand auswählen" @@ -10075,11 +10077,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "&Log anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "&Werkzeugleiste anzeigen" @@ -10087,11 +10089,11 @@ msgstr "&Werkzeugleiste anzeigen" msgid "Show Active Title in Window Title" msgstr "Aktiven Titel in Fenstertitel anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Alles anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Australien anzeigen" @@ -10104,7 +10106,7 @@ msgstr "Zeige momentanes Spiel auf Discord" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL anzeigen" @@ -10117,7 +10119,7 @@ msgstr "" msgid "Show FPS" msgstr "FPS anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Bildzähler anzeigen" @@ -10125,15 +10127,15 @@ msgstr "Bildzähler anzeigen" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Frankreich anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "GameCube anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Deutschland anzeigen" @@ -10145,23 +10147,23 @@ msgstr "Golf-Modus-Überlagerung anzeigen" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Eingabebildschirm anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Italien anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Korea anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Lag-Zähler anzeigen" @@ -10169,7 +10171,7 @@ msgstr "Lag-Zähler anzeigen" msgid "Show Language:" msgstr "Anzeigesprache:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Protokoll&konfiguration anzeigen" @@ -10181,7 +10183,7 @@ msgstr "NetPlay-Nachrichten anzeigen" msgid "Show NetPlay Ping" msgstr "NetPlay-Ping anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Niederlande anzeigen" @@ -10189,7 +10191,7 @@ msgstr "Niederlande anzeigen" msgid "Show On-Screen Display Messages" msgstr "Bildschirmnachrichten zeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "PAL anzeigen" @@ -10202,19 +10204,19 @@ msgstr "PC anzeigen" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Plattformen anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Regionen anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Russland anzeigen" @@ -10222,7 +10224,7 @@ msgstr "Russland anzeigen" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Spanien anzeigen" @@ -10234,19 +10236,19 @@ msgstr "" msgid "Show Statistics" msgstr "Statistiken anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Systemuhr anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Taiwan anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "USA anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Unbekannte anzeigen" @@ -10258,15 +10260,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii anzeigen" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Welt anzeigen" @@ -10385,7 +10387,7 @@ msgstr "Seitwärts umschalten" msgid "Sideways Wii Remote" msgstr "Wiimote seitwärts" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Signaturendatenbank" @@ -10636,7 +10638,7 @@ msgstr "Standard-Controller" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "&NetPlay starten..." @@ -10644,7 +10646,7 @@ msgstr "&NetPlay starten..." msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Aufzeichnung der Eingabe starten" @@ -10738,7 +10740,7 @@ msgstr "Stereoskopischer 3D-Modus" msgid "Stereoscopic 3D Mode:" msgstr "Stereoskopischer 3D-Modus:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopie" @@ -10760,7 +10762,7 @@ msgstr "Stick" msgid "Stop" msgstr "Stopp" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Wiedergabe/Aufzeichnung der Eingabe stoppen" @@ -10841,8 +10843,8 @@ msgstr "Eingabestift" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Erfolg" @@ -10869,7 +10871,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "Spielstände wurden erfolgreich exportiert" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Zertifikate aus NAND erfolgreich extrahiert" @@ -10881,12 +10883,12 @@ msgstr "Datei erfolgreich extrahiert." msgid "Successfully extracted system data." msgstr "Systemdaten erfolgreich extrahiert." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Spielstand wurde erfolgreich importiert." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Der Titel wurde erfolgreich in den NAND installiert." @@ -10982,7 +10984,7 @@ msgstr "Symbolname:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symbole" @@ -11002,7 +11004,7 @@ msgstr "Reale Wiimotes synchronisieren und diese koppeln" msgid "Synchronize GPU thread" msgstr "GPU-Thread synchronisieren" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11033,7 +11035,7 @@ msgstr "Synchronisiere Spielstände..." msgid "System Language:" msgstr "Systemsprache:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS-Eingabe" @@ -11046,7 +11048,7 @@ msgstr "TAS-Werkzeuge" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Tags" @@ -11064,7 +11066,7 @@ msgstr "Schweif" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Screenshot erstellen" @@ -11148,7 +11150,7 @@ msgstr "Die IPL-Datei ist kein bekannter guter Dump. (CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "Die Partitionen der Meisterstücke fehlen." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11156,7 +11158,7 @@ msgstr "" "Das NAND konnte nicht repariert werden. Es wird empfohlen, deine aktuellen " "Daten zu sichern und mit einem frischen NAND neu anzufangen." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "Das NAND wurde repariert." @@ -11468,6 +11470,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "Die ausgewählte Datei \"{0}\" existiert nicht" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -11502,6 +11510,12 @@ msgstr "Die Updatepartition fehlt." msgid "The update partition is not at its normal position." msgstr "Die Update-Partition ist nicht in der normalen Position." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "Die {0} Partition hat kein gültiges Dateisystem." @@ -11530,7 +11544,7 @@ msgstr "Es gibt nichts zum rückgängig machen!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11772,14 +11786,14 @@ msgstr "" "\n" "Unbekannter ucode (CRC = {0:08x}) - erzwinge AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" "Dieser Wert wird zum Konvergenzwert aus den Grafikeinstellungen hinzugefügt." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11842,7 +11856,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Titel" @@ -11856,7 +11870,7 @@ msgstr "Zu" msgid "To:" msgstr "Zu:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "&Vollbildmodus umschalten" @@ -12113,7 +12127,7 @@ msgstr "" "Kompilierung beseitigt, während die Leistung nur minimal beeinflusst wird. " "Die Ergebnisse hängen jedoch vom Verhalten des Grafiktreibers ab." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Konnte RSO-Module nicht automatisch erkennen" @@ -12179,11 +12193,11 @@ msgstr "Unkomprimierte GC/Wii-Abbilder (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Spielstand Laden rückgängig machen" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Spielstand Speichern rückgängig machen" @@ -12204,7 +12218,7 @@ msgstr "" "Titels aus dem NAND entfernt, ohne die gespeicherten Daten zu löschen. " "Fortsetzen?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Vereinigte Staaten" @@ -12463,7 +12477,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Verwende einen einzigen Tiefenpuffer für beide Augen. Wird von einigen " @@ -12503,7 +12517,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Benutzereinstellungen" @@ -12707,7 +12721,7 @@ msgstr "Lautstärke erhöhen" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD-Dateien (*.wad)" @@ -12842,7 +12856,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Warnungen" @@ -13065,11 +13079,11 @@ msgstr "Wii und Wiimote" msgid "Wii data is not public yet" msgstr "Wii-Daten sind noch nicht öffentlich" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii-Spielstände (*.bin);;Alle Dateien (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "WiiTools MEGA-Signaturdatei" @@ -13306,6 +13320,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13342,7 +13362,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "auto" @@ -13375,7 +13395,7 @@ msgstr "" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "fake-completion" @@ -13419,7 +13439,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "kein" diff --git a/Languages/po/dolphin-emu.pot b/Languages/po/dolphin-emu.pot index a793459e56..02e613a1d2 100644 --- a/Languages/po/dolphin-emu.pot +++ b/Languages/po/dolphin-emu.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -305,7 +305,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -326,7 +326,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "" @@ -334,7 +334,7 @@ msgstr "" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -342,11 +342,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -354,15 +354,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -370,7 +370,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -378,7 +378,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "" @@ -417,11 +417,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "" @@ -441,27 +441,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -469,15 +469,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "" @@ -497,7 +497,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -509,7 +509,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "" @@ -517,11 +517,11 @@ msgstr "" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -535,15 +535,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "" @@ -551,7 +551,7 @@ msgstr "" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -560,23 +560,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "" @@ -584,7 +584,7 @@ msgstr "" msgid "&Properties" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "" @@ -592,7 +592,7 @@ msgstr "" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "" @@ -610,15 +610,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -626,7 +626,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -634,7 +634,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "" @@ -642,11 +642,11 @@ msgstr "" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "" @@ -660,17 +660,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "" @@ -682,11 +682,11 @@ msgstr "" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1103,7 +1103,7 @@ msgid "Accuracy:" msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1277,7 +1277,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "" @@ -1506,15 +1506,15 @@ msgstr "" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1532,7 +1532,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1639,7 +1639,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1742,7 +1742,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "" @@ -1814,7 +1814,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1850,7 +1850,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1927,7 +1927,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1989,7 +1989,7 @@ msgstr "" msgid "C Stick" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2085,7 +2085,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2156,7 +2156,7 @@ msgstr "" msgid "Change &Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "" @@ -2218,7 +2218,7 @@ msgstr "" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2256,11 +2256,11 @@ msgstr "" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2295,7 +2295,7 @@ msgstr "" msgid "Clear" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2316,7 +2316,7 @@ msgstr "" msgid "Close" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2363,7 +2363,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2400,7 +2400,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2536,7 +2536,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2547,7 +2547,7 @@ msgstr "" msgid "Connect" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "" @@ -2555,7 +2555,7 @@ msgstr "" msgid "Connect USB Keyboard" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2575,7 +2575,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2698,7 +2698,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3018,7 +3018,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3214,7 +3214,7 @@ msgstr "" msgid "Default" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3274,7 +3274,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3287,7 +3287,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "" @@ -3309,11 +3309,11 @@ msgstr "" msgid "Detect" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3388,7 +3388,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3396,7 +3396,7 @@ msgstr "" msgid "Disable Fog" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3469,7 +3469,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3500,17 +3500,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3671,7 +3671,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "" @@ -3683,7 +3683,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "" @@ -3761,7 +3761,7 @@ msgstr "" msgid "Dutch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "" @@ -3809,7 +3809,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3876,7 +3876,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4029,7 +4029,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4069,7 +4069,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4130,7 +4130,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4213,7 +4213,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4260,18 +4260,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4408,7 +4408,7 @@ msgstr "" msgid "Euphoria" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4489,7 +4489,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "" @@ -4504,7 +4504,7 @@ msgstr "" msgid "Export Recording" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "" @@ -4532,7 +4532,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4560,7 +4560,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4598,7 +4598,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "" @@ -4616,7 +4616,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4710,7 +4710,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4737,18 +4737,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4775,7 +4775,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4785,8 +4785,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4798,7 +4798,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4970,19 +4970,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5030,7 +5030,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5076,7 +5076,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5090,18 +5090,18 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "" @@ -5614,7 +5614,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "" @@ -5658,7 +5658,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "" @@ -5729,7 +5729,7 @@ msgid "Gecko Codes" msgstr "" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5755,7 +5755,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5832,7 +5832,7 @@ msgstr "" msgid "Green Right" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5907,7 +5907,7 @@ msgstr "" msgid "Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6181,7 +6181,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6196,7 +6196,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6301,8 +6301,8 @@ msgstr "" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "" @@ -6311,10 +6311,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "" @@ -6355,7 +6355,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6375,7 +6375,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6438,7 +6438,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6463,7 +6463,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6538,11 +6538,11 @@ msgstr "" msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6550,47 +6550,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6602,11 +6602,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6617,7 +6617,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6676,7 +6676,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6818,11 +6818,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6838,11 +6838,11 @@ msgstr "" msgid "Load" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6854,7 +6854,7 @@ msgstr "" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6964,19 +6964,19 @@ msgstr "" msgid "Load State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6988,16 +6988,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7005,7 +7005,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7044,7 +7044,7 @@ msgstr "" msgid "Log Configuration" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7124,7 +7124,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7141,10 +7141,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7195,7 +7196,7 @@ msgstr "" msgid "Memory Card" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7280,8 +7281,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7289,7 +7290,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7352,9 +7353,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7363,7 +7365,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7389,7 +7391,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7597,7 +7599,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7656,7 +7658,7 @@ msgstr "" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "" @@ -7778,7 +7780,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "" @@ -7786,13 +7788,13 @@ msgstr "" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7807,7 +7809,7 @@ msgstr "" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7913,11 +7915,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8019,7 +8021,7 @@ msgstr "" msgid "Pause" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8057,7 +8059,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8091,7 +8093,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8108,7 +8110,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8339,7 +8341,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8395,11 +8397,11 @@ msgstr "" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8553,7 +8555,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8651,7 +8653,7 @@ msgstr "" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8883,11 +8885,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "" @@ -8910,7 +8912,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8931,11 +8933,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -8997,23 +8999,23 @@ msgstr "" msgid "Save State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9033,11 +9035,11 @@ msgstr "" msgid "Save as..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9048,11 +9050,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9060,7 +9062,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9094,7 +9096,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "" @@ -9121,7 +9123,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9129,7 +9131,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9166,7 +9168,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9210,7 +9212,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9218,7 +9220,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "" @@ -9304,7 +9306,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9312,7 +9314,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9329,7 +9331,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "" @@ -9536,11 +9538,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "" @@ -9548,11 +9550,11 @@ msgstr "" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9565,7 +9567,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9578,7 +9580,7 @@ msgstr "" msgid "Show FPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9586,15 +9588,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9606,23 +9608,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9630,7 +9632,7 @@ msgstr "" msgid "Show Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "" @@ -9642,7 +9644,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9650,7 +9652,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "" @@ -9663,19 +9665,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9683,7 +9685,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9695,19 +9697,19 @@ msgstr "" msgid "Show Statistics" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9719,15 +9721,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9836,7 +9838,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10076,7 +10078,7 @@ msgstr "" msgid "Start" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10084,7 +10086,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10178,7 +10180,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10200,7 +10202,7 @@ msgstr "" msgid "Stop" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10271,8 +10273,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10299,7 +10301,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10311,12 +10313,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10409,7 +10411,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10429,7 +10431,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10458,7 +10460,7 @@ msgstr "" msgid "System Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "" @@ -10471,7 +10473,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10489,7 +10491,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "" @@ -10571,13 +10573,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10847,6 +10849,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10878,6 +10886,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10906,7 +10920,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11096,13 +11110,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11155,7 +11169,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "" @@ -11169,7 +11183,7 @@ msgstr "" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11415,7 +11429,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11474,11 +11488,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "" @@ -11496,7 +11510,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11747,7 +11761,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11785,7 +11799,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11979,7 +11993,7 @@ msgstr "" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12080,7 +12094,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "" @@ -12263,11 +12277,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12484,6 +12498,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12520,7 +12540,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12553,7 +12573,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12597,7 +12617,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" diff --git a/Languages/po/el.po b/Languages/po/el.po index d8985651d2..f8b1be1322 100644 --- a/Languages/po/el.po +++ b/Languages/po/el.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: MRCYO Dev, 2023\n" "Language-Team: Greek (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -316,7 +316,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Περί" @@ -337,7 +337,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Ρυθμίσεις Ήχου" @@ -345,7 +345,7 @@ msgstr "&Ρυθμίσεις Ήχου" msgid "&Auto Update:" msgstr "&Αυτόματη Ενημέρωση:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Αυτόματη Εκκίνηση" @@ -353,11 +353,11 @@ msgstr "&Αυτόματη Εκκίνηση" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Σημεία Διακοπής" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Ιχνηλάτης Σφαλμάτων" @@ -365,15 +365,15 @@ msgstr "&Ιχνηλάτης Σφαλμάτων" msgid "&Cancel" msgstr "&Ακύρωση" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Διαχειριστής Cheats" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Έλεγχος για Ενημερώσεις..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -381,7 +381,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -389,7 +389,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Ρυθμίσεις Χειριστηρίων" @@ -428,11 +428,11 @@ msgstr "" msgid "&Edit..." msgstr "&Επεξεργασία..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Εξαγωγή Δίσκου" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Εξομοίωση" @@ -452,27 +452,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Αρχείο" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Γραμματοσειρά..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Προώθηση ανά Καρέ" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -480,15 +480,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Ρυθμίσεις Γραφικών" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Βοήθεια" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Ρυθμίσεις Πλήκτρων Συντόμευσης" @@ -508,7 +508,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -520,7 +520,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -528,11 +528,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Γλώσσα:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Φόρτωση Σημείου Αποθήκευσης" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -546,15 +546,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Μνήμη" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Ταινία" @@ -562,7 +562,7 @@ msgstr "&Ταινία" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Δίκτυο" @@ -571,23 +571,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Άνοιγμα..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Ρυθμίσεις" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Παύση" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Αναπαραγωγή" @@ -595,7 +595,7 @@ msgstr "&Αναπαραγωγή" msgid "&Properties" msgstr "&Ιδιότητες" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Μόνο Για Ανάγνωση" @@ -603,7 +603,7 @@ msgstr "&Μόνο Για Ανάγνωση" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Καταχωρητές" @@ -621,15 +621,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Επανεκκίνηση" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -637,7 +637,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -645,7 +645,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&Όριο Ταχύτητας:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Διακοπή" @@ -653,11 +653,11 @@ msgstr "&Διακοπή" msgid "&Theme:" msgstr "&Θέμα:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Εργαλεία" @@ -671,17 +671,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Προβολή" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Ιστοσελίδα" @@ -693,11 +693,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Ναι" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1117,7 +1117,7 @@ msgid "Accuracy:" msgstr "Ακρίβεια:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1291,7 +1291,7 @@ msgstr "Προσθήκη..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Διεύθυνση" @@ -1520,15 +1520,15 @@ msgstr "Εξομάλυνση Ορίων:" msgid "Any Region" msgstr "Οποιαδήποτε Περιοχή" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1546,7 +1546,7 @@ msgstr "Apploader Ημερομηνία:" msgid "Apply" msgstr "Εφαρμογή" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1653,7 +1653,7 @@ msgstr "Αυτόματη Προσαρμογή Μεγέθους Παραθύρο msgid "Auto-Hide" msgstr "Αυτόματη Απόκρυψη" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1756,7 +1756,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Εικονίδιο" @@ -1828,7 +1828,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1864,7 +1864,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1941,7 +1941,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -2003,7 +2003,7 @@ msgstr "" msgid "C Stick" msgstr "Stick Κάμερας " -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2099,7 +2099,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2170,7 +2170,7 @@ msgstr "" msgid "Change &Disc" msgstr "Αλλαγή &Δίσκου" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Αλλαγή &Δίσκου..." @@ -2232,7 +2232,7 @@ msgstr "Αναζήτηση Cheat" msgid "Cheats Manager" msgstr "Διαχειριστής Cheats" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Έλεγχος NAND..." @@ -2270,11 +2270,11 @@ msgstr "Επιλέξτε ένα αρχείο για άνοιγμα" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2309,7 +2309,7 @@ msgstr "" msgid "Clear" msgstr "Καθάρισ." -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2330,7 +2330,7 @@ msgstr "" msgid "Close" msgstr "Κλείσιμο" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Ρυ&θμίσεις" @@ -2377,7 +2377,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2414,7 +2414,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Συμπίεση" @@ -2550,7 +2550,7 @@ msgstr "Επιβεβαίωση αλλαγής backend " msgid "Confirm on Stop" msgstr "Επιβεβαίωση Διακοπής" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2561,7 +2561,7 @@ msgstr "Επιβεβαίωση" msgid "Connect" msgstr "Σύνδεση" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Σύνδεση Σανίδας Ισορροπίας" @@ -2569,7 +2569,7 @@ msgstr "Σύνδεση Σανίδας Ισορροπίας" msgid "Connect USB Keyboard" msgstr "Σύνδεση Πληκτρολογίου USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Σύνδεση Wii Remote %1" @@ -2589,7 +2589,7 @@ msgstr "Σύνδεση Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Σύνδεση Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Σύνδεση Wii Remotes" @@ -2712,7 +2712,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Σύγκλιση:" @@ -3034,7 +3034,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Τρέχουσα Περιοχή" @@ -3230,7 +3230,7 @@ msgstr "" msgid "Default" msgstr "Προεπιλ." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3290,7 +3290,7 @@ msgstr "" msgid "Depth" msgstr "Βάθος" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3303,7 +3303,7 @@ msgstr "Βάθος:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Περιγραφή" @@ -3325,11 +3325,11 @@ msgstr "" msgid "Detect" msgstr "Ανίχνευση" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3405,7 +3405,7 @@ msgstr "Απενεργοποίηση EFB VRAM Αντίγραφα" msgid "Disable Emulation Speed Limit" msgstr "Απενεργοποίηση Ορίου Ταχύτητας Εξομοίωσης" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3413,7 +3413,7 @@ msgstr "" msgid "Disable Fog" msgstr "Απενεργοποίηση Ομίχλης" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Απενεργοποίηση JIT Cache" @@ -3488,7 +3488,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3519,17 +3519,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3693,7 +3693,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Εξαγωγή Ήχου" @@ -3705,7 +3705,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Εξαγωγή EFB Target" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Εξαγωγή Καρέ" @@ -3783,7 +3783,7 @@ msgstr "" msgid "Dutch" msgstr "Ολλανδικά" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "Έ&ξοδος" @@ -3831,7 +3831,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Επεξεργαστής" @@ -3898,7 +3898,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4051,7 +4051,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4091,7 +4091,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4154,7 +4154,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4239,7 +4239,7 @@ msgstr "Εισαγωγή κωδικού" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4286,18 +4286,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4436,7 +4436,7 @@ msgstr "" msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Ευρώπη" @@ -4517,7 +4517,7 @@ msgstr "" msgid "Experimental" msgstr "Πειραματικός" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Εξαγωγή Όλων Των Αποθηκεύσεων Wii" @@ -4532,7 +4532,7 @@ msgstr "Η Εξαγωγή Απέτυχε" msgid "Export Recording" msgstr "Εξαγωγή Εγγραφής" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Εξαγωγή Εγγραφής..." @@ -4560,7 +4560,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4588,7 +4588,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4626,7 +4626,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Αναπαραγωγή FIFO" @@ -4644,7 +4644,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4738,7 +4738,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4765,18 +4765,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4803,7 +4803,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4813,8 +4813,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4826,7 +4826,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4998,19 +4998,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5058,7 +5058,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Αποτυχία" @@ -5104,7 +5104,7 @@ msgstr "Πληροφορίες Αρχείου" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5118,18 +5118,18 @@ msgstr "Πληροφορίες Αρχείου" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Όνομα Αρχείου" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Διαδρομή Αρχείου" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Μέγεθος Αρχείου" @@ -5642,7 +5642,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID Παιχνιδιού" @@ -5686,7 +5686,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Ρυθμίσεις Συγκεκριμένου Παιχνιδιού" @@ -5757,7 +5757,7 @@ msgid "Gecko Codes" msgstr "Κωδικοί Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5783,7 +5783,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5860,7 +5860,7 @@ msgstr "Αριστερό Πράσινο" msgid "Green Right" msgstr "Δεξί Πράσινο" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Προβολή Πλέγματος" @@ -5935,7 +5935,7 @@ msgstr "" msgid "Hide" msgstr "Απόκρυψη" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6209,7 +6209,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6224,7 +6224,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6329,8 +6329,8 @@ msgstr "Πληροφορίες" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Πληροφορίες" @@ -6339,10 +6339,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Είσοδος" @@ -6383,7 +6383,7 @@ msgstr "" msgid "Install Update" msgstr "Εγκατάσταση Ενημέρωσης" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Εγκατάσταση WAD..." @@ -6403,7 +6403,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6466,7 +6466,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Interpreter (πιο αργή απ' όλες)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6491,7 +6491,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6566,11 +6566,11 @@ msgstr "Ιταλικά" msgid "Italy" msgstr "Ιταλία" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6578,47 +6578,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6630,11 +6630,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6645,7 +6645,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Ιαπωνία" @@ -6704,7 +6704,7 @@ msgstr "" msgid "Kick Player" msgstr "Διώξιμο Παίκτη" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Κορέα" @@ -6849,11 +6849,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Λίστα Στηλών" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Προβολή Λίστας" @@ -6869,11 +6869,11 @@ msgstr "" msgid "Load" msgstr "Φόρτωσ." -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6885,7 +6885,7 @@ msgstr "Φόρτωση Τροποποιημένων Υφών" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Φόρτωση Κυρίως Μενού GameCube" @@ -6995,19 +6995,19 @@ msgstr "Φόρτωση Σημείου Αποθήκευσης 8" msgid "Load State Slot 9" msgstr "Φόρτωση Σημείου Αποθήκευσης 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -7019,16 +7019,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7036,7 +7036,7 @@ msgstr "" msgid "Load..." msgstr "Φόρτωση..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7075,7 +7075,7 @@ msgstr "Καταγραφή" msgid "Log Configuration" msgstr "Ρυθμίσεις Καταγραφής" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7155,7 +7155,7 @@ msgstr "Κύριο Stick" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Δημιουργός" @@ -7172,10 +7172,11 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Διαχείριση NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7228,7 +7229,7 @@ msgstr "" msgid "Memory Card" msgstr "Κάρτα Μνήμης" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Διαχειριστής Καρτών Μνήμης" @@ -7313,8 +7314,8 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7322,7 +7323,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7385,9 +7386,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "Έλεγχος NAND " @@ -7396,7 +7398,7 @@ msgstr "Έλεγχος NAND " msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7422,7 +7424,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7630,7 +7632,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Δεν εντοπίστηκαν προβλήματα." @@ -7689,7 +7691,7 @@ msgstr "Καμία" msgid "North America" msgstr "Βόρεια Αμερική" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Μη Ορισμένο" @@ -7811,7 +7813,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Online &Εγχειρίδια " @@ -7819,13 +7821,13 @@ msgstr "Online &Εγχειρίδια " msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7840,7 +7842,7 @@ msgstr "Άνοιγμα" msgid "Open &Containing Folder" msgstr "Άνοιγμα &Περιεχόμενου Φακέλου" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7946,11 +7948,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Α&ναπαραγωγή Εγγραφής Χειρισμών..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8052,7 +8054,7 @@ msgstr "Φάκελοι" msgid "Pause" msgstr "Παύση" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Παύση στο Τέλος της Ταινίας" @@ -8090,7 +8092,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Φωτισμός ανά Pixel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Εκτελέστε Διαδικτυακή Ενημέρωση Συστήματος" @@ -8124,7 +8126,7 @@ msgstr "" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8141,7 +8143,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Πλατφόρμα" @@ -8372,7 +8374,7 @@ msgstr "" msgid "Public" msgstr "Δημόσιος" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Εκκαθάριση Μνήμης Cache Λίστας Παιχνιδιών " @@ -8428,11 +8430,11 @@ msgstr "R-Αναλογική" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8586,7 +8588,7 @@ msgid "Refreshing..." msgstr "Ανανέωση..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Περιοχή" @@ -8684,7 +8686,7 @@ msgstr "Επανεκκίνηση" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8916,11 +8918,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Απ&οθήκευση Σημείου Αποθήκευσης" @@ -8943,7 +8945,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8964,11 +8966,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9030,23 +9032,23 @@ msgstr "Αποθήκευση Σημείου Αποθήκευσης 8" msgid "Save State Slot 9" msgstr "Αποθήκευση Σημείου Αποθήκευσης 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9066,11 +9068,11 @@ msgstr "" msgid "Save as..." msgstr "Αποθήκευση ως..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9081,11 +9083,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9093,7 +9095,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9127,7 +9129,7 @@ msgstr "Στιγμιότυπο" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Αναζήτηση" @@ -9154,7 +9156,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9162,7 +9164,7 @@ msgstr "" msgid "Search games..." msgstr "Αναζήτηση παιχνιδιών..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9199,7 +9201,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9243,7 +9245,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Επιλογή Θέσης %1 - %2" @@ -9251,7 +9253,7 @@ msgstr "Επιλογή Θέσης %1 - %2" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Επιλογή Θέσης Αποθήκευσης" @@ -9337,7 +9339,7 @@ msgstr "" msgid "Select a game" msgstr "Επιλέξτε ένα παιχνίδι" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Επιλέξτε ένα αρχείο για εγκατάσταση στην NAND" @@ -9345,7 +9347,7 @@ msgstr "Επιλέξτε ένα αρχείο για εγκατάσταση στ msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9362,7 +9364,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Επιλέξτε αρχείο αποθήκευσης" @@ -9572,11 +9574,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Εμφάνιση Παραθύρου Κατα&γραφής " -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Εμφάνιση Γραμμής &Εργαλείων" @@ -9584,11 +9586,11 @@ msgstr "Εμφάνιση Γραμμής &Εργαλείων" msgid "Show Active Title in Window Title" msgstr "Εμφάνιση Ενεργού Τίτλου στον Τίτλο Παραθύρου" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Εμφάνιση Αυστραλίας" @@ -9601,7 +9603,7 @@ msgstr "Εμφάνιση Τρέχοντος Παιχνιδιού σε Discord" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Εμφάνιση ELF/DOL" @@ -9614,7 +9616,7 @@ msgstr "" msgid "Show FPS" msgstr "Εμφάνιση FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Εμφάνιση Μετρητή Καρέ" @@ -9622,15 +9624,15 @@ msgstr "Εμφάνιση Μετρητή Καρέ" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Εμφάνιση Γαλλίας" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Εμφάνιση GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Εμφάνιση Γερμανίας" @@ -9642,23 +9644,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Εμφάνιση Προβολής Χειρισμών" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Εμφάνιση Ιταλίας" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Εμφάνιση Κορέας" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Εμφάνιση Μετρητή Καθυστέρησης " @@ -9666,7 +9668,7 @@ msgstr "Εμφάνιση Μετρητή Καθυστέρησης " msgid "Show Language:" msgstr "Εμφάνιση Γλώσσας:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Εμφάνιση Ρυθμίσεων &Καταγραφέα" @@ -9678,7 +9680,7 @@ msgstr "Εμφάνιση Μηνυμάτων NetPlay" msgid "Show NetPlay Ping" msgstr "Εμφάνιση NetPlay Ping" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Εμφάνιση Ολλανδίας" @@ -9686,7 +9688,7 @@ msgstr "Εμφάνιση Ολλανδίας" msgid "Show On-Screen Display Messages" msgstr "Εμφάνιση Μηνυμάτων στην Οθόνη " -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Εμφάνιση PAL" @@ -9699,19 +9701,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Εμφάνιση Πλατφόρμας" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Εμφάνιση Περιοχών" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Εμφάνιση Ρωσίας" @@ -9719,7 +9721,7 @@ msgstr "Εμφάνιση Ρωσίας" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Εμφάνιση Ισπανίας" @@ -9731,19 +9733,19 @@ msgstr "" msgid "Show Statistics" msgstr "Εμφάνιση Στατιστικών" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Εμφάνιση Ώρας Συστήματος" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Εμφάνιση Ταϊβάν" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Εμφάνιση USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Εμφάνιση Αγνώστων" @@ -9755,15 +9757,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Εμφάνιση WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Εμφάνιση Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Εμφάνιση Κόσμου" @@ -9872,7 +9874,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "Πλαγιαστό Wii Remote" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10112,7 +10114,7 @@ msgstr "Τυπικός Controller" msgid "Start" msgstr "Εκκίνηση" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Έναρξη &NetPlay..." @@ -10120,7 +10122,7 @@ msgstr "Έναρξη &NetPlay..." msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Εκκίνηση Ε&γγραφής Χειρισμών" @@ -10214,7 +10216,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Στερεοσκοπική 3D Λειτουργία:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Στερεοσκοπία" @@ -10236,7 +10238,7 @@ msgstr "Stick" msgid "Stop" msgstr "Διακοπή" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10307,8 +10309,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Επιτυχία" @@ -10335,7 +10337,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10347,12 +10349,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10445,7 +10447,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10465,7 +10467,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "Συγχρονισμός του νήματος της GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10494,7 +10496,7 @@ msgstr "" msgid "System Language:" msgstr "Γλώσσα Συστήματος:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS Είσοδος" @@ -10507,7 +10509,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Ετικέτες" @@ -10525,7 +10527,7 @@ msgstr "" msgid "Taiwan" msgstr "Ταϊβάν" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Δημιουργία Στιγμιότυπου" @@ -10607,13 +10609,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10884,6 +10886,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10915,6 +10923,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10943,7 +10957,7 @@ msgstr "Δεν υπάρχει τίποτα προς αναίρεση!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11140,13 +11154,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11199,7 +11213,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Τίτλος" @@ -11213,7 +11227,7 @@ msgstr "Εώς" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Εναλλαγή &Πλήρους Οθόνης" @@ -11459,7 +11473,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11518,11 +11532,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Αναίρεση Φόρτωσης Σημείου Αποθ. " -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Αναίρεση Αποθήκευσης Σημείου Αποθ. " @@ -11540,7 +11554,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Ηνωμένες Πολιτείες" @@ -11793,7 +11807,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11831,7 +11845,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Ρυθμίσεις Χρήστη" @@ -12025,7 +12039,7 @@ msgstr "Αύξηση Έντασης" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD αρχεία (*.wad)" @@ -12126,7 +12140,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Προειδοποίηση" @@ -12309,11 +12323,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12531,6 +12545,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12567,7 +12587,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "αυτόματα" @@ -12600,7 +12620,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12644,7 +12664,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "κανένα" diff --git a/Languages/po/en.po b/Languages/po/en.po index dd6ba69020..898a59fb64 100644 --- a/Languages/po/en.po +++ b/Languages/po/en.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emu\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2011-01-06 14:53+0100\n" "Last-Translator: BhaaL \n" "Language-Team: \n" @@ -304,7 +304,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -325,7 +325,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "" @@ -333,7 +333,7 @@ msgstr "" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -341,11 +341,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -353,15 +353,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -369,7 +369,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -377,7 +377,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "" @@ -416,11 +416,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "" @@ -440,27 +440,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -468,15 +468,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "" @@ -496,7 +496,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -508,7 +508,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "" @@ -516,11 +516,11 @@ msgstr "" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -534,15 +534,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "" @@ -550,7 +550,7 @@ msgstr "" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -559,23 +559,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "" @@ -583,7 +583,7 @@ msgstr "" msgid "&Properties" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "" @@ -591,7 +591,7 @@ msgstr "" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "" @@ -609,15 +609,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -625,7 +625,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -633,7 +633,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "" @@ -641,11 +641,11 @@ msgstr "" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "" @@ -659,17 +659,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "" @@ -681,11 +681,11 @@ msgstr "" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1102,7 +1102,7 @@ msgid "Accuracy:" msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1276,7 +1276,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "" @@ -1505,15 +1505,15 @@ msgstr "" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1531,7 +1531,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1638,7 +1638,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1741,7 +1741,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "" @@ -1813,7 +1813,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1849,7 +1849,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1926,7 +1926,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1988,7 +1988,7 @@ msgstr "" msgid "C Stick" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2084,7 +2084,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2155,7 +2155,7 @@ msgstr "" msgid "Change &Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "" @@ -2217,7 +2217,7 @@ msgstr "" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2255,11 +2255,11 @@ msgstr "" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2294,7 +2294,7 @@ msgstr "" msgid "Clear" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2315,7 +2315,7 @@ msgstr "" msgid "Close" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2362,7 +2362,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2399,7 +2399,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2535,7 +2535,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2546,7 +2546,7 @@ msgstr "" msgid "Connect" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "" @@ -2554,7 +2554,7 @@ msgstr "" msgid "Connect USB Keyboard" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2574,7 +2574,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2697,7 +2697,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3017,7 +3017,7 @@ msgid "" "leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3213,7 +3213,7 @@ msgstr "" msgid "Default" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3273,7 +3273,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3286,7 +3286,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "" @@ -3308,11 +3308,11 @@ msgstr "" msgid "Detect" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3387,7 +3387,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3395,7 +3395,7 @@ msgstr "" msgid "Disable Fog" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3468,7 +3468,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3499,17 +3499,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3670,7 +3670,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "" @@ -3682,7 +3682,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "" @@ -3760,7 +3760,7 @@ msgstr "" msgid "Dutch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "" @@ -3808,7 +3808,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3875,7 +3875,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4028,7 +4028,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4068,7 +4068,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4129,7 +4129,7 @@ msgid "" "" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4212,7 +4212,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4259,18 +4259,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4407,7 +4407,7 @@ msgstr "" msgid "Euphoria" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4488,7 +4488,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "" @@ -4503,7 +4503,7 @@ msgstr "" msgid "Export Recording" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "" @@ -4531,7 +4531,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4559,7 +4559,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4597,7 +4597,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "" @@ -4615,7 +4615,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4709,7 +4709,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4736,18 +4736,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4774,7 +4774,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4784,8 +4784,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4797,7 +4797,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4969,19 +4969,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5029,7 +5029,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5075,7 +5075,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5089,18 +5089,18 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "" @@ -5613,7 +5613,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "" @@ -5657,7 +5657,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "" @@ -5728,7 +5728,7 @@ msgid "Gecko Codes" msgstr "" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5754,7 +5754,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5831,7 +5831,7 @@ msgstr "" msgid "Green Right" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5906,7 +5906,7 @@ msgstr "" msgid "Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6180,7 +6180,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6195,7 +6195,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6300,8 +6300,8 @@ msgstr "" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "" @@ -6310,10 +6310,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "" @@ -6354,7 +6354,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6374,7 +6374,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6437,7 +6437,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6462,7 +6462,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6537,11 +6537,11 @@ msgstr "" msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6549,47 +6549,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6601,11 +6601,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6616,7 +6616,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6675,7 +6675,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6817,11 +6817,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6837,11 +6837,11 @@ msgstr "" msgid "Load" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6853,7 +6853,7 @@ msgstr "" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6963,19 +6963,19 @@ msgstr "" msgid "Load State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6987,16 +6987,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7004,7 +7004,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7043,7 +7043,7 @@ msgstr "" msgid "Log Configuration" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7123,7 +7123,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7140,10 +7140,11 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7194,7 +7195,7 @@ msgstr "" msgid "Memory Card" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7279,8 +7280,8 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7288,7 +7289,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7351,9 +7352,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7362,7 +7364,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7388,7 +7390,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7596,7 +7598,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7655,7 +7657,7 @@ msgstr "" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "" @@ -7777,7 +7779,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "" @@ -7785,13 +7787,13 @@ msgstr "" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7806,7 +7808,7 @@ msgstr "" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7912,11 +7914,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8018,7 +8020,7 @@ msgstr "" msgid "Pause" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8056,7 +8058,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8090,7 +8092,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8107,7 +8109,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8338,7 +8340,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8394,11 +8396,11 @@ msgstr "" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8552,7 +8554,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8650,7 +8652,7 @@ msgstr "" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8882,11 +8884,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "" @@ -8909,7 +8911,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8930,11 +8932,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -8996,23 +8998,23 @@ msgstr "" msgid "Save State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9032,11 +9034,11 @@ msgstr "" msgid "Save as..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9047,11 +9049,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9059,7 +9061,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9093,7 +9095,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "" @@ -9120,7 +9122,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9128,7 +9130,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9165,7 +9167,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9209,7 +9211,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9217,7 +9219,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "" @@ -9303,7 +9305,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9311,7 +9313,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9328,7 +9330,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "" @@ -9535,11 +9537,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "" @@ -9547,11 +9549,11 @@ msgstr "" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9564,7 +9566,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9577,7 +9579,7 @@ msgstr "" msgid "Show FPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9585,15 +9587,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9605,23 +9607,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9629,7 +9631,7 @@ msgstr "" msgid "Show Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "" @@ -9641,7 +9643,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9649,7 +9651,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "" @@ -9662,19 +9664,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9682,7 +9684,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9694,19 +9696,19 @@ msgstr "" msgid "Show Statistics" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9718,15 +9720,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9835,7 +9837,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10075,7 +10077,7 @@ msgstr "" msgid "Start" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10083,7 +10085,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10177,7 +10179,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10199,7 +10201,7 @@ msgstr "" msgid "Stop" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10270,8 +10272,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10298,7 +10300,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10310,12 +10312,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10408,7 +10410,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10428,7 +10430,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10457,7 +10459,7 @@ msgstr "" msgid "System Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "" @@ -10470,7 +10472,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10488,7 +10490,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "" @@ -10570,13 +10572,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10846,6 +10848,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10877,6 +10885,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10905,7 +10919,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11095,13 +11109,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11154,7 +11168,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "" @@ -11168,7 +11182,7 @@ msgstr "" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11414,7 +11428,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11473,11 +11487,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "" @@ -11495,7 +11509,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11746,7 +11760,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11784,7 +11798,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11978,7 +11992,7 @@ msgstr "" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12079,7 +12093,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "" @@ -12262,11 +12276,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12483,6 +12497,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12519,7 +12539,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12552,7 +12572,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12596,7 +12616,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" diff --git a/Languages/po/es.po b/Languages/po/es.po index 23957380d1..6cad40021c 100644 --- a/Languages/po/es.po +++ b/Languages/po/es.po @@ -31,7 +31,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Víctor González, 2021-2023\n" "Language-Team: Spanish (http://app.transifex.com/delroth/dolphin-emu/" @@ -213,10 +213,12 @@ msgid "" "%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " "hardcore)" msgstr "" +"%1 ha desbloqueado %2/%3 logros (%4 en el modo «hardcore»), con un total de " +"%5/%6 puntos (%7 en el modo «hardcore»)" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" -msgstr "" +msgstr "%1 ha desbloqueado %2/%3 logros, con un total de %4/%5 puntos" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" @@ -238,7 +240,7 @@ msgstr "%1 ms" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 msgid "%1 points" -msgstr "" +msgstr "%1 puntos" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" @@ -348,7 +350,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Acerca de" @@ -369,7 +371,7 @@ msgstr "&Añadir función" msgid "&Add..." msgstr "&Añadir..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Ajustes de &audio" @@ -377,7 +379,7 @@ msgstr "Ajustes de &audio" msgid "&Auto Update:" msgstr "Actualización automática:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "Comienzo &automático" @@ -385,11 +387,11 @@ msgstr "Comienzo &automático" msgid "&Borderless Window" msgstr "Ventana sin &bordes" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Puntos de interrupción" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Rastreador de errores" @@ -397,15 +399,15 @@ msgstr "&Rastreador de errores" msgid "&Cancel" msgstr "&Cancelar" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "Administrador de &trucos" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Buscar actualizaciones..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Borrar símbolos" @@ -413,7 +415,7 @@ msgstr "&Borrar símbolos" msgid "&Clone..." msgstr "&Clonar..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Código" @@ -421,7 +423,7 @@ msgstr "&Código" msgid "&Connected" msgstr "&Conectado" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "Ajustes de &mandos" @@ -460,11 +462,11 @@ msgstr "&Editar código..." msgid "&Edit..." msgstr "&Editar..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Expulsar disco" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulación" @@ -484,27 +486,27 @@ msgstr "&Exportar estado" msgid "&Export as .gci..." msgstr "&Exportar como .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Archivo" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Tipo de letra..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "Avanzar &fotograma" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "Ajustes de &cámara libre" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Generar el mapa de símbolos a partir de..." -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&Repositorio en GitHub" @@ -512,15 +514,15 @@ msgstr "&Repositorio en GitHub" msgid "&Go to start of function" msgstr "&Ir al principio de la función" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Ajustes de &gráficos" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "A&yuda" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Ajustes de a&tajos" @@ -540,7 +542,7 @@ msgstr "&Importar estado" msgid "&Import..." msgstr "&Importar..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "Base de &Infinity" @@ -552,7 +554,7 @@ msgstr "&Insertar blr" msgid "&Interframe Blending" msgstr "&Fusión de fotogramas" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -560,11 +562,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Idioma:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Cargar estado" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "Cargar mapa de símbo&los" @@ -578,15 +580,15 @@ msgstr "&Cargar archivo en dirección actual" msgid "&Lock Watches" msgstr "&Bloquear variables vigiladas" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "B&loquear posición de ventanas" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memoria" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Grabación" @@ -594,7 +596,7 @@ msgstr "&Grabación" msgid "&Mute" msgstr "&Silenciar" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Red" @@ -603,23 +605,23 @@ msgid "&No" msgstr "&No" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Abrir..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opciones" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Parchear funciones HLE" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Jugar" @@ -627,7 +629,7 @@ msgstr "&Jugar" msgid "&Properties" msgstr "&Propiedades" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Modo de solo lectura" @@ -635,7 +637,7 @@ msgstr "&Modo de solo lectura" msgid "&Refresh List" msgstr "&Actualizar lista" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registros" @@ -653,15 +655,15 @@ msgid "&Rename symbol" msgstr "&Renombrar símbolo" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Reiniciar" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Administrador de paquetes de recursos" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Guardar mapa de símbolos" @@ -669,7 +671,7 @@ msgstr "&Guardar mapa de símbolos" msgid "&Scan e-Reader Card(s)..." msgstr "E%scanear tarjeta(s) de e-Reader..." -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "Portal de &Skylanders" @@ -677,7 +679,7 @@ msgstr "Portal de &Skylanders" msgid "&Speed Limit:" msgstr "&Límite de velocidad:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Detener" @@ -685,11 +687,11 @@ msgstr "&Detener" msgid "&Theme:" msgstr "&Tema visual:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Hilos" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Herramientas" @@ -703,17 +705,17 @@ msgstr "&Quitar ROM" msgid "&Unlock Watches" msgstr "Desblo&quear variables vigiladas" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Vista" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Vigilar" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Página web" @@ -725,11 +727,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Sí" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "No se encontró «%1», no se han generado nombres de símbolos" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "No se encontró «%1», probando con la búsqueda de funciones comunes" @@ -1185,7 +1187,7 @@ msgid "Accuracy:" msgstr "Exactitud:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "Logros" @@ -1376,7 +1378,7 @@ msgstr "Añadir..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Dirección:" @@ -1637,15 +1639,15 @@ msgstr "Suavizado de bordes:" msgid "Any Region" msgstr "Cualquier región" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Añadir firma a" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Añadir al archivo de firma existente..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Aplicar archivo de firma..." @@ -1666,7 +1668,7 @@ msgstr "Fecha del «apploader»:" msgid "Apply" msgstr "Aplicar" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Aplicar archivo de firma" @@ -1779,7 +1781,7 @@ msgstr "Autoajustar tamaño de ventana" msgid "Auto-Hide" msgstr "Ocultar automáticamente" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "¿Autodetectar módulos RSO?" @@ -1888,7 +1890,7 @@ msgstr "El valor elegido no es correcto." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Imagen" @@ -1962,7 +1964,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Tamaño del bloque" @@ -2000,7 +2002,7 @@ msgstr "" "Se ha activado el modo de acceso directo a Bluetooth, pero no se puede " "utilizar porque Dolphin se ha compilado sin la biblioteca libusb." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Arrancar pausado" @@ -2080,7 +2082,7 @@ msgstr "Error del adaptador para banda ancha" msgid "Broadband Adapter MAC Address" msgstr "Dirección MAC del adaptador para banda ancha" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Buscar sesiones de juego en red..." @@ -2144,7 +2146,7 @@ msgstr "Por:" msgid "C Stick" msgstr "Stick C" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "C&rear archivo de firma..." @@ -2253,7 +2255,7 @@ msgstr "No puedes empezar el juego en red con un juego en ejecución." #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2325,7 +2327,7 @@ msgstr "Centrar y calibrar" msgid "Change &Disc" msgstr "Cambiar &disco" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Cambiar &disco..." @@ -2400,7 +2402,7 @@ msgstr "Buscar trucos" msgid "Cheats Manager" msgstr "Administrador de trucos" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Comprobar NAND..." @@ -2440,11 +2442,11 @@ msgstr "Selecciona un archivo para abrir" msgid "Choose a file to open or create" msgstr "Selecciona un archivo a abrir o crear" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Selecciona un archivo de entrada principal" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Selecciona un archivo de entrada secundario" @@ -2479,7 +2481,7 @@ msgstr "Mando clásico" msgid "Clear" msgstr "Borrar" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Borrar caché" @@ -2500,7 +2502,7 @@ msgstr "Clonar y &editar código..." msgid "Close" msgstr "Cerrar" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Co&nfiguración" @@ -2547,7 +2549,7 @@ msgstr "Corrección de color:" msgid "Color Space" msgstr "Espacio de color" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Combinar dos archivos de firmas..." @@ -2591,7 +2593,7 @@ msgstr "Compilación de sombreadores" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Compresión" @@ -2778,7 +2780,7 @@ msgstr "Confirmar cambio de motor" msgid "Confirm on Stop" msgstr "Confirmar detención" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2789,7 +2791,7 @@ msgstr "Confirmar" msgid "Connect" msgstr "Conectar" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Conectar la Balance Board" @@ -2797,7 +2799,7 @@ msgstr "Conectar la Balance Board" msgid "Connect USB Keyboard" msgstr "Conectar teclado USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Conectar mando de Wii %1" @@ -2817,7 +2819,7 @@ msgstr "Conectar mando de Wii 3" msgid "Connect Wii Remote 4" msgstr "Conectar mando de Wii 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Conectar mandos de Wii" @@ -2894,6 +2896,11 @@ msgid "" "display.

HDR output is required for this setting to take effect." "

If unsure, leave this at 200." msgstr "" +"Controla la luminancia base de una superficie «blanco papel» en Cd/m². Ideal " +"para ajustar un monitor HDR a condiciones diferentes de iluminación " +"ambiental.

Es necesario activar la salida HDR para que este cambio " +"tenga efecto.

Si tienes dudas, deja esta opción en " +"200." #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" @@ -2960,7 +2967,7 @@ msgstr "" msgid "Convergence" msgstr "Convergencia" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Convergencia:" @@ -3033,6 +3040,16 @@ msgid "" "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" +"Convierte los colores de los espacios de color para los que estaban " +"diseñadas Wii/GC, sRGB/Rec.709.

No hay forma de saber para qué " +"espacio de color concreto estaba diseñado cada juego porque existían varios " +"estándares y la mayoría de los juegos no los tenían en cuenta, así que no es " +"correcto suponer un formato a partir de la región de un disco de juego. " +"Elige el que te parezca más natural o el que se utilice en la región para la " +"que fue desarrollado el juego.

La salida HDR necesita mostrar todos " +"los colores de los espacios de color PAL y NTSC-J." +"

Si tienes dudas, deja esta opción desactivada." #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" @@ -3332,7 +3349,7 @@ msgstr "" "dibujado.

Si tienes dudas, deja esta opción " "desactivada." -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Región actual" @@ -3362,7 +3379,7 @@ msgstr "Opciones de fecha en tiempo real personalizada (RTC)" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 msgid "Custom:" -msgstr "" +msgstr "Personalizado:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" @@ -3534,7 +3551,7 @@ msgstr "Disminuir Y" msgid "Default" msgstr "Valor predeterminado" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Configuración predeterminada (solo lectura)" @@ -3600,7 +3617,7 @@ msgstr "¿Borrar el archivo «{0}»?" msgid "Depth" msgstr "Profundidad" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Porcentaje de profundidad:" @@ -3613,7 +3630,7 @@ msgstr "Profundidad:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Descripción" @@ -3635,11 +3652,11 @@ msgstr "Separado" msgid "Detect" msgstr "Detectar" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Detección de módulos RSO" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Doble núcleo determinista:" @@ -3714,7 +3731,7 @@ msgstr "Desactivar copias del EFB a la VRAM" msgid "Disable Emulation Speed Limit" msgstr "Desactivar límite de velocidad de emulación" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Desactivar FastMem" @@ -3722,7 +3739,7 @@ msgstr "Desactivar FastMem" msgid "Disable Fog" msgstr "Desactivar niebla" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Desactivar caché JIT" @@ -3814,7 +3831,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "¿Quieres añadir «%1» a la lista de carpetas de juegos?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "¿Seguro que quieres borrar la lista de nombres simbólicos?" @@ -3845,17 +3862,17 @@ msgstr "Registro FIFO de Dolphin (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Preajuste de modificación de juego para Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Archivo de mapa de Dolphin (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Archivo de firma CSV de Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Archivo de firma de Dolphin" @@ -4032,7 +4049,7 @@ msgstr "Volcar &FakeVMEM" msgid "Dump &MRAM" msgstr "Volcar &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Volcar audio" @@ -4044,7 +4061,7 @@ msgstr "Volcar texturas base" msgid "Dump EFB Target" msgstr "Volcar superficie del EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Volcar fotogramas" @@ -4132,7 +4149,7 @@ msgstr "Duración de liberación del botón turbo (fotogramas)" msgid "Dutch" msgstr "Holandés" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Salir" @@ -4188,7 +4205,7 @@ msgid "Edit..." msgstr "Editar..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Editor" @@ -4258,7 +4275,7 @@ msgstr "" "esta opción puede provocar problemas de estabilidad. Valor predeterminado: " "activado." -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "Dispositivos USB emulados" @@ -4316,7 +4333,7 @@ msgstr "RTC personalizado" #: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 msgid "Enable Debugging UI" -msgstr "" +msgstr "Activar opciones de depuración" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" @@ -4421,7 +4438,7 @@ msgstr "" "únicamente el juego al que se esté jugando.

No tiene relación alguna " "con la Rich Presence de Discord." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4479,7 +4496,7 @@ msgstr "" "Emula el sistema Dolby Pro Logic II con un sonido envolvente 5.1. Funciona " "solo en algunos motores de sonido." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4579,7 +4596,7 @@ msgstr "" "

Si tienes dudas, deja esta opción desactivada." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4684,7 +4701,7 @@ msgstr "Introduce la contraseña" msgid "Enter the DNS server to use:" msgstr "Introduce el servidor de DNS que quieres utilizar:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Introduce la dirección del módulo RSO:" @@ -4731,18 +4748,18 @@ msgstr "Introduce la dirección del módulo RSO:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4887,7 +4904,7 @@ msgstr "Se encontraron errores en {0} bloques sin uso de la partición {1}." msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4987,7 +5004,7 @@ msgstr "Nombre de variable previsto." msgid "Experimental" msgstr "Experimental" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exportar todas las partidas guardadas de Wii" @@ -5002,7 +5019,7 @@ msgstr "Fallo al exportar" msgid "Export Recording" msgstr "Exportar grabación" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exportar grabación..." @@ -5030,7 +5047,7 @@ msgstr "Exportar como .&gcs..." msgid "Export as .&sav..." msgstr "Exportar como .&sav..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -5058,7 +5075,7 @@ msgstr "Externo" msgid "External Frame Buffer (XFB)" msgstr "Búfer de imagen externo (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Extraer certificados de la NAND" @@ -5096,7 +5113,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Reproductor FIFO" @@ -5116,7 +5133,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "No se ha podido añadir esta sesión al índice de juego en red: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "No se ha podido añadir al archivo de firma «%1»" @@ -5220,7 +5237,7 @@ msgstr "No se ha(n) podido exportar %n de %1 archivo(s) de guardado." msgid "Failed to export the following save files:" msgstr "No se ha podido exportar los siguientes archivos de guardado:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "No se han podido extraer los certificados de la NAND." @@ -5250,14 +5267,14 @@ msgstr "No se ha podido encontrar uno o más símbolos D3D" msgid "Failed to import \"%1\"." msgstr "No se ha podido importar «%1»." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "No se ha podido importar el archivo de guardado. Por favor, lanza el juego " "otra vez, e inténtalo de nuevo." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5265,7 +5282,7 @@ msgstr "" "No se ha podido importar el archivo de guardado. El archivo parece estar " "corrupto o no es un archivo válido de Wii." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5299,7 +5316,7 @@ msgid "Failed to install pack: %1" msgstr "No se ha podido instalar el paquete: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "No se ha podido instalar el título en la NAND." @@ -5311,8 +5328,8 @@ msgstr "" "No se han podido recibir conexiones en el puerto %1. ¿Hay otra instancia del " "servidor de juego en red funcionando?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "No se ha podido cargar el módulo RSO en %1" @@ -5324,7 +5341,7 @@ msgstr "No se ha podido cargar d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "No se ha podido cargar dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "No se ha podido cargar el archivo de mapa «%1»" @@ -5523,19 +5540,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "No se ha podido guardar el registro FIFO." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "No se ha podido guardar el mapa de código en la ruta «%1»" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "No se ha podido guardar el archivo de firma «%1»" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "No se ha podido guardar el mapa de símbolos en la ruta «%1»" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "No se ha podido guardar en el archivo de firma «%1»" @@ -5585,7 +5602,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Fallido" @@ -5633,7 +5650,7 @@ msgstr "Detalles del archivo" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Formato del archivo" @@ -5647,18 +5664,18 @@ msgstr "Información del archivo" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Nombre del archivo" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Ruta del archivo" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Tamaño del archivo" @@ -6210,7 +6227,7 @@ msgstr "Game Boy Advance en el puerto %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 msgid "Game Color Space:" -msgstr "" +msgstr "Espacio de color del juego:" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 msgid "Game Config" @@ -6230,10 +6247,10 @@ msgstr "Gamma del juego" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 msgid "Game Gamma:" -msgstr "" +msgstr "Gamma del juego:" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID de juego" @@ -6282,7 +6299,7 @@ msgstr "" msgid "Game region does not match" msgstr "La región del juego no coincide" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Ajustes específicos del juego " @@ -6353,7 +6370,7 @@ msgid "Gecko Codes" msgstr "Códigos Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6379,7 +6396,7 @@ msgstr "Generar un nuevo identificador para estadísticas" msgid "Generated AR code." msgstr "Se ha generado el código AR." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Nombres de símbolos generados desde «%1»" @@ -6461,7 +6478,7 @@ msgstr "Verde izquierdo" msgid "Green Right" msgstr "Verde derecho" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Vista en cuadrícula" @@ -6488,7 +6505,7 @@ msgstr "Cd/m² de blanco «papel» de HDR" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 msgid "HDR Paper White Nits:" -msgstr "" +msgstr "Cd/m² de blanco «papel» de HDR:" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" @@ -6536,7 +6553,7 @@ msgstr "Hexadecimal" msgid "Hide" msgstr "Esconder" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Ocultar todo" @@ -6882,7 +6899,7 @@ msgstr "" "disminuye ligeramente el rendimiento.

Si tienes " "dudas, deja esta opción desactivada." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Importar copia de respaldo de la NAND en formato BootMii..." @@ -6897,7 +6914,7 @@ msgstr "Fallo al importar" msgid "Import Save File(s)" msgstr "Importar archivo(s) de guardado" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importar partidas guardadas de Wii..." @@ -7013,8 +7030,8 @@ msgstr "Información" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Información" @@ -7023,10 +7040,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Desactivar salvapantallas durante la emulación" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Entrada" @@ -7067,7 +7084,7 @@ msgstr "Partición de instalación (%1)" msgid "Install Update" msgstr "Instalar actualización" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Instalar WAD..." @@ -7087,7 +7104,7 @@ msgstr "Instrucción" msgid "Instruction Breakpoint" msgstr "Punto de interrupción de instrucción" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instrucción:" @@ -7156,7 +7173,7 @@ msgstr "Error interno al generar el código AR." msgid "Interpreter (slowest)" msgstr "Intérprete (muy lento)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Intérprete de núcleo" @@ -7183,7 +7200,7 @@ msgstr "Paquete %1 no válido proporcionado: %2" msgid "Invalid Player ID" msgstr "ID de jugador incorrecto" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Dirección de módulo RSO incorrecta: %1" @@ -7259,11 +7276,11 @@ msgstr "Italiano" msgid "Italy" msgstr "Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "Sin enlazado de bloques JIT" @@ -7271,47 +7288,47 @@ msgstr "Sin enlazado de bloques JIT" msgid "JIT Blocks" msgstr "Bloques JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "Sin rama JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "Sin coma flotante JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "Sin números enteros JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "Sin LoadStore de coma flotante JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "Sin LoadStore JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "Sin LoadStore con parejas JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "Sin LoadStore lXz JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "Sin LoadStore lbzx JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "Sin LoadStore lwz JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "Sin JIT (núcleo JIT)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "Sin emparejamiento JIT" @@ -7323,11 +7340,11 @@ msgstr "Recompilador JIT para ARM64 (recomendado)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "Recompilador JIT para x86-64 (recomendado)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "Sin registro de caché de JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "Sin SystemRegisters JIT" @@ -7341,7 +7358,7 @@ msgstr "" "memoria caché. Esto no debería haber pasado. Te rogamos que informes del " "fallo en el gestor de incidencias. Dolphin se cerrará." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japón" @@ -7400,7 +7417,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Echar al jugador" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Corea" @@ -7551,11 +7568,11 @@ msgstr "Luces" msgid "Limit Chunked Upload Speed:" msgstr "Limite la velocidad de subida de datos:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Columnas en la lista" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Vista en lista" @@ -7571,11 +7588,11 @@ msgstr "Escuchando" msgid "Load" msgstr "Cargar" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Cargar archiv&o de mapa incorrecto..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Cargar archiv&o de mapa adicional..." @@ -7587,7 +7604,7 @@ msgstr "Cargar texturas personalizadas" msgid "Load File" msgstr "Cargar archivo" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Cargar menú principal de GameCube" @@ -7697,19 +7714,19 @@ msgstr "Cargar estado 8" msgid "Load State Slot 9" msgstr "Cargar estado 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Cargar estado desde un archivo" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Cargar estado desde la ranura seleccionada" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Cargar estado desde una ranura" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Cargar menú del sistema Wii %1" @@ -7721,16 +7738,16 @@ msgstr "Cargar y escribir los datos guardados del anfitrión" msgid "Load from Selected Slot" msgstr "Cargar la ranura seleccionada" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Cargar desde la ranura %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Cargar archivo de mapa" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "Cargar menú del sistema vWii %1" @@ -7738,7 +7755,7 @@ msgstr "Cargar menú del sistema vWii %1" msgid "Load..." msgstr "Cargar..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Símbolos cargados desde «%1»" @@ -7784,7 +7801,7 @@ msgstr "Registro" msgid "Log Configuration" msgstr "Configuración de registro" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Registros de cobertura de instrucciones JIT" @@ -7868,7 +7885,7 @@ msgstr "Palanca principal" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Creador" @@ -7890,10 +7907,11 @@ msgstr "" "del efecto.

Si tienes dudas, deja esta opción " "desactivada." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Administrar NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "Muestreo manual de texturas" @@ -7944,7 +7962,7 @@ msgstr "Punto de interrupción en memoria" msgid "Memory Card" msgstr "Tarjeta de memoria" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Administrador de tarjetas de memoria" @@ -8045,8 +8063,8 @@ msgstr "" "

Si tienes dudas, deja esta opción desactivada." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Módulos encontrados: %1" @@ -8054,7 +8072,7 @@ msgstr "Módulos encontrados: %1" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Sombras monoscópicas" @@ -8122,9 +8140,10 @@ msgstr "Multiplicador" msgid "N&o to All" msgstr "N&o a todo" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "Comprobación de NAND" @@ -8133,7 +8152,7 @@ msgstr "Comprobación de NAND" msgid "NKit Warning" msgstr "Advertencia NKit" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -8158,8 +8177,14 @@ msgid "" "match it here.

If unsure, leave this at 2.35." msgstr "" +"NTSC-M y NTSC-J están diseñados para un gamma aproximado de 2,2. PAL está " +"diseñado para un gamma aproximado de 2,8.
Ninguno de estos valores eran " +"respetados necesariamente por los juegos o los televisores.
2,35 es un " +"buen valor genérico para todas las regiones.

Si un juego te permite " +"elegir un valor de gamma, debes igualarlo aquí.

Si " +"tienes dudas, deja esta opción en 2,35." -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8375,7 +8400,7 @@ msgstr "No hay ningún juego en ejecución." msgid "No game running." msgstr "No hay ningún juego en ejecución." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "No se ha detectado ningún problema." @@ -8440,7 +8465,7 @@ msgstr "Ninguno" msgid "North America" msgstr "Norteamérica" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "No definido" @@ -8571,7 +8596,7 @@ msgstr "" "geometría como de vértices para expandir puntos y líneas se seleccionará un " "sombreador de vértices. Esta opción podría afectar al rendimiento.

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Documentación en línea" @@ -8579,7 +8604,7 @@ msgstr "&Documentación en línea" msgid "Only Show Collection" msgstr "Mostrar solo tu colección" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8587,7 +8612,7 @@ msgstr "" "Solo añadir símbolos con prefijo:\n" "(Dejar en blanco para añadir todos los símbolos)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8604,7 +8629,7 @@ msgstr "Abrir" msgid "Open &Containing Folder" msgstr "Abrir &carpeta contenedora" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "Abrir carpeta de &usuario" @@ -8710,11 +8735,11 @@ msgstr "Otro juego..." msgid "Overwritten" msgstr "Sobrescrito" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Reproducir pu&lsaciones grabadas..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8816,7 +8841,7 @@ msgstr "Rutas" msgid "Pause" msgstr "Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pausar al terminar la grabación" @@ -8857,7 +8882,7 @@ msgstr "Velocidad máxima de los movimientos de balanceo hacia afuera." msgid "Per-Pixel Lighting" msgstr "Iluminación por píxel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Actualizar la consola a través de Internet" @@ -8891,7 +8916,7 @@ msgstr "Espacio de la dirección física" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Elige una tipografía de depuración" @@ -8908,7 +8933,7 @@ msgid "Pitch Up" msgstr "Cabeceo hacia abajo" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Plataforma" @@ -9157,7 +9182,7 @@ msgstr "Progreso" msgid "Public" msgstr "Público" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Vaciar la caché de la lista de juegos" @@ -9214,11 +9239,11 @@ msgstr "R analógico" msgid "READY" msgstr "Listo" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "Módulos RSO" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "Autodetección RSO" @@ -9383,7 +9408,7 @@ msgid "Refreshing..." msgstr "Actualizando..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Región" @@ -9488,7 +9513,7 @@ msgstr "Reiniciar" msgid "Reset All" msgstr "Reiniciar todo" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Reiniciar el ignorado de errores y advertencias" @@ -9697,7 +9722,7 @@ msgstr "Carpeta de sincronización de la SD:" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 msgid "SDR Display Gamma Target" -msgstr "" +msgstr "Gamma para monitores SDR" #: Source/Core/Core/HW/GBAPadEmu.h:43 #: Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp:42 @@ -9726,11 +9751,11 @@ msgstr "Entorno SSL" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Gua&rdar código" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Gua&rdar estado" @@ -9753,7 +9778,7 @@ msgstr "Guardar todo" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Exportar guardado" @@ -9774,11 +9799,11 @@ msgstr "Guardado de juego" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "Archivos de guardado de juegos (*.sav);; Todos los archivos (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Importar guardado" @@ -9840,23 +9865,23 @@ msgstr "Ranura de guardado 8" msgid "Save State Slot 9" msgstr "Ranura de guardado 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Guardar estado en archivo" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Guardar estado en la ranura más antigua" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Guardar estado en la ranura seleccionada" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Guardar estado en ranura" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Guardar map&a de símbolos como..." @@ -9876,11 +9901,11 @@ msgstr "Guardar como preajuste..." msgid "Save as..." msgstr "Guardar como..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Guardar archivo de salida combinado como" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9894,11 +9919,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Guardar en el mismo directorio que la ROM" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Guardar archivo de mapa" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Guardar archivo de firmas" @@ -9906,7 +9931,7 @@ msgstr "Guardar archivo de firmas" msgid "Save to Selected Slot" msgstr "Guardar en la ranura seleccionada" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Guardar en la ranura %1 - %2" @@ -9942,7 +9967,7 @@ msgstr "Pantallazo" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Buscar" @@ -9971,7 +9996,7 @@ msgstr "" "Actualmente no se puede buscar en el espacio de la memoria virtual. Ejecuta " "el juego durante unos minutos y vuelve a intentarlo." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Buscar una instrucción" @@ -9979,7 +10004,7 @@ msgstr "Buscar una instrucción" msgid "Search games..." msgstr "Buscar juegos..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Búsqueda de instrucciones" @@ -10018,7 +10043,7 @@ msgid "Select Dump Path" msgstr "Seleccionar ruta de volcado" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Seleccionar directorio de exportación" @@ -10062,7 +10087,7 @@ msgstr "Seleccionar colección de Skylanders" msgid "Select Skylander File" msgstr "Seleccionar archivo de Skylander" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Ranura de guardado %1 - %2" @@ -10070,7 +10095,7 @@ msgstr "Ranura de guardado %1 - %2" msgid "Select State" msgstr "Cargar ranura de guardado" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Seleccionar ranura de guardado" @@ -10156,7 +10181,7 @@ msgstr "Seleccionar archivo" msgid "Select a game" msgstr "Seleccionar juego" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Seleccionar título a instalar en la NAND" @@ -10164,7 +10189,7 @@ msgstr "Seleccionar título a instalar en la NAND" msgid "Select e-Reader Cards" msgstr "Seleccionar tarjetas e-Reader" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Elige la dirección del módulo RSO:" @@ -10181,7 +10206,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Seleccionar archivo de claves (volcado OTP/SEEPROM)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Selecciona el archivo de guardado" @@ -10429,11 +10454,11 @@ msgstr "Mando Shinkansen" msgid "Show % Speed" msgstr "Mostrar velocidad porcentual" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Mostrar ®istro" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Mostrar barra de herramien&tas" @@ -10441,11 +10466,11 @@ msgstr "Mostrar barra de herramien&tas" msgid "Show Active Title in Window Title" msgstr "Mostrar nombre del juego actual en el título de la ventana" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Mostrar todo" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Australia" @@ -10458,7 +10483,7 @@ msgstr "Mostrar el juego actual en Discord" msgid "Show Disabled Codes First" msgstr "Mostrar primero los códigos desactivados" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Mostrar ELF/DOL" @@ -10471,7 +10496,7 @@ msgstr "Mostrar primero los códigos activados" msgid "Show FPS" msgstr "Mostrar FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Mostrar fotogramas por segundo (FPS)" @@ -10479,15 +10504,15 @@ msgstr "Mostrar fotogramas por segundo (FPS)" msgid "Show Frame Times" msgstr "Mostrar duraciones de fotogramas" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Francia" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Mostrar GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Alemania" @@ -10499,23 +10524,23 @@ msgstr "Mostrar superposición de modo de golf" msgid "Show Infinity Base" msgstr "Mostrar base de Infinity" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Mostrar registro de teclas" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "Japón" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Corea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Mostrar indicador de retardo" @@ -10523,7 +10548,7 @@ msgstr "Mostrar indicador de retardo" msgid "Show Language:" msgstr "Mostrar idioma:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Mostrar configuración de ®istro" @@ -10535,7 +10560,7 @@ msgstr "Mostrar mensajes de juego en red" msgid "Show NetPlay Ping" msgstr "Mostrar latencia de juego en red" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Holanda" @@ -10543,7 +10568,7 @@ msgstr "Holanda" msgid "Show On-Screen Display Messages" msgstr "Mostrar mensajes en pantalla" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Región PAL" @@ -10556,19 +10581,19 @@ msgstr "Mostrar PC" msgid "Show Performance Graphs" msgstr "Mostrar gráficas de rendimiento" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Mostrar plataformas" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Mostrar regiones" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Mostrar contador de regrabaciones" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Rusia" @@ -10576,7 +10601,7 @@ msgstr "Rusia" msgid "Show Skylanders Portal" msgstr "Mostrar portal de Skylanders" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "España" @@ -10588,19 +10613,19 @@ msgstr "Mostrar colores según velocidad" msgid "Show Statistics" msgstr "Mostrar estadísticas" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Mostrar reloj del sistema" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Taiwán" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Estados Unidos" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Otros" @@ -10612,15 +10637,15 @@ msgstr "Mostrar duraciones de VBlanks" msgid "Show VPS" msgstr "Mostrar VPS" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Mostrar WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Mostrar Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Mostrar juegos internacionales" @@ -10758,7 +10783,7 @@ msgstr "Cambiar de/a horizontal" msgid "Sideways Wii Remote" msgstr "Mando de Wii en horizontal" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Base de datos de firmas" @@ -11031,7 +11056,7 @@ msgstr "Mando de juego estándar" msgid "Start" msgstr "Comenzar" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Comenzar &juego en red..." @@ -11039,7 +11064,7 @@ msgstr "Comenzar &juego en red..." msgid "Start New Cheat Search" msgstr "Iniciar una nueva búsqueda de trucos" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Grabar pulsaciones" @@ -11133,7 +11158,7 @@ msgstr "Modo 3D estereoscópico" msgid "Stereoscopic 3D Mode:" msgstr "Modo 3D estereoscópico:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Estereoscopia" @@ -11155,7 +11180,7 @@ msgstr "Palanca" msgid "Stop" msgstr "Detener" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Detener la reproducción o grabación de pulsaciones" @@ -11237,8 +11262,8 @@ msgstr "Stylus" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Todo correcto" @@ -11265,7 +11290,7 @@ msgstr "Exportados satisfactoriamente %n de %1 archivo(s) de guardado." msgid "Successfully exported save files" msgstr "Las partidas guardadas se han exportado correctamente." -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Se han extraído correctamente los certificados de la NAND." @@ -11277,12 +11302,12 @@ msgstr "El archivo se ha extraído correctamente." msgid "Successfully extracted system data." msgstr "Los datos del sistema se han extraído correctamente." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Archivo de guardado importado correctamente." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "El título ha sido instalado correctamente en la NAND." @@ -11383,7 +11408,7 @@ msgstr "Nombre de símbolo:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Símbolos" @@ -11403,7 +11428,7 @@ msgstr "Sincroniza y empareja mandos de Wii reales." msgid "Synchronize GPU thread" msgstr "Sincronizar con el hilo de GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11437,7 +11462,7 @@ msgstr "Sincronizando datos guardados..." msgid "System Language:" msgstr "Idioma del sistema:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Entrada TAS" @@ -11450,7 +11475,7 @@ msgstr "Herramientas TAS" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Etiquetas" @@ -11468,7 +11493,7 @@ msgstr "Cola" msgid "Taiwan" msgstr "Taiwán" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Capturar pantalla" @@ -11535,6 +11560,11 @@ msgid "" "\n" "Do you really want to switch to Direct3D 11? If unsure, select 'No'." msgstr "" +"El renderizador de Direct3D 11 requiere soporte para características no " +"soportadas por la configuración de tu sistema. Puedes seguir usando este " +"motor, pero puedes encontrar artefactos gráficos en algunos juegos.\n" +"\n" +"¿Realmente quieres cambiar a Direct3D 11? Si tienes dudas, selecciona «No»." #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." @@ -11554,7 +11584,7 @@ msgstr "El archivo IPL no es un volcado correcto conocido. (CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "Faltan las particiones de los Clásicos" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11562,7 +11592,7 @@ msgstr "" "No se pudo reparar la NAND. Recomendamos que vuelvas a volcar los datos de " "la consola original y pruebes otra vez desde cero." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "La NAND ha sido reparada." @@ -11904,6 +11934,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "El archivo especificado «{0}» no existe" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "La tarjeta de memoria elegida ya contiene un archivo «%1»." @@ -11938,6 +11974,12 @@ msgstr "Falta la partición de actualización." msgid "The update partition is not at its normal position." msgstr "La partición de actualización no está en su posición normal." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "La partición {0} no tiene un sistema de archivos válido." @@ -11966,7 +12008,7 @@ msgstr "¡No hay nada que deshacer!" msgid "There was an issue adding a shortcut to the desktop" msgstr "Ha habido un problema al añadir el acceso directo al escritorio" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -12217,7 +12259,7 @@ msgstr "" "\n" "Ucode desconocido (CRC = {0:08x}) - forzando AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -12225,7 +12267,7 @@ msgstr "" "Este valor se añade al valor de convergencia establecido en la configuración " "de gráficos." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -12288,7 +12330,7 @@ msgstr "Tiempo de espera agotado" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Título" @@ -12302,7 +12344,7 @@ msgstr "A" msgid "To:" msgstr "A:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Alternar &pantalla completa" @@ -12566,7 +12608,7 @@ msgstr "" "afectando mínimamente al rendimiento, pero los resultados dependerán del " "controlador de vídeo." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "No se puede detectar el módulo RSO" @@ -12633,11 +12675,11 @@ msgstr "Archivos ISO de GC/Wii sin comprimir (*.iso *.gcm)" msgid "Undead" msgstr "Muertos" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Deshacer carga del estado" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Deshacer guardado del estado" @@ -12657,7 +12699,7 @@ msgstr "" "Si desinstalas el archivo WAD, eliminarás la versión actual del título que " "se encuentra en la NAND sin borrar sus datos guardados. ¿Quieres continuar?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Estados Unidos" @@ -12764,19 +12806,19 @@ msgstr "Desbloquear cursor" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 msgid "Unlocked" -msgstr "" +msgstr "Desbloqueado" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 msgid "Unlocked %1 times this session" -msgstr "" +msgstr "Desbloqueado %1 veces en esta sesión" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 msgid "Unlocked (Casual)" -msgstr "" +msgstr "Desbloqueado (modo casual)" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 msgid "Unlocked this session" -msgstr "" +msgstr "Desbloqueado en esta sesión" #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" @@ -12930,7 +12972,7 @@ msgstr "" "texturas.

Si tienes dudas, deja esta opción " "desactivada." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Utilizar un único búfer de profundidad para ambos ojos. Necesario para " @@ -12991,7 +13033,7 @@ msgstr "" "Puedes seguir usando los botones «El código no ha sido ejecutado»/«El código " "ha sido ejecutado» para reducir más los resultados." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Configuración del usuario" @@ -13201,7 +13243,7 @@ msgstr "Subir volumen" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "Archivos WAD (*.wad)" @@ -13343,7 +13385,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Advertencia" @@ -13572,11 +13614,11 @@ msgstr "Wii y su mando" msgid "Wii data is not public yet" msgstr "Los datos de Wii todavía no son públicos" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Archivos de guardado de Wii (*.bin);;Todos los archivos (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "Archivo de firmas MEGA de WiiTools" @@ -13842,6 +13884,12 @@ msgstr "" "¿Quieres parar para resolver el problema?\n" "Si seleccionas «No», el audio se oirá con ruidos." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13878,7 +13926,7 @@ msgstr "alineado" msgid "any value" msgstr "cualquier valor" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "Automático" @@ -13911,7 +13959,7 @@ msgstr "Tarjetas e-Reader (*.raw);;Todos los archivos (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "Finalización falsa" @@ -13957,7 +14005,7 @@ msgstr "" "Guardados de mGBA (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *.ss8 *." "ss9);;Todos los archivos (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "Desactivar" @@ -13982,7 +14030,7 @@ msgstr "s" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 msgid "sRGB" -msgstr "" +msgstr "sRGB" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" diff --git a/Languages/po/fa.po b/Languages/po/fa.po index da56f21368..3a03a2c40d 100644 --- a/Languages/po/fa.po +++ b/Languages/po/fa.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: H.Khakbiz , 2011\n" "Language-Team: Persian (http://app.transifex.com/delroth/dolphin-emu/" @@ -308,7 +308,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -329,7 +329,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "" @@ -337,7 +337,7 @@ msgstr "" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -345,11 +345,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&نقاط انفصال" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -357,15 +357,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -373,7 +373,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -381,7 +381,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "" @@ -420,11 +420,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&برابرسازی" @@ -444,27 +444,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&فایل" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&پيشروى فریم" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -472,15 +472,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "تنظیمات &گرافیک" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&کمک" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "تنظیم &شرت کاتها" @@ -500,7 +500,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -512,7 +512,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&جیت" @@ -520,11 +520,11 @@ msgstr "&جیت" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&بارگذاری وضعیت" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -538,15 +538,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&حافظه" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "" @@ -554,7 +554,7 @@ msgstr "" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -563,23 +563,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&باز کردن..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&گزینه ها" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "مکث" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&شروع بازی" @@ -587,7 +587,7 @@ msgstr "&شروع بازی" msgid "&Properties" msgstr "خواص" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "" @@ -595,7 +595,7 @@ msgstr "" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "ثبت کردن" @@ -613,15 +613,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "شروع &دوباره" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -629,7 +629,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -637,7 +637,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&توقف" @@ -645,11 +645,11 @@ msgstr "&توقف" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&ابزارها" @@ -663,17 +663,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&دیدگاه" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "" @@ -685,11 +685,11 @@ msgstr "&ویکی" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1106,7 +1106,7 @@ msgid "Accuracy:" msgstr "دقت:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1280,7 +1280,7 @@ msgstr "اضافه کردن..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "" @@ -1509,15 +1509,15 @@ msgstr "آنتی آلیاسینگ:" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1535,7 +1535,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1642,7 +1642,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1745,7 +1745,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "نشان" @@ -1817,7 +1817,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1853,7 +1853,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1930,7 +1930,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1992,7 +1992,7 @@ msgstr "" msgid "C Stick" msgstr "استیک سی" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2088,7 +2088,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2159,7 +2159,7 @@ msgstr "" msgid "Change &Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "تعویض &دیسک..." @@ -2221,7 +2221,7 @@ msgstr "جستجوی کد تقلب" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2259,11 +2259,11 @@ msgstr "انتخاب فایل برای باز کردن" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2298,7 +2298,7 @@ msgstr "" msgid "Clear" msgstr "پاک کردن" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2319,7 +2319,7 @@ msgstr "" msgid "Close" msgstr "بستن" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2366,7 +2366,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2403,7 +2403,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2539,7 +2539,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "تائید برای توقف" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2550,7 +2550,7 @@ msgstr "" msgid "Connect" msgstr "اتصال" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "" @@ -2558,7 +2558,7 @@ msgstr "" msgid "Connect USB Keyboard" msgstr "اتصال کیبورد USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2578,7 +2578,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2701,7 +2701,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3021,7 +3021,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3217,7 +3217,7 @@ msgstr "" msgid "Default" msgstr "پیش فرز" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3277,7 +3277,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3290,7 +3290,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "شرح" @@ -3312,11 +3312,11 @@ msgstr "" msgid "Detect" msgstr "شناسایی" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3391,7 +3391,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3399,7 +3399,7 @@ msgstr "" msgid "Disable Fog" msgstr "از کارانداختن مه" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3472,7 +3472,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3503,17 +3503,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3674,7 +3674,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "نسخه برداری صدا" @@ -3686,7 +3686,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "نسخه برداری مقصد ای اف بی" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "نسخه برداری فریم ها" @@ -3764,7 +3764,7 @@ msgstr "" msgid "Dutch" msgstr "هلندی" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "خ&روج" @@ -3812,7 +3812,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3879,7 +3879,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4032,7 +4032,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4072,7 +4072,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4133,7 +4133,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4218,7 +4218,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4265,18 +4265,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4414,7 +4414,7 @@ msgstr "" msgid "Euphoria" msgstr "خوشی" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4495,7 +4495,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "" @@ -4510,7 +4510,7 @@ msgstr "" msgid "Export Recording" msgstr "صادر کردن ضبط" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "صادر کردن ضبط..." @@ -4538,7 +4538,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4566,7 +4566,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4604,7 +4604,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "پخش کننده فیفو" @@ -4622,7 +4622,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4716,7 +4716,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4743,18 +4743,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4781,7 +4781,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4791,8 +4791,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4804,7 +4804,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4976,19 +4976,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5036,7 +5036,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5082,7 +5082,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5096,18 +5096,18 @@ msgstr "مشخصات فایل" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "" @@ -5620,7 +5620,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "" @@ -5664,7 +5664,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "تنظیمات مشخصات بازی" @@ -5735,7 +5735,7 @@ msgid "Gecko Codes" msgstr "کدهای گیکو" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5761,7 +5761,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5838,7 +5838,7 @@ msgstr "سبز چپ" msgid "Green Right" msgstr "سبز راست" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5913,7 +5913,7 @@ msgstr "" msgid "Hide" msgstr "مخفی" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6187,7 +6187,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6202,7 +6202,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6307,8 +6307,8 @@ msgstr "مشخصات" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "مشخصات" @@ -6317,10 +6317,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "ورودی" @@ -6361,7 +6361,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6381,7 +6381,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6444,7 +6444,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6469,7 +6469,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6544,11 +6544,11 @@ msgstr "ایتالیایی" msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6556,47 +6556,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6608,11 +6608,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6623,7 +6623,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6682,7 +6682,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6827,11 +6827,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6847,11 +6847,11 @@ msgstr "" msgid "Load" msgstr "بارگذاری" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6863,7 +6863,7 @@ msgstr "بارگذاری بافت اشیاء دلخواه" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6973,19 +6973,19 @@ msgstr "بارگذاری وضعیت - شکاف ۸" msgid "Load State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6997,16 +6997,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7014,7 +7014,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7053,7 +7053,7 @@ msgstr "ثبت وقایع" msgid "Log Configuration" msgstr "پیکر بندی ثبت وقایع" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7133,7 +7133,7 @@ msgstr "استیک اصلی" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7150,10 +7150,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7204,7 +7205,7 @@ msgstr "" msgid "Memory Card" msgstr "کارت حافظه" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7289,8 +7290,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7298,7 +7299,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7361,9 +7362,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7372,7 +7374,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7398,7 +7400,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7606,7 +7608,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7665,7 +7667,7 @@ msgstr "هیچ" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "ست نشده است" @@ -7787,7 +7789,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "" @@ -7795,13 +7797,13 @@ msgstr "" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7816,7 +7818,7 @@ msgstr "گشودن" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7922,11 +7924,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8028,7 +8030,7 @@ msgstr "مسیرها" msgid "Pause" msgstr "مکث" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8066,7 +8068,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "نورپردازی به ازای هر پیکسل" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8100,7 +8102,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8117,7 +8119,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8348,7 +8350,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8404,11 +8406,11 @@ msgstr "آر آنالوگ" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8562,7 +8564,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8660,7 +8662,7 @@ msgstr "شروع دوباره" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8892,11 +8894,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "ذخ&یره وضعیت" @@ -8919,7 +8921,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8940,11 +8942,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9006,23 +9008,23 @@ msgstr "ذخیره وضعیت - شکاف ۸" msgid "Save State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9042,11 +9044,11 @@ msgstr "" msgid "Save as..." msgstr "ذخیره بعنوان..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9057,11 +9059,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9069,7 +9071,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9103,7 +9105,7 @@ msgstr "عکس فوری" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "جستجو" @@ -9130,7 +9132,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9138,7 +9140,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9175,7 +9177,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9219,7 +9221,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9227,7 +9229,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "" @@ -9313,7 +9315,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9321,7 +9323,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9338,7 +9340,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "انتخاب فایل ذخیره" @@ -9545,11 +9547,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "نمایش &ثبت وقایع" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "نمایش نوار &ابزار" @@ -9557,11 +9559,11 @@ msgstr "نمایش نوار &ابزار" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9574,7 +9576,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9587,7 +9589,7 @@ msgstr "" msgid "Show FPS" msgstr "نمایش فریم بر ثانیه" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9595,15 +9597,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "نمایش فرانسه" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "نمایش گیم کیوب" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9615,23 +9617,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "نمایش ورودی تصویر" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "نمایش ایتالیا" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "نمایش کره" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9639,7 +9641,7 @@ msgstr "" msgid "Show Language:" msgstr "نمایش زبان:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "نمایش &پیکربندی ثبت وقایع" @@ -9651,7 +9653,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9659,7 +9661,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "نمایش پال" @@ -9672,19 +9674,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "نمایش پایگاه ها" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "نمایش مناطق" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9692,7 +9694,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9704,19 +9706,19 @@ msgstr "" msgid "Show Statistics" msgstr "نمایش آمار" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "نمایش تایوان" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "نمایش ایالات متحده آمریکا" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9728,15 +9730,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "نمایش وی" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9845,7 +9847,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10085,7 +10087,7 @@ msgstr "کنترولر استاندارد" msgid "Start" msgstr "شروع" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10093,7 +10095,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10187,7 +10189,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10209,7 +10211,7 @@ msgstr "استیک" msgid "Stop" msgstr "توقف" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10280,8 +10282,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10308,7 +10310,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10320,12 +10322,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10418,7 +10420,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10438,7 +10440,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10467,7 +10469,7 @@ msgstr "" msgid "System Language:" msgstr "زبان سیستم:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "ورودی تاس" @@ -10480,7 +10482,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10498,7 +10500,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "گرفتن عکس فوری" @@ -10580,13 +10582,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10856,6 +10858,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10887,6 +10895,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10915,7 +10929,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11109,13 +11123,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11168,7 +11182,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "عنوان" @@ -11182,7 +11196,7 @@ msgstr "به" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11428,7 +11442,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11487,11 +11501,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "خنثی کردن وضعیت بارگذاری" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "" @@ -11509,7 +11523,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11760,7 +11774,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11798,7 +11812,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11992,7 +12006,7 @@ msgstr "" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12093,7 +12107,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "اخطار" @@ -12276,11 +12290,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12497,6 +12511,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12533,7 +12553,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12566,7 +12586,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12610,7 +12630,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" diff --git a/Languages/po/fi.po b/Languages/po/fi.po index 47868202e9..65b5fdd4d0 100644 --- a/Languages/po/fi.po +++ b/Languages/po/fi.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Aleksi, 2023\n" "Language-Team: Finnish (http://app.transifex.com/delroth/dolphin-emu/" @@ -328,7 +328,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Tietoa" @@ -349,7 +349,7 @@ msgstr "&Lisää funktio" msgid "&Add..." msgstr "&Lisää..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Ääniasetukset" @@ -357,7 +357,7 @@ msgstr "&Ääniasetukset" msgid "&Auto Update:" msgstr "&Automaattinen päivitys:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automaattinen käynnistys" @@ -365,11 +365,11 @@ msgstr "&Automaattinen käynnistys" msgid "&Borderless Window" msgstr "&Reunaton ikkuna" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Keskeytyskohdat" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Vianhallintajärjestelmä" @@ -377,15 +377,15 @@ msgstr "&Vianhallintajärjestelmä" msgid "&Cancel" msgstr "&Peruuta" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Huijauskoodien hallinta" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Tarkista päivitykset..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Tyhjennä symbolit" @@ -393,7 +393,7 @@ msgstr "&Tyhjennä symbolit" msgid "&Clone..." msgstr "&Kloonaa..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Koodi" @@ -401,7 +401,7 @@ msgstr "&Koodi" msgid "&Connected" msgstr "&Yhdistetty" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Ohjainasetukset" @@ -440,11 +440,11 @@ msgstr "&Muokkaa koodia..." msgid "&Edit..." msgstr "&Muokkaa..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Poista levy" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulaatio" @@ -464,27 +464,27 @@ msgstr "&Vie tila..." msgid "&Export as .gci..." msgstr "Vie .gci-muodossa..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Tiedosto" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Fontti..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Kehys kerrallaan" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "&Vapaan katselun asetukset" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Luo symbolit lähteestä" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub-repositorio" @@ -492,15 +492,15 @@ msgstr "&GitHub-repositorio" msgid "&Go to start of function" msgstr "&Mene funktion alkuun" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Grafiikka-asetukset" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Ohjeet" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Pikanäppäinasetukset" @@ -520,7 +520,7 @@ msgstr "&Tuo tila..." msgid "&Import..." msgstr "&Tuo..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "&Infinity-alusta" @@ -532,7 +532,7 @@ msgstr "&Lisää blr" msgid "&Interframe Blending" msgstr "&Kehysten välinen sekoitus" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -540,11 +540,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Kieli:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Lataa tila" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Lataa symbolikartta" @@ -558,15 +558,15 @@ msgstr "&Lataa tiedosto nykyiseen osoitteeseen" msgid "&Lock Watches" msgstr "&Lukitse vahdit" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&Lukitse käyttöliittymäelementit paikoilleen" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Muisti" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Nauhoitus" @@ -574,7 +574,7 @@ msgstr "&Nauhoitus" msgid "&Mute" msgstr "&Mykistä" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Verkko" @@ -583,23 +583,23 @@ msgid "&No" msgstr "&Ei" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Avaa..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Asetukset" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Muuta HLE-funktiot" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Keskeytä" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Käynnistä" @@ -607,7 +607,7 @@ msgstr "&Käynnistä" msgid "&Properties" msgstr "&Ominaisuudet" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Vain luku -tila" @@ -615,7 +615,7 @@ msgstr "&Vain luku -tila" msgid "&Refresh List" msgstr "&Päivitä lista" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Rekisterit" @@ -633,15 +633,15 @@ msgid "&Rename symbol" msgstr "&Nimeä symboli uudelleen" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Nollaa" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Resurssipakettien hallinta" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Tallenna symbolikartta" @@ -649,7 +649,7 @@ msgstr "&Tallenna symbolikartta" msgid "&Scan e-Reader Card(s)..." msgstr "&Skannaa e-Reader kortteja..." -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "&Skylanders-portaali" @@ -657,7 +657,7 @@ msgstr "&Skylanders-portaali" msgid "&Speed Limit:" msgstr "&Nopeusrajoitus:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Lopeta" @@ -665,11 +665,11 @@ msgstr "&Lopeta" msgid "&Theme:" msgstr "&Teema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Säikeet" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Työkalut" @@ -683,17 +683,17 @@ msgstr "&Poista ROM" msgid "&Unlock Watches" msgstr "&Poista vahtien lukitus" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Näytä" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Vahti" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Kotisivu" @@ -705,11 +705,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "K&yllä" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "Kohdetta '%1' ei löydy, symbolinimiä ei luotu" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "Kohdetta '%1' ei löydy, etsitään sen sijaan yleisiä funktioita" @@ -1155,7 +1155,7 @@ msgid "Accuracy:" msgstr "Tarkkuus:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1349,7 +1349,7 @@ msgstr "Lisää..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Osoite" @@ -1607,15 +1607,15 @@ msgstr "Reunanpehmennys:" msgid "Any Region" msgstr "Mikä vain alue" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Lisää allekirjoitus kohteeseen" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Lisää allekirjoitus &olemassaolevaan allekirjoitustiedostoon..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Käyt&ä allekirjoitustiedostoa..." @@ -1635,7 +1635,7 @@ msgstr "Apploaderin päiväys:" msgid "Apply" msgstr "Käytä" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Käytä allekirjoitustiedostoa" @@ -1748,7 +1748,7 @@ msgstr "Säädä ikkunan kokoa automaattisesti" msgid "Auto-Hide" msgstr "Automaattinen piilotus" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Havaitaanko RSO-moduulit automaattisesti?" @@ -1857,7 +1857,7 @@ msgstr "Virheellinen arvo annettu" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banneri" @@ -1931,7 +1931,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Lohkokoko" @@ -1969,7 +1969,7 @@ msgstr "" "Bluetooth-läpipäästötila on käytössä, mutta Dolphin on käännetty ilman " "libusb-kirjastoa. Läpipäästötilaa ei voi käyttää." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Käynnistä keskeytettynä" @@ -2046,7 +2046,7 @@ msgstr "Broadband-sovittimen virhe" msgid "Broadband Adapter MAC Address" msgstr "Broadband-sovittimen MAC-osoit" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Selaa &nettipeli-istuntoja..." @@ -2111,7 +2111,7 @@ msgstr "Tekijä(t):" msgid "C Stick" msgstr "C-sauva" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "L&uo allekirjoitustiedosto..." @@ -2217,7 +2217,7 @@ msgstr "Nettipeli-istuntoa ei voi käynnistää, kun peli on vielä käynnissä! #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2291,7 +2291,7 @@ msgstr "Keskitä ja kalibr" msgid "Change &Disc" msgstr "Vaihda &levy" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Vaihda &levy..." @@ -2368,7 +2368,7 @@ msgstr "Koodihaku" msgid "Cheats Manager" msgstr "Koodien hallinta" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Tarkista NAND..." @@ -2408,11 +2408,11 @@ msgstr "Valitse avattava tiedosto" msgid "Choose a file to open or create" msgstr "Valitse luotava tai avattava tiedosto" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Valitse ensisijainen syötetiedosto" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Valitse toissijainen syötetiedosto" @@ -2447,7 +2447,7 @@ msgstr "Classic Controller" msgid "Clear" msgstr "Tyhjennä" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Tyhjennä välimuisti" @@ -2468,7 +2468,7 @@ msgstr "Kloonaa ja &muokkaa koodia..." msgid "Close" msgstr "Sulje" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "As&etukset" @@ -2515,7 +2515,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Yhdistä &kaksi allekirjoitustiedostoa..." @@ -2558,7 +2558,7 @@ msgstr "Käännetään varjostimia" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Pakkausmenetelmä" @@ -2694,7 +2694,7 @@ msgstr "Vahvista sisäisen järjestelmän muutos" msgid "Confirm on Stop" msgstr "Vahvista pysäytyksessä" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2705,7 +2705,7 @@ msgstr "Vahvistus" msgid "Connect" msgstr "Yhdistä" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Yhdistä tasapainolauta" @@ -2713,7 +2713,7 @@ msgstr "Yhdistä tasapainolauta" msgid "Connect USB Keyboard" msgstr "Yhdistä USB-näppäimistö" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Yhdistä Wii Remote %1" @@ -2733,7 +2733,7 @@ msgstr "Yhdistä Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Yhdistä Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Yhdistä Wii Remoteja" @@ -2876,7 +2876,7 @@ msgstr "" msgid "Convergence" msgstr "Yhtenevyys" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Yhtenevyys:" @@ -3240,7 +3240,7 @@ msgstr "" "

Ellet ole varma, jätä tämä valitsematta." -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Nykyinen alue" @@ -3443,7 +3443,7 @@ msgstr "Vähennä Y:tä" msgid "Default" msgstr "Oletus" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Oletusasetukset (vain luku)" @@ -3510,7 +3510,7 @@ msgstr "Poistetaanko olemassaoleva tiedosto '{0}'?" msgid "Depth" msgstr "Syvyys" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Syvyysprosentti:" @@ -3523,7 +3523,7 @@ msgstr "Syvyys:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Kuvaus" @@ -3545,11 +3545,11 @@ msgstr "Irrallinen" msgid "Detect" msgstr "Havaitse" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Havaitaan RSO-moduuleja" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Deterministinen kaksoisydintila:" @@ -3624,7 +3624,7 @@ msgstr "Poista EFB-VRAM-kopiointi käytöstä" msgid "Disable Emulation Speed Limit" msgstr "Poista emulaation nopeusrajoitus" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Poista nopea muistihaku (Fastmem) käytöstä" @@ -3632,7 +3632,7 @@ msgstr "Poista nopea muistihaku (Fastmem) käytöstä" msgid "Disable Fog" msgstr "Poista sumu käytöstä" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Poista JIT-välimuisti käytöstä" @@ -3724,7 +3724,7 @@ msgstr "Sallitko Dolphinin lähettävän tietoja Dolphinin kehittäjille?" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Haluatko lisätä polun \"%1\" pelipolkujen listaan?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Haluatko tyhjentää symbolinimien listan?" @@ -3756,17 +3756,17 @@ msgstr "Dolphin FIFO -loki (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Dolphinin pelimodien esiasestukset" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphinin karttatiedosto (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Dolphinin allekirjoitusten CSV-tiedosto" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Dolphinin allekirjoitustiedosto" @@ -3940,7 +3940,7 @@ msgstr "Tee &FakeVMEM-vedos" msgid "Dump &MRAM" msgstr "Tee &MRAM-vedos" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Tee äänivedos" @@ -3952,7 +3952,7 @@ msgstr "Tee perustekstuurivedos" msgid "Dump EFB Target" msgstr "Tee EFB-kohteen vedos" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Tee kehysvedos" @@ -4039,7 +4039,7 @@ msgstr "Turbo-painikkeen irrottamisen pituus (kehyksiä):" msgid "Dutch" msgstr "Hollanti" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "P&oistu" @@ -4095,7 +4095,7 @@ msgid "Edit..." msgstr "Muokkaa..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Muokkain" @@ -4164,7 +4164,7 @@ msgstr "" "Emuloi oikean laitteiston optisen levyn nopeutta. Käytöstä poistaminen " "saattaa aiheutaa epävakautta. Oletuksena True" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "Emuloidut USB-laitteet" @@ -4320,7 +4320,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4365,7 +4365,7 @@ msgstr "" "Käyttää Dolby Pro Logic II -emulointia hyödyntäen 5.1-surround-ääntä. " "Saatavilla vain joillain järjestelmillä." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4454,7 +4454,7 @@ msgstr "" "

Ellet ole varma, jätä tämä valitsematta." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4550,7 +4550,7 @@ msgstr "Anna salasana" msgid "Enter the DNS server to use:" msgstr "Syötä käytettävä DNS-palvelin:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Syötä RSO-moduulin osoite:" @@ -4597,18 +4597,18 @@ msgstr "Syötä RSO-moduulin osoite:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4752,7 +4752,7 @@ msgstr "Virheitä löytyi {0} käyttämättömästä lohkosta osiossa {1}." msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Eurooppa" @@ -4850,7 +4850,7 @@ msgstr "Odotettiin muuttujanimeä" msgid "Experimental" msgstr "Kokeellinen" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Vie kaikki Wii-tallennustiedostot" @@ -4865,7 +4865,7 @@ msgstr "Vieminen epäonnistui" msgid "Export Recording" msgstr "Vie nauhoitus" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Vie nauhoitus..." @@ -4893,7 +4893,7 @@ msgstr "Vie .&gcs-muodossa..." msgid "Export as .&sav..." msgstr "Vie .&sav-muodossa..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4921,7 +4921,7 @@ msgstr "Ulkoinen" msgid "External Frame Buffer (XFB)" msgstr "Ulkoinen kehyspuskuri (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Vie varmenteet NAND-muistista" @@ -4959,7 +4959,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO-toistaja" @@ -4979,7 +4979,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Tämän istunnon lisääminen nettipeli-indeksiin epäonnistui: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Allekirjoitustiedoston '%1' lisääminen epäonnistui" @@ -5077,7 +5077,7 @@ msgstr "Tallennustiedostoista %n:n %1:sta vienti epäonnistui." msgid "Failed to export the following save files:" msgstr "Seuraavien tallennustiedostojen vienti epäonnistui:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Varmenteiden vienti NAND-muistista epäonnistui" @@ -5107,14 +5107,14 @@ msgstr "Yhden tai useamman D3D-symbolin haku epäonnistui" msgid "Failed to import \"%1\"." msgstr "Kohteen \"%1\" tuonti epäonnistui." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Tallennustiedoston tuonti epäonnistui. Käynnistä peli kerran ja yritä sitten " "uudelleen." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5122,7 +5122,7 @@ msgstr "" "Tallennustiedoston tuonti epäonnistui. Annettu tiedosto on vioittunut tai ei " "ole kelvollinen Wii-tallennustiedosto." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5156,7 +5156,7 @@ msgid "Failed to install pack: %1" msgstr "Paketin asennus epäonnistui: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Tämän julkaisun asennus NAND-muistiin epäonnistui." @@ -5167,8 +5167,8 @@ msgid "" msgstr "" "Portissa %1 kuuntelu epäonnistui. Onko toinen nettipeli-istunto käynnissä?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "RSO-moduulin lataaminen epäonnistui kohdassa %1" @@ -5180,7 +5180,7 @@ msgstr "d3d11.dll:n lataus epäonnistui" msgid "Failed to load dxgi.dll" msgstr "dxgi.dll:n lataus epäonnistui" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Karttatiedoston '%1' lataus epäonnistui" @@ -5374,19 +5374,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "FIFO-lokin tallennus epäonnistui." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Koodikartan tallentaminen polkuun '%1' epäonnistui" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Allekirjoitustiedoston tallentaminen tiedostoon '%1' epäonnistui" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Symbolikartan tallentaminen polkuun '%1' epäonnistui" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Allekirjoitustiedoston '%1' tallentaminen epäonnistui" @@ -5436,7 +5436,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Virhe" @@ -5484,7 +5484,7 @@ msgstr "Tiedoston tiedot" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Tiedostomuoto" @@ -5498,18 +5498,18 @@ msgstr "Tiedoston tiedot" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Tiedostonimi" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Tiedostopolku" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Tiedostokoko" @@ -6071,7 +6071,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Pelin tunniste" @@ -6119,7 +6119,7 @@ msgstr "" msgid "Game region does not match" msgstr "Pelin alue on eri" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Pelikohtaiset asetukset" @@ -6190,7 +6190,7 @@ msgid "Gecko Codes" msgstr "Gecko-koodit" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6216,7 +6216,7 @@ msgstr "Luo uusi tilastoidentiteetti" msgid "Generated AR code." msgstr "Luo AR-koodi." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Luotu symbolinimet lähteestä '%1'" @@ -6299,7 +6299,7 @@ msgstr "Vihreä vasen" msgid "Green Right" msgstr "Vihreä oikea" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Ruudukkonäkymä" @@ -6374,7 +6374,7 @@ msgstr "Heksadesimaali" msgid "Hide" msgstr "Piilota" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Piilota kaikki" @@ -6718,7 +6718,7 @@ msgstr "" "

Ellet ole varma, jätä tämä valitsematta." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Tuo BootMii-NAND-varmuuskopio..." @@ -6733,7 +6733,7 @@ msgstr "Tuonti epäonnistui" msgid "Import Save File(s)" msgstr "Tuo tallennustiedosto(ja)" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Tuo Wii-tallennustiedosto..." @@ -6848,8 +6848,8 @@ msgstr "Tiedot" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Tiedot" @@ -6858,10 +6858,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Estä näytönsäästäjä emuloidessa" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Syöte" @@ -6902,7 +6902,7 @@ msgstr "Asennusosio (%1)" msgid "Install Update" msgstr "Asenna päivitys" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Asenna WAD..." @@ -6922,7 +6922,7 @@ msgstr "Käsky" msgid "Instruction Breakpoint" msgstr "Käskyn keskeytyskohta" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Käsky:" @@ -6991,7 +6991,7 @@ msgstr "Sisäinen virhe AR-koodia luonnissa." msgid "Interpreter (slowest)" msgstr "Tulkki (hitain)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Tulkkiydin" @@ -7016,7 +7016,7 @@ msgstr "Virheellinen paketti %1 annettu: %2" msgid "Invalid Player ID" msgstr "Virheellinen pelaajatunniste" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Virheellinen RSO-moduulin osoite: %1" @@ -7091,11 +7091,11 @@ msgstr "Italia" msgid "Italy" msgstr "Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT:n lohkolinkitys pois" @@ -7103,47 +7103,47 @@ msgstr "JIT:n lohkolinkitys pois" msgid "JIT Blocks" msgstr "JIT-lohkot" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT-haara pois" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT-liukuluku pois" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT-kokonaisluku pois" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT-liukuluku-lukukirjoitus pois" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT-lukukirjoitus pois" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT-paritettu-lukukirjoitus pois" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT-IXz-lukukirjoitus pois" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT-Ibzx-lukukirjoitus pois" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT-Iwz-lukukirjoitus pois" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT pois (JIT-ydin)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT-paritettu pois" @@ -7155,11 +7155,11 @@ msgstr "JIT-kääntäjä ARM64-alustalle (suositus)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "JIT-kääntäjä x86-64-alustalle (suositus)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "JIT-rekisterivälimuisti pois" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT-järjestelmärekisterit pois" @@ -7173,7 +7173,7 @@ msgstr "" "Näin ei pitäisi koskaan tapahtua. Ilmoitathan tästä ongelmasta " "vianhallintajärjestelmään. Dolphin sulkeutuu nyt." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japani" @@ -7232,7 +7232,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Poista pelaaja" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -7383,11 +7383,11 @@ msgstr "Valo" msgid "Limit Chunked Upload Speed:" msgstr "Rajoita lohkotun lähetyksen nopeutta:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Listan sarakkeet" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Listanäkymä" @@ -7403,11 +7403,11 @@ msgstr "Kuunnellaan" msgid "Load" msgstr "Lataa" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Lataa &huono karttatiedosto..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Lataa &muu karttatiedosto..." @@ -7419,7 +7419,7 @@ msgstr "Lataa muokatut tekstuurit" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Lataa GameCube-päävalikko" @@ -7529,19 +7529,19 @@ msgstr "Palauta tila 8" msgid "Load State Slot 9" msgstr "Palauta tila 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Palauta tila tiedostosta" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Palauta tila valitusta paikasta" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Palauta tila paikasta" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Käynnistä Wii-järjestelmävalikko %1" @@ -7553,16 +7553,16 @@ msgstr "Lataa ja kirjoita isäntäkoneen tallennustiedosto" msgid "Load from Selected Slot" msgstr "Palauta tila valitusta paikasta" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Palauta tila paikasta %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Lataa karttatiedosto" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "Käynnistä vWii-järjestelmävalikko %1" @@ -7570,7 +7570,7 @@ msgstr "Käynnistä vWii-järjestelmävalikko %1" msgid "Load..." msgstr "Lataa..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Symbolit lähteestä '%1' ladattu" @@ -7616,7 +7616,7 @@ msgstr "Loki" msgid "Log Configuration" msgstr "Lokiasetukset" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Kirjoita JIT:n käskykattavuus lokiin" @@ -7700,7 +7700,7 @@ msgstr "Pääohjainsauva" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Tekijä" @@ -7722,10 +7722,11 @@ msgstr "" "

Ellet ole varma, jätä tämä valitsematta." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Hallitse NAND-muistia" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "Manuaalinen tekstuuriotanta" @@ -7777,7 +7778,7 @@ msgstr "Muistin keskeytyskohta" msgid "Memory Card" msgstr "Muistikortti" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Muistikorttien hallinta" @@ -7882,8 +7883,8 @@ msgstr "" "

Ellet ole varma, jätä tämä valitsematta." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Löydetyt moduulit: %1" @@ -7891,7 +7892,7 @@ msgstr "Löydetyt moduulit: %1" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskooppiset varjot" @@ -7958,9 +7959,10 @@ msgstr "Kerroin" msgid "N&o to All" msgstr "E&i kaikkiin" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND-tarkistus" @@ -7969,7 +7971,7 @@ msgstr "NAND-tarkistus" msgid "NKit Warning" msgstr "NKit-varoitus" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7995,7 +7997,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8211,7 +8213,7 @@ msgstr "Peli ei ole käynnissä." msgid "No game running." msgstr "Peli ei ole käynnissä." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Ongelmia ei löytynyt." @@ -8275,7 +8277,7 @@ msgstr "Ei mikään" msgid "North America" msgstr "Pohjois-Amerikka" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Ei asetettu" @@ -8406,7 +8408,7 @@ msgstr "" "kulmapistevarjostimia pisteiden ja janojen laajentamiseen, tämä asetus " "valitsee kulmapistevarjostimen. Se voi vaikuttaa suorituskykyyn.

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Verkko-&ohje" @@ -8414,7 +8416,7 @@ msgstr "Verkko-&ohje" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8422,7 +8424,7 @@ msgstr "" "Lisää vain symbolit, jotka alkavat näin:\n" "(Jätä tyhjäksi saadaksesi kaikki symbolit)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8439,7 +8441,7 @@ msgstr "Avaa" msgid "Open &Containing Folder" msgstr "Avaa &kansio" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "Avaa &käyttäjäkansio" @@ -8545,11 +8547,11 @@ msgstr "Muu peli..." msgid "Overwritten" msgstr "Ylikirjoitettu" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Toista nauhoitus..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8651,7 +8653,7 @@ msgstr "Polut" msgid "Pause" msgstr "Keskeytä" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Keskeytä nauhoituksen loputtua" @@ -8692,7 +8694,7 @@ msgstr "Korkein nopeus ulospäin suuntautuville heilahduksille." msgid "Per-Pixel Lighting" msgstr "Kuvapistekohtainen valaistus" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Tee verkossa järjestelmäpäivitys" @@ -8726,7 +8728,7 @@ msgstr "Fyysinen osoiteavaruus" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Valitse virheenjäljitysfontti" @@ -8743,7 +8745,7 @@ msgid "Pitch Up" msgstr "Nyökkäyskulma ylös" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Alusta" @@ -8988,7 +8990,7 @@ msgstr "Edistyminen" msgid "Public" msgstr "Julkinen" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Tyhjennä peliluettelon välimuisti" @@ -9044,11 +9046,11 @@ msgstr "R-analogi" msgid "READY" msgstr "VALMIS" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO-moduulit" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO:n automaattinen havainta" @@ -9210,7 +9212,7 @@ msgid "Refreshing..." msgstr "Päivittyy..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Alue" @@ -9313,7 +9315,7 @@ msgstr "Nollaa" msgid "Reset All" msgstr "Nollaa kaikki" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Nollaa ohittaen paniikkikäsittelijä" @@ -9551,11 +9553,11 @@ msgstr "SSL-konteksti" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Ta&llenna koodi" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Tal&lenna tila" @@ -9578,7 +9580,7 @@ msgstr "Tallenna kaikki" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Tallennustiedostojen vienti" @@ -9599,11 +9601,11 @@ msgstr "Pelin tallennustiedosto" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "Pelien tallennustiedostot (*.sav);;Kaikki tiedostot (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Tallennustiedostojen tuonti" @@ -9665,23 +9667,23 @@ msgstr "Tallenna tila 8" msgid "Save State Slot 9" msgstr "Tallenna tila 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Tallenna tila tiedostoon" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Tallenna tilan vanhimpaan paikkaan" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Tallenna tila valittuun paikkaan" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Tallenna tila paikkaan" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Tallenna symbolikartta &nimellä..." @@ -9701,11 +9703,11 @@ msgstr "Tallenna esiasetuksena..." msgid "Save as..." msgstr "Tallenna nimellä..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Tallenna yhdistetty ulostulotiedosto nimellä" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9719,11 +9721,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Tallenna ROMin kanssa samaan hakemistoon" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Tallenna karttatiedosto" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Tallenna allekirjoitustiedosto" @@ -9731,7 +9733,7 @@ msgstr "Tallenna allekirjoitustiedosto" msgid "Save to Selected Slot" msgstr "Tallenna tila valittuun paikkaan" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Tallenna tila paikkaan %1 - %2" @@ -9767,7 +9769,7 @@ msgstr "Kuvakaappaus" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Haku" @@ -9796,7 +9798,7 @@ msgstr "" "Haku ei ole tällä hetkellä mahdollinen näennäisosoiteavaruudessa. Pelaa " "peliä hetken aikaa ja yritä uudelleen." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Etsi käskyä" @@ -9804,7 +9806,7 @@ msgstr "Etsi käskyä" msgid "Search games..." msgstr "Etsi pelejä..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Etsi käsky" @@ -9843,7 +9845,7 @@ msgid "Select Dump Path" msgstr "Valitse vedostiedostojen polku" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Valitse vientihakemisto" @@ -9887,7 +9889,7 @@ msgstr "" msgid "Select Skylander File" msgstr "Valitse Skylander-tiedosto" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Valitse paikka %1 - %2" @@ -9895,7 +9897,7 @@ msgstr "Valitse paikka %1 - %2" msgid "Select State" msgstr "Valitse tilatallennus" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Valitse tilatallennuksen paikka" @@ -9981,7 +9983,7 @@ msgstr "Valitse tiedosto" msgid "Select a game" msgstr "Valitse peli" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Valitse NAND-muistiin asennettava julkaisu" @@ -9989,7 +9991,7 @@ msgstr "Valitse NAND-muistiin asennettava julkaisu" msgid "Select e-Reader Cards" msgstr "Valitse e-Reader-kortti" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Valitse RSO-moduulin osoite" @@ -10006,7 +10008,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Valitse avaintiedosto (OTP-/SEEPROM-vedos)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Valitse tallennustiedosto" @@ -10250,11 +10252,11 @@ msgstr "Shinkansen-ohjain" msgid "Show % Speed" msgstr "Näytä prosentuaalinen nopeus" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Näytä &loki" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Näytä &työkalupalkki" @@ -10262,11 +10264,11 @@ msgstr "Näytä &työkalupalkki" msgid "Show Active Title in Window Title" msgstr "Näytä aktiivinen julkaisu ikkunan otsikossa" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Näytä kaikki" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Näytä Australia" @@ -10279,7 +10281,7 @@ msgstr "Näytä peli Discordissa" msgid "Show Disabled Codes First" msgstr "Näytä käytöstä poistetut koodit ensin" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Näytä ELF/DOL" @@ -10292,7 +10294,7 @@ msgstr "Näytä käytössä olevat koodit ensin" msgid "Show FPS" msgstr "Näytä kehysnopeus" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Näytä kehyslaskuri" @@ -10300,15 +10302,15 @@ msgstr "Näytä kehyslaskuri" msgid "Show Frame Times" msgstr "Näytä kehysajat" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Näytä Ranska" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Näytä GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Näytä Saksa" @@ -10320,23 +10322,23 @@ msgstr "Näytä golf-tilan kerros" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Näytä syötteet" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Näytä Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "Näytä Japani" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Näytä Korea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Näytä viivelaskuri" @@ -10344,7 +10346,7 @@ msgstr "Näytä viivelaskuri" msgid "Show Language:" msgstr "Kieli:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Näytä lokin &asetukset" @@ -10356,7 +10358,7 @@ msgstr "Näytä nettipelin viestit" msgid "Show NetPlay Ping" msgstr "Näytä nettipelin vasteaika" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Näytä Alankomaat" @@ -10364,7 +10366,7 @@ msgstr "Näytä Alankomaat" msgid "Show On-Screen Display Messages" msgstr "Näytä ruudulle tulevat näyttöviestit" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Näytä PAL" @@ -10377,19 +10379,19 @@ msgstr "Näytä ohjelmalaskuri" msgid "Show Performance Graphs" msgstr "Näytä suorituskykykaaviot" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Näytä alustat" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Näytä alueet" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Näytä uudelleennauhoituslasksuri" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Näytä Venäjä" @@ -10397,7 +10399,7 @@ msgstr "Näytä Venäjä" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Näytä Espanja" @@ -10409,19 +10411,19 @@ msgstr "Näytä nopeusvärit" msgid "Show Statistics" msgstr "Näytä tilastot" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Näytä järjestelmän kellonaika" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Näytä Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Näytä USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Näytä tuntematon" @@ -10433,15 +10435,15 @@ msgstr "Näytä VBlank-ajat" msgid "Show VPS" msgstr "Näytä VPS-laskuri" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Näytä WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Näytä Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Näytä maailma" @@ -10576,7 +10578,7 @@ msgstr "Vaakasuuntaisuus päälle/pois" msgid "Sideways Wii Remote" msgstr "Vaakasuuntainen Wii Remote" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Allekirjoitustietokanta" @@ -10841,7 +10843,7 @@ msgstr "Vakio-ohjain" msgid "Start" msgstr "Aloita" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Aloita &nettipeli..." @@ -10849,7 +10851,7 @@ msgstr "Aloita &nettipeli..." msgid "Start New Cheat Search" msgstr "Aloita uusi huijauskoodihaku" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Aloita syötteen nauhoitus" @@ -10943,7 +10945,7 @@ msgstr "Stereoskooppinen 3D -tila" msgid "Stereoscopic 3D Mode:" msgstr "Stereoskooppinen 3D -tila:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopia" @@ -10965,7 +10967,7 @@ msgstr "Ohjaussauva" msgid "Stop" msgstr "Lopeta" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Lopeta syötteen toisto/nauhoitus" @@ -11046,8 +11048,8 @@ msgstr "Osoitinkynä" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Onnistui" @@ -11074,7 +11076,7 @@ msgstr "Tallennustiedostoista %n:n %1:stä vienti onnistui." msgid "Successfully exported save files" msgstr "Tallennustiedostojen vienti onnistui" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Varmenteiden vienti NAND-muistista onnistui" @@ -11086,12 +11088,12 @@ msgstr "Tiedoston purku onnistui." msgid "Successfully extracted system data." msgstr "Järjestelmädatan vienti onnistui." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Tallennustiedoston tuonti onnistui." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Julkaisun asentaminen NAND-muistiin onnistui." @@ -11192,7 +11194,7 @@ msgstr "Symbolin nimi:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symbolit" @@ -11212,7 +11214,7 @@ msgstr "Synkronoi oikeita Wii Remote -ohjaimia ja luo laitepareja" msgid "Synchronize GPU thread" msgstr "Synkronoi grafiikkasuorittimen säie" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11246,7 +11248,7 @@ msgstr "Tallennustiedostojen synkronointi käynnissä..." msgid "System Language:" msgstr "Järjestelmän kieli:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS-syöte" @@ -11259,7 +11261,7 @@ msgstr "TAS-työkalut" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Tunnisteet" @@ -11277,7 +11279,7 @@ msgstr "Häntä" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Ota kuvakaappaus" @@ -11363,7 +11365,7 @@ msgstr "IPL-tiedosto ei ole tunnettu hyvä vedos. (CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "Masterpiece-osiot puuttuvat." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11371,7 +11373,7 @@ msgstr "" "NAND-muistin korjaus epäonnistui. On suositeltavaa, että teet varmuuskopion " "nykyisestä datasta ja aloitat uudelleen tyhjällä NAND-muistilla." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND-muistin korjaus onnistui." @@ -11699,6 +11701,12 @@ msgstr "Annettu yhteisavaimen indeksi on {0}, kun sen tulisi olla {1}." msgid "The specified file \"{0}\" does not exist" msgstr "Annettua tiedostoa \"{0}\" ei ole olemassa" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "Kohdemuistikortilla on jo tiedosto \"%1\"." @@ -11732,6 +11740,12 @@ msgstr "Päivitysosio puuttuu." msgid "The update partition is not at its normal position." msgstr "Päivitysosio ei ole tavallisella paikallaan." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "Osiolla {0} ei ole kelvollista tiedostojärjestelmää." @@ -11760,7 +11774,7 @@ msgstr "Mitään kumottavaa ei ole!" msgid "There was an issue adding a shortcut to the desktop" msgstr "Pikakuvakkeen lisääminen epäonnistui" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11997,13 +12011,13 @@ msgstr "" "\n" "DSP-HLE: Tuntematon mikrokoodi (CRC = {0:08x}) - pakotetaan AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "Tämä arvo lisätään grafiikka-asetusten määräämään yhtenevyysarvoon." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "Tämä arvo kerrotaan grafiikka-asetusten määräämällä syvyydellä." @@ -12063,7 +12077,7 @@ msgstr "Aikakatkaisu" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Julkaisu" @@ -12077,7 +12091,7 @@ msgstr "Minne" msgid "To:" msgstr "Minne:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "&Koko ruudun tila päälle/pois" @@ -12340,7 +12354,7 @@ msgstr "" "kokonaan pätkinnän ja aiheuttaa häviävän pieniä suorituskykyvaikutuksia, " "mutta tämä riippuu grafiikka-ajurien toiminnasta." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "RSO-moduulin tunnistus epäonnistui" @@ -12408,11 +12422,11 @@ msgstr "Pakkaamattomat GC-/Wii-levykuvat (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Kumoa tilan palauttaminen" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Kumoa tilan tallentaminen" @@ -12433,7 +12447,7 @@ msgstr "" "version NAND-muistista poistamatta kuitenkaan sen tallennustiedostoa. " "Jatketaanko?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Yhdysvallat" @@ -12706,7 +12720,7 @@ msgstr "" "

Ellet ole varma, jätä tämä valitsematta." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Käyttää yhteistä syvyyspuskuria molemmille silmille. Muutamat pelit vaativat " @@ -12766,7 +12780,7 @@ msgstr "" "Voit jatkaa 'Koodi tuli suoritetuksi'- ja 'Koodi ei tullut suoritetuksi'-" "painikkeiden käyttöä tarkentaaksesi tulosta." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Käyttäjän asetukset" @@ -12974,7 +12988,7 @@ msgstr "Äänenvoimakkuuden suurennus" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD-tiedostot (*.wad)" @@ -13106,7 +13120,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Varoitus" @@ -13332,11 +13346,11 @@ msgstr "Wii ja Wii Remote" msgid "Wii data is not public yet" msgstr "Wii-data ei ole vielä julkista" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii-tallennustiedostot (*.bin);;Kaikki tiedostot (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "WiiTools-allekirjoituksen MEGA-tiedosto" @@ -13596,6 +13610,12 @@ msgstr "" "Haluatko lopettaa nyt korjataksesi ongelman?\n" "Jos valitset \"Ei\", ääni voi olla pätkivää." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13632,7 +13652,7 @@ msgstr "kohdistettu" msgid "any value" msgstr "mikä vain arvo" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "automaattinen" @@ -13665,7 +13685,7 @@ msgstr "e-Reader-kortit (*.raw);;Kaikki tiedostot (*)" msgid "errno" msgstr "virhekoodi" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "näennäisläpäisy" @@ -13711,7 +13731,7 @@ msgstr "" "mGBA-tilatallennukset (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *.ss8 " "*.ss9);;Kaikki tiedostot (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "ei mikään" diff --git a/Languages/po/fr.po b/Languages/po/fr.po index 75d7211690..23de39d947 100644 --- a/Languages/po/fr.po +++ b/Languages/po/fr.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Pascal , 2013-2023\n" "Language-Team: French (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -199,10 +199,12 @@ msgid "" "%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " "hardcore)" msgstr "" +"%1 a débloqué %2/%3 succès (%4 en hardcore), ce qui vaut %5/%6 points (%7 en " +"hardcore)" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" -msgstr "" +msgstr "%1 a débloqué %2/%3 succès, ce qui vaut %4/%5 points" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" @@ -224,7 +226,7 @@ msgstr "%1 ms" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 msgid "%1 points" -msgstr "" +msgstr "%1 points" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" @@ -334,7 +336,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&À propos" @@ -355,7 +357,7 @@ msgstr "&Ajouter une fonction" msgid "&Add..." msgstr "&Ajouter..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Paramètres &audio" @@ -363,7 +365,7 @@ msgstr "Paramètres &audio" msgid "&Auto Update:" msgstr "Mise à jour &automatique :" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "Démarrage &automatique" @@ -371,11 +373,11 @@ msgstr "Démarrage &automatique" msgid "&Borderless Window" msgstr "Fenêtre sans &bordures" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Points d'arrêt" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "Suivi des &bugs" @@ -383,15 +385,15 @@ msgstr "Suivi des &bugs" msgid "&Cancel" msgstr "&Annuler" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "Gestionnaire de &cheats" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "Rechercher des &mises à jour..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Effacer les symboles" @@ -399,7 +401,7 @@ msgstr "&Effacer les symboles" msgid "&Clone..." msgstr "&Cloner..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Code" @@ -407,7 +409,7 @@ msgstr "&Code" msgid "&Connected" msgstr "&Connecté" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "Paramètres des &manettes" @@ -446,11 +448,11 @@ msgstr "&Modifier le code" msgid "&Edit..." msgstr "&Éditer..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Éjecter le disque" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Émulation" @@ -470,27 +472,27 @@ msgstr "&Exporter l'état..." msgid "&Export as .gci..." msgstr "&Exporter comme .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fichier" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Police..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Avancement d'image" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "Réglages de la &Vue libre" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Générer les symboles depuis" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "Dépôt &GitHub" @@ -498,15 +500,15 @@ msgstr "Dépôt &GitHub" msgid "&Go to start of function" msgstr "&Aller au début de la fonction" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Paramètres &graphiques" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Aide" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Paramètres des &Raccouris clavier" @@ -526,7 +528,7 @@ msgstr "&Importer l'état..." msgid "&Import..." msgstr "&Importer..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "&Infinity Base" @@ -538,7 +540,7 @@ msgstr "&Insérer blr" msgid "&Interframe Blending" msgstr "Fusion &inter-images" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -546,11 +548,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Langue :" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Charger l'état" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Charger une Carte de Symboles" @@ -564,15 +566,15 @@ msgstr "&Charger le fichier à l'adresse actuelle" msgid "&Lock Watches" msgstr "&Verrouiller les observations" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "Verrouiller l'emplacement des &Widgets" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Mémoire" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "Fil&m" @@ -580,7 +582,7 @@ msgstr "Fil&m" msgid "&Mute" msgstr "&Couper le son" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Réseau" @@ -589,23 +591,23 @@ msgid "&No" msgstr "&Non" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Ouvrir..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Options" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Patcher les fonctions HLE" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pause" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Démarrer" @@ -613,7 +615,7 @@ msgstr "&Démarrer" msgid "&Properties" msgstr "&Propriétés" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "Mode &Lecture seule" @@ -621,7 +623,7 @@ msgstr "Mode &Lecture seule" msgid "&Refresh List" msgstr "&Actualiser la liste" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registres" @@ -639,15 +641,15 @@ msgid "&Rename symbol" msgstr "&Renommer symbole" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Reset" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "Gestionnaire de Packs de &Ressources" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Sauvegarder la carte des symboles" @@ -655,7 +657,7 @@ msgstr "&Sauvegarder la carte des symboles" msgid "&Scan e-Reader Card(s)..." msgstr "&Lire la ou les carte(s) e-Reader..." -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "&Portail Skylanders" @@ -663,7 +665,7 @@ msgstr "&Portail Skylanders" msgid "&Speed Limit:" msgstr "&Limite de vitesse :" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Stop" @@ -671,11 +673,11 @@ msgstr "&Stop" msgid "&Theme:" msgstr "&Thème :" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Threads" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Outils" @@ -689,17 +691,17 @@ msgstr "&Décharger la ROM" msgid "&Unlock Watches" msgstr "&Déverrouiller les observations" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Affichage" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Regarder" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "Site &web" @@ -711,11 +713,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Oui" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' introuvable, aucun nom de symbole généré" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' introuvable, recherche de fonctions communes à la place" @@ -1171,7 +1173,7 @@ msgid "Accuracy:" msgstr "Précision :" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "Succès" @@ -1363,7 +1365,7 @@ msgstr "Ajouter..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adresse" @@ -1619,15 +1621,15 @@ msgstr "Anti-Aliasing :" msgid "Any Region" msgstr "Toutes régions" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Ajouter la signature à" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Ajouter à un fichier de signature &existant..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "A&ppliquer un fichier de signature" @@ -1648,7 +1650,7 @@ msgstr "Date de l'Apploader :" msgid "Apply" msgstr "Appliquer" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Appliquer un fichier de signature" @@ -1761,7 +1763,7 @@ msgstr "Ajuster auto. la taille de la fenêtre" msgid "Auto-Hide" msgstr "Cacher automatiquement" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Détecter automatiquement les modules RSO ?" @@ -1870,7 +1872,7 @@ msgstr "Mauvaise valeur fournie." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Bannière" @@ -1944,7 +1946,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Taille des blocs" @@ -1982,7 +1984,7 @@ msgstr "" "Le mode pour passer outre le Bluetooth est activé, mais Dolphin a été " "compilé sans libusb. Ce mode ne peut donc pas être utilisé." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Démarrer sur Pause" @@ -2060,7 +2062,7 @@ msgstr "Erreur d'adaptateur réseau" msgid "Broadband Adapter MAC Address" msgstr "Adresse MAC de l'adaptateur réseau" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Parcourir les sessions &NetPlay..." @@ -2125,7 +2127,7 @@ msgstr "Par :" msgid "C Stick" msgstr "Stick C" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "&Créer un Fichier Signature..." @@ -2236,7 +2238,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2312,7 +2314,7 @@ msgstr "Centrer et étalonner" msgid "Change &Disc" msgstr "&Changer de disque" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "&Changer de disque..." @@ -2388,7 +2390,7 @@ msgstr "Rechercher un cheat" msgid "Cheats Manager" msgstr "Gestionnaire de Cheats" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Vérifier la NAND..." @@ -2428,11 +2430,11 @@ msgstr "Choisir un fichier à ouvrir" msgid "Choose a file to open or create" msgstr "Choisissez un fichier à ouvrir ou créer" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Choisir le fichier d'entrée prioritaire." -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Choisir le fichier d'entrée secondaire." @@ -2467,7 +2469,7 @@ msgstr "Manette classique" msgid "Clear" msgstr "Effacer" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Effacer le cache" @@ -2488,7 +2490,7 @@ msgstr "&Cloner et modifier le Code..." msgid "Close" msgstr "Fermer" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Co&nfiguration" @@ -2535,7 +2537,7 @@ msgstr "Correction de couleur :" msgid "Color Space" msgstr "Espace de couleur" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Combiner &deux fichiers de signature..." @@ -2578,7 +2580,7 @@ msgstr "Compilation des Shaders" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Compression" @@ -2764,7 +2766,7 @@ msgstr "Confirmez le changement de moteur" msgid "Confirm on Stop" msgstr "Confirmer l'arrêt de l'émulation" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2775,7 +2777,7 @@ msgstr "Confirmation" msgid "Connect" msgstr "Connecter" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Connecter la Balance Board" @@ -2783,7 +2785,7 @@ msgstr "Connecter la Balance Board" msgid "Connect USB Keyboard" msgstr "Connecter le clavier USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Connecter la Wiimote %1" @@ -2803,7 +2805,7 @@ msgstr "Connecter la Wiimote 3" msgid "Connect Wii Remote 4" msgstr "Connecter la Wiimote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Connecter les Wiimotes" @@ -2879,6 +2881,11 @@ msgid "" "display.

HDR output is required for this setting to take effect." "

If unsure, leave this at 200." msgstr "" +"Contrôle la luminance de base d'une feuille de papier blanc en nits. Utile " +"pour ajuster en fonction des différentes conditions de lumière lors de " +"l'utilisation d'un écran HDR.

Une sortie en HDR est requise pour que " +"ce réglage ait un effet.

Dans le doute, réglez la " +"valeur à 200." #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" @@ -2946,7 +2953,7 @@ msgstr "" msgid "Convergence" msgstr "Convergence" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Convergence :" @@ -3019,6 +3026,16 @@ msgid "" "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" +"Convertit les espaces de couleurs pour lesquelles les GC/Wii étaient conçues " +"vers du sRGB/Rec.709.

Il n'est pas possible de savoir l'espace de " +"couleur exact pour lequel les jeux ont été conçus, sachant qu'il y avait " +"plusieurs standards et que la plupart des jeux n'en tenaient pas compte, il " +"n'est donc pas correct d'en déduire un format en fonction de la région du " +"disque. Sélectionnez simplement celui qui vous semble le plus naturel, ou la " +"région dans laquelle ce jeu a été développé.

Une sortie HDR est " +"requise pour afficher toutes les couleurs de l'espace de couleurs PAL et " +"NTSC-J.

Dans le doute, décochez cette case." #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" @@ -3317,7 +3334,7 @@ msgstr "" "

Dans le doute, décochez cette case." -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Région actuelle" @@ -3347,7 +3364,7 @@ msgstr "Options pour l'horloge personnalisée" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 msgid "Custom:" -msgstr "" +msgstr "Personnalisé :" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" @@ -3520,7 +3537,7 @@ msgstr "Réduire Y" msgid "Default" msgstr "Par défaut" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Configuration par défaut (lecture seule)" @@ -3586,7 +3603,7 @@ msgstr "Supprimer le fichier '{0}' ?" msgid "Depth" msgstr "Profondeur" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Pourcentage de la profondeur :" @@ -3599,7 +3616,7 @@ msgstr "Profondeur :" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Description" @@ -3621,11 +3638,11 @@ msgstr "Détaché" msgid "Detect" msgstr "Détecter" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Détection des modules RSO" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Double cœur déterministe :" @@ -3700,7 +3717,7 @@ msgstr "Désactiver les copies EFB dans la VRAM" msgid "Disable Emulation Speed Limit" msgstr "Désactiver la limite de vitesse" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Désactiver Fastmem" @@ -3708,7 +3725,7 @@ msgstr "Désactiver Fastmem" msgid "Disable Fog" msgstr "Désactiver le brouillard" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Désactiver le cache JIT" @@ -3800,7 +3817,7 @@ msgstr "Autorisez-vous Dolphin à envoyer des informations à ses développeurs msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Voulez-vous ajouter \"%1\" à la liste des dossiers de jeux ?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Voulez-vous effacer la liste des noms de symboles ?" @@ -3831,17 +3848,17 @@ msgstr "Journal FIFO de Dolphin (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Préréglage de mod de jeu pour Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Fichier de carte pour Dolphin (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Fichier CSV de signature de Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Fichier de signature de Dolphin" @@ -4018,7 +4035,7 @@ msgstr "Dumper &FakeVMEM" msgid "Dump &MRAM" msgstr "Dumper la &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Enregistrer le son" @@ -4030,7 +4047,7 @@ msgstr "Copier les textures de base" msgid "Dump EFB Target" msgstr "Copier l'EFB cible" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Enregistrer les images" @@ -4117,7 +4134,7 @@ msgstr "Durée de relâchement du bouton Turbo (en images) :" msgid "Dutch" msgstr "Néerlandais" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Quitter" @@ -4173,7 +4190,7 @@ msgid "Edit..." msgstr "Modifier..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Éditeur" @@ -4242,7 +4259,7 @@ msgstr "" "Émule la vitesse de lecture du lecteur de disques de la console. Désactiver " "ceci peut provoquer des instabilités. Activé par défaut." -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "Appareils USB émulés" @@ -4300,7 +4317,7 @@ msgstr "Activer l'horloge personnalisée" #: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 msgid "Enable Debugging UI" -msgstr "" +msgstr "Activer l'interface de débogage" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" @@ -4405,7 +4422,7 @@ msgstr "" "qui est joué.

Cela n'a aucune incidence sur la rich presence de " "Discord." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4463,7 +4480,7 @@ msgstr "" "Active l'émulation du Dolby Pro Logic II en utilisant le surround 5.1. Pour " "certains moteurs uniquement." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4562,7 +4579,7 @@ msgstr "" "systèmes où le CPU n'est pas assez puissant.

Dans " "le doute, décochez cette case." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4664,7 +4681,7 @@ msgstr "Entrez le mot de passe" msgid "Enter the DNS server to use:" msgstr "Entrez le serveur DNS à utiliser :" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Entrer l'adresse du module RSO :" @@ -4711,18 +4728,18 @@ msgstr "Entrer l'adresse du module RSO :" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4871,7 +4888,7 @@ msgstr "" msgid "Euphoria" msgstr "Euphorie" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europe" @@ -4970,7 +4987,7 @@ msgstr "Nom de variable attendu." msgid "Experimental" msgstr "Expérimental" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exporter toutes les sauvegardes Wii" @@ -4985,7 +5002,7 @@ msgstr "L'exportation a échoué" msgid "Export Recording" msgstr "Exporter l'enregistrement..." -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exporter l'enregistrement..." @@ -5013,7 +5030,7 @@ msgstr "Exporter comme .&gcs..." msgid "Export as .&sav..." msgstr "Exporter comme .&sav..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -5041,7 +5058,7 @@ msgstr "Externe" msgid "External Frame Buffer (XFB)" msgstr "Buffer externe d'image (External Frame Buffer - XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Extraire les certificats de la NAND" @@ -5079,7 +5096,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Lecteur FIFO" @@ -5099,7 +5116,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Impossible d'ajouter cette session à l'index NetPlay : %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Impossible d'ajouter cela au fichier de signature '%1'" @@ -5200,7 +5217,7 @@ msgstr "Échec de l'exportation de %n sur %1 fichier(s) de sauvegarde." msgid "Failed to export the following save files:" msgstr "Échec de l'exportation des fichiers de sauvegarde suivants :" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Impossible d'extraire les certificats depuis la NAND" @@ -5230,14 +5247,14 @@ msgstr "Impossible de trouver un ou plusieurs symboles D3D" msgid "Failed to import \"%1\"." msgstr "Impossible d'importer \"%1\"." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Impossible d'importer le fichier de sauvegarde. Veuillez démarrer le jeu une " "fois, puis réessayez." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5245,7 +5262,7 @@ msgstr "" "Impossible d'importer le fichier de sauvegarde. Le fichier indiqué semble " "corrompu ou n'est pas une sauvegarde valide de Wii." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5279,7 +5296,7 @@ msgid "Failed to install pack: %1" msgstr "Impossible d'installer le pack %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Impossible d'installer ce titre dans la NAND." @@ -5291,8 +5308,8 @@ msgstr "" "Impossible d'écouter le port %1. Est-ce qu'une autre instance de serveur " "Netplay est en exécution ?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Impossible de charger le module RSO à %1" @@ -5304,7 +5321,7 @@ msgstr "Impossible de charger d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "Impossible de charger dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Impossible d'ouvrir le fichier de carte '%1'" @@ -5503,19 +5520,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Echec de l'enregistrement du journal FIFO." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Impossible de sauvegarder la carte du code vers le dossier '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Impossible de sauvegarder le fichier de signature '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Impossible de sauvegarder la carte des symboles vers le dossier '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Impossible de sauvegarder vers le fichier de signature '%1'" @@ -5565,7 +5582,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Échec" @@ -5613,7 +5630,7 @@ msgstr "Détails du fichier" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Format du fichier" @@ -5627,18 +5644,18 @@ msgstr "Infos du fichier" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Nom du fichier" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Chemin du fichier" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Taille du fichier" @@ -6187,7 +6204,7 @@ msgstr "Game Boy Advance sur le Port %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 msgid "Game Color Space:" -msgstr "" +msgstr "Espace de couleurs du jeu :" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 msgid "Game Config" @@ -6207,10 +6224,10 @@ msgstr "Gamma du jeu" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 msgid "Game Gamma:" -msgstr "" +msgstr "Gamma du jeu :" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID du jeu" @@ -6259,7 +6276,7 @@ msgstr "" msgid "Game region does not match" msgstr "La région du jeu ne concorde pas" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Paramètres spécifiques au jeu" @@ -6330,7 +6347,7 @@ msgid "Gecko Codes" msgstr "Codes Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6356,7 +6373,7 @@ msgstr "Générer une nouvelle identité pour les statistiques" msgid "Generated AR code." msgstr "Code AR généré." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Nom des symboles générés à partir de '%1'" @@ -6438,7 +6455,7 @@ msgstr "Vert Gauche" msgid "Green Right" msgstr "Vert Droite" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Grille" @@ -6465,7 +6482,7 @@ msgstr "HDR Paper White Nits" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 msgid "HDR Paper White Nits:" -msgstr "" +msgstr "Luminosité HDR Paper white :" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" @@ -6513,7 +6530,7 @@ msgstr "Hexadécimal" msgid "Hide" msgstr "Cacher" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Tout masquer" @@ -6860,7 +6877,7 @@ msgstr "" "abaissant légèrement les performances.

Dans le " "doute, décochez cette case." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Importer une sauvegarde BootMii de la NAND..." @@ -6875,7 +6892,7 @@ msgstr "L'importation a échoué" msgid "Import Save File(s)" msgstr "Importer le(s) fichier(s) de sauvegarde" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importer une sauvegarde Wii..." @@ -6991,8 +7008,8 @@ msgstr "Information" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Information" @@ -7001,10 +7018,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Désactiver l'écran de veille pendant l'émulation" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Entrée" @@ -7045,7 +7062,7 @@ msgstr "Partition d'installation (%1)" msgid "Install Update" msgstr "Installer la mise à jour" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Installer un WAD..." @@ -7065,7 +7082,7 @@ msgstr "Instruction" msgid "Instruction Breakpoint" msgstr "Point d'arrêt instruction" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instruction :" @@ -7134,7 +7151,7 @@ msgstr "Erreur interne lors de la génération du code AR." msgid "Interpreter (slowest)" msgstr "Interpréteur (TRÈS lent)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Interpreter Core" @@ -7159,7 +7176,7 @@ msgstr "Pack %1 non valide indiqué : %2" msgid "Invalid Player ID" msgstr "ID joueur non valide" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Adresse du module RSO non valide : %1" @@ -7236,11 +7253,11 @@ msgstr "Italien" msgid "Italy" msgstr "Italie" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT Block Linking Off" @@ -7248,47 +7265,47 @@ msgstr "JIT Block Linking Off" msgid "JIT Blocks" msgstr "Blocs JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT Branch Off" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FloatingPoint Off" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Integer Off" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LoadStore Floating Off" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LoadStore Off" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LoadStore Paired Off" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LoadStore lXz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT LoadStore lbzx Off" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LoadStore lwz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Off (JIT Core)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Paired Off" @@ -7300,11 +7317,11 @@ msgstr "Recompilateur JIT pour ARM64 (recommandé)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "Recompilateur JIT pour x86-64 (recommandé)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "Cache de registre JIT désactivé" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" @@ -7318,7 +7335,7 @@ msgstr "" "ne devrait jamais arriver. Veuillez transmettre cet incident au suivi de " "bugs. Dolphin va maintenant quitter." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japon" @@ -7377,7 +7394,7 @@ msgstr "Kio" msgid "Kick Player" msgstr "Sortir le joueur" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Corée" @@ -7528,11 +7545,11 @@ msgstr "Lumière" msgid "Limit Chunked Upload Speed:" msgstr "Limite de vitesse d'envoi de parcelles de données :" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Colonnes de la liste" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Liste" @@ -7548,11 +7565,11 @@ msgstr "Écoute" msgid "Load" msgstr "Charger" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Charger un fichier de carte de &défauts..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Charger un &Autre fichier de carte..." @@ -7564,7 +7581,7 @@ msgstr "Charger textures personnalisées" msgid "Load File" msgstr "Charger le fichier" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Charger le Menu Principal de la GameCube" @@ -7674,19 +7691,19 @@ msgstr "Charger l'état du Slot 8" msgid "Load State Slot 9" msgstr "Charger l'état du Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Charger un état depuis un fichier" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Charge l'état depuis l'emplacement sélectionné" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Charger un état depuis un slot" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Charger le Menu Système Wii %1" @@ -7698,16 +7715,16 @@ msgstr "Charger et enregistrer les données de sauvegarde chez l'hôte." msgid "Load from Selected Slot" msgstr "Charger depuis l'emplacement sélectionné" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Chargement depuis le Slot %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Charger un fichier de carte" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "Charger le menu %1 du système vWii" @@ -7715,7 +7732,7 @@ msgstr "Charger le menu %1 du système vWii" msgid "Load..." msgstr "Charger..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Symboles chargés à partir de '%1'" @@ -7761,7 +7778,7 @@ msgstr "Journal" msgid "Log Configuration" msgstr "Configuration de la journalisation" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Log JIT Instruction Coverage" @@ -7845,7 +7862,7 @@ msgstr "Stick principal" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Concepteur" @@ -7867,10 +7884,11 @@ msgstr "" "

\n" "Dans le doute, décochez cette case." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Gestion de NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "Échantillonnage manuel de la texture" @@ -7921,7 +7939,7 @@ msgstr "Point d'arrêt mémoire" msgid "Memory Card" msgstr "Carte mémoire" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Gestionnaire de cartes mémoires" @@ -8027,8 +8045,8 @@ msgstr "" "effet.

Dans le doute, décochez cette case." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Modules trouvés : %1" @@ -8036,7 +8054,7 @@ msgstr "Modules trouvés : %1" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Ombres monoscopiques" @@ -8104,9 +8122,10 @@ msgstr "Multiplicateur" msgid "N&o to All" msgstr "Non à &tout" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "Vérification de la NAND" @@ -8115,7 +8134,7 @@ msgstr "Vérification de la NAND" msgid "NKit Warning" msgstr "Avertissement pour NKit" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -8140,8 +8159,14 @@ msgid "" "match it here.

If unsure, leave this at 2.35." msgstr "" +"NTSC-M et NTSC-J ont un gamma d'environ 2.2. PAL a un gamma d'environ 2.8." +"
Aucun des deux n'était obligatoirement pris en compte par les jeux ou " +"les TV.
2.35 est une bonne valeur qui peut convenir à toutes les régions." +"

Si un jeu vous permet de choisir une valeur gamma, copiez-la ici." +"

Dans le doute, laissez la valeur à 2.35." -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8357,7 +8382,7 @@ msgstr "Aucun jeu en fonctionnement." msgid "No game running." msgstr "Aucun jeu en fonctionnement." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Aucun souci n'a été détecté" @@ -8422,7 +8447,7 @@ msgstr "Aucune" msgid "North America" msgstr "Amérique du Nord" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Non défini" @@ -8554,7 +8579,7 @@ msgstr "" "et les shaders vertex pour étendre des points et des lignes, utiliser le " "shader vertex. Peut affecter les performances.

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Documentation en ligne" @@ -8562,7 +8587,7 @@ msgstr "&Documentation en ligne" msgid "Only Show Collection" msgstr "Afficher uniquement la Collection" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8570,7 +8595,7 @@ msgstr "" "Uniquement ajouter les symboles avec le préfixe :\n" "(Vide pour tous les symboles) " -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8587,7 +8612,7 @@ msgstr "Ouvrir" msgid "Open &Containing Folder" msgstr "Ouvrir l'emplacement du fichier" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "Ouvrir le dossier &utilisateur" @@ -8693,11 +8718,11 @@ msgstr "Autres jeux..." msgid "Overwritten" msgstr "Écrasé" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Jouer l'enregistrement..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8799,7 +8824,7 @@ msgstr "Dossiers" msgid "Pause" msgstr "Pause" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pause à la fin du Film" @@ -8841,7 +8866,7 @@ msgstr "Vitesse maximale des mouvements de va-et-vient." msgid "Per-Pixel Lighting" msgstr "Eclairage par pixel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Effectuer une mise à jour en ligne" @@ -8875,7 +8900,7 @@ msgstr "Espace d'adresse physique" msgid "PiB" msgstr "Pio" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Choisissez une police pour le débogage" @@ -8892,7 +8917,7 @@ msgid "Pitch Up" msgstr "Monter" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Plateforme" @@ -9142,7 +9167,7 @@ msgstr "Progression" msgid "Public" msgstr "Publique" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Purger le cache de la liste de jeu" @@ -9200,11 +9225,11 @@ msgstr "R Analog." msgid "READY" msgstr "PRÊT" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "Modules RSO" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "Détection automatique du RSO" @@ -9367,7 +9392,7 @@ msgid "Refreshing..." msgstr "Actualisation..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Région" @@ -9470,7 +9495,7 @@ msgstr "Reset" msgid "Reset All" msgstr "Tout réinitialiser" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Réinitialiser Ignorer le gestionnaire de panique" @@ -9678,7 +9703,7 @@ msgstr "Dossier de synchronisation SD :" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 msgid "SDR Display Gamma Target" -msgstr "" +msgstr "Gamma cible d'un écran SDR" #: Source/Core/Core/HW/GBAPadEmu.h:43 #: Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp:42 @@ -9707,11 +9732,11 @@ msgstr "Contexte SSL" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Sau&vegarder le code" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Sau&vegarder l'état" @@ -9734,7 +9759,7 @@ msgstr "Tout enregistrer" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Exportation de la sauvegarde" @@ -9755,11 +9780,11 @@ msgstr "Sauvegarde du jeu" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "Fichiers de sauvegarde de jeu (*.sav);;Tous les fichiers (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Importation de la sauvegarde" @@ -9821,23 +9846,23 @@ msgstr "Sauvegarder l'état vers le Slot 8" msgid "Save State Slot 9" msgstr "Sauvegarder l'état vers le Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Sauvegarder l'état dans un fichier" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Sauvegarder l'état dans le slot le plus ancien" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Sauvegarder l'état dans l'emplacement sélectionné" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Sauvegarder l'état dans le slot" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Sauvegarder la carte des symboles &sous..." @@ -9857,11 +9882,11 @@ msgstr "Enregistrer sous le préréglage..." msgid "Save as..." msgstr "Enregistrer sous..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Sauvegarder le fichier de sortie combinée sous" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9875,11 +9900,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Placer la sauvegarde dans le même dossier que la ROM" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Sauvegarder le fichier de carte" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Sauvegarder le fichier de signature" @@ -9887,7 +9912,7 @@ msgstr "Sauvegarder le fichier de signature" msgid "Save to Selected Slot" msgstr "Sauvegarder vers l'emplacement sélectionné" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Sauvegarder dans le slot %1 - %2" @@ -9925,7 +9950,7 @@ msgstr "Capt écran" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Rechercher" @@ -9954,7 +9979,7 @@ msgstr "" "La recherche n'est pour l'instant pas possible dans l'espace d'adresse " "virtuelle. Exécutez le jeu pendant un moment et essayez à nouveau." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Rechercher une instruction" @@ -9962,7 +9987,7 @@ msgstr "Rechercher une instruction" msgid "Search games..." msgstr "Rechercher des jeux..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Rechercher une instruction" @@ -10000,7 +10025,7 @@ msgid "Select Dump Path" msgstr "Sélectionner le dossier pour le dump :" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Sélectionner le dossier d'exportation" @@ -10044,7 +10069,7 @@ msgstr "Sélectionner la collection Skylander" msgid "Select Skylander File" msgstr "Sélectionnez un fichier Skylander" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Sélectionner le slot %1 - %2" @@ -10052,7 +10077,7 @@ msgstr "Sélectionner le slot %1 - %2" msgid "Select State" msgstr "Sélectionner l'état" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Sélectionner l'emplacement de l'état" @@ -10138,7 +10163,7 @@ msgstr "Sélectionner un fichier" msgid "Select a game" msgstr "Sélectionner un jeu" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Sélectionner un titre à installer dans la NAND" @@ -10146,7 +10171,7 @@ msgstr "Sélectionner un titre à installer dans la NAND" msgid "Select e-Reader Cards" msgstr "Sélectionner les cartes e-Reader" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Sélectionner l'adresse du module RSO :" @@ -10163,7 +10188,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Sélectionner le fichier des clés (dump OTP/SEEPROM)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Sélectionner le fichier à enregistrer" @@ -10407,11 +10432,11 @@ msgstr "Manette Shinkansen" msgid "Show % Speed" msgstr "Afficher le % de vitesse" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Afficher le &journal" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Afficher la barre d'&outils" @@ -10419,11 +10444,11 @@ msgstr "Afficher la barre d'&outils" msgid "Show Active Title in Window Title" msgstr "Affiche le titre en cours dans le nom de la fenêtre" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Tout afficher" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Afficher Australie" @@ -10436,7 +10461,7 @@ msgstr "Afficher le jeu en cours sur Discord" msgid "Show Disabled Codes First" msgstr "Afficher d'abord les codes désactivés" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Afficher les ELF/DOL" @@ -10449,7 +10474,7 @@ msgstr "Afficher d'abord les codes activés" msgid "Show FPS" msgstr "Afficher le nombre de FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Afficher le compteur d'images" @@ -10457,15 +10482,15 @@ msgstr "Afficher le compteur d'images" msgid "Show Frame Times" msgstr "Afficher le temps de rendu par image" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Afficher France" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Afficher GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Afficher Allemagne" @@ -10477,23 +10502,23 @@ msgstr "Afficher le Mode golf en surimpression" msgid "Show Infinity Base" msgstr "Afficher la Base Infinity" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Afficher les entrées du contrôleur" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Afficher Italie" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "Afficher JPN" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Afficher Corée" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Afficher le compteur de lags" @@ -10501,7 +10526,7 @@ msgstr "Afficher le compteur de lags" msgid "Show Language:" msgstr "Afficher en :" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Afficher la config. de journalisation" @@ -10513,7 +10538,7 @@ msgstr "Afficher les messages NetPlay" msgid "Show NetPlay Ping" msgstr "Afficher le ping du NetPlay" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Afficher Pays-bas" @@ -10521,7 +10546,7 @@ msgstr "Afficher Pays-bas" msgid "Show On-Screen Display Messages" msgstr "Afficher les messages informatifs" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Afficher PAL" @@ -10534,19 +10559,19 @@ msgstr "Afficher PC" msgid "Show Performance Graphs" msgstr "Afficher les graphiques de performance" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Afficher les plateformes" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Afficher les régions" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Afficher le compteur de réenregistrements" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Afficher Russie" @@ -10554,7 +10579,7 @@ msgstr "Afficher Russie" msgid "Show Skylanders Portal" msgstr "Afficher le Portail Skylanders" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Afficher Espagne" @@ -10566,19 +10591,19 @@ msgstr "Afficher les couleurs selon la vitesse" msgid "Show Statistics" msgstr "Afficher les statistiques" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Afficher l'heure du système" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Afficher Taïwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Afficher USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Afficher les inconnus" @@ -10590,15 +10615,15 @@ msgstr "Afficher les durées de VBlank" msgid "Show VPS" msgstr "Afficher les VPS" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Afficher les WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Afficher Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Afficher Monde" @@ -10735,7 +10760,7 @@ msgstr "Utiliser à l'horizontale" msgid "Sideways Wii Remote" msgstr "Wiimote à l'horizontale" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Base de données de Signatures" @@ -11011,7 +11036,7 @@ msgstr "Contrôleur standard" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Démarrer &NetPlay..." @@ -11019,7 +11044,7 @@ msgstr "Démarrer &NetPlay..." msgid "Start New Cheat Search" msgstr "Démarrer une nouvelle recherche de cheat" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Démarrer l'enregistrement de l'entrée" @@ -11113,7 +11138,7 @@ msgstr "Mode de stéréoscopie 3D" msgid "Stereoscopic 3D Mode:" msgstr "Mode de stéréoscopie 3D :" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stéréoscopie" @@ -11135,7 +11160,7 @@ msgstr "Stick" msgid "Stop" msgstr "Arrêter" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Arrêter de jouer/enregistrer l'entrée" @@ -11216,8 +11241,8 @@ msgstr "Style" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Succès !" @@ -11244,7 +11269,7 @@ msgstr "Exportation avec succès de %n sur %1 fichier(s) de sauvegarde." msgid "Successfully exported save files" msgstr "Fichiers de sauvegarde exportés avec succès." -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Certificats extraits avec succès depuis la NAND" @@ -11256,12 +11281,12 @@ msgstr "Fichier extrait avec succès." msgid "Successfully extracted system data." msgstr "Extraction avec succès des données du système." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Fichier de sauvegarde importé avec succès." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Ce titre a été installé avec succès dans la NAND." @@ -11363,7 +11388,7 @@ msgstr "Nom du symbole :" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symboles" @@ -11383,7 +11408,7 @@ msgstr "Synchroniser les Wiimotes physiques et les jumeler" msgid "Synchronize GPU thread" msgstr "Synchroniser le thread du GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11416,7 +11441,7 @@ msgstr "Synchronisation des données de sauvegarde..." msgid "System Language:" msgstr "Langue du système :" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Entrée TAS" @@ -11429,7 +11454,7 @@ msgstr "Outils TAS" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Tags" @@ -11447,7 +11472,7 @@ msgstr "Tail" msgid "Taiwan" msgstr "Taïwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Capture d'écran" @@ -11514,6 +11539,13 @@ msgid "" "\n" "Do you really want to switch to Direct3D 11? If unsure, select 'No'." msgstr "" +"Le moteur de rendu Direct3D 11 requiert des fonctionnalités qui ne sont pas " +"prises en charge par la configuration de votre système. Vous pouvez toujours " +"utiliser ce moteur, mais vous rencontrerez des artéfacts graphiques dans " +"certains jeux.\n" +"\n" +"Souhaitez-vous vraiment utiliser Direct3D 11 ? Dans le doute, sélectionnez " +"'Non'." #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." @@ -11533,7 +11565,7 @@ msgstr "Le fichier IPL n'est pas connu comme un dump correct. (CRC32 : {0:x})" msgid "The Masterpiece partitions are missing." msgstr "La partition des Chefs-d'œuvre est manquante." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11541,7 +11573,7 @@ msgstr "" "Impossible de réparer la NAND. Il est recommandé de sauvegarder vos données " "actuelles et de recommencer avec une nouvelle NAND." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "La NAND a été réparée." @@ -11878,6 +11910,12 @@ msgstr "L'index de la clé commune spécifiée est {0} au lieu de {1}." msgid "The specified file \"{0}\" does not exist" msgstr "Le fichier spécifié \"{0}\" n'existe pas" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "La carte mémoire cible contient déjà un fichier nommé \"%1\"." @@ -11912,6 +11950,12 @@ msgstr "La partition des mises à jour est manquante." msgid "The update partition is not at its normal position." msgstr "La partition des mises à jour n'est pas à sa position normale." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "La partition n°{0} n'a pas de système de fichiers valide." @@ -11940,7 +11984,7 @@ msgstr "Il n'y a rien à annuler !" msgid "There was an issue adding a shortcut to the desktop" msgstr "Il y a eu un problème lors de l'ajout du raccourci sur le Bureau" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -12190,7 +12234,7 @@ msgstr "" "\n" "ucode inconnu (CRC = {0:08x}) - forçage de AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -12198,7 +12242,7 @@ msgstr "" "Cette valeur est ajoutée à la valeur de la convergence définie dans la " "configuration des graphiques." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -12262,7 +12306,7 @@ msgstr "Délai dépassé" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Titre" @@ -12276,7 +12320,7 @@ msgstr "À" msgid "To:" msgstr "jusqu'à :" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Activer le &plein écran" @@ -12540,7 +12584,7 @@ msgstr "" "impact minimal sur les performances, mais cela dépend du comportement du " "driver de la carte graphique." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Impossible de détecter automatiquement le module RSO" @@ -12607,11 +12651,11 @@ msgstr "Images GC/Wii non compressées (*.iso *.gcm)" msgid "Undead" msgstr "Mort-vivant" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "&Annuler le lancement d'état" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Annuler la sauvegarde de l'état" @@ -12631,7 +12675,7 @@ msgstr "" "Désinstaller le WAD va supprimer la version actuellement installée de ce " "titre dans la NAND sans supprimer ses données de sauvegarde. Continuer ?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "États-Unis" @@ -12738,19 +12782,19 @@ msgstr "Débloquer le curseur" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 msgid "Unlocked" -msgstr "" +msgstr "Débloqué" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 msgid "Unlocked %1 times this session" -msgstr "" +msgstr "Débloqué %1 fois pendant cette session" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 msgid "Unlocked (Casual)" -msgstr "" +msgstr "Débloqué (occasionnel)" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 msgid "Unlocked this session" -msgstr "" +msgstr "Débloqué pendant cette session" #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" @@ -12901,7 +12945,7 @@ msgstr "" "compatible avec l'Échantillonnage manuel de texture. Dans " "le doute, décochez cette case." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Utiliser un buffer de simple profondeur pour les deux yeux. Requis pour " @@ -12966,7 +13010,7 @@ msgstr "" "Vous pouvez continuer à utiliser 'Le code n'a pas été exécuté'/'Le code a " "été exécuté' pour affiner les résultats." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Configuration personnalisée" @@ -13176,7 +13220,7 @@ msgstr "Augmenter" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "Fichiers WAD (*.wad)" @@ -13315,7 +13359,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Avertissement" @@ -13543,11 +13587,11 @@ msgstr "Wii et Wiimote" msgid "Wii data is not public yet" msgstr "Données Wii pas encore publiques" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Fichiers de sauvegarde de Wii (*.bin);;Tous les fichiers (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "Fichier MEGA de signature de WiiTools" @@ -13814,6 +13858,12 @@ msgstr "" "Souhaitez-vous corriger maintenant le problème ?\n" "Si vous sélectionnez \"Non\", le son risque d'être détérioré." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13850,7 +13900,7 @@ msgstr "aligné" msgid "any value" msgstr "toute valeur" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "Auto" @@ -13883,7 +13933,7 @@ msgstr "Cartes e-Reader (*.raw);;Tous les fichiers (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "Faux achèvement" @@ -13929,7 +13979,7 @@ msgstr "" "Sauvegardes d'état mGBA (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *." "ss8 *.ss9);;Tous les fichiers (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "Aucun" @@ -13954,7 +14004,7 @@ msgstr "s" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 msgid "sRGB" -msgstr "" +msgstr "sRGB" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" diff --git a/Languages/po/hr.po b/Languages/po/hr.po index 71d62b5705..aa46eee0ae 100644 --- a/Languages/po/hr.po +++ b/Languages/po/hr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Alberto Poljak , 2013-2014\n" "Language-Team: Croatian (http://app.transifex.com/delroth/dolphin-emu/" @@ -308,7 +308,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -329,7 +329,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "" @@ -337,7 +337,7 @@ msgstr "" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -345,11 +345,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Pauze" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -357,15 +357,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -373,7 +373,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -381,7 +381,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "" @@ -420,11 +420,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulacija" @@ -444,27 +444,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Datoteka" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Upravljač sličica po sekundi" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -472,15 +472,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Postavke Grafike" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Pomoć" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Postavke prečica na tipkovnici" @@ -500,7 +500,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -512,7 +512,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -520,11 +520,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Učitaj stanje igre" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -538,15 +538,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memorija" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "" @@ -554,7 +554,7 @@ msgstr "" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -563,23 +563,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Otvori..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opcije" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pauza" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Pokreni igru" @@ -587,7 +587,7 @@ msgstr "&Pokreni igru" msgid "&Properties" msgstr "&Svojstva" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "" @@ -595,7 +595,7 @@ msgstr "" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registri" @@ -613,15 +613,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Resetiraj" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -629,7 +629,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -637,7 +637,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Zaustavi igru" @@ -645,11 +645,11 @@ msgstr "&Zaustavi igru" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Alati" @@ -663,17 +663,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Pogled" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "" @@ -685,11 +685,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1106,7 +1106,7 @@ msgid "Accuracy:" msgstr "Kvaliteta:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1280,7 +1280,7 @@ msgstr "Dodaj..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "" @@ -1509,15 +1509,15 @@ msgstr "Anti-Aliasing:" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1535,7 +1535,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1642,7 +1642,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1745,7 +1745,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Transparent" @@ -1817,7 +1817,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1853,7 +1853,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1930,7 +1930,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1992,7 +1992,7 @@ msgstr "" msgid "C Stick" msgstr "C Gljiva" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2088,7 +2088,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2159,7 +2159,7 @@ msgstr "" msgid "Change &Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Promjeni &Disk..." @@ -2221,7 +2221,7 @@ msgstr "Tražilica" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2259,11 +2259,11 @@ msgstr "Odaberite datoteku za otvaranje" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2298,7 +2298,7 @@ msgstr "" msgid "Clear" msgstr "Očisti" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2319,7 +2319,7 @@ msgstr "" msgid "Close" msgstr "Zatvori" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2366,7 +2366,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2403,7 +2403,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2539,7 +2539,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Potvrdite zaustavljanje igre" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2550,7 +2550,7 @@ msgstr "" msgid "Connect" msgstr "Spoji" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "" @@ -2558,7 +2558,7 @@ msgstr "" msgid "Connect USB Keyboard" msgstr "Priključite USB tipkovnicu" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2578,7 +2578,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2701,7 +2701,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3021,7 +3021,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3217,7 +3217,7 @@ msgstr "" msgid "Default" msgstr "Standardne vrijednosti" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3277,7 +3277,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3290,7 +3290,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Opis" @@ -3312,11 +3312,11 @@ msgstr "" msgid "Detect" msgstr "Otkrij" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3391,7 +3391,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3399,7 +3399,7 @@ msgstr "" msgid "Disable Fog" msgstr "Onemogući maglu" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3472,7 +3472,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3503,17 +3503,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3674,7 +3674,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Dumpiraj Zvuk" @@ -3686,7 +3686,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Dumpiraj odabranu EFB metu" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Dumpiraj Slike" @@ -3764,7 +3764,7 @@ msgstr "" msgid "Dutch" msgstr "Nizozemski" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "I&zlaz" @@ -3812,7 +3812,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3879,7 +3879,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4032,7 +4032,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4072,7 +4072,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4133,7 +4133,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4218,7 +4218,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4265,18 +4265,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4414,7 +4414,7 @@ msgstr "" msgid "Euphoria" msgstr "Euforija" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4495,7 +4495,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "" @@ -4510,7 +4510,7 @@ msgstr "" msgid "Export Recording" msgstr "Izvedi Snimku Videa" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Izvedi Snimku Videa..." @@ -4538,7 +4538,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4566,7 +4566,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4604,7 +4604,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO Pokretač Datoteka" @@ -4622,7 +4622,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4716,7 +4716,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4743,18 +4743,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4781,7 +4781,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4791,8 +4791,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4804,7 +4804,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4976,19 +4976,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5036,7 +5036,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5082,7 +5082,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5096,18 +5096,18 @@ msgstr "Informacije o Datoteci" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "" @@ -5620,7 +5620,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "" @@ -5664,7 +5664,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Specifične postavke za igru" @@ -5735,7 +5735,7 @@ msgid "Gecko Codes" msgstr "Gecko Kodovi" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5761,7 +5761,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5838,7 +5838,7 @@ msgstr "Zelena Lijevo" msgid "Green Right" msgstr "Zelena Desno" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5913,7 +5913,7 @@ msgstr "" msgid "Hide" msgstr "Sakrij" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6187,7 +6187,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6202,7 +6202,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6307,8 +6307,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informacije" @@ -6317,10 +6317,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Unos" @@ -6361,7 +6361,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6381,7 +6381,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6444,7 +6444,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6469,7 +6469,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6544,11 +6544,11 @@ msgstr "Talijanski" msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6556,47 +6556,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6608,11 +6608,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6623,7 +6623,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6682,7 +6682,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6827,11 +6827,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6847,11 +6847,11 @@ msgstr "" msgid "Load" msgstr "Učitaj" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6863,7 +6863,7 @@ msgstr "Učitaj Posebne Teksture" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6973,19 +6973,19 @@ msgstr "Učitaj Stanje Igre 8" msgid "Load State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6997,16 +6997,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7014,7 +7014,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7053,7 +7053,7 @@ msgstr "Zapis" msgid "Log Configuration" msgstr "Konfiguracija Zapisa" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7133,7 +7133,7 @@ msgstr "Glavna Gljiva" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7150,10 +7150,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7204,7 +7205,7 @@ msgstr "" msgid "Memory Card" msgstr "Memorijska Kartica" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7289,8 +7290,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7298,7 +7299,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7361,9 +7362,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7372,7 +7374,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7398,7 +7400,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7606,7 +7608,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7665,7 +7667,7 @@ msgstr "Ništa" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Nije Postavljeno" @@ -7787,7 +7789,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "" @@ -7795,13 +7797,13 @@ msgstr "" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7816,7 +7818,7 @@ msgstr "Otvori" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7922,11 +7924,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8028,7 +8030,7 @@ msgstr "Mape" msgid "Pause" msgstr "Pauza" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8066,7 +8068,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Osvjetljenje po pikselu" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8100,7 +8102,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8117,7 +8119,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8348,7 +8350,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8404,11 +8406,11 @@ msgstr "R-Analogan" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8562,7 +8564,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8660,7 +8662,7 @@ msgstr "Resetiraj" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8892,11 +8894,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Sn&imi stanje igre" @@ -8919,7 +8921,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8940,11 +8942,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9006,23 +9008,23 @@ msgstr "Snimi Stanje Igre 8" msgid "Save State Slot 9" msgstr "Mjesto za Stanje Snimanja 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9042,11 +9044,11 @@ msgstr "" msgid "Save as..." msgstr "Snimi kao..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9057,11 +9059,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9069,7 +9071,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9103,7 +9105,7 @@ msgstr "UslikajZaslon" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Traži" @@ -9130,7 +9132,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9138,7 +9140,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9175,7 +9177,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9219,7 +9221,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9227,7 +9229,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "" @@ -9313,7 +9315,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9321,7 +9323,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9338,7 +9340,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Odaberite snimak igre" @@ -9545,11 +9547,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Pokaži &Zapis" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Pokaži &Alatnu Traku" @@ -9557,11 +9559,11 @@ msgstr "Pokaži &Alatnu Traku" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9574,7 +9576,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9587,7 +9589,7 @@ msgstr "" msgid "Show FPS" msgstr "Pokaži FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9595,15 +9597,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Pokaži Francusku" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Pokaži GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9615,23 +9617,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Pokaži Unos Tipki" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Pokaži Italiju" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Pokaži Koreju" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9639,7 +9641,7 @@ msgstr "" msgid "Show Language:" msgstr "Pokaži Jezik:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Pokaži Konfiguraciju za &Zapis" @@ -9651,7 +9653,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9659,7 +9661,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Pokaži PAL" @@ -9672,19 +9674,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Pokaži Platforme" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Pokaži Regije" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9692,7 +9694,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9704,19 +9706,19 @@ msgstr "" msgid "Show Statistics" msgstr "Pokaži Statistike" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Pokaži Taivan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Pokaži SAD" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9728,15 +9730,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Pokaži Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9845,7 +9847,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10085,7 +10087,7 @@ msgstr "Standardni Kontroler" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10093,7 +10095,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10187,7 +10189,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10209,7 +10211,7 @@ msgstr "Gljiva" msgid "Stop" msgstr "Zaustavi" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10280,8 +10282,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10308,7 +10310,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10320,12 +10322,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10418,7 +10420,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10438,7 +10440,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "Sinkroniziraj GPU threadove" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10467,7 +10469,7 @@ msgstr "" msgid "System Language:" msgstr "Jezik Sustava:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS Unos" @@ -10480,7 +10482,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10498,7 +10500,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Uslikaj Ekran" @@ -10580,13 +10582,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10856,6 +10858,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10887,6 +10895,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10915,7 +10929,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11105,13 +11119,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11164,7 +11178,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Naslov" @@ -11178,7 +11192,7 @@ msgstr "Do" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11424,7 +11438,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11483,11 +11497,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Poništi Posljednje Učitavanje" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "" @@ -11505,7 +11519,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11756,7 +11770,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11794,7 +11808,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11988,7 +12002,7 @@ msgstr "" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12089,7 +12103,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Upozorenje" @@ -12272,11 +12286,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12493,6 +12507,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12529,7 +12549,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12562,7 +12582,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12606,7 +12626,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" diff --git a/Languages/po/hu.po b/Languages/po/hu.po index d620f85583..eb9d1b3429 100644 --- a/Languages/po/hu.po +++ b/Languages/po/hu.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Evin, 2016,2023\n" "Language-Team: Hungarian (http://app.transifex.com/delroth/dolphin-emu/" @@ -313,7 +313,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Névjegy" @@ -334,7 +334,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Audió beállítások" @@ -342,7 +342,7 @@ msgstr "&Audió beállítások" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -350,11 +350,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Töréspontok" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -362,15 +362,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -378,7 +378,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -386,7 +386,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Vezérlő beállítások" @@ -425,11 +425,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emuláció" @@ -449,27 +449,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fájl" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "Képkocka léptetése" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub tárház" @@ -477,15 +477,15 @@ msgstr "&GitHub tárház" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Grafikai beállítások" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Súgó" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Gyorsbillentyű beállítások" @@ -505,7 +505,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -517,7 +517,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -525,11 +525,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Állapot betöltése" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -543,15 +543,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memória" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Film" @@ -559,7 +559,7 @@ msgstr "&Film" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -568,23 +568,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Megnyitás..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Beállítások" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Szünet" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Indítás" @@ -592,7 +592,7 @@ msgstr "&Indítás" msgid "&Properties" msgstr "&Tulajdonságok" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Írásvédett mód" @@ -600,7 +600,7 @@ msgstr "&Írásvédett mód" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Regiszterek" @@ -618,15 +618,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Alapbeállítások" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -634,7 +634,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -642,7 +642,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Stop" @@ -650,11 +650,11 @@ msgstr "&Stop" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Eszközök" @@ -668,17 +668,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Nézet" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Figyelés" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Weboldal" @@ -690,11 +690,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1111,7 +1111,7 @@ msgid "Accuracy:" msgstr "Pontosság:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1285,7 +1285,7 @@ msgstr "Hozzáadás" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Cím" @@ -1514,15 +1514,15 @@ msgstr "Élsimítás:" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1540,7 +1540,7 @@ msgstr "Betöltőprogram dátuma:" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1647,7 +1647,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1750,7 +1750,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1822,7 +1822,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1858,7 +1858,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1935,7 +1935,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1997,7 +1997,7 @@ msgstr "" msgid "C Stick" msgstr "C kar" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2093,7 +2093,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2165,7 +2165,7 @@ msgstr "" msgid "Change &Disc" msgstr "Lemez&váltás" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Lemez&váltás..." @@ -2227,7 +2227,7 @@ msgstr "Csalás keresése" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2265,11 +2265,11 @@ msgstr "Válassz megnyitandó fájlt" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2304,7 +2304,7 @@ msgstr "" msgid "Clear" msgstr "Törlés" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2325,7 +2325,7 @@ msgstr "" msgid "Close" msgstr "Bezárás" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2372,7 +2372,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2409,7 +2409,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2545,7 +2545,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Megerősítés leállításkor" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2556,7 +2556,7 @@ msgstr "" msgid "Connect" msgstr "Csatlakozás" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Balance Board csatlakoztatása" @@ -2564,7 +2564,7 @@ msgstr "Balance Board csatlakoztatása" msgid "Connect USB Keyboard" msgstr "USB billentyűzet csatlakoztatása" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2584,7 +2584,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2707,7 +2707,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Konvergencia:" @@ -3027,7 +3027,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3223,7 +3223,7 @@ msgstr "" msgid "Default" msgstr "Alapértelmezett" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3283,7 +3283,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3296,7 +3296,7 @@ msgstr "Mélység:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Leírás" @@ -3318,11 +3318,11 @@ msgstr "" msgid "Detect" msgstr "Észlelés" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3397,7 +3397,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "Emulációs sebességkorlát kikapcsolása" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3405,7 +3405,7 @@ msgstr "" msgid "Disable Fog" msgstr "Köd kikapcsolása" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3478,7 +3478,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3509,17 +3509,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3680,7 +3680,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Hang kimentése" @@ -3692,7 +3692,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "EFB cél kimentése" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Képkockák kimentése" @@ -3770,7 +3770,7 @@ msgstr "" msgid "Dutch" msgstr "Holland" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "K&ilépés" @@ -3818,7 +3818,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3885,7 +3885,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4038,7 +4038,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4078,7 +4078,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4141,7 +4141,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4226,7 +4226,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4273,18 +4273,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4423,7 +4423,7 @@ msgstr "" msgid "Euphoria" msgstr "Eufória" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Európa" @@ -4504,7 +4504,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Minden Wii mentés exportálása" @@ -4519,7 +4519,7 @@ msgstr "" msgid "Export Recording" msgstr "Felvétel exportálása" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Felvétel exportálása..." @@ -4547,7 +4547,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4575,7 +4575,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "Küldő képkockapuffer (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4613,7 +4613,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO lejátszó" @@ -4631,7 +4631,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4725,7 +4725,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4752,18 +4752,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4790,7 +4790,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4800,8 +4800,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4813,7 +4813,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4985,19 +4985,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5045,7 +5045,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5091,7 +5091,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5105,18 +5105,18 @@ msgstr "Fájl információ" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Fájlnév" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Fájlméret" @@ -5629,7 +5629,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Játék azonosító" @@ -5673,7 +5673,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Játékfüggő beállítások" @@ -5744,7 +5744,7 @@ msgid "Gecko Codes" msgstr "Gecko kódok" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5770,7 +5770,7 @@ msgstr "Új statisztikai azonosító generálása" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5847,7 +5847,7 @@ msgstr "Zöld balra" msgid "Green Right" msgstr "Zöld jobbra" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5922,7 +5922,7 @@ msgstr "" msgid "Hide" msgstr "Elrejtés" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6196,7 +6196,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6211,7 +6211,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Wii mentés importálása..." @@ -6316,8 +6316,8 @@ msgstr "Infó" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Információk" @@ -6326,10 +6326,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Bemenet" @@ -6370,7 +6370,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "WAD telepítése..." @@ -6390,7 +6390,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6453,7 +6453,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Értelmező (leglassabb)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6478,7 +6478,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6554,11 +6554,11 @@ msgstr "Olasz" msgid "Italy" msgstr "Olaszország" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6566,47 +6566,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6618,11 +6618,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6633,7 +6633,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japán" @@ -6692,7 +6692,7 @@ msgstr "" msgid "Kick Player" msgstr "Játékos kirúgása" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -6837,11 +6837,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6857,11 +6857,11 @@ msgstr "" msgid "Load" msgstr "Betöltés" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6873,7 +6873,7 @@ msgstr "Egyedi textúrák betöltése" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6983,19 +6983,19 @@ msgstr "Állapot betöltése, foglalat 8" msgid "Load State Slot 9" msgstr "Állapot betöltése, foglalat 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Állapot betöltése a választott foglalatból" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -7007,16 +7007,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7024,7 +7024,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7063,7 +7063,7 @@ msgstr "Napló" msgid "Log Configuration" msgstr "Napló beállítások" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7143,7 +7143,7 @@ msgstr "Főkar" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Készítő" @@ -7160,10 +7160,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7214,7 +7215,7 @@ msgstr "" msgid "Memory Card" msgstr "Memóriakártya" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7299,8 +7300,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7308,7 +7309,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoszkóp árnyékok" @@ -7371,9 +7372,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7382,7 +7384,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7408,7 +7410,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7616,7 +7618,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7677,7 +7679,7 @@ msgstr "Nincs" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Nincs megadva" @@ -7799,7 +7801,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Online &dokumentáció" @@ -7807,13 +7809,13 @@ msgstr "Online &dokumentáció" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7828,7 +7830,7 @@ msgstr "Megnyitás" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7934,11 +7936,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Bemeneti fe&lvétel lejátszása..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8040,7 +8042,7 @@ msgstr "Elérési utak" msgid "Pause" msgstr "Szünet" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Szünet a videó végén" @@ -8078,7 +8080,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Képpont alapú megvilágítás" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8112,7 +8114,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8129,7 +8131,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Platform" @@ -8360,7 +8362,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8416,11 +8418,11 @@ msgstr "Jobb analóg" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8574,7 +8576,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Régió" @@ -8672,7 +8674,7 @@ msgstr "Alapbeállítások" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8904,11 +8906,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Á&llapot mentése" @@ -8931,7 +8933,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8952,11 +8954,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9018,23 +9020,23 @@ msgstr "Állapot mentése, foglalat 8" msgid "Save State Slot 9" msgstr "Állapot mentése, foglalat 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Állapot mentése a választott foglalatba" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9054,11 +9056,11 @@ msgstr "" msgid "Save as..." msgstr "Mentés másként..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9069,11 +9071,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9081,7 +9083,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9115,7 +9117,7 @@ msgstr "Pillanatkép" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Keresés" @@ -9142,7 +9144,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9150,7 +9152,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9187,7 +9189,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9231,7 +9233,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9239,7 +9241,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Állapot kiválasztása, foglalat" @@ -9325,7 +9327,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9333,7 +9335,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9350,7 +9352,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Válassz mentési fájlt" @@ -9560,11 +9562,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Nap&ló megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Eszközt&ár megjelenítése" @@ -9572,11 +9574,11 @@ msgstr "Eszközt&ár megjelenítése" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Ausztrália megjelenítése" @@ -9589,7 +9591,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL megjelenítése" @@ -9602,7 +9604,7 @@ msgstr "" msgid "Show FPS" msgstr "FPS megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Képkockaszámoló megjelenítése" @@ -9610,15 +9612,15 @@ msgstr "Képkockaszámoló megjelenítése" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Franciaország megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "GameCube megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Németország megjelenítése" @@ -9630,23 +9632,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Bemeneti kijelző megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Olaszország megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Korea megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Eltérési szám megjelenítése" @@ -9654,7 +9656,7 @@ msgstr "Eltérési szám megjelenítése" msgid "Show Language:" msgstr "Nyelv megjelenítése:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Naplózási &beállítások megjelenítése" @@ -9666,7 +9668,7 @@ msgstr "NetPlay üzenetek mgejelenítése" msgid "Show NetPlay Ping" msgstr "NetPlay ping mgejelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Hollandia megjelenítése" @@ -9674,7 +9676,7 @@ msgstr "Hollandia megjelenítése" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "PAL megjelenítése" @@ -9687,19 +9689,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Platformok megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Régiók megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Oroszország megjelenítése" @@ -9707,7 +9709,7 @@ msgstr "Oroszország megjelenítése" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Spanyolország megjelenítése" @@ -9719,19 +9721,19 @@ msgstr "" msgid "Show Statistics" msgstr "Statisztikák megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Rendszeróra megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Tajvan megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "USA megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Ismeretlen megjelenítése" @@ -9743,15 +9745,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii megjelenítése" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Világ megjelenítése" @@ -9860,7 +9862,7 @@ msgstr "Oldalra tartás kapcsoló" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10100,7 +10102,7 @@ msgstr "Szabványos vezérlő" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "&NetPlay indítása..." @@ -10108,7 +10110,7 @@ msgstr "&NetPlay indítása..." msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Bemenet rögzítésének indítása" @@ -10202,7 +10204,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Sztereoszkópikus 3D mód:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Sztereoszkóp" @@ -10224,7 +10226,7 @@ msgstr "Kar" msgid "Stop" msgstr "Stop" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10295,8 +10297,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10323,7 +10325,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10335,12 +10337,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10433,7 +10435,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10453,7 +10455,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "GPU szál szinkronizálása" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10482,7 +10484,7 @@ msgstr "" msgid "System Language:" msgstr "Rendszer nyelve:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS bemenet" @@ -10495,7 +10497,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10513,7 +10515,7 @@ msgstr "" msgid "Taiwan" msgstr "Tajvan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Pillanatkép készítése" @@ -10595,13 +10597,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10871,6 +10873,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10902,6 +10910,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10930,7 +10944,7 @@ msgstr "Nincs mit visszavonni!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11124,7 +11138,7 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -11132,7 +11146,7 @@ msgstr "" "Ez az érték hozzáadódik a grafikai beállításokban megadott konvergencia " "értékhez." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11187,7 +11201,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Cím" @@ -11201,7 +11215,7 @@ msgstr "Eddig:" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11447,7 +11461,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11506,11 +11520,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Állapot betöltésének visszavonása" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Állapot mentésének visszavonása" @@ -11528,7 +11542,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11779,7 +11793,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Egyetlen mélységpuffert használ mindkét szemhez. Néhány játékhoz szükséges." @@ -11818,7 +11832,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -12012,7 +12026,7 @@ msgstr "Hangerő fel" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12113,7 +12127,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Figyelem" @@ -12296,11 +12310,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12518,6 +12532,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12554,7 +12574,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "automatikus" @@ -12587,7 +12607,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "fake-completion" @@ -12631,7 +12651,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "nincs" diff --git a/Languages/po/it.po b/Languages/po/it.po index f9ec6c80d6..bc1d0d9189 100644 --- a/Languages/po/it.po +++ b/Languages/po/it.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Mewster , 2023\n" "Language-Team: Italian (http://app.transifex.com/delroth/dolphin-emu/" @@ -192,10 +192,12 @@ msgid "" "%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " "hardcore)" msgstr "" +"%1 ha sbloccato %2/%3 achievement (%4 hardcore) del valore di %5/%6 punti " +"(%7 hardcore)" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" -msgstr "" +msgstr "%1 ha sbloccato %2/%3 achievement del valore di %4/%5 punti" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" @@ -217,7 +219,7 @@ msgstr "%1 ms" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 msgid "%1 points" -msgstr "" +msgstr "%1 punti" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" @@ -327,7 +329,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&A proposito di..." @@ -348,7 +350,7 @@ msgstr "&Aggiungi Funzione" msgid "&Add..." msgstr "&Aggiungi..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Impostazioni &Audio" @@ -356,7 +358,7 @@ msgstr "Impostazioni &Audio" msgid "&Auto Update:" msgstr "&Aggiornamento Automatico:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Avvio Automatico" @@ -364,11 +366,11 @@ msgstr "&Avvio Automatico" msgid "&Borderless Window" msgstr "&Finestra Senza Bordi" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Punti di interruzione" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Bug Tracker" @@ -376,15 +378,15 @@ msgstr "&Bug Tracker" msgid "&Cancel" msgstr "&Annulla" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Gestore Trucchi" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Controlla la Presenza di Aggiornamenti..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "Pulis&ci Simboli" @@ -392,7 +394,7 @@ msgstr "Pulis&ci Simboli" msgid "&Clone..." msgstr "&Clona..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Codice" @@ -400,7 +402,7 @@ msgstr "&Codice" msgid "&Connected" msgstr "&Connesso" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "Impostazioni &Controller" @@ -439,11 +441,11 @@ msgstr "&Modifica Codice..." msgid "&Edit..." msgstr "&Modifica..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Espelli Disco" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulazione" @@ -463,27 +465,27 @@ msgstr "&Esporta Stato..." msgid "&Export as .gci..." msgstr "&Esporta come .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&File" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Font..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Fotogramma per Fotogramma" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "Impostazioni &Camera Libera" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Genera Simboli Da" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "Repository &GitHub" @@ -491,15 +493,15 @@ msgstr "Repository &GitHub" msgid "&Go to start of function" msgstr "&Vai all'inizio della funzione" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Impostazioni &Video" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Aiuto" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Impostazioni &Tasti di Scelta Rapida" @@ -519,7 +521,7 @@ msgstr "&Importa Stato..." msgid "&Import..." msgstr "&Importa..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "&Base Infinity" @@ -531,7 +533,7 @@ msgstr "&Inserisci blr" msgid "&Interframe Blending" msgstr "&Blending Interframe" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -539,11 +541,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Lingua:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Carica Stato di Gioco" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "Carica Mappa dei Simbo&li" @@ -557,15 +559,15 @@ msgstr "&Carica file all'indirizzo corrente" msgid "&Lock Watches" msgstr "&Blocca Espressioni di Controllo" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&Blocca Widget" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memoria" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Filmato" @@ -573,7 +575,7 @@ msgstr "&Filmato" msgid "&Mute" msgstr "&Muto" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Network" @@ -582,23 +584,23 @@ msgid "&No" msgstr "&No" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Apri..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opzioni" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Patch Funzioni HLE" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Gioca" @@ -606,7 +608,7 @@ msgstr "&Gioca" msgid "&Properties" msgstr "&Proprietà" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "Modalità &Sola-lettura" @@ -614,7 +616,7 @@ msgstr "Modalità &Sola-lettura" msgid "&Refresh List" msgstr "&Aggiorna Elenco" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registri" @@ -632,15 +634,15 @@ msgid "&Rename symbol" msgstr "&Rinomina simbolo" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Resetta" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Resource Pack Manager" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Salva Mappa dei Simboli" @@ -648,7 +650,7 @@ msgstr "&Salva Mappa dei Simboli" msgid "&Scan e-Reader Card(s)..." msgstr "&Scansiona Carte e-Reader" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "&Skylanders Portal" @@ -656,7 +658,7 @@ msgstr "&Skylanders Portal" msgid "&Speed Limit:" msgstr "&Limite Velocità" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Arresta" @@ -664,11 +666,11 @@ msgstr "&Arresta" msgid "&Theme:" msgstr "&Tema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Thread" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Strumenti" @@ -682,17 +684,17 @@ msgstr "&Rimuovi ROM" msgid "&Unlock Watches" msgstr "&Sblocca Espressioni di Controllo" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Visualizza" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "(&W) Espressione di controllo" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Website" @@ -704,11 +706,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Sì" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' non trovato, non sono stati generati nomi dei simboli" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' non trovato, ora cercherò nomi di funzioni comuni" @@ -1160,7 +1162,7 @@ msgid "Accuracy:" msgstr "Precisione:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "Achievement" @@ -1352,7 +1354,7 @@ msgstr "Aggiungi..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Indirizzo" @@ -1611,15 +1613,15 @@ msgstr "Anti-Aliasing:" msgid "Any Region" msgstr "Qualunque Regione" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Accoda signature a" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Accoda ad un Fil&e di Signature Preesistente..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "A&pplica File Signature..." @@ -1639,7 +1641,7 @@ msgstr "Data dell'Apploader" msgid "Apply" msgstr "Applica" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Applica file di signature" @@ -1751,7 +1753,7 @@ msgstr "Ridimensiona Automaticamente la Finestra" msgid "Auto-Hide" msgstr "Nascondi Automaticamente" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Individua automaticamente i moduli RSO?" @@ -1860,7 +1862,7 @@ msgstr "Valore non valido." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1935,7 +1937,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Dimensione Blocco" @@ -1973,7 +1975,7 @@ msgstr "" "La modalità ponte Bluetooth è abilitata, ma Dolphin è stato compilato senza " "libusb. La modalità ponte non può essere utilizzata." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Avvia in Pausa" @@ -2051,7 +2053,7 @@ msgstr "Errore Broadband Adapter" msgid "Broadband Adapter MAC Address" msgstr "Indirizzo MAC Adattatore Broadband" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Sfoglia Sessioni %NetPlay..." @@ -2116,7 +2118,7 @@ msgstr "Da:" msgid "C Stick" msgstr "C Stick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "C&rea File di Signature..." @@ -2224,7 +2226,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2297,7 +2299,7 @@ msgstr "Centra e Calibra" msgid "Change &Disc" msgstr "Cambia &Disco" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Cambia &Disco..." @@ -2370,7 +2372,7 @@ msgstr "Cerca Codice" msgid "Cheats Manager" msgstr "Gestione Codici" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Controlla NAND..." @@ -2410,11 +2412,11 @@ msgstr "Scegli un file da aprire" msgid "Choose a file to open or create" msgstr "Scegli un file da aprire o creare" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Scegli file di input prioritario" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Scegli file di input secondario" @@ -2449,7 +2451,7 @@ msgstr "Controller Classico" msgid "Clear" msgstr "Pulisci" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Pulisci Cache" @@ -2470,7 +2472,7 @@ msgstr "&Clona e Modifica Codice" msgid "Close" msgstr "Chiudi" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Co&nfigurazione" @@ -2517,7 +2519,7 @@ msgstr "Correzione Colore:" msgid "Color Space" msgstr "Spazio dei Colori" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Combina &Due File Signature..." @@ -2561,7 +2563,7 @@ msgstr "Compilazione degli Shader" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Compressione" @@ -2745,7 +2747,7 @@ msgstr "Conferma cambio backend" msgid "Confirm on Stop" msgstr "Arresto su Conferma" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2756,7 +2758,7 @@ msgstr "Conferma" msgid "Connect" msgstr "Collega" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Collega Balance Board" @@ -2764,7 +2766,7 @@ msgstr "Collega Balance Board" msgid "Connect USB Keyboard" msgstr "Collega Tastiera USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Collega Wii Remote %1" @@ -2784,7 +2786,7 @@ msgstr "Collega Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Collega Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Connetti Wii Remote" @@ -2860,6 +2862,10 @@ msgid "" "display.

HDR output is required for this setting to take effect." "

If unsure, leave this at 200." msgstr "" +"Controlla la luminosità base di una superficie bianca in nits. Serve per " +"adattarla a diverse condizioni di illuminazione ambientale con uno schermo " +"HDR.

L'output HDR è richiesto perché questa funzione abbia effetto." +"

Nel dubbio, lascia a 200." #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" @@ -2925,7 +2931,7 @@ msgstr "" msgid "Convergence" msgstr "Convergenza" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Convergenza:" @@ -2998,6 +3004,15 @@ msgid "" "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" +"Converte i colori dallo spazio colori per cui i giochi GC/Wii sono stati " +"pensati a sRGB/Rec.709.

Non c'è modo di sapere l'esatto spazio colori " +"concepito per un determinato gioco,
data la presenza di numerosi " +"standard, spesso ignorati,
per cui non è possibile determinare un formato " +"dalla sola regionalità di un gioco.
Scegli quello che ti sembra più " +"naturale, o che corrisponde alla regione in cui il gioco è stato sviluppato." +"

L'output HDR è necessario per mostrare tutti i colori dallo spazio " +"colori PAL e NTSC-J.

Nel dubbio, lascia " +"deselezionato." #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" @@ -3296,7 +3311,7 @@ msgstr "" "

Nel dubbio, lascia deselezionato." -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Regione Corrente" @@ -3326,7 +3341,7 @@ msgstr "Opzioni RTC Custom" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 msgid "Custom:" -msgstr "" +msgstr "Personalizzato:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" @@ -3499,7 +3514,7 @@ msgstr "Riduci Y" msgid "Default" msgstr "Default" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Configurazione di Default (Sola Lettura)" @@ -3565,7 +3580,7 @@ msgstr "Eliminare il file esistente '{0}'?" msgid "Depth" msgstr "Profondità" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Percentuale Profondità:" @@ -3578,7 +3593,7 @@ msgstr "Profondità:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Descrizione" @@ -3600,11 +3615,11 @@ msgstr "Scollegato" msgid "Detect" msgstr "Rileva" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Individuazione Moduli RSO" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Dual core deterministico:" @@ -3680,7 +3695,7 @@ msgstr "Disattiva Copie EFB VRAM" msgid "Disable Emulation Speed Limit" msgstr "Disabilita Limite Velocità di Emulazione" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Disabilita Fastmem" @@ -3688,7 +3703,7 @@ msgstr "Disabilita Fastmem" msgid "Disable Fog" msgstr "Disabilita Nebbia" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Disabilita Cache JIT" @@ -3778,7 +3793,7 @@ msgstr "Autorizzi Dolphin a inviare informazioni agli sviluppatori di Dolphin?" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Vuoi aggiungere \"%1\" alla lista dei Percorsi di Gioco?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Vuoi cancellare la lista dei nomi dei simboli?" @@ -3809,17 +3824,17 @@ msgstr "Log FIFO Dolphin (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Preset Dolphin Game Mod" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "File Mappa Dolphin (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "File Signature CSV Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "File Signature Dolphin" @@ -3994,7 +4009,7 @@ msgstr "Dump &FakeVMEM" msgid "Dump &MRAM" msgstr "Dump &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Dump Audio" @@ -4006,7 +4021,7 @@ msgstr "Dump Texture Base" msgid "Dump EFB Target" msgstr "Dump del Target EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Dump dei Frame" @@ -4093,7 +4108,7 @@ msgstr "Durata Rilascio Pulsante Turbo (in frame):" msgid "Dutch" msgstr "Olandese" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Esci" @@ -4149,7 +4164,7 @@ msgid "Edit..." msgstr "Modifica..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Editor" @@ -4218,7 +4233,7 @@ msgstr "" "Emula la velocità disco dell'hardware reale. Disabilitarlo potrebbe causare " "instabilità. L'impostazione predefinita è Abilitato" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "Dispositivi USB Emulati" @@ -4276,7 +4291,7 @@ msgstr "Abilita RTC Custom" #: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 msgid "Enable Debugging UI" -msgstr "" +msgstr "Abilita UI Debugging" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" @@ -4380,7 +4395,7 @@ msgstr "" "facendo il giocatore nel gioco. Se è disabilitata, il sito mostrerà soltanto " "il nome del gioco in uso.

Non influenza la rich presence di Discord." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4437,7 +4452,7 @@ msgstr "" "Abilita l'emulazione Dolby Pro Logic II utilizzando il surround 5.1. Solo " "con determinati backend." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4531,7 +4546,7 @@ msgstr "" "CPU fa da collo di bottiglia.

Nel dubbio, lascia " "deselezionato." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4633,7 +4648,7 @@ msgstr "Inserisci la password" msgid "Enter the DNS server to use:" msgstr "Inserisci il server DNS da utilizzare:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Inserisci l'indirizzo del modulo RSO:" @@ -4680,18 +4695,18 @@ msgstr "Inserisci l'indirizzo del modulo RSO:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4838,7 +4853,7 @@ msgstr "" msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4935,7 +4950,7 @@ msgstr "Prevista nome variabile." msgid "Experimental" msgstr "Sperimentale" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Esporta tutti i Salvataggi Wii" @@ -4950,7 +4965,7 @@ msgstr "Esportazione non Riuscita" msgid "Export Recording" msgstr "Esporta Registrazione" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Esporta Registrazione..." @@ -4978,7 +4993,7 @@ msgstr "Esporta come .&gcs..." msgid "Export as .&sav..." msgstr "Esporta come .&sav..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -5006,7 +5021,7 @@ msgstr "Esterno" msgid "External Frame Buffer (XFB)" msgstr "External Frame Buffer (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Estrai Certificati da NAND" @@ -5044,7 +5059,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Lettore FIFO" @@ -5064,7 +5079,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Fallito l'inserimento di questa sessione all'indice NetPlay: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Impossibile aggiungere il file di signature '%1'" @@ -5165,7 +5180,7 @@ msgstr "Fallita l'esportazione di %n su %1 file di salvataggio." msgid "Failed to export the following save files:" msgstr "Fallita l'esportazione dei seguenti file di salvataggio:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Fallita estrazione dei certificati dalla NAND" @@ -5195,14 +5210,14 @@ msgstr "Impossibile trovare uno o più simboli D3D" msgid "Failed to import \"%1\"." msgstr "Importazione di \"%1\" non riuscita." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Fallita l'importazione del salvataggio. Avvia il gioco una volta, poi " "riprova." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5210,7 +5225,7 @@ msgstr "" "Fallita l'importazione del salvataggio. Il file sembra corrotto o non è un " "file di salvataggio Wii valido." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5244,7 +5259,7 @@ msgid "Failed to install pack: %1" msgstr "Fallita installazione del pack: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Fallita installazione del titolo nella NAND." @@ -5256,8 +5271,8 @@ msgstr "" "Fallito l'ascolto sulla porta %1. C'è già un'altra istanza di un server " "NetPlay in esecuzione?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Fallito caricamento del modulo RSO a %1" @@ -5269,7 +5284,7 @@ msgstr "Caricamento d3d11.dll non riuscito" msgid "Failed to load dxgi.dll" msgstr "Caricamento dxgi.dll non riuscito" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Fallita l'apertura del file mappa '%1'" @@ -5468,19 +5483,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Fallito il salvataggio del log FIFO." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Impossibile salvare la mappa del codice nel percorso '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Impossibile salvare il file di signature '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Impossibile salvare la mappa dei simboli nel percorso '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Impossibile salvare nel file di signature '%1'" @@ -5530,7 +5545,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Errore" @@ -5578,7 +5593,7 @@ msgstr "Dettagli del File" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Formato del File" @@ -5592,18 +5607,18 @@ msgstr "Info File" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Nome File" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Percorso:" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Dimensioni del File" @@ -6146,7 +6161,7 @@ msgstr "Game Boy Advance sulla Porta %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 msgid "Game Color Space:" -msgstr "" +msgstr "Spazio Colore di Gioco:" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 msgid "Game Config" @@ -6166,10 +6181,10 @@ msgstr "Gamma di Gioco" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 msgid "Game Gamma:" -msgstr "" +msgstr "Gamma di Gioco:" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID Gioco" @@ -6218,7 +6233,7 @@ msgstr "" msgid "Game region does not match" msgstr "La regione del gioco non coincide" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Impostazioni Specifiche del Gioco" @@ -6289,7 +6304,7 @@ msgid "Gecko Codes" msgstr "Codici Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6315,7 +6330,7 @@ msgstr "Genera una nuova Identità Statistiche" msgid "Generated AR code." msgstr "Codice AR generato." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Generati nomi dei simboli da '%1'" @@ -6397,7 +6412,7 @@ msgstr "Verde Sinistro" msgid "Green Right" msgstr "Verde Destro" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Vista a Griglia" @@ -6424,7 +6439,7 @@ msgstr "HDR Paper White Nits" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 msgid "HDR Paper White Nits:" -msgstr "" +msgstr "HDR Paper White Nits:" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" @@ -6472,7 +6487,7 @@ msgstr "Esadecimale" msgid "Hide" msgstr "Nascondi" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Nascondi Tutto" @@ -6814,7 +6829,7 @@ msgstr "" "

Nel dubbio, lascia deselezionato." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Importa Backup NAND BootMII..." @@ -6829,7 +6844,7 @@ msgstr "Importazione non Riuscita" msgid "Import Save File(s)" msgstr "Importa File di Salvataggio" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importa Salvataggio Wii..." @@ -6944,8 +6959,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informazioni" @@ -6954,10 +6969,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Disabilita lo Screensaver durante l'Emulazione" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Input" @@ -6998,7 +7013,7 @@ msgstr "Partizione di Installazione (%1)" msgid "Install Update" msgstr "Installa Aggiornamento" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Installa WAD..." @@ -7018,7 +7033,7 @@ msgstr "Istruzione" msgid "Instruction Breakpoint" msgstr "Punto di Interruzione" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Istruzione:" @@ -7087,7 +7102,7 @@ msgstr "Errore interno durante la generazione del codice AR." msgid "Interpreter (slowest)" msgstr "Interpreter (il più lento)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Interpreter Core" @@ -7112,7 +7127,7 @@ msgstr "Pack non valido %1 fornito: %2" msgid "Invalid Player ID" msgstr "ID Giocatore non valido" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Indirizzo del modulo RSO non valido: %1" @@ -7189,11 +7204,11 @@ msgstr "Italiano" msgid "Italy" msgstr "Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "Disattiva Linking dei Blocchi JIT" @@ -7201,47 +7216,47 @@ msgstr "Disattiva Linking dei Blocchi JIT" msgid "JIT Blocks" msgstr "Blocchi JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT Branch Off" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FloatingPoint Off" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Integer Off" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LoadStore Floating Off" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LoadStore Off" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LoadStore Paired Off" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LoadStore lXz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT LoadStore lbzx Off" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LoadStore lwz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Off (JIT Core)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Paired Off" @@ -7253,11 +7268,11 @@ msgstr "Ricompilatore JIT per ARM64 (consigliato)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "Ricompilatore JIT per x86-64 (consigliato)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "Registro Cache JIT Off" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" @@ -7271,7 +7286,7 @@ msgstr "" "cache. Questo non dovrebbe mai accadere. Per cortesia segnala questo " "problema nel bug tracker. Dolphin ora terminerà." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Giappone" @@ -7330,7 +7345,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Kicka Giocatore" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Corea" @@ -7481,11 +7496,11 @@ msgstr "Luce" msgid "Limit Chunked Upload Speed:" msgstr "Limite Velocità di Chunked Upload:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Lista Colonne" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Vista a Lista" @@ -7501,11 +7516,11 @@ msgstr "Ascolto" msgid "Load" msgstr "Carica" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "(&B) Carica Mappa Invalida..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "(&O) Carica Altra Mappa..." @@ -7517,7 +7532,7 @@ msgstr "Carica Texture Personalizzate" msgid "Load File" msgstr "Carica File" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Carica Main Menu GameCube" @@ -7627,19 +7642,19 @@ msgstr "Carica Stato di Gioco da Slot 8" msgid "Load State Slot 9" msgstr "Carica Stato di Gioco da Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Carica Stato da File" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Carica Stato dallo Slot Selezionato" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Carica Stato da Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Carica Menu di Sistema Wii %1" @@ -7651,16 +7666,16 @@ msgstr "Carica e Scrivi Salvataggio dell'Host" msgid "Load from Selected Slot" msgstr "Carica dallo Slot Selezionato" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Carica da Slot %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Carica mappa" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "Carica Menu di Sistema vWii %1" @@ -7668,7 +7683,7 @@ msgstr "Carica Menu di Sistema vWii %1" msgid "Load..." msgstr "Carica..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Caricati simboli da '%1'" @@ -7712,7 +7727,7 @@ msgstr "Log" msgid "Log Configuration" msgstr "Configurazione Log" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Log della Copertura delle Istruzioni JIT" @@ -7796,7 +7811,7 @@ msgstr "Levetta Principale" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Produttore" @@ -7818,10 +7833,11 @@ msgstr "" "

Nel dubbio, lascia deselezionato." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Gestisci NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "Texture Sampling Manuale" @@ -7873,7 +7889,7 @@ msgstr "Punto di Interruzione dei Dati" msgid "Memory Card" msgstr "Memory Card" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Memory Card Manager" @@ -7976,8 +7992,8 @@ msgstr "" "

Nel dubbio, lascia deselezionato." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Moduli trovati: %1" @@ -7985,7 +8001,7 @@ msgstr "Moduli trovati: %1" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Ombre Monoscopiche" @@ -8054,9 +8070,10 @@ msgstr "Moltiplicatore" msgid "N&o to All" msgstr "N&o a Tutto" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "Controllo NAND" @@ -8065,7 +8082,7 @@ msgstr "Controllo NAND" msgid "NKit Warning" msgstr "Attenzione NKit" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -8090,8 +8107,13 @@ msgid "" "match it here.

If unsure, leave this at 2.35." msgstr "" +"NTSC-M e NTSC-J hanno come gamma obiettivo ~2.2. PAL ha come gamma obiettivo " +"~2.8.
Nessuno dei due è stato necessariamente imposto dai giochi o dalle " +"TV.
2.35 è un buon valore generico per tutte le regioni.

Se un " +"gioco permette di scegliere un valore gamma, impostalo qui." +"

Nel dubbio, lascia a 2.35." -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8307,7 +8329,7 @@ msgstr "Nessun gioco è in esecuzione." msgid "No game running." msgstr "Nessun gioco in esecuzione." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Non sono stati rilevati problemi." @@ -8373,7 +8395,7 @@ msgstr "Nessuno" msgid "North America" msgstr "Nord America" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Non Impostato" @@ -8504,7 +8526,7 @@ msgstr "" "espandere vertici e linee, utilizza sempre il vertex shader. Potrebbe " "influire sulle performance.

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Documentazione Online" @@ -8512,7 +8534,7 @@ msgstr "&Documentazione Online" msgid "Only Show Collection" msgstr "Mostra Solo Collezione" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8520,7 +8542,7 @@ msgstr "" "Inserisci solo simboli con prefisso:\n" "(Vuoto per tutti i simboli)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8537,7 +8559,7 @@ msgstr "Apri" msgid "Open &Containing Folder" msgstr "Apri &Percorso File" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "Apri Cartella &Utente" @@ -8643,11 +8665,11 @@ msgstr "Altro gioco..." msgid "Overwritten" msgstr "Sovrascritto" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Riproduci Registrazione Input..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8749,7 +8771,7 @@ msgstr "Percorsi" msgid "Pause" msgstr "Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pausa al Termine del Filmato" @@ -8790,7 +8812,7 @@ msgstr "Velocità massima per oscillare verso l'esterno" msgid "Per-Pixel Lighting" msgstr "Illuminazione Per-Pixel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Avviare Aggiornamento di Sistema Online" @@ -8824,7 +8846,7 @@ msgstr "Spazio dell'indirizzo fisico" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Scegli un font di debug" @@ -8841,7 +8863,7 @@ msgid "Pitch Up" msgstr "Inclinazione in Alto" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Piattaforma" @@ -9089,7 +9111,7 @@ msgstr "Avanzamento" msgid "Public" msgstr "Pubblica" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Pulisci Cache Lista Giochi" @@ -9145,11 +9167,11 @@ msgstr "R-Analogico" msgid "READY" msgstr "PRONTO" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "Moduli RSO" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "Auto-rilevamento RSO" @@ -9309,7 +9331,7 @@ msgid "Refreshing..." msgstr "Aggiornamento..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Regione" @@ -9412,7 +9434,7 @@ msgstr "Resetta" msgid "Reset All" msgstr "Resetta Tutto" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Resetta Ignora Avvisi di Errore" @@ -9620,7 +9642,7 @@ msgstr "Cartella Sync SD:" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 msgid "SDR Display Gamma Target" -msgstr "" +msgstr "SDR Display Gamma Target" #: Source/Core/Core/HW/GBAPadEmu.h:43 #: Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp:42 @@ -9649,11 +9671,11 @@ msgstr "Contesto SSL" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Sal&va Codice" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Sal&va Stato di Gioco" @@ -9676,7 +9698,7 @@ msgstr "Salva Tutto" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Esporta Salvataggio" @@ -9697,11 +9719,11 @@ msgstr "Salvataggio di Gioco" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "File di Salvataggio di Gioco (*.sav);;Tutti i File (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Importa Salvataggio" @@ -9763,23 +9785,23 @@ msgstr "Salva Stato di Gioco nello Slot 8" msgid "Save State Slot 9" msgstr "Salva Stato di Gioco nello Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Salva Stato su File" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Salva Stato su Slot più Vecchio" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Salva Stato nello Slot Selezionato" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Salva Stato su Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Salva Mappa dei Simboli &Come..." @@ -9799,11 +9821,11 @@ msgstr "Salva come Preset..." msgid "Save as..." msgstr "Salva come..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Salva file combinato in output come" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9817,11 +9839,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Salva nella Stessa Directory della ROM" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Salva file mappa" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Salva file di signature" @@ -9829,7 +9851,7 @@ msgstr "Salva file di signature" msgid "Save to Selected Slot" msgstr "Salva nello Slot Selezionato" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Salva su Slot %1 - %2" @@ -9865,7 +9887,7 @@ msgstr "Screenshot" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Cerca" @@ -9894,7 +9916,7 @@ msgstr "" "La ricerca non è attualmente possibile nello spazio di indirizzo virtuale. " "Esegui il gioco per un po', quindi riprova." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Cerca un'Istruzione" @@ -9902,7 +9924,7 @@ msgstr "Cerca un'Istruzione" msgid "Search games..." msgstr "Cerca giochi..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Ricerca istruzione" @@ -9940,7 +9962,7 @@ msgid "Select Dump Path" msgstr "Seleziona Percorso Dump" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Seleziona Directory di Estrazione" @@ -9984,7 +10006,7 @@ msgstr "Seleziona Collezione Skylander" msgid "Select Skylander File" msgstr "Seleziona File Skylander" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Seleziona Slot %1 - %2" @@ -9992,7 +10014,7 @@ msgstr "Seleziona Slot %1 - %2" msgid "Select State" msgstr "Seleziona Stato di Gioco" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Seleziona Slot di Stato" @@ -10078,7 +10100,7 @@ msgstr "Seleziona un file" msgid "Select a game" msgstr "Seleziona un gioco" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Seleziona un titolo da installare su NAND" @@ -10086,7 +10108,7 @@ msgstr "Seleziona un titolo da installare su NAND" msgid "Select e-Reader Cards" msgstr "Seleziona Carte e-Reader" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Scegli l'indirizzo del modulo RSO:" @@ -10103,7 +10125,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Seleziona il file contenente le chiavi (dump OTP/SEEPROM)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Seleziona il file di salvataggio" @@ -10347,11 +10369,11 @@ msgstr "Controller Shinkansen" msgid "Show % Speed" msgstr "Mostra Velocità %" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Mostra Finestra di &Log" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Mostra Barra degli St&rumenti" @@ -10359,11 +10381,11 @@ msgstr "Mostra Barra degli St&rumenti" msgid "Show Active Title in Window Title" msgstr "Mostra Gioco Corrente nella Barra del Titolo" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Mostra Tutto" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Mostra Australia" @@ -10376,7 +10398,7 @@ msgstr "Mostra Gioco Corrente su Discord" msgid "Show Disabled Codes First" msgstr "Mostra Prima Codici Inattivi" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Mostra ELF/DOL" @@ -10389,7 +10411,7 @@ msgstr "Mostra Prima Codici Attivi" msgid "Show FPS" msgstr "Mostra FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Mostra Contatore Frame" @@ -10397,15 +10419,15 @@ msgstr "Mostra Contatore Frame" msgid "Show Frame Times" msgstr "Mostra Tempi Frame" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Mostra Francia" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Mostra GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Mostra Germania" @@ -10417,23 +10439,23 @@ msgstr "Mostra Overlay Modalità Golf" msgid "Show Infinity Base" msgstr "Mostra Base Infinity" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Mostra Tasti di Input" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Mostra Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "Mostra JPN" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Mostra Corea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Mostra Contatore Lag" @@ -10441,7 +10463,7 @@ msgstr "Mostra Contatore Lag" msgid "Show Language:" msgstr "Mostra Lingua:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Mostra &Configurazione Log" @@ -10453,7 +10475,7 @@ msgstr "Mostra Messaggi NetPlay" msgid "Show NetPlay Ping" msgstr "Mostra Ping NetPlay" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Mostra Olanda" @@ -10461,7 +10483,7 @@ msgstr "Mostra Olanda" msgid "Show On-Screen Display Messages" msgstr "Mostra Messaggi su Schermo" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Mostra PAL" @@ -10474,19 +10496,19 @@ msgstr "Mostra PC" msgid "Show Performance Graphs" msgstr "Mostra Grafico di Performance" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Mostra Piattaforme" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Mostra Regioni" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Mostra Contatore Re-registrazioni" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Mostra Russia" @@ -10494,7 +10516,7 @@ msgstr "Mostra Russia" msgid "Show Skylanders Portal" msgstr "Mostra Portale Skylanders" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Mostra Spagna" @@ -10506,19 +10528,19 @@ msgstr "Mostra Colori Velocità" msgid "Show Statistics" msgstr "Mostra Informazioni" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Mostra Orologio di Sistema" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Mostra Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Mostra USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Mostra Sconosciuto" @@ -10530,15 +10552,15 @@ msgstr "Mostra Tempi VBlank" msgid "Show VPS" msgstr "Mostra VPS" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Mostra WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Mostra Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Mostra Mondo" @@ -10673,7 +10695,7 @@ msgstr "Attiva/Disattiva posizione di traverso" msgid "Sideways Wii Remote" msgstr "Wii Remote in posizione di traverso" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Database Firme" @@ -10942,7 +10964,7 @@ msgstr "Controller Standard" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Avvia &NetPlay" @@ -10950,7 +10972,7 @@ msgstr "Avvia &NetPlay" msgid "Start New Cheat Search" msgstr "Inizia Nuova Ricerca Cheat" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Avvia Re&gistrazione Input" @@ -11044,7 +11066,7 @@ msgstr "Modalità Stereoscopia 3D" msgid "Stereoscopic 3D Mode:" msgstr "Modalità Stereoscopia 3D" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoscopia" @@ -11066,7 +11088,7 @@ msgstr "Levetta" msgid "Stop" msgstr "Arresta" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Interrompi Riproduzione/Registrazione Input" @@ -11147,8 +11169,8 @@ msgstr "Stilo" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Completato" @@ -11175,7 +11197,7 @@ msgstr "Esportati con successo %n file di salvataggio su %1." msgid "Successfully exported save files" msgstr "File di salvataggio esportati con successo" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "I certificati sono stati estratti con successo dalla NAND" @@ -11187,12 +11209,12 @@ msgstr "File estratto con successo." msgid "Successfully extracted system data." msgstr "Dati di sistema estratti con successo." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Salvataggio importato con successo." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Il titolo è stato installato con successo su NAND." @@ -11293,7 +11315,7 @@ msgstr "Nome del simbolo:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Simboli" @@ -11313,7 +11335,7 @@ msgstr "Sincronizza e abbina Wii Remote reali" msgid "Synchronize GPU thread" msgstr "Sincronizza thread GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11346,7 +11368,7 @@ msgstr "Sincronizzazione dei dati di salvataggio in corso..." msgid "System Language:" msgstr "Lingua di Sistema:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS Input" @@ -11359,7 +11381,7 @@ msgstr "Strumenti TAS" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Tag" @@ -11377,7 +11399,7 @@ msgstr "Coda" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Cattura uno Screenshot" @@ -11444,6 +11466,11 @@ msgid "" "\n" "Do you really want to switch to Direct3D 11? If unsure, select 'No'." msgstr "" +"Il renderer Direct3D 11 richiede il supporto a funzionalità non disponibili " +"sulla tua configurazione di sistema. Potrai comunque usare questo backend, " +"ma riscontrerai artefatti grafici su alcuni giochi.\n" +"\n" +"Vuoi davvero passare a Direct3D 11? Nel dubbio, seleziona 'No'." #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." @@ -11463,7 +11490,7 @@ msgstr "Il file IPL non è un dump conosciuto ben formato. (CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "Le partizioni Capolavori sono assenti." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11471,7 +11498,7 @@ msgstr "" "Non è stato possibile riparare la NAND. Si consiglia di fare un backup dei " "dati attualmente presenti e ricominciare con una NAND pulita." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "La NAND è stata riparata." @@ -11803,6 +11830,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "il file specificato \"{0}\" non esiste" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "La memory card di destinazione contiene già un file \"%1\"." @@ -11838,6 +11871,12 @@ msgid "The update partition is not at its normal position." msgstr "" "La partizione di aggiornamento non si trova nella posizione predefinita." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "La partizione {0} non contiene un file system valido." @@ -11866,7 +11905,7 @@ msgstr "Non c'è nulla da annullare!" msgid "There was an issue adding a shortcut to the desktop" msgstr "Non è stato possibile creare un collegamento sul desktop." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -12113,7 +12152,7 @@ msgstr "" "\n" "Ucode sconosciuto (CRC = {0:08x}) - AXWii forzato" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -12121,7 +12160,7 @@ msgstr "" "Questo valore viene sommato alla convergenza impostata nelle configurazioni " "grafiche." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -12184,7 +12223,7 @@ msgstr "Tempo Scaduto" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Titolo" @@ -12198,7 +12237,7 @@ msgstr "a" msgid "To:" msgstr "Da:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Attiva/Disattiva &Schermo intero" @@ -12461,7 +12500,7 @@ msgstr "" "durante la compilazione degli shader con un minore impatto sulle " "performance, ma il risultato dipende dai driver della scheda grafica." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Impossibile individuare automaticamente il modulo RSO" @@ -12528,11 +12567,11 @@ msgstr "Immagini GC/Wii non compresse (*.iso *.gcm)" msgid "Undead" msgstr "Non-morti" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Annulla Caricamento Stato di Gioco" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Annulla Salvataggio dello Stato di Gioco" @@ -12553,7 +12592,7 @@ msgstr "" "attualmente installata su NAND senza cancellarne i file di salvataggio. " "Continuare?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Stati Uniti" @@ -12661,19 +12700,19 @@ msgstr "Sblocca il Cursore" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 msgid "Unlocked" -msgstr "" +msgstr "Sbloccato" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 msgid "Unlocked %1 times this session" -msgstr "" +msgstr "Sbloccato %1 volte questa sessione" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 msgid "Unlocked (Casual)" -msgstr "" +msgstr "Sbloccato (Casual)" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 msgid "Unlocked this session" -msgstr "" +msgstr "Sbloccato questa sessione" #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" @@ -12824,7 +12863,7 @@ msgstr "" "compatibile con Texture Sampling Manuale.

Nel " "dubbio, lascia deselezionato." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Utilizza un singolo buffer di profondità per entrambi gli occhi. Necessario " @@ -12886,7 +12925,7 @@ msgstr "" "Puoi continuare ad usare 'Il codice è stato eseguito'/'Il codice non è stato " "eseguito' per filtrare ulteriormente i risultati." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Configurazione Utente" @@ -13094,7 +13133,7 @@ msgstr "Alza il Volume" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "File WAD (*.wad)" @@ -13229,7 +13268,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Attenzione" @@ -13454,11 +13493,11 @@ msgstr "Wii e Wii Remote" msgid "Wii data is not public yet" msgstr "Dati Wii non ancora pubblici" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "File di salvataggio Wii (*.bin);;Tutti i File (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "File WIITools Signature MEGA" @@ -13723,6 +13762,12 @@ msgstr "" "Vuoi terminare l'emulazione per correggere il problema?\n" "Se selezioni \"No\", l'audio potrebbe risultare ingarbugliato." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13759,7 +13804,7 @@ msgstr "allineato" msgid "any value" msgstr "qualunque valore" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "auto" @@ -13792,7 +13837,7 @@ msgstr "Carte e-Reader (*.raw);;Tutti i File (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "esecuzione finta" @@ -13838,7 +13883,7 @@ msgstr "" "Salvataggi Stato mGBA (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *.ss8 " "*.ss9);;Tutti i File (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "inattivo" @@ -13863,7 +13908,7 @@ msgstr "s" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 msgid "sRGB" -msgstr "" +msgstr "sRGB" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" diff --git a/Languages/po/ja.po b/Languages/po/ja.po index 542c58d113..1ffe6922c0 100644 --- a/Languages/po/ja.po +++ b/Languages/po/ja.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: DanbSky , 2015-2022\n" "Language-Team: Japanese (http://app.transifex.com/delroth/dolphin-emu/" @@ -334,7 +334,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "Dolphinについて(&A)" @@ -355,7 +355,7 @@ msgstr "&Add function" msgid "&Add..." msgstr "追加...(&A)" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "サウンド設定(&A)" @@ -363,7 +363,7 @@ msgstr "サウンド設定(&A)" msgid "&Auto Update:" msgstr "自動更新(&A)" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automatic Start" @@ -371,11 +371,11 @@ msgstr "&Automatic Start" msgid "&Borderless Window" msgstr "ボーダレス ウィンドウ(&B)" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Breakpoints" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "バグトラッカー(&B)" @@ -383,15 +383,15 @@ msgstr "バグトラッカー(&B)" msgid "&Cancel" msgstr "キャンセル(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "チートマネージャ(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "Dolphinのアップデート(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Clear Symbols" @@ -399,7 +399,7 @@ msgstr "&Clear Symbols" msgid "&Clone..." msgstr "クローン(&C)..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Code" @@ -407,7 +407,7 @@ msgstr "&Code" msgid "&Connected" msgstr "接続(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "コントローラ設定(&C)" @@ -446,11 +446,11 @@ msgstr "コードを編集...(&E)" msgid "&Edit..." msgstr "編集...(&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "ディスクの取り出し(&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "エミュレーション(&E)" @@ -470,27 +470,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "GCI形式でエクスポート..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "ファイル(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Font..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "Frame Advance(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "フリールックの設定(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Generate Symbols From" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "GitHub リポジトリ(&G)" @@ -498,15 +498,15 @@ msgstr "GitHub リポジトリ(&G)" msgid "&Go to start of function" msgstr "&Go to start of function" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "グラフィック設定(&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "ヘルプ(&H)" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "ホットキーのカスタマイズ(&H)" @@ -526,7 +526,7 @@ msgstr "" msgid "&Import..." msgstr "インポート...(&I)" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -538,7 +538,7 @@ msgstr "&Insert blr" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -546,11 +546,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "UIの言語(&L):" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "ステートロード(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Load Symbol Map" @@ -564,15 +564,15 @@ msgstr "&Load file to current address" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "ツールバーの位置を固定(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memory" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "記録(&M)" @@ -580,7 +580,7 @@ msgstr "記録(&M)" msgid "&Mute" msgstr "ミュート(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Network" @@ -589,23 +589,23 @@ msgid "&No" msgstr "いいえ(&N)" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "開く(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "設定(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Patch HLE Functions" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "一時停止(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "開始(&P)" @@ -613,7 +613,7 @@ msgstr "開始(&P)" msgid "&Properties" msgstr "プロパティ(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "読み込み専用(&R)" @@ -621,7 +621,7 @@ msgstr "読み込み専用(&R)" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registers" @@ -639,15 +639,15 @@ msgid "&Rename symbol" msgstr "&Rename symbol" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "リセット(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "リソースパックマネージャー(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Save Symbol Map" @@ -655,7 +655,7 @@ msgstr "&Save Symbol Map" msgid "&Scan e-Reader Card(s)..." msgstr "カードeのスキャン...(&S)" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -663,7 +663,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "速度制限(&S):" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "停止(&S)" @@ -671,11 +671,11 @@ msgstr "停止(&S)" msgid "&Theme:" msgstr "テーマ(&T):" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Threads" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "ツール(&T)" @@ -689,17 +689,17 @@ msgstr "ROMを取り外してリセット(&U)" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "表示(&V)" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Watch" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "公式Webサイト(&W)" @@ -711,11 +711,11 @@ msgstr "公式Wiki(英語)で動作状況を確認(&W)" msgid "&Yes" msgstr "はい(&Y)" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' not found, no symbol names generated" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' not found, scanning for common functions instead" @@ -1156,7 +1156,7 @@ msgid "Accuracy:" msgstr "精度:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1346,7 +1346,7 @@ msgstr "追加" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Address" @@ -1604,15 +1604,15 @@ msgstr "アンチエイリアス:" msgid "Any Region" msgstr "すべて" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Append signature to" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Append to &Existing Signature File..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Appl&y Signature File..." @@ -1633,7 +1633,7 @@ msgstr "Apploaderの日付" msgid "Apply" msgstr "適用" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Apply signature file" @@ -1746,7 +1746,7 @@ msgstr "ウィンドウサイズを自動調整" msgid "Auto-Hide" msgstr "未操作時に隠す" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Auto-detect RSO modules?" @@ -1852,7 +1852,7 @@ msgstr "Bad value provided." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "バナー" @@ -1924,7 +1924,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "ブロックサイズ" @@ -1963,7 +1963,7 @@ msgstr "" "ドされました。\n" "パススルーの機能は使えません。" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Boot to Pause" @@ -2040,7 +2040,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "ブロードバンドアダプタ MACアドレス設定" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "ネットプレイセッションブラウザ(&N)" @@ -2105,7 +2105,7 @@ msgstr "" msgid "C Stick" msgstr "Cスティック" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "C&reate Signature File..." @@ -2209,7 +2209,7 @@ msgstr "ゲーム実行中はネットプレイセッションを開始できま #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2281,7 +2281,7 @@ msgstr "センタリングとキャリブレーション" msgid "Change &Disc" msgstr "ディスクの入れ替え(&D)" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "ディスクの入れ替え(&D)" @@ -2348,7 +2348,7 @@ msgstr "コードサーチ" msgid "Cheats Manager" msgstr "チートマネージャ" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "NANDの整合性チェックを実行" @@ -2387,11 +2387,11 @@ msgstr "メモリーカードを選択" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Choose priority input file" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Choose secondary input file" @@ -2426,7 +2426,7 @@ msgstr "クラシックコントローラ" msgid "Clear" msgstr "全消去" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Clear Cache" @@ -2447,7 +2447,7 @@ msgstr "コピーして編集...(&E)" msgid "Close" msgstr "閉じる" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Dolphinの設定(&N)" @@ -2494,7 +2494,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Combine &Two Signature Files..." @@ -2531,7 +2531,7 @@ msgstr "シェーダをコンパイル中..." #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "圧縮形式" @@ -2667,7 +2667,7 @@ msgstr "ビデオAPI変更の確認" msgid "Confirm on Stop" msgstr "動作停止時に確認" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2678,7 +2678,7 @@ msgstr "確認" msgid "Connect" msgstr "ホストに接続" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "バランスWii ボードを接続" @@ -2686,7 +2686,7 @@ msgstr "バランスWii ボードを接続" msgid "Connect USB Keyboard" msgstr "USBキーボードの接続をエミュレート" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "%1 のWiiリモコンを接続" @@ -2706,7 +2706,7 @@ msgstr "3PのWiiリモコンを接続" msgid "Connect Wii Remote 4" msgstr "4PのWiiリモコンを接続" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Wiiリモコンの接続" @@ -2841,7 +2841,7 @@ msgstr "" msgid "Convergence" msgstr "収束点" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "収束点 (Convergence):" @@ -3176,7 +3176,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "現在の地域" @@ -3376,7 +3376,7 @@ msgstr "Y方向 減少" msgid "Default" msgstr "既定" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "デフォルト設定(読み取り専用)" @@ -3436,7 +3436,7 @@ msgstr "既存のファイル '{0}' を削除しますか?" msgid "Depth" msgstr "深度" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "深度 比率変更:" @@ -3449,7 +3449,7 @@ msgstr "深度 (Depth):" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "説明" @@ -3471,11 +3471,11 @@ msgstr "Detached" msgid "Detect" msgstr "検出" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Detecting RSO Modules" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Deterministic dual core: " @@ -3550,7 +3550,7 @@ msgstr "Disable EFB VRAM Copies" msgid "Disable Emulation Speed Limit" msgstr "エミュレーション速度 無効化" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Disable Fastmem" @@ -3558,7 +3558,7 @@ msgstr "Disable Fastmem" msgid "Disable Fog" msgstr "Disable Fog" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Disable JIT Cache" @@ -3645,7 +3645,7 @@ msgstr "Dolphinの開発者への情報提供にご協力いただけますか msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "\"%1\" をゲームパスリストに追加しますか?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Do you want to clear the list of symbol names?" @@ -3676,17 +3676,17 @@ msgstr "Dolphin FIFO ログファイル (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin Map File (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Dolphin Signature CSV File" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Dolphin Signature File" @@ -3853,7 +3853,7 @@ msgstr "Dump &FakeVMEM" msgid "Dump &MRAM" msgstr "Dump &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "サウンドのダンプを行う(WAV形式)" @@ -3865,7 +3865,7 @@ msgstr "Dump Base Textures" msgid "Dump EFB Target" msgstr "EFBターゲットをダンプ" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "フレームのダンプを行う(AVI形式)" @@ -3946,7 +3946,7 @@ msgstr "" msgid "Dutch" msgstr "オランダ語" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "終了" @@ -3999,7 +3999,7 @@ msgid "Edit..." msgstr "Edit..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "エディタ" @@ -4066,7 +4066,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4222,7 +4222,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4264,7 +4264,7 @@ msgstr "" "Dolby Pro Logic II を使用した5.1サラウンドのエミュレーションを行います。特定" "のAPIでのみ有効" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4341,7 +4341,7 @@ msgstr "" "す。

よく分からなければ、チェックを入れないでくださ" "い。" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4432,7 +4432,7 @@ msgstr "ここにパスワードを入力" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Enter the RSO module address:" @@ -4479,18 +4479,18 @@ msgstr "Enter the RSO module address:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4632,7 +4632,7 @@ msgstr "Errors were found in {0} unused blocks in the {1} partition." msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "ヨーロッパ" @@ -4728,7 +4728,7 @@ msgstr "" msgid "Experimental" msgstr "実験的" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "全てのWiiセーブデータをエクスポート" @@ -4743,7 +4743,7 @@ msgstr "エクスポート失敗" msgid "Export Recording" msgstr "録画ファイルのエクスポート" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "録画ファイルのエクスポート" @@ -4771,7 +4771,7 @@ msgstr "GCS形式でエクスポート..." msgid "Export as .&sav..." msgstr "SAV形式でエクスポート..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4799,7 +4799,7 @@ msgstr "External" msgid "External Frame Buffer (XFB)" msgstr "External Frame Buffer (外部フレームバッファ)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "証明書ファイルをNANDから取り出す" @@ -4837,7 +4837,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO プレーヤー" @@ -4857,7 +4857,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Failed to append to signature file '%1'" @@ -4952,7 +4952,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "次のセーブファイルをエクスポートできませんでした:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "証明書ファイルの取り出しに失敗" @@ -4979,18 +4979,18 @@ msgstr "Failed to find one or more D3D symbols" msgid "Failed to import \"%1\"." msgstr "\"%1\" をインポートできませんでした" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5017,7 +5017,7 @@ msgid "Failed to install pack: %1" msgstr "リソースパック %1 をインストールできませんでした" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "タイトルのインストールに失敗" @@ -5029,8 +5029,8 @@ msgstr "" "ポート番号 %1 で待ち受けできませんでした。別のネットプレイサーバーが実行中に" "なっていませんか?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Failed to load RSO module at %1" @@ -5042,7 +5042,7 @@ msgstr "Failed to load d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "Failed to load dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Failed to load map file '%1'" @@ -5220,19 +5220,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "FIFOログの保存に失敗しました" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Failed to save code map to path '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Failed to save signature file '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Failed to save symbol map to path '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Failed to save to signature file '%1'" @@ -5280,7 +5280,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "失敗" @@ -5326,7 +5326,7 @@ msgstr "ファイル情報" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "ファイル形式" @@ -5340,18 +5340,18 @@ msgstr "ファイル情報" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "ファイル名" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "ファイルサイズ" @@ -5900,7 +5900,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ゲームID" @@ -5944,7 +5944,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "固有設定" @@ -6015,7 +6015,7 @@ msgid "Gecko Codes" msgstr "Geckoコード" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6041,7 +6041,7 @@ msgstr "新しい統計IDを作成する" msgid "Generated AR code." msgstr "Generated AR code." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Generated symbol names from '%1'" @@ -6122,7 +6122,7 @@ msgstr "緑 - 左" msgid "Green Right" msgstr "緑 - 右" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "グリッド表示" @@ -6197,7 +6197,7 @@ msgstr "Hexadecimal" msgid "Hide" msgstr "隠す" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "すべて非表示" @@ -6517,7 +6517,7 @@ msgstr "" "

よく分からなければ、チェックを入れないでください。" "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "BootMii NAND バックアップをインポート" @@ -6532,7 +6532,7 @@ msgstr "インポートに失敗" msgid "Import Save File(s)" msgstr "セーブファイルのインポート" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Wii セーブデータのインポート" @@ -6643,8 +6643,8 @@ msgstr "情報" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "情報" @@ -6653,10 +6653,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "エミュレーション中はスクリーンセーバーを起動させない" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "入力" @@ -6697,7 +6697,7 @@ msgstr "" msgid "Install Update" msgstr "自動更新" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "WiiメニューにWADファイルを追加" @@ -6717,7 +6717,7 @@ msgstr "Instruction" msgid "Instruction Breakpoint" msgstr "Instruction Breakpoint" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instruction:" @@ -6786,7 +6786,7 @@ msgstr "Internal error while generating AR code." msgid "Interpreter (slowest)" msgstr "Interpreter (非常に低速)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Interpreter Core" @@ -6811,7 +6811,7 @@ msgstr "無効なリソースパック %1 が与えられました:%2" msgid "Invalid Player ID" msgstr "無効なプレイヤーID" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Invalid RSO module address: %1" @@ -6886,11 +6886,11 @@ msgstr "イタリア語" msgid "Italy" msgstr "イタリア" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT Block Linking Off" @@ -6898,47 +6898,47 @@ msgstr "JIT Block Linking Off" msgid "JIT Blocks" msgstr "JIT Blocks" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT Branch Off" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FloatingPoint Off" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Integer Off" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LoadStore Floating Off" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LoadStore Off" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LoadStore Paired Off" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LoadStore lXz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT LoadStore lbzx Off" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LoadStore lwz Off" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Off (JIT Core)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Paired Off" @@ -6950,11 +6950,11 @@ msgstr "JIT Recompiler for ARM64 (推奨)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "JIT Recompiler for x86-64 (推奨)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "JIT Register Cache Off" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters Off" @@ -6968,7 +6968,7 @@ msgstr "" "このエラーは起こらないはずです。この状況をバグトラッカーへ報告してください。" "Dolphinを終了します。" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "日本" @@ -7027,7 +7027,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "選択したプレイヤーをキック" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "韓国" @@ -7178,11 +7178,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "Limit Chunked Upload Speed:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "ゲームリストカラムの表示" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "リスト表示" @@ -7198,11 +7198,11 @@ msgstr "Listening" msgid "Load" msgstr "読込" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Load &Bad Map File..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Load &Other Map File..." @@ -7214,7 +7214,7 @@ msgstr "カスタムテクスチャを読み込む" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "ゲームキューブ メインメニューを起動" @@ -7324,19 +7324,19 @@ msgstr "ステートロード - スロット 8" msgid "Load State Slot 9" msgstr "ステートロード - スロット 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "ファイルからロード" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "選択したスロットから読込" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "次のスロットからロード" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Wiiメニューを起動 %1" @@ -7348,16 +7348,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "選択したスロットから読込" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "スロット %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Load map file" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7365,7 +7365,7 @@ msgstr "" msgid "Load..." msgstr "読込" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Loaded symbols from '%1'" @@ -7408,7 +7408,7 @@ msgstr "ログ" msgid "Log Configuration" msgstr "ログの設定" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Log JIT Instruction Coverage" @@ -7492,7 +7492,7 @@ msgstr "コントロールスティック" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "メーカー" @@ -7513,10 +7513,11 @@ msgstr "" "ません。

よく分からなければ、チェックを入れないでく" "ださい。" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Wii NANDの管理" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7569,7 +7570,7 @@ msgstr "Memory Breakpoint" msgid "Memory Card" msgstr "メモリーカード" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "GCメモリーカードマネージャ" @@ -7664,8 +7665,8 @@ msgstr "" "機能を使用するにはゲームの再起動が必要です。

よく分" "からなければ、チェックを入れないでください。" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Modules found: %1" @@ -7673,7 +7674,7 @@ msgstr "Modules found: %1" msgid "Mono" msgstr "モノラル" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoscopic Shadows" @@ -7736,9 +7737,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND 整合性チェック" @@ -7747,7 +7749,7 @@ msgstr "NAND 整合性チェック" msgid "NKit Warning" msgstr "NKit Warning" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7773,7 +7775,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7981,7 +7983,7 @@ msgstr "No game is running." msgid "No game running." msgstr "No game running." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "問題は見つかりませんでした" @@ -8045,7 +8047,7 @@ msgstr "なし" msgid "North America" msgstr "北アメリカ" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "未定義" @@ -8171,7 +8173,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "オンラインガイドを表示(&D)" @@ -8179,7 +8181,7 @@ msgstr "オンラインガイドを表示(&D)" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8187,7 +8189,7 @@ msgstr "" "Only append symbols with prefix:\n" "(Blank for all symbols)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8204,7 +8206,7 @@ msgstr "開く" msgid "Open &Containing Folder" msgstr "実体ファイルのあるフォルダを開く(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -8310,11 +8312,11 @@ msgstr "他のタイトル" msgid "Overwritten" msgstr "Overwritten" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "録画ファイルを再生(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8416,7 +8418,7 @@ msgstr "フォルダ" msgid "Pause" msgstr "一時停止" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "再生終了時に一時停止" @@ -8457,7 +8459,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Per-Pixel Lighting" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Wii システムアップデート" @@ -8491,7 +8493,7 @@ msgstr "Physical address space" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Pick a debug font" @@ -8508,7 +8510,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "機種" @@ -8750,7 +8752,7 @@ msgstr "" msgid "Public" msgstr "誰でも" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "ゲームリストのキャッシュを消去" @@ -8808,11 +8810,11 @@ msgstr "R (アナログ)" msgid "READY" msgstr "READY" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO Modules" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO auto-detection" @@ -8972,7 +8974,7 @@ msgid "Refreshing..." msgstr "セッションリストを更新中..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "地域" @@ -9076,7 +9078,7 @@ msgstr "初期化" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Reset Ignore Panic Handler" @@ -9308,11 +9310,11 @@ msgstr "SSL context" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Sa&ve Code" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "ステートセーブ(&V)" @@ -9335,7 +9337,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -9356,11 +9358,11 @@ msgstr "セーブデータ" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "ゲームボーイアドバンス セーブファイル (*.sav);;すべてのファイル (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9422,23 +9424,23 @@ msgstr "ステートセーブ - スロット 8" msgid "Save State Slot 9" msgstr "ステートセーブ - スロット 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "ファイルとして保存" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "最古のステートに上書き保存" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "選択したスロットに保存" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "次のスロットに保存" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Save Symbol Map &As..." @@ -9458,11 +9460,11 @@ msgstr "" msgid "Save as..." msgstr "ファイルとして保存" -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Save combined output file as" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9476,11 +9478,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "ROMと同じフォルダにセーブファイルを保存する" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Save map file" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Save signature file" @@ -9488,7 +9490,7 @@ msgstr "Save signature file" msgid "Save to Selected Slot" msgstr "選択したスロットに保存" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "スロット %1 - %2" @@ -9522,7 +9524,7 @@ msgstr "画面撮影" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Search" @@ -9551,7 +9553,7 @@ msgstr "" "Search currently not possible in virtual address space. Please run the game " "for a bit and try again." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Search for an Instruction" @@ -9559,7 +9561,7 @@ msgstr "Search for an Instruction" msgid "Search games..." msgstr "ゲームタイトルを検索" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Search instruction" @@ -9596,7 +9598,7 @@ msgid "Select Dump Path" msgstr "ダンプ先を選択" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "エクスポート先フォルダを選択" @@ -9640,7 +9642,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "スロット %1 - %2" @@ -9648,7 +9650,7 @@ msgstr "スロット %1 - %2" msgid "Select State" msgstr "スロットの選択" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "スロットの選択" @@ -9734,7 +9736,7 @@ msgstr "" msgid "Select a game" msgstr "タイトルを選択" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "NANDにインストールするタイトルを選択" @@ -9742,7 +9744,7 @@ msgstr "NANDにインストールするタイトルを選択" msgid "Select e-Reader Cards" msgstr "カードeファイルの選択" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Select the RSO module address:" @@ -9759,7 +9761,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "キーファイル (OTP/SEEPROM ダンプ)を選択" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "セーブファイルを選択" @@ -9993,11 +9995,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "ログを表示(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "ツールバー(&T)" @@ -10005,11 +10007,11 @@ msgstr "ツールバー(&T)" msgid "Show Active Title in Window Title" msgstr "タイトルバーに起動中のゲーム名を表示" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "すべて表示" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "オーストラリア" @@ -10022,7 +10024,7 @@ msgstr "Discordにプレイ中のゲームを表示" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL" @@ -10035,7 +10037,7 @@ msgstr "" msgid "Show FPS" msgstr "FPSを表示" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "フレームカウンタを表示" @@ -10043,15 +10045,15 @@ msgstr "フレームカウンタを表示" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "フランス" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "ゲームキューブ" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "ドイツ" @@ -10063,23 +10065,23 @@ msgstr "Show Golf Mode Overlay" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "入力された操作を表示" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "イタリア" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "日本" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "韓国" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "ラグカウンタを表示" @@ -10087,7 +10089,7 @@ msgstr "ラグカウンタを表示" msgid "Show Language:" msgstr "次の言語で表示" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "ログの設定を表示(&C)" @@ -10099,7 +10101,7 @@ msgstr "ネットプレイ:OSD表示" msgid "Show NetPlay Ping" msgstr "ネットプレイ:Ping表示" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "オランダ" @@ -10107,7 +10109,7 @@ msgstr "オランダ" msgid "Show On-Screen Display Messages" msgstr "オンスクリーンメッセージを表示" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "PAL規格の地域" @@ -10120,19 +10122,19 @@ msgstr "Show PC" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "特定機種のソフトだけを表示" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "次の地域のソフトだけを表示" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "ロシア" @@ -10140,7 +10142,7 @@ msgstr "ロシア" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "スペイン" @@ -10152,19 +10154,19 @@ msgstr "" msgid "Show Statistics" msgstr "統計情報を表示" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "システム時間を表示" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "台湾" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "アメリカ合衆国" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "不明" @@ -10176,15 +10178,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD(Wiiウェア/VC/Wiiチャンネル)" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "地域なし" @@ -10304,7 +10306,7 @@ msgstr "横持ち 切替" msgid "Sideways Wii Remote" msgstr "横持ち(Sideways)で使用" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Signature Database" @@ -10563,7 +10565,7 @@ msgstr "標準コントローラ" msgid "Start" msgstr "スタート" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "ネットプレイを開始(&N)" @@ -10571,7 +10573,7 @@ msgstr "ネットプレイを開始(&N)" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "操作の記録を開始(&C)" @@ -10665,7 +10667,7 @@ msgstr "表示方式" msgid "Stereoscopic 3D Mode:" msgstr "表示方式" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "立体視" @@ -10687,7 +10689,7 @@ msgstr "スティック" msgid "Stop" msgstr "停止" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "操作の再生/記録を停止" @@ -10768,8 +10770,8 @@ msgstr "スタイラス" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "完了" @@ -10796,7 +10798,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "セーブファイルのエクスポートに成功しました" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "証明書ファイルの取り出しに成功しました" @@ -10808,12 +10810,12 @@ msgstr "ファイルの取り出しに成功しました" msgid "Successfully extracted system data." msgstr "システムデータの取り出しに成功しました" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "タイトルのインストールに成功しました" @@ -10914,7 +10916,7 @@ msgstr "Symbol name:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symbols" @@ -10934,7 +10936,7 @@ msgstr "実機Wiiリモコンとのペアリングを行う" msgid "Synchronize GPU thread" msgstr "Synchronize GPU thread" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10967,7 +10969,7 @@ msgstr "セーブデータの同期中..." msgid "System Language:" msgstr "システムの言語:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS用入力ウィンドウを表示" @@ -10980,7 +10982,7 @@ msgstr "TAS関係" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "タグを表示" @@ -10998,7 +11000,7 @@ msgstr "Tail" msgid "Taiwan" msgstr "台湾" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "画面撮影" @@ -11082,7 +11084,7 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "The Masterpiece partitions are missing." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11090,7 +11092,7 @@ msgstr "" "NANDを修復できませんでした。現在のデータをバックアップして、NANDのダンプから" "やり直すことをオススメします" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NANDの修復に成功しました" @@ -11369,6 +11371,12 @@ msgstr "The specified common key index is {0} but should be {1}." msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -11403,6 +11411,12 @@ msgstr "The update partition is missing." msgid "The update partition is not at its normal position." msgstr "The update partition is not at its normal position." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "The {0} partition does not have a valid file system." @@ -11431,7 +11445,7 @@ msgstr "取り消すものがありません!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11647,13 +11661,13 @@ msgstr "" "\n" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "ここで設定した値は、グラフィック設定でセットした収束距離に加算されます" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "ここで設定した値は、グラフィック設定でセットした収束距離に乗算されます" @@ -11706,7 +11720,7 @@ msgstr "Timed Out" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "タイトル" @@ -11720,7 +11734,7 @@ msgstr "終了" msgid "To:" msgstr "終了" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "全画面表示 切り替え(&F)" @@ -11978,7 +11992,7 @@ msgstr "" "パフォーマンスへの影響を最小限に抑えつつカクつきが解消されるはずですが、実際" "どのような結果になるかは使用中のビデオドライバに依存します。" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Unable to auto-detect RSO module" @@ -12045,11 +12059,11 @@ msgstr "未圧縮のGC/Wii ISOファイル (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "直前のステートロードを取消" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "直前のステートセーブの取消" @@ -12068,7 +12082,7 @@ msgid "" msgstr "" "セーブデータを残してNAND内からこのタイトルを削除します。よろしいですか?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "米国" @@ -12321,7 +12335,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "両方の目に単一のデプスバッファを使用します。必要となるタイトルはわずかです。" @@ -12378,7 +12392,7 @@ msgstr "" "You can continue to use 'Code did not get executed'/'Code has been executed' " "to narrow down the results." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "ユーザー設定" @@ -12582,7 +12596,7 @@ msgstr "音量を上げる" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WADファイル (*.wad)" @@ -12696,7 +12710,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "警告" @@ -12879,11 +12893,11 @@ msgstr "WiiとWiiリモコン" msgid "Wii data is not public yet" msgstr "Wii data is not public yet" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii セーブファイル (*.bin);;すべてのファイル (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -13109,6 +13123,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13145,7 +13165,7 @@ msgstr "aligned" msgid "any value" msgstr "any value" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "自動 (auto)" @@ -13178,7 +13198,7 @@ msgstr "カードeファイル (*.raw);;すべてのファイル (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "擬似シングルコア (fake-completion)" @@ -13224,7 +13244,7 @@ msgstr "" "mGBA ステートセーブファイル (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 " "*.ss8 *.ss9);;すべてのファイル (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "なし" diff --git a/Languages/po/ko.po b/Languages/po/ko.po index ee4119a500..9a6baad789 100644 --- a/Languages/po/ko.po +++ b/Languages/po/ko.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Siegfried, 2013-2023\n" "Language-Team: Korean (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -326,7 +326,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "돌핀 정보(&A)" @@ -347,7 +347,7 @@ msgstr "함수 추가 (&A)" msgid "&Add..." msgstr "추가... (&A)" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "오디오 설정(&A)" @@ -355,7 +355,7 @@ msgstr "오디오 설정(&A)" msgid "&Auto Update:" msgstr "자동 업데이트(&A):" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "자동 시작 (&A)" @@ -363,11 +363,11 @@ msgstr "자동 시작 (&A)" msgid "&Borderless Window" msgstr "틀 없는 창(&B)" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "중단점 (&B)" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "버그 추적자(&B)" @@ -375,15 +375,15 @@ msgstr "버그 추적자(&B)" msgid "&Cancel" msgstr "취소(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "치트 매니저(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "업데이트 확인(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "부호 지우기 (& C)" @@ -391,7 +391,7 @@ msgstr "부호 지우기 (& C)" msgid "&Clone..." msgstr "복제... (&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "코드 (&C)" @@ -399,7 +399,7 @@ msgstr "코드 (&C)" msgid "&Connected" msgstr "연결된(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "컨트롤러 설정(&C)" @@ -438,11 +438,11 @@ msgstr "코드 수정... (&E)" msgid "&Edit..." msgstr "편집... (&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "디스크 꺼내기(&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "에뮬레이션(&E)" @@ -462,27 +462,27 @@ msgstr "상태 내보내기...(&E)" msgid "&Export as .gci..." msgstr ".gci 로 내보내기... (&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "파일(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "폰트 (&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "프레임 진행(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "자유 보기 설정(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "부호 생성 (&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "GitHub 저장소(&G)" @@ -490,15 +490,15 @@ msgstr "GitHub 저장소(&G)" msgid "&Go to start of function" msgstr "함수의 시작으로 가기(&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "그래픽 설정(&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "도움말(&H)" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "단축키 설정(&H)" @@ -518,7 +518,7 @@ msgstr "상태 가져오기...(&I)" msgid "&Import..." msgstr "가져오기... (&I)" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -530,7 +530,7 @@ msgstr "blr 삽입 (&I)" msgid "&Interframe Blending" msgstr "프레임간 혼합(&I)" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "JIT(&J)" @@ -538,11 +538,11 @@ msgstr "JIT(&J)" msgid "&Language:" msgstr "언어(&L):" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "상태 로드(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "로드 부호 맵 (&L)" @@ -556,15 +556,15 @@ msgstr "파일을 현재 주소로 로드합니다 (&L)" msgid "&Lock Watches" msgstr "관찰들 고정 (&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "위젯 고정(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "메모리(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "무비(&M)" @@ -572,7 +572,7 @@ msgstr "무비(&M)" msgid "&Mute" msgstr "음소거(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "네트워크(&N)" @@ -581,23 +581,23 @@ msgid "&No" msgstr "아니요(&N)" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "열기...(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "옵션(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "HLE 함수 패치 (&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "일시정지(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "실행(&P)" @@ -605,7 +605,7 @@ msgstr "실행(&P)" msgid "&Properties" msgstr "속성(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "읽기 전용 모드(&R)" @@ -613,7 +613,7 @@ msgstr "읽기 전용 모드(&R)" msgid "&Refresh List" msgstr "목록 새로고침(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "레지스터 (&R)" @@ -631,15 +631,15 @@ msgid "&Rename symbol" msgstr "부호 이름 바꾸기 (&R)" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "리셋(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "리소스 팩 매니저(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "부호 맵 저장 (&S)" @@ -647,7 +647,7 @@ msgstr "부호 맵 저장 (&S)" msgid "&Scan e-Reader Card(s)..." msgstr "e-Reader 카드 스캔...(&S)" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "스카이랜더스 포탈 (&S)" @@ -655,7 +655,7 @@ msgstr "스카이랜더스 포탈 (&S)" msgid "&Speed Limit:" msgstr "속도 제한(&S):" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "중지(&S)" @@ -663,11 +663,11 @@ msgstr "중지(&S)" msgid "&Theme:" msgstr "테마(&T):" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "쓰레드(&T)" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "도구(&T)" @@ -681,17 +681,17 @@ msgstr "롬 언로드(&U)" msgid "&Unlock Watches" msgstr "관찰들 고정풀기 (&U)" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "보기(&V)" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "관찰(&W)" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "웹사이트(&W)" @@ -703,11 +703,11 @@ msgstr "위키(&W)" msgid "&Yes" msgstr "예(&Y)" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' 이 발견되지 않았습니다, 생성된 부호 이름이 없습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' 이 발견되지 않았습니다, 공통 함수들을 대신 스캔합니다" @@ -1150,7 +1150,7 @@ msgid "Accuracy:" msgstr "정확성:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1340,7 +1340,7 @@ msgstr "추가..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "주소" @@ -1595,15 +1595,15 @@ msgstr "안티-앨리어싱:" msgid "Any Region" msgstr "아무 지역" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "서명 덧붙이기" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "존재하는 서명 파일에 덧붙이기... (&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "서명 파일 적용... (&y)" @@ -1623,7 +1623,7 @@ msgstr "앱로더 날짜:" msgid "Apply" msgstr "적용" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "서명 파일 적용" @@ -1734,7 +1734,7 @@ msgstr "창 크기 자동 조정" msgid "Auto-Hide" msgstr "자동-숨기기" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "RSO 모듈을 자동-감지할까요?" @@ -1842,7 +1842,7 @@ msgstr "안 좋은 값이 제공되었습니다." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "배너" @@ -1914,7 +1914,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "블락 크기" @@ -1952,7 +1952,7 @@ msgstr "" "블루투스 패스쓰루 모드가 켜졌습니다, 하지만 돌핀이 libusb 없이 빌드되었습니" "다. 패스쓰루 모드를 사용할 수 없습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "부팅하고 멈추기" @@ -2029,7 +2029,7 @@ msgstr "광대역 어댑터 에러" msgid "Broadband Adapter MAC Address" msgstr "광대역 어댑터 맥 어드레스" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "넷플레이 세션들 둘러보기...(&N)" @@ -2093,7 +2093,7 @@ msgstr "만든이:" msgid "C Stick" msgstr "C 스틱" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "서명 파일 생성... (&C)" @@ -2197,7 +2197,7 @@ msgstr "게임이 여전히 구동되는 동안에 넷플레이 세션을 시작 #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2268,7 +2268,7 @@ msgstr "중앙과 측정" msgid "Change &Disc" msgstr "디스크 변경(&D)" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "디스크 변경...(&D)" @@ -2340,7 +2340,7 @@ msgstr "치트 찾기" msgid "Cheats Manager" msgstr "치트 관리자" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "NAND 체크..." @@ -2380,11 +2380,11 @@ msgstr "열 파일 선택하기" msgid "Choose a file to open or create" msgstr "열거나 만들 파일 선택" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "우선 입력 파일 선택" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "차선 입력 파일 선택" @@ -2419,7 +2419,7 @@ msgstr "클래식 컨트롤러" msgid "Clear" msgstr "지움" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "캐시 청소" @@ -2440,7 +2440,7 @@ msgstr "복제하고 코드 수정... (&E)" msgid "Close" msgstr "닫기" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "환경설정(&n)" @@ -2487,7 +2487,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "두 서명 파일을 합치기... (&T)" @@ -2530,7 +2530,7 @@ msgstr "쉐이더들 컴파일하기" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "압축" @@ -2666,7 +2666,7 @@ msgstr "백엔드 변경 확정" msgid "Confirm on Stop" msgstr "멈출 때 확인" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2677,7 +2677,7 @@ msgstr "확정" msgid "Connect" msgstr "연결" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "밸런스 보드 연결" @@ -2685,7 +2685,7 @@ msgstr "밸런스 보드 연결" msgid "Connect USB Keyboard" msgstr "USB 키보드 연결" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Wii 리모트 %1 연결" @@ -2705,7 +2705,7 @@ msgstr "Wii 리모트 3 연결" msgid "Connect Wii Remote 4" msgstr "Wii 리모트 4 연결" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Wii 리모트 연결" @@ -2843,7 +2843,7 @@ msgstr "" msgid "Convergence" msgstr "수렴" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "수렴:" @@ -3203,7 +3203,7 @@ msgstr "" "로우 통계에 효과가 있을지 모릅니다.

잘 모르겠으면, " "체크 해제해 두세요." -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "현재 지역" @@ -3403,7 +3403,7 @@ msgstr "Y 감소" msgid "Default" msgstr "기본" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "기본 환경 (읽기 전용)" @@ -3468,7 +3468,7 @@ msgstr "존재하는 파일 '{0}' 를 삭제합니까?" msgid "Depth" msgstr "깊이" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "깊이 퍼센트:" @@ -3481,7 +3481,7 @@ msgstr "깊이:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "설명" @@ -3503,11 +3503,11 @@ msgstr "떨어진" msgid "Detect" msgstr "감지" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "RSO 모듈 감지하기" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "결정론적 듀얼 코어:" @@ -3582,7 +3582,7 @@ msgstr "EFB 비디오램 복사 비활성" msgid "Disable Emulation Speed Limit" msgstr "에뮬레이션 속도 제한 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Fastmem 비활성" @@ -3590,7 +3590,7 @@ msgstr "Fastmem 비활성" msgid "Disable Fog" msgstr "안개 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "JIT 캐시 비활성" @@ -3679,7 +3679,7 @@ msgstr "돌핀이 정보를 돌핀 개발자들에게 보고하도록 허가하 msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "\"%1\" 를 게임 경로들의 목록에 추가하고 싶습니까?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "부호 이름 목록을 청소할까요?" @@ -3710,17 +3710,17 @@ msgstr "돌핀 FIFO 로그 (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "돌핀 게임 모드 프리셋" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "돌핀 맵 파일 (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "돌핀 서명 CSV 파일" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "돌핀 서명 파일" @@ -3893,7 +3893,7 @@ msgstr "가짜가상메모리 덤프(&F)" msgid "Dump &MRAM" msgstr "MRAM 덤프(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "오디오 덤프" @@ -3905,7 +3905,7 @@ msgstr "기반 텍스처 덤프" msgid "Dump EFB Target" msgstr "EFB 타겟 덤프" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "프레임들 덤프" @@ -3990,7 +3990,7 @@ msgstr "터보 버튼 떼기의 기간 (프레임)" msgid "Dutch" msgstr "네덜란드어" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "종료(&x)" @@ -4044,7 +4044,7 @@ msgid "Edit..." msgstr "편집..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "에디터" @@ -4111,7 +4111,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4267,7 +4267,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4309,7 +4309,7 @@ msgstr "" "5.1 서라운드를 사용하는 돌비 프로 로직 II 에뮬레이션을 켭니다. 특정 백엔드 전" "용." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4392,7 +4392,7 @@ msgstr "" "

잘 모르겠으면, 체크 해제해 두세요." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4487,7 +4487,7 @@ msgstr "패스워드 입력" msgid "Enter the DNS server to use:" msgstr "사용할 DNS 서버를 입력:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "RSO 모듈 주소를 입력:" @@ -4534,18 +4534,18 @@ msgstr "RSO 모듈 주소를 입력:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4689,7 +4689,7 @@ msgstr "{1} 파티션에 {0} 사용되지 않은 블락들에서 에러들이 msgid "Euphoria" msgstr "유포리아" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "유럽" @@ -4784,7 +4784,7 @@ msgstr "변수 이름을 예상했습니다." msgid "Experimental" msgstr "실험적" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "모든 Wii 저장을 내보내기" @@ -4799,7 +4799,7 @@ msgstr "내보내기를 실패했습니다" msgid "Export Recording" msgstr "입력 기록 내보내기" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "입력 기록 내보내기..." @@ -4827,7 +4827,7 @@ msgstr ".gcs 로 내보내기... (&g)" msgid "Export as .&sav..." msgstr ".sav 로 내보내기... (&s)" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4855,7 +4855,7 @@ msgstr "외부의" msgid "External Frame Buffer (XFB)" msgstr "외부 프레임 버퍼 (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "NAND 에서 증명서 추출" @@ -4893,7 +4893,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO 플레이어" @@ -4913,7 +4913,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "넷플레이 목록 : %1 에 이 세션을 추가하는데에 실패했습니다" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "서명 파일 '%1' 에 덧붙이기에 실패했습니다." @@ -5007,7 +5007,7 @@ msgstr "%1 저장 파일(들)로부터 %n 를 내보내기에 실패했습니다 msgid "Failed to export the following save files:" msgstr "다음 저장 파일들을 내보내기에 실패했습니다:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "NAND 에서 증명서 추출에 실패했습니다" @@ -5037,14 +5037,14 @@ msgstr "하나 이상의 D3D 부호 찾기에 실패했습니다" msgid "Failed to import \"%1\"." msgstr "\"%1\" 가져오기에 실패했습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "저장 파일을 가져오기에 실패했습니다. 해당 게임을 한번 띄워주세요, 그리고 다" "시 시도하세요." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5052,7 +5052,7 @@ msgstr "" "저장 파일 가져오기에 실패했습니다. 주어진 파일은 오염되었거나 적합한 Wii 저장" "이 아닙니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5085,7 +5085,7 @@ msgid "Failed to install pack: %1" msgstr "팩 설치에 실패했습니다: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "NAND 에 이 타이틀 설치에 실패했습니다." @@ -5097,8 +5097,8 @@ msgstr "" "포트 %1 듣기에 실패했습니다. 구동 중인 다른 넷플레이 서버 인스턴스가 있습니" "까?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "%1 에서 RSO 모듈 로드에 실패했습니다" @@ -5110,7 +5110,7 @@ msgstr "d3d11.dll 로드에 실패했습니다" msgid "Failed to load dxgi.dll" msgstr "dxgi.dll 로드에 실패했습니다" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "맵 파일 '%1' 을 로드에 실패했습니다." @@ -5297,19 +5297,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "FIFO 로그 저장에 실패했습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "경로 '%1' 에 코드 맵 저장을 실패했습니다" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "서명 파일 '%1' 을 저장에 실패했습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "경로 '%1' 에 심볼 맵 저장을 실패했습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "서명 파일 '%1' 에 저장에 실패했습니다." @@ -5359,7 +5359,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "실패" @@ -5407,7 +5407,7 @@ msgstr "파일 세부사항" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "파일 형식" @@ -5421,18 +5421,18 @@ msgstr "파일 정보" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "파일 이름" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "파일 경로" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "파일 크기" @@ -5985,7 +5985,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "게임 ID" @@ -6032,7 +6032,7 @@ msgstr "" msgid "Game region does not match" msgstr "게임 지역이 맞지 않습니다" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "게임-상세 설정" @@ -6103,7 +6103,7 @@ msgid "Gecko Codes" msgstr "Gecko 코드" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6129,7 +6129,7 @@ msgstr "새로운 통계 식별자 생성" msgid "Generated AR code." msgstr "AR 코드를 생성했습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "'%1' 에서 부호 이름들을 생성했습니다" @@ -6210,7 +6210,7 @@ msgstr "초록 왼쪽" msgid "Green Right" msgstr "초록 오른쪽" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "격자 보기" @@ -6285,7 +6285,7 @@ msgstr "16진수" msgid "Hide" msgstr "숨기기" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "모두 숨기기" @@ -6619,7 +6619,7 @@ msgstr "" "

잘 모르겠으면, 체크 해제해 두세요." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "BootMii NAND 백업 가져오기..." @@ -6634,7 +6634,7 @@ msgstr "가져오기를 실패했습니다" msgid "Import Save File(s)" msgstr "저장 파일(들)을 가져오기" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Wii 저장 가져오기" @@ -6747,8 +6747,8 @@ msgstr "정보" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "정보" @@ -6757,10 +6757,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "에뮬하는 동안 화면보호기를 감춥니다" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "입력" @@ -6801,7 +6801,7 @@ msgstr "파티션 (%1) 설치" msgid "Install Update" msgstr "업데이트 설치" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "WAD 설치..." @@ -6821,7 +6821,7 @@ msgstr "명령" msgid "Instruction Breakpoint" msgstr "명령 중단점" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "명령:" @@ -6890,7 +6890,7 @@ msgstr "AR 코드를 생성하는 동안 내부 에러." msgid "Interpreter (slowest)" msgstr "인터프리터 (가장 느림)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "인터프리터 코어" @@ -6915,7 +6915,7 @@ msgstr "부적합한 %1 이 제공됨: %2" msgid "Invalid Player ID" msgstr "부적합한 플레이어 아이디" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "부적합 RSO 모듈 주소: %1" @@ -6990,11 +6990,11 @@ msgstr "이탈리아어" msgid "Italy" msgstr "이탈리아" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT 블록 연결 끄기" @@ -7002,47 +7002,47 @@ msgstr "JIT 블록 연결 끄기" msgid "JIT Blocks" msgstr "JIT 블록들" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT 분기 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT 소수점 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT 정수 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT 로드스토어 부동 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT 로드스토어 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT 로드스토어 짝짓기 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT 로드스토어 lXz 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT 로드스토어 lbzx 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT 로드스토어 lwz 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT 끄기 (JIT 코어)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT 짝짓기 끄기" @@ -7054,11 +7054,11 @@ msgstr "ARM64 용 JIT 리컴파일러 (권장)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "x86-64 용 JIT 리컴파일러 (권장)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "JIT 레지스터 캐시 끄기" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT 시스템레지스터 끄기" @@ -7071,7 +7071,7 @@ msgstr "" "JIT 이 캐시 청소후에 코드 공간 찾기에 실패했습니다. 이것은 절대 일어나서는 안" "됩니다. 버그 트랙커에 이 사고를 보고해주세요. 돌핀은 지금 나갈 것입니다." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "일본" @@ -7130,7 +7130,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "플레이어 차기" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "한국" @@ -7281,11 +7281,11 @@ msgstr "왼쪽" msgid "Limit Chunked Upload Speed:" msgstr "덩어리된 업로드 스피드 제한:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "목록 세로줄" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "목록 보기" @@ -7301,11 +7301,11 @@ msgstr "듣기" msgid "Load" msgstr "로드" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "배드 맵 파일 로드... (&B)" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "다른 맵 파일 로드... (&O)" @@ -7317,7 +7317,7 @@ msgstr "커스텀 텍스처 로드" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "게임큐브 메인 메뉴 로드" @@ -7427,19 +7427,19 @@ msgstr "슬롯 8 상태 로드" msgid "Load State Slot 9" msgstr "슬롯 9 상태 로드" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "파일에서 상태 로드" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "선택된 슬롯에서 상태를 로드합니다" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "슬롯에서 상태 로드" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Wii 시스템 메뉴 %1 로드" @@ -7451,16 +7451,16 @@ msgstr "호스트의 저장 데이터 로드하고 쓰기" msgid "Load from Selected Slot" msgstr "선택된 슬롯에서 로드" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "슬롯 %1 - %2 로부터 로드" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "맵 파일 로드" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "vWii 시스템 메뉴 %1 로드" @@ -7468,7 +7468,7 @@ msgstr "vWii 시스템 메뉴 %1 로드" msgid "Load..." msgstr "로드..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "'%1' 에서 부호들이 로드되었습니다" @@ -7513,7 +7513,7 @@ msgstr "로그" msgid "Log Configuration" msgstr "로그 환경설정" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "JIT 명령 커버리지 로그" @@ -7596,7 +7596,7 @@ msgstr "메인 스틱" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "제작사" @@ -7617,10 +7617,11 @@ msgstr "" "게임들을 망가뜨릴 것입니다.

잘 모르겠으면, 이것을 체" "크 해제해 두세요." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "NAND 관리" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "수동 텍스처 샘플링" @@ -7671,7 +7672,7 @@ msgstr "메모리 중단점" msgid "Memory Card" msgstr "메모리 카드" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "메모리 카드 관리자" @@ -7769,8 +7770,8 @@ msgstr "" "션 리셋이 필요할 수도 있습니다.

잘 모르겠으면, 체크 " "해제해 두세요." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "발견된 모듈: %1" @@ -7778,7 +7779,7 @@ msgstr "발견된 모듈: %1" msgid "Mono" msgstr "단일" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "모노스코픽 그림자" @@ -7843,9 +7844,10 @@ msgstr "곱하는 수" msgid "N&o to All" msgstr "모두 아니오(&o)" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND 체크" @@ -7854,7 +7856,7 @@ msgstr "NAND 체크" msgid "NKit Warning" msgstr "NKit 경고" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7880,7 +7882,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8096,7 +8098,7 @@ msgstr "구동중인 게임이 없습니다." msgid "No game running." msgstr "구동중인 게임이 없습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "이슈가 감지되지 않았습니다." @@ -8159,7 +8161,7 @@ msgstr "없음" msgid "North America" msgstr "북 아메리카" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "설정 안됨" @@ -8289,7 +8291,7 @@ msgstr "" "합니다, 작업을 위해서는 꼭지점 쉐이더를 선택하세요. 성능 효과가 있을 수도." "

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "온라인 문서(&D)" @@ -8297,7 +8299,7 @@ msgstr "온라인 문서(&D)" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8305,7 +8307,7 @@ msgstr "" "접두사를 가진 부호들만 덧붙입니다:\n" "(모든 부호들은 빈칸)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8322,7 +8324,7 @@ msgstr "열기" msgid "Open &Containing Folder" msgstr "담고 있는 폴더 열기(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "사용자 폴더 열기 (&U)" @@ -8428,11 +8430,11 @@ msgstr "다른 게임..." msgid "Overwritten" msgstr "덮어 쓰여진" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "입력 기록 플레이...(&l)" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8534,7 +8536,7 @@ msgstr "경로" msgid "Pause" msgstr "일시정지" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "무비의 끝에서 일시정지" @@ -8575,7 +8577,7 @@ msgstr "바깥쪽 스윙 이동의 피크 가속도" msgid "Per-Pixel Lighting" msgstr "픽셀단위 광원" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "온라인 시스템 업데이트 하기" @@ -8609,7 +8611,7 @@ msgstr "물리적 주소 공간" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "디버그 폰트 고르기" @@ -8626,7 +8628,7 @@ msgid "Pitch Up" msgstr "피치 올리기" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "플랫폼" @@ -8869,7 +8871,7 @@ msgstr "진행" msgid "Public" msgstr "공공" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "게임 목록 캐시 제거" @@ -8925,11 +8927,11 @@ msgstr "R-아날로그" msgid "READY" msgstr "준비" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO 모듈" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO 자동-감지" @@ -9089,7 +9091,7 @@ msgid "Refreshing..." msgstr "새로고침..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "지역" @@ -9192,7 +9194,7 @@ msgstr "리셋" msgid "Reset All" msgstr "모두 리셋" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "패닉 핸들러 무시를 리셋" @@ -9428,11 +9430,11 @@ msgstr "SSL 맥락" msgid "START" msgstr "시작" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "코드 저장 (&v)" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "상태 저장(&v) " @@ -9455,7 +9457,7 @@ msgstr "모두 저장" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "저장 내보내기" @@ -9476,11 +9478,11 @@ msgstr "게임 저장" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "게임 저장 파일들 (*.sav);;모든 파일들 (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "저장 가져오기" @@ -9542,23 +9544,23 @@ msgstr "슬롯 8 상태 저장" msgid "Save State Slot 9" msgstr "슬롯 9 상태 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "파일에 상태 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "가장 오래된 슬롯에 상태 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "선택된 슬롯에 상태를 저장합니다" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "슬롯에 상태 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "심볼 맵 다른 이름으로 저장... (&A)" @@ -9578,11 +9580,11 @@ msgstr "프리셋 다른 이름으로 저장..." msgid "Save as..." msgstr "다른 이름으로 저장..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "합쳐진 출력 파일 다른 이름으로 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9596,11 +9598,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "롬과 같은 디렉토리에 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "맵 파일 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "서명 파일 저장" @@ -9608,7 +9610,7 @@ msgstr "서명 파일 저장" msgid "Save to Selected Slot" msgstr "선택된 슬롯에 저장" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "슬롯 %1 - %2 에 저장" @@ -9642,7 +9644,7 @@ msgstr "스크린샷" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "찾기" @@ -9671,7 +9673,7 @@ msgstr "" "가상 주소 공간에서는 현재 검색할 수 없습니다. 게임을 잠시 구동하신 후에 다시 " "시도하세요." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "명령에 대한 찾기" @@ -9679,7 +9681,7 @@ msgstr "명령에 대한 찾기" msgid "Search games..." msgstr "게임들 검색..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "명령 찾기" @@ -9716,7 +9718,7 @@ msgid "Select Dump Path" msgstr "덤프 경로 선택" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "내보내기 디렉토리 선택" @@ -9760,7 +9762,7 @@ msgstr "" msgid "Select Skylander File" msgstr "스카이랜더 파일 선택" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "슬롯 %1 - %2 선택" @@ -9768,7 +9770,7 @@ msgstr "슬롯 %1 - %2 선택" msgid "Select State" msgstr "상태 선택" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "상태 슬롯 선택" @@ -9854,7 +9856,7 @@ msgstr "파일 선택" msgid "Select a game" msgstr "게임 선택" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "NAND 에 설치할 타이틀 선택" @@ -9862,7 +9864,7 @@ msgstr "NAND 에 설치할 타이틀 선택" msgid "Select e-Reader Cards" msgstr "e-Reader 카드 선택" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "RSO 모듈 주소 선택:" @@ -9879,7 +9881,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "키 파일 선택 (OTP/SEEPROM 덤프)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "저장 파일을 선택" @@ -10118,11 +10120,11 @@ msgstr "신간선 컨트롤러" msgid "Show % Speed" msgstr "% 속도 보여주기" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "로그 보기(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "툴바 표시(&T)" @@ -10130,11 +10132,11 @@ msgstr "툴바 표시(&T)" msgid "Show Active Title in Window Title" msgstr "창 제목에 활성 타이틀 보여주기" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "모두 보여주기" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "오스트레일리아" @@ -10147,7 +10149,7 @@ msgstr "디스코드에 현재 게임을 보여주기" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL" @@ -10160,7 +10162,7 @@ msgstr "" msgid "Show FPS" msgstr "FPS 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "프레임 카운터 보기" @@ -10168,15 +10170,15 @@ msgstr "프레임 카운터 보기" msgid "Show Frame Times" msgstr "프레임 타임 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "프랑스" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "게임큐브" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "독일" @@ -10188,23 +10190,23 @@ msgstr "골프 모드 오버레이 보기" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "입력 표시 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "이탈리아" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "일본 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "한국" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "랙 카운터 보기" @@ -10212,7 +10214,7 @@ msgstr "랙 카운터 보기" msgid "Show Language:" msgstr "언어 보기:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "로그 환경설정(&C)" @@ -10224,7 +10226,7 @@ msgstr "넷플레이 메시지 보기" msgid "Show NetPlay Ping" msgstr "넷플레이 핑 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "네덜란드" @@ -10232,7 +10234,7 @@ msgstr "네덜란드" msgid "Show On-Screen Display Messages" msgstr "온-스크린 메시지 보여주기" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "PAL (유럽 방식)" @@ -10245,19 +10247,19 @@ msgstr "PC 보기" msgid "Show Performance Graphs" msgstr "성능 그래프 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "플랫폼 표시" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "지역 표시" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "재녹화 횟수 보이기" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "러시아" @@ -10265,7 +10267,7 @@ msgstr "러시아" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "스페인" @@ -10277,19 +10279,19 @@ msgstr "속도 색 보여주기" msgid "Show Statistics" msgstr "통계 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "시스템 클럭 보기" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "타이완" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "USA (미국 방식)" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "알려지지 않음" @@ -10301,15 +10303,15 @@ msgstr "VBlank 타임 보기" msgid "Show VPS" msgstr "VPS 보여주기" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "세계" @@ -10443,7 +10445,7 @@ msgstr "옆방향 토글" msgid "Sideways Wii Remote" msgstr "Wii 리모트 옆으로" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "서명 데이터베이스" @@ -10701,7 +10703,7 @@ msgstr "표준 컨트롤러" msgid "Start" msgstr "시작" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "넷플레이 시작(&N)" @@ -10709,7 +10711,7 @@ msgstr "넷플레이 시작(&N)" msgid "Start New Cheat Search" msgstr "새로운 치트 검색 시작" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "입력 기록 시작(&c)" @@ -10803,7 +10805,7 @@ msgstr "입체 3D 모드" msgid "Stereoscopic 3D Mode:" msgstr "입체 3D 모드:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "입체 영상" @@ -10825,7 +10827,7 @@ msgstr "스틱" msgid "Stop" msgstr "중지" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "입력 재생/기록 중지" @@ -10904,8 +10906,8 @@ msgstr "스타일러스" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "성공" @@ -10932,7 +10934,7 @@ msgstr "%1 저장 파일(들)로부터 %n 를 성공적으로 내보냈습니다 msgid "Successfully exported save files" msgstr "저장 파일들을 성공적으로 내보냈습니다" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "NAND 에서 증명서를 성공적으로 추출했습니다" @@ -10944,12 +10946,12 @@ msgstr "성공적으로 파일 압축을 풀었습니다." msgid "Successfully extracted system data." msgstr "성공적으로 시스템 데이터 압축을 풀었습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "저장 파일을 성공적으로 내보냈습니다." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "NAND 에 이 타이틀을 성공적으로 설치했습니다." @@ -11050,7 +11052,7 @@ msgstr "부호 이름:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "부호들" @@ -11070,7 +11072,7 @@ msgstr "실제 Wii 리모트를 동기화하고 페어링" msgid "Synchronize GPU thread" msgstr "GPU 쓰레드 동기화" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11101,7 +11103,7 @@ msgstr "저장 데이터를 동기화합니다..." msgid "System Language:" msgstr "시스템 언어:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS 입력" @@ -11114,7 +11116,7 @@ msgstr "TAS 도구" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "태그" @@ -11132,7 +11134,7 @@ msgstr "꼬리" msgid "Taiwan" msgstr "타이완" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "스크린샷 찍기" @@ -11217,7 +11219,7 @@ msgstr "IPL 파일이 알려진 좋은 덤프가 아닙니다. (CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "명작 파티션들이 빠져있습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11225,7 +11227,7 @@ msgstr "" "NAND 는 고쳐질 수 없었습니다. 현재 데이터 백업이 권장됩니다 그리고 생생한 " "NAND 로 다시 시작하세요." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND 가 고쳐졌습니다." @@ -11549,6 +11551,12 @@ msgstr "명시된 공통 키 인덱스는 {0} 입니다 하지만 {1} 이어야 msgid "The specified file \"{0}\" does not exist" msgstr "기술된 \"{0}\" 파일은 존재하지 않습니다" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "대상 메모리 카드가 이미 파일 \"%1\" 을 가지고 있습니다." @@ -11582,6 +11590,12 @@ msgstr "업데이트 파티션이 빠져있습니다." msgid "The update partition is not at its normal position." msgstr "업데이트 파티션이 정상적 위치에 있지 않습니다." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "{0} 파티션은 적합한 파일 시스템이 없습니다." @@ -11610,7 +11624,7 @@ msgstr "되돌릴 것이 없습니다!" msgid "There was an issue adding a shortcut to the desktop" msgstr "데스크탑에 바로가기 추가하기에 문제가 있었습니다" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11846,13 +11860,13 @@ msgstr "" "\n" "알려지지 않은 ucode (CRC = {0:08x}) - 강제 AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "이 값은 그래픽 환경설정에 설정된 수렴 값에 추가되어집니다." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "이 값은 그래픽 환경설정에서 설정된 깊이와 곱해집니다." @@ -11911,7 +11925,7 @@ msgstr "시간 초과" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "타이틀" @@ -11925,7 +11939,7 @@ msgstr "To" msgid "To:" msgstr "까지:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "전체화면 토글(&F)" @@ -12185,7 +12199,7 @@ msgstr "" "의 경우 미약한 성능 타격을 얻는 반면 쉐이더 컴파일 버벅임을 완전제거합니다, " "하지만 결과는 비디오 드라이버 행동에 달려있습니다." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "RSO 모듈을 자동-감지할 수 없습니다" @@ -12252,11 +12266,11 @@ msgstr "압축풀린 GC/Wii 이미지들 (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "상태 로드 되돌리기" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "상태 저장 되돌리기" @@ -12276,7 +12290,7 @@ msgstr "" "WAD 를 언인스톨하면 NAND 에서 현재 설치된 이 타이틀 버전을 저장 데이터를 지우" "지 않고 제거하게 됩니다." -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "미국" @@ -12543,7 +12557,7 @@ msgstr "" "현재 수동 텍스처 샘플링과 호환이 않됩니다.

잘 모르겠" "으면, 체크 해제해 두세요." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "양쪽 눈에 대해 하나의 깊이 버퍼를 사용합니다. 소수 게임들을 위해 필요합니다." @@ -12599,7 +12613,7 @@ msgstr "" "해당 결과를 좁히기 위해 '코드가 실행되어지지 않았습니다'/'코드가 실행되엇습니" "다' 를 계속 사용할 수 있습니다." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "사용자 환경" @@ -12806,7 +12820,7 @@ msgstr "볼륨 증가" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD 파일 (*.wad)" @@ -12932,7 +12946,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "경고" @@ -13153,11 +13167,11 @@ msgstr "Wii 와 Wii 리모트" msgid "Wii data is not public yet" msgstr "Wii 데이터는 아직 공개가 아닙니다" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii 저장 파일 (*.bin);;모든 파일 (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "WiiTools 서명 MEGA 파일" @@ -13418,6 +13432,12 @@ msgstr "" "문제를 고치기 위해 지금 멈추시겠습니까?\n" "\"아니오\" 를 선택하면, 오디오가 혼란스러울지도 모릅니다." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13454,7 +13474,7 @@ msgstr "정렬됨" msgid "any value" msgstr "아무 값" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "자동" @@ -13487,7 +13507,7 @@ msgstr "e-Reader 카드 (*.raw);;모든 파일 (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "가짜-완료" @@ -13533,7 +13553,7 @@ msgstr "" "mGBA 저장 상태 (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *.ss8 *." "ss9);;모든 파일 (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "없음" diff --git a/Languages/po/ms.po b/Languages/po/ms.po index 56098dc651..aa94be16a0 100644 --- a/Languages/po/ms.po +++ b/Languages/po/ms.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: abuyop , 2018\n" "Language-Team: Malay (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -315,7 +315,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "Perih&al" @@ -336,7 +336,7 @@ msgstr "&Tambah fungsi" msgid "&Add..." msgstr "T&ambah" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Tetapan &Audio" @@ -344,7 +344,7 @@ msgstr "Tetapan &Audio" msgid "&Auto Update:" msgstr "&Auto Kemaskini:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Mula Automatik" @@ -352,11 +352,11 @@ msgstr "&Mula Automatik" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Titik Henti" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -364,15 +364,15 @@ msgstr "" msgid "&Cancel" msgstr "&Batal" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Pengurus Menipu" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Kosongkan Simbol" @@ -380,7 +380,7 @@ msgstr "&Kosongkan Simbol" msgid "&Clone..." msgstr "&Klon..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "K&od" @@ -388,7 +388,7 @@ msgstr "K&od" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "Tetapan Ka&walan" @@ -427,11 +427,11 @@ msgstr "&Sunting Kod..." msgid "&Edit..." msgstr "&Sunting..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulasi" @@ -451,27 +451,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fail" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Fon..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "B&ingkai Lanjutan" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Jana Simbol Dari" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "Repositori &GitHub" @@ -479,15 +479,15 @@ msgstr "Repositori &GitHub" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Tetapan &Grafik" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Bantuan" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Tetapan Kekunci Pa&nas" @@ -507,7 +507,7 @@ msgstr "" msgid "&Import..." msgstr "&Import..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -519,7 +519,7 @@ msgstr "&Sisip blr" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -527,11 +527,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Bahasa:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Muat Keadaan" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Muat Peta Simbol" @@ -545,15 +545,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Ingatan" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "Ce&reka" @@ -561,7 +561,7 @@ msgstr "Ce&reka" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -570,23 +570,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "B&uka..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "Pi&lihan" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Tampal Fungsi HLE" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Jeda" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Main" @@ -594,7 +594,7 @@ msgstr "&Main" msgid "&Properties" msgstr "Si&fat" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "Mod Ba&ca-Sahaja" @@ -602,7 +602,7 @@ msgstr "Mod Ba&ca-Sahaja" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Daftar" @@ -620,15 +620,15 @@ msgid "&Rename symbol" msgstr "&Nama semula simbol" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "T&etap Semula" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Simpan Peta Simbol" @@ -636,7 +636,7 @@ msgstr "&Simpan Peta Simbol" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -644,7 +644,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&Had Kelajuan:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Henti" @@ -652,11 +652,11 @@ msgstr "&Henti" msgid "&Theme:" msgstr "&Tema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "Ala&tan" @@ -670,17 +670,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Lihat" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Tonton" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Laman Sesawang" @@ -692,11 +692,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' tidak ditemui, tiada nama simbol dijana" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' tidak ditemui, mengimbas fungsi umum sebagai ganti" @@ -1115,7 +1115,7 @@ msgid "Accuracy:" msgstr "Ketepatan:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1289,7 +1289,7 @@ msgstr "Tambah..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Alamat" @@ -1528,15 +1528,15 @@ msgstr "Anti-Alias:" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1554,7 +1554,7 @@ msgstr "Tarikh Pemuatapl:" msgid "Apply" msgstr "Laksana" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1661,7 +1661,7 @@ msgstr "Auto-Laras Saiz Tetingkap" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1764,7 +1764,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Sepanduk" @@ -1836,7 +1836,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1874,7 +1874,7 @@ msgstr "" "Mod passthrough Bluetooth dibenarkan, tetapi Dolphin dibina tanpa libusb. " "Mod passthrough tidak dapat digunakan." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "But untuk Dijeda" @@ -1951,7 +1951,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -2013,7 +2013,7 @@ msgstr "" msgid "C Stick" msgstr "Batang C" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2109,7 +2109,7 @@ msgstr "Tidak dapat memulakan Sesi NetPlay ketika permainan masih berlangsung!" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2181,7 +2181,7 @@ msgstr "" msgid "Change &Disc" msgstr "Ubah &Cakera" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Ubah &Cakera..." @@ -2243,7 +2243,7 @@ msgstr "Gelitar Menipu" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Periksa NAND..." @@ -2283,11 +2283,11 @@ msgstr "Pilih satu fail untuk dibuka" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2322,7 +2322,7 @@ msgstr "Pengawal Klasik" msgid "Clear" msgstr "Kosongkan" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2343,7 +2343,7 @@ msgstr "Klon dan &Sunting Kod..." msgid "Close" msgstr "Tutup" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Ko&nfigurasi" @@ -2390,7 +2390,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2427,7 +2427,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2563,7 +2563,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Sahkan bil Berhenti" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2574,7 +2574,7 @@ msgstr "Pengesahan" msgid "Connect" msgstr "Sambung" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Sambung Papan Imbang" @@ -2582,7 +2582,7 @@ msgstr "Sambung Papan Imbang" msgid "Connect USB Keyboard" msgstr "Sambung Papan Kekunci USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Sambung Wii Remote %1" @@ -2602,7 +2602,7 @@ msgstr "Sambung Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Sambung Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Sambung Wii Remote" @@ -2725,7 +2725,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Ketumpuan:" @@ -3053,7 +3053,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Wilayah Semasa" @@ -3249,7 +3249,7 @@ msgstr "" msgid "Default" msgstr "Lalai" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3309,7 +3309,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Peratus Kedalaman:" @@ -3322,7 +3322,7 @@ msgstr "Kedalaman:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Keterangan" @@ -3344,11 +3344,11 @@ msgstr "" msgid "Detect" msgstr "Kesan" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Dwi-teras berketentuan:" @@ -3423,7 +3423,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "Lumpuhkan Had Kelajuan Emulasi" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3431,7 +3431,7 @@ msgstr "" msgid "Disable Fog" msgstr "Lumpuhkan Kabus" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3505,7 +3505,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Anda mahu tambah \"%1\" ke dalam senarai Laluan Permainan?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Anda mahu kosongkan senarai nama simbol?" @@ -3536,17 +3536,17 @@ msgstr "Log FIFO Dolphin (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Fail Peta Dolphin (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3709,7 +3709,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Longgok Audio" @@ -3721,7 +3721,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Longgok Sasaran EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Longgok Bingkai" @@ -3799,7 +3799,7 @@ msgstr "" msgid "Dutch" msgstr "Bahasa Belanda" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "Ke&luar" @@ -3847,7 +3847,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3914,7 +3914,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4067,7 +4067,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4109,7 +4109,7 @@ msgstr "" "Benarkan emulasi Dolby Pro Logic II menggunakan sekeliling 5.1. Bahagian " "belakang tertentu sahaja." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4172,7 +4172,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4257,7 +4257,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Masukkan alamat modul RSO:" @@ -4304,18 +4304,18 @@ msgstr "Masukkan alamat modul RSO:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4456,7 +4456,7 @@ msgstr "" msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Eropah" @@ -4537,7 +4537,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Eskport Semua Simpan Wii" @@ -4552,7 +4552,7 @@ msgstr "" msgid "Export Recording" msgstr "Eksport Rakaman" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Eksport Rakaman..." @@ -4580,7 +4580,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4608,7 +4608,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "Penimbal Bingkai Luaran (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Ekstrak Sijil dari NAND" @@ -4646,7 +4646,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Pemain FIFO" @@ -4664,7 +4664,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4758,7 +4758,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Gagal mengekstrak sijil dari NAND" @@ -4785,18 +4785,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4823,7 +4823,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Gagal memasang tajuk ini ke NAND." @@ -4835,8 +4835,8 @@ msgstr "" "Gagal mendengar pada port %1. Adakah kejadian lain pelayan NetPlay masih " "berjalan?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Gagal memuatkan modul RSO pada %1" @@ -4848,7 +4848,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -5020,19 +5020,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Gagal menyimpan log FIFO." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5080,7 +5080,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5126,7 +5126,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5140,18 +5140,18 @@ msgstr "Maklumat Fail" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Nama Fail" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Saiz Fail" @@ -5666,7 +5666,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID Permainan" @@ -5710,7 +5710,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Tetapan Khusus-Permainan" @@ -5781,7 +5781,7 @@ msgid "Gecko Codes" msgstr "Kod Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5807,7 +5807,7 @@ msgstr "Jana satu Identiti Statistik Baharu" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Nama simbol terjana dari '%1'" @@ -5884,7 +5884,7 @@ msgstr "Hijau Kiri" msgid "Green Right" msgstr "Hijau Kanan" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Paparan Grid" @@ -5959,7 +5959,7 @@ msgstr "Heksadesimal" msgid "Hide" msgstr "Sembunyi" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6243,7 +6243,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Import Sandar NAND BootMii..." @@ -6258,7 +6258,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Import Simpan Wii..." @@ -6365,8 +6365,8 @@ msgstr "Maklumat" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Maklumat" @@ -6375,10 +6375,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Input" @@ -6419,7 +6419,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Pasang WAD..." @@ -6439,7 +6439,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "Titik Henti Arahan" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6502,7 +6502,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Pentafsir (paling perlahan)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6527,7 +6527,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "ID Pemain Tidak Sah" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Alamat modul RSO tidak sah: %1" @@ -6602,11 +6602,11 @@ msgstr "Itali" msgid "Italy" msgstr "Itali" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6614,47 +6614,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6666,11 +6666,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6681,7 +6681,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Jepun" @@ -6740,7 +6740,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Tendang Pemain" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -6885,11 +6885,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Lajur Senarai" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Paparan Senarai" @@ -6905,11 +6905,11 @@ msgstr "" msgid "Load" msgstr "Muat" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Muat Fail Peta &Lain..." @@ -6921,7 +6921,7 @@ msgstr "Muat Tekstur Suai" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Muat Menu Utama GameCube" @@ -7031,19 +7031,19 @@ msgstr "Muat Slot Keadaan 8" msgid "Load State Slot 9" msgstr "Muat Slot Keadaan 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Muat Keadaan dari Fail" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Muat Keadaan dari Slot Terpilih" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Muat Keadaan dari Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Muat Menu Sistem Wii %1" @@ -7055,16 +7055,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "Muat dari Slot Terpilih" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Muat dari Slot %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Muat fail peta" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7072,7 +7072,7 @@ msgstr "" msgid "Load..." msgstr "Muat..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Simbol dimuatkan dari '%1'" @@ -7111,7 +7111,7 @@ msgstr "Log" msgid "Log Configuration" msgstr "Log Konfigurasi" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7191,7 +7191,7 @@ msgstr "Bidak Utama" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Pembuat:" @@ -7208,10 +7208,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7262,7 +7263,7 @@ msgstr "Titik Henti Ingatan" msgid "Memory Card" msgstr "Kad Ingatan" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7351,8 +7352,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7360,7 +7361,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Bayang Monoskopik" @@ -7423,9 +7424,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "Semak NAND" @@ -7434,7 +7436,7 @@ msgstr "Semak NAND" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7460,7 +7462,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7668,7 +7670,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Tiada isu dikesan." @@ -7729,7 +7731,7 @@ msgstr "Tiada" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Tidak Ditetapkan" @@ -7851,7 +7853,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Dokumentasi Atas Talian" @@ -7859,13 +7861,13 @@ msgstr "&Dokumentasi Atas Talian" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7882,7 +7884,7 @@ msgstr "Buka" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7988,11 +7990,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Ma&in Rakaman Input..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8094,7 +8096,7 @@ msgstr "Laluan" msgid "Pause" msgstr "Jeda" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Jeda Dipenghujung Cereka" @@ -8132,7 +8134,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Pencahayaan Per-Piksel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Lakukan Kemaskini Sistem Atas-Talian" @@ -8166,7 +8168,7 @@ msgstr "" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Ambil satu fon nyahpepijat" @@ -8183,7 +8185,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Platform" @@ -8418,7 +8420,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8474,11 +8476,11 @@ msgstr "Analog-R" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "Modul RSO" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8632,7 +8634,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Wilayah" @@ -8730,7 +8732,7 @@ msgstr "Tetap Semula" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8962,11 +8964,11 @@ msgstr "" msgid "START" msgstr "MULA" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Keadaan S&impan" @@ -8989,7 +8991,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -9010,11 +9012,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9076,23 +9078,23 @@ msgstr "Simpan Slot Keadaan 8" msgid "Save State Slot 9" msgstr "Simpan Slot Keadaan 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Simpan Keadaan ke Fail" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Simpan Keadaan ke Slot Terlama" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Simpan Keadaan ke Slot Terpilih" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Simpan Keadaan ke Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Simpan Peta Simbol Sebag&ai..." @@ -9112,11 +9114,11 @@ msgstr "" msgid "Save as..." msgstr "Simpan sebagai..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9127,11 +9129,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Simpan fail peta" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Simpan fail tandatangan" @@ -9139,7 +9141,7 @@ msgstr "Simpan fail tandatangan" msgid "Save to Selected Slot" msgstr "Simpan ke Slot Terpilih" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Simpan ke Slot %1 - %2" @@ -9175,7 +9177,7 @@ msgstr "CkpSkrin" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Gelintar" @@ -9202,7 +9204,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9210,7 +9212,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9247,7 +9249,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9291,7 +9293,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Pilih Slot %1 - %2" @@ -9299,7 +9301,7 @@ msgstr "Pilih Slot %1 - %2" msgid "Select State" msgstr "Pilih Keadaan" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Pilih Slot Keadaan" @@ -9385,7 +9387,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Pilih satu tajuk untuk dipasang ke dalam NAND" @@ -9393,7 +9395,7 @@ msgstr "Pilih satu tajuk untuk dipasang ke dalam NAND" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9410,7 +9412,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Pilih fail kunci (longgok OTP/SEEPROM)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Pilih fail simpan" @@ -9620,11 +9622,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Tunjuk &Log" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Tunjuk Palang Ala&t" @@ -9632,11 +9634,11 @@ msgstr "Tunjuk Palang Ala&t" msgid "Show Active Title in Window Title" msgstr "Tunjuk Tajuk Aktif dalam Tajuk Tetingkap" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Tunjuk Australia" @@ -9649,7 +9651,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Tunjuk ELF/DOL" @@ -9662,7 +9664,7 @@ msgstr "" msgid "Show FPS" msgstr "Tunjuk FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Tunjuk Kiraan Bingkai" @@ -9670,15 +9672,15 @@ msgstr "Tunjuk Kiraan Bingkai" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Tunjuk Perancis" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Tunjuk GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Tunjuk Jerman" @@ -9690,23 +9692,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Tunjuk Paparan Input" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Tunjuk Itali" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Tunjuk Korea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Tunjuk Kiraan Lengah" @@ -9714,7 +9716,7 @@ msgstr "Tunjuk Kiraan Lengah" msgid "Show Language:" msgstr "Tunjuk Bahasa:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Tunjuk K&onfigurasi Log" @@ -9726,7 +9728,7 @@ msgstr "Tunjuk Mesej NetPlay" msgid "Show NetPlay Ping" msgstr "Tunjuk Ping NetPlay" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Tunjuk Belanda" @@ -9734,7 +9736,7 @@ msgstr "Tunjuk Belanda" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Tunjuk PAL" @@ -9747,19 +9749,19 @@ msgstr "Tunjuk PC" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Tunjuk Platform" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Tunjuk Wilayah" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Tunjuk Rusia" @@ -9767,7 +9769,7 @@ msgstr "Tunjuk Rusia" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Tunjuk Sepanyol" @@ -9779,19 +9781,19 @@ msgstr "" msgid "Show Statistics" msgstr "Tunjuk Statistik" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Tunjuk Jam Sistem" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Tunjuk Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Tunjuk USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Tunjuk Tidak Diketahui" @@ -9803,15 +9805,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Tunjuk WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Tunjuk Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Tunjuk Dunia" @@ -9920,7 +9922,7 @@ msgstr "Togol Sisi" msgid "Sideways Wii Remote" msgstr "Wii Remote Sisi" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Pangkalan Data Tandatangan" @@ -10162,7 +10164,7 @@ msgstr "Pengawal Piawai" msgid "Start" msgstr "Mula" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Mula &NetPlay..." @@ -10170,7 +10172,7 @@ msgstr "Mula &NetPlay..." msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Mula Me&rakam Input" @@ -10264,7 +10266,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Mod Stereoskopik 3D:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopi" @@ -10286,7 +10288,7 @@ msgstr "Bidak" msgid "Stop" msgstr "Henti" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Henti Memainkan/Merakam Input" @@ -10357,8 +10359,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Berjaya" @@ -10385,7 +10387,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "Berjaya mengimport fail simpan" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Berjaya mengekstrak sijil dari NAND" @@ -10397,12 +10399,12 @@ msgstr "Berjaya mengekstrak fail." msgid "Successfully extracted system data." msgstr "Berjaya mengekstrak data sistem." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Berjaya memasang tajuk ini ke NAND." @@ -10495,7 +10497,7 @@ msgstr "Nama simbol:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Simbol" @@ -10515,7 +10517,7 @@ msgstr "Segerak Wii Remotes sebenar dan pasangankannya" msgid "Synchronize GPU thread" msgstr "Segerakkan bebenang GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10544,7 +10546,7 @@ msgstr "" msgid "System Language:" msgstr "Bahasa Sistem:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Input TAS" @@ -10557,7 +10559,7 @@ msgstr "Alatan TAS" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10575,7 +10577,7 @@ msgstr "" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Ambil Cekupan Skrin" @@ -10657,7 +10659,7 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -10665,7 +10667,7 @@ msgstr "" "NAND tidak dapat dibaiki. Adalah disarankan menyandar data semasa anda dan " "mula kembali dengan NAND yang baharu." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND telah dibaiki." @@ -10939,6 +10941,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10972,6 +10980,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -11000,7 +11014,7 @@ msgstr "Tiada apa hendak dibuat asal!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11203,7 +11217,7 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -11211,7 +11225,7 @@ msgstr "" "Nilai ini telah ditambah dengan nilai ketumpuan yang ditetapkan dalam " "konfigurasi grafik." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11265,7 +11279,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Tajuk" @@ -11279,7 +11293,7 @@ msgstr "Ke" msgid "To:" msgstr "Ke:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Togol &Skrin Penuh" @@ -11525,7 +11539,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11588,11 +11602,11 @@ msgstr "Imej GC/Wii Tak Mampat (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Buat Asal Muat Keadaan" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Buat Asal Keadaan Simpan" @@ -11612,7 +11626,7 @@ msgstr "" "Menyahpasang WAD akan membuang versi terpasang semasa bagi tajuk ini dari " "NAND tanpa memadam data simpannya. Mahu teruskan?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Amerika Syarikat" @@ -11865,7 +11879,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Guna penimbal kedalaman tunggal untuk kedua-dua belah mata. Diperlukan untuk " @@ -11905,7 +11919,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -12099,7 +12113,7 @@ msgstr "Volum Naik" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "Fail WAD (*.wad)" @@ -12200,7 +12214,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Amaran" @@ -12383,11 +12397,11 @@ msgstr "Wii dan Wii Remote" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Fail simpan Wii (*.bin);;Semua Fail (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12608,6 +12622,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12644,7 +12664,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "auto" @@ -12677,7 +12697,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "pelengkapan-palsu" @@ -12721,7 +12741,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "tiada" diff --git a/Languages/po/nb.po b/Languages/po/nb.po index e911b67b45..7b548b88ab 100644 --- a/Languages/po/nb.po +++ b/Languages/po/nb.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: d1fcc80a35d5442129c384ac221ef98f_d2a8fa7 " ", 2015\n" @@ -330,7 +330,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Om" @@ -351,7 +351,7 @@ msgstr "&Legg til funksjon" msgid "&Add..." msgstr "&Legg til..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Lyd-innstillinger" @@ -359,7 +359,7 @@ msgstr "&Lyd-innstillinger" msgid "&Auto Update:" msgstr "&Autooppdater:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automatisk start" @@ -367,11 +367,11 @@ msgstr "&Automatisk start" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Brytepunkter" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Feilsporer" @@ -379,15 +379,15 @@ msgstr "&Feilsporer" msgid "&Cancel" msgstr "&Avbryt" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Juksekodebehandler" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Se etter oppdateringer..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Tøm symboler" @@ -395,7 +395,7 @@ msgstr "&Tøm symboler" msgid "&Clone..." msgstr "&Dupliser..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Kode" @@ -403,7 +403,7 @@ msgstr "&Kode" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Kontroller-innstillinger" @@ -442,11 +442,11 @@ msgstr "&Rediger kode…" msgid "&Edit..." msgstr "&Rediger..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Løs ut disk" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulering" @@ -466,27 +466,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fil" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Skrift…" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Bilde for bilde" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "%Generer symboler fra" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub-pakkebrønn" @@ -494,15 +494,15 @@ msgstr "&GitHub-pakkebrønn" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Grafikkinnstillinger" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Hjelp" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Innstillinger for &hurtigtaster" @@ -522,7 +522,7 @@ msgstr "" msgid "&Import..." msgstr "&Importer..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -534,7 +534,7 @@ msgstr "&Sett inn blr" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -542,11 +542,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Språk:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "Åpne hurtiglagring" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Last symbolkart" @@ -560,15 +560,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&Lås fast moduler" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Minne" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Film" @@ -576,7 +576,7 @@ msgstr "&Film" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Nettverk" @@ -585,23 +585,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Åpne…" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Innstillinger" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Patch HLE-funksjoner" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pause" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Spill" @@ -609,7 +609,7 @@ msgstr "&Spill" msgid "&Properties" msgstr "&Egenskaper" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Skrivebeskyttet modus" @@ -617,7 +617,7 @@ msgstr "&Skrivebeskyttet modus" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registere" @@ -635,15 +635,15 @@ msgid "&Rename symbol" msgstr "&Gi symbol nytt navn" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Tilbakestill" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Ressurspakke-behandler" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Lagre symbolkart" @@ -651,7 +651,7 @@ msgstr "&Lagre symbolkart" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -659,7 +659,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&Fartsgrense:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "S&topp" @@ -667,11 +667,11 @@ msgstr "S&topp" msgid "&Theme:" msgstr "&Drakt:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Tråder" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Verktøy" @@ -685,17 +685,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "Vi&s" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Se" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Nettside" @@ -707,11 +707,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' ikke funnet, ingen symbolnavn generert" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' ikke funnet, scanner for vanlige funksjoner istedet" @@ -1144,7 +1144,7 @@ msgid "Accuracy:" msgstr "Nøyaktighet:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1318,7 +1318,7 @@ msgstr "Legg til…" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adresse" @@ -1556,15 +1556,15 @@ msgstr "Kantutjevning:" msgid "Any Region" msgstr "Alle regioner" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Legg signatur til" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Føy på til &eksisterende signaturfil..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Legg p&å Singaturfil..." @@ -1582,7 +1582,7 @@ msgstr "Programinnlaster-dato:" msgid "Apply" msgstr "Bruk" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Bruk signaturfil" @@ -1693,7 +1693,7 @@ msgstr "Automatisk justering av vindusstørrelse" msgid "Auto-Hide" msgstr "Gjem automatisk" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Vil du auto-oppdage RSO-moduler?" @@ -1796,7 +1796,7 @@ msgstr "Dårlig verdi angitt." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1868,7 +1868,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Blokkstørrelse" @@ -1906,7 +1906,7 @@ msgstr "" "Blåtann gjennomstrømningsmodus er aktivert, men Dolphin ble bygd uten " "Libusdb. Gjennomstrømmingsmodus kan ikke benyttes." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Start opp i pausemodus" @@ -1983,7 +1983,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Utforsk &NetPlay-sesjoner..." @@ -2045,7 +2045,7 @@ msgstr "" msgid "C Stick" msgstr "C-joystick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "Lag Signatu&rfil..." @@ -2141,7 +2141,7 @@ msgstr "Kan ikke starte en NetPlay-økt mens et spill er aktivt!" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2213,7 +2213,7 @@ msgstr "Sentrer og kalibrer" msgid "Change &Disc" msgstr "Endre &disk" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Endre &disk…" @@ -2276,7 +2276,7 @@ msgstr "Juksekodesøk" msgid "Cheats Manager" msgstr "Juksekodebehandler" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Sjekk NAND..." @@ -2316,11 +2316,11 @@ msgstr "Velg en fil å åpne" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Velg prioritetsinputfil" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Velg andre input fil" @@ -2355,7 +2355,7 @@ msgstr "Klassisk kontroller" msgid "Clear" msgstr "Nullstill" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Tøm mellomlager" @@ -2376,7 +2376,7 @@ msgstr "Klon og &rediger kode..." msgid "Close" msgstr "Lukk" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "&Oppsett" @@ -2423,7 +2423,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Kombiner &to signaturfiler..." @@ -2460,7 +2460,7 @@ msgstr "Komplierer skygger" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Kompresjon" @@ -2596,7 +2596,7 @@ msgstr "Bekreft endring av backend" msgid "Confirm on Stop" msgstr "Bekreft ved stans" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2607,7 +2607,7 @@ msgstr "Bekreftelse" msgid "Connect" msgstr "Koble til" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Koble til balansebrett" @@ -2615,7 +2615,7 @@ msgstr "Koble til balansebrett" msgid "Connect USB Keyboard" msgstr "Koble til USB-tastatur" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Koble til Wii Remote %1" @@ -2635,7 +2635,7 @@ msgstr "Koble til Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Koble til Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Koble til Wii Remote-er" @@ -2764,7 +2764,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Konvergens:" @@ -3092,7 +3092,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Nåværende region" @@ -3288,7 +3288,7 @@ msgstr "" msgid "Default" msgstr "Standard" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Standard Konfigurasjon (Kun Lesing)" @@ -3348,7 +3348,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Dybdeprosent:" @@ -3361,7 +3361,7 @@ msgstr "Dybde:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Beskrivelse" @@ -3383,11 +3383,11 @@ msgstr "Frakoblet" msgid "Detect" msgstr "Finn automatisk" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Deterministisk dobbelkjerne:" @@ -3462,7 +3462,7 @@ msgstr "Slå av EFB VRAM Kopier" msgid "Disable Emulation Speed Limit" msgstr "Skru av hastighetsbegrensning av emulering" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3470,7 +3470,7 @@ msgstr "" msgid "Disable Fog" msgstr "Skru av tåke" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Deaktiver JIT-lager" @@ -3543,7 +3543,7 @@ msgstr "Tillater du at Dolphin samler inn informasjon til Dolphins utviklere?" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Vil du legge til «%1» i listen over spillfilbaner?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Vil du tømme listen over symbolnavn?" @@ -3574,17 +3574,17 @@ msgstr "Dolphin FIFO-Logg (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin Map Fil (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Dolphin-signatur-CSV-fil" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Dolphin-signaturfil" @@ -3749,7 +3749,7 @@ msgstr "Dump &FakeVMEM" msgid "Dump &MRAM" msgstr "Dump &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Dump lyd" @@ -3761,7 +3761,7 @@ msgstr "Dump grunnteksturer" msgid "Dump EFB Target" msgstr "Dump EFB-mål" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Dumping av bilder" @@ -3839,7 +3839,7 @@ msgstr "" msgid "Dutch" msgstr "Nederlandsk" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Avslutt" @@ -3887,7 +3887,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Editor" @@ -3954,7 +3954,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4107,7 +4107,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4149,7 +4149,7 @@ msgstr "" "Aktiver Dolby Pro Logic II-emulering med 5.1 surround. Kun for enkelte " "bakender." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4212,7 +4212,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4297,7 +4297,7 @@ msgstr "Oppgi passord" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Skriv inn RSO-moduladresse:" @@ -4344,18 +4344,18 @@ msgstr "Skriv inn RSO-moduladresse:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4497,7 +4497,7 @@ msgstr "" msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4578,7 +4578,7 @@ msgstr "" msgid "Experimental" msgstr "Eksperimentell" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Eksporter alle Wii-lagringsfiler" @@ -4593,7 +4593,7 @@ msgstr "" msgid "Export Recording" msgstr "Eksporter opptak" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Eksporter opptak…" @@ -4621,7 +4621,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4649,7 +4649,7 @@ msgstr "Ekstern" msgid "External Frame Buffer (XFB)" msgstr "Eksternt bildebuffer (EFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Pakk ut sertifikater fra NAND" @@ -4687,7 +4687,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO-spiller" @@ -4707,7 +4707,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Kunne ikke legge til denne sesjonen i NetPlay-indeksen: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Kunne ikke legge til på signaturfil '%1'" @@ -4801,7 +4801,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "Kunne ikke eksportere følgende lagringsfiler:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Klarte ikke å pakke ut sertifikater fra NAND" @@ -4828,18 +4828,18 @@ msgstr "Kunne ikke finne en eller flere D3D-symboler" msgid "Failed to import \"%1\"." msgstr "Kunne ikke importere \"%1\"." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4866,7 +4866,7 @@ msgid "Failed to install pack: %1" msgstr "Kunne ikke installere pakke: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Klarte ikke å installere denne tittelen til NAND." @@ -4878,8 +4878,8 @@ msgstr "" "Klarte ikke å lytte til port %1. Kjøres det en annen instans av NetPlay-" "tjeneren?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Kunne ikke laste RSO-modul ved %1" @@ -4891,7 +4891,7 @@ msgstr "Kunne ikke laste d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "Kunne ikke laste dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Kunne ikke laste map-fil '%1'" @@ -5068,19 +5068,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Lagring av FIFO-logg mislyktes." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Kunne ikke lagre kodemapping til sti '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Kunne ikke lagre signaturfil '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Kunne ikke lagre symbolkart til sti '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Kunne ikke lagre til signaturfil '%1'" @@ -5128,7 +5128,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Feil" @@ -5174,7 +5174,7 @@ msgstr "Fildetaljer" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Filformat" @@ -5188,18 +5188,18 @@ msgstr "Fil-informasjon" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Filnavn" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Filbane" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Filstørrelse" @@ -5717,7 +5717,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Spill-ID" @@ -5761,7 +5761,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Spill-spesifikke innstillinger" @@ -5832,7 +5832,7 @@ msgid "Gecko Codes" msgstr "Gecko-juksekoder" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5858,7 +5858,7 @@ msgstr "Opprett en ny statistikk-identitet" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Genererte symbolnavn fra '%1'" @@ -5935,7 +5935,7 @@ msgstr "Grønn venstre" msgid "Green Right" msgstr "Grønn høyre" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Rutenettvisning" @@ -6010,7 +6010,7 @@ msgstr "Heksadesimal" msgid "Hide" msgstr "Gjem" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6293,7 +6293,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Importer BootMii NAND sikkerhetskopi..." @@ -6308,7 +6308,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importer Wii-lagringsfil …" @@ -6415,8 +6415,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informasjon" @@ -6425,10 +6425,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Inngang" @@ -6469,7 +6469,7 @@ msgstr "" msgid "Install Update" msgstr "Installer oppdatering" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Installer WAD…" @@ -6489,7 +6489,7 @@ msgstr "Instruksjon" msgid "Instruction Breakpoint" msgstr "Instruksjonsstoppunkt" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instruksjon:" @@ -6552,7 +6552,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Fortolker (tregest)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Fortolkerkjerne" @@ -6577,7 +6577,7 @@ msgstr "Ugyldig Pakke %1 oppgitt: %2" msgid "Invalid Player ID" msgstr "Ugyldig spiller-ID" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Ugyldig RSO-moduladresse: %1" @@ -6652,11 +6652,11 @@ msgstr "Italiensk" msgid "Italy" msgstr "Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT Blokklinking Av" @@ -6664,47 +6664,47 @@ msgstr "JIT Blokklinking Av" msgid "JIT Blocks" msgstr "JIT-blokker" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT Branching Av" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FlytTall Av" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Heltall Av" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LastLagre Flyt Av" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LastLagre Av" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LastLagre Parret Av" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LastLagre lXz Av" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT Ibzx Av" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LastLagre Iwz Av" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Av (JIT Kjerne)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Parret Av" @@ -6716,11 +6716,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT Systemregistre Av" @@ -6731,7 +6731,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japan" @@ -6790,7 +6790,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Spark spiller" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -6939,11 +6939,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "Begrens Klump-opplastningshastighet:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Listekolonner" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Listevisning" @@ -6959,11 +6959,11 @@ msgstr "Lytter" msgid "Load" msgstr "Last" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Last &Dårlig kartfil..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Last &Annen kartfil..." @@ -6975,7 +6975,7 @@ msgstr "Last inn brukerlagde teksturer" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Last inn GameCube-hovedmeny" @@ -7085,19 +7085,19 @@ msgstr "Åpne hurtiglagringsplass nr. 8" msgid "Load State Slot 9" msgstr "Åpne hurtiglagringsplass nr. 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Last inn tilstand fra fil" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Last inn tilstand fra valgt kortplass" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Last inn tilstand fra kortplass" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Last inn Wii-systemmeny %1" @@ -7109,16 +7109,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "Last fra valgt kortplass" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Last inn fra kortplass %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Last kartfil" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7126,7 +7126,7 @@ msgstr "" msgid "Load..." msgstr "Last..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Lastet symboler fra '%1'" @@ -7165,7 +7165,7 @@ msgstr "Logg" msgid "Log Configuration" msgstr "Logg-innstillinger" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Jit-logg Instruksjonsdekning" @@ -7245,7 +7245,7 @@ msgstr "Hoved-joystick" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Skaper" @@ -7262,10 +7262,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Administrer NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7316,7 +7317,7 @@ msgstr "Minne Stoppunkt" msgid "Memory Card" msgstr "Minnekort" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Minnekortbehandler" @@ -7405,8 +7406,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7414,7 +7415,7 @@ msgstr "" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskopiske skygger" @@ -7477,9 +7478,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND-sjekk" @@ -7488,7 +7490,7 @@ msgstr "NAND-sjekk" msgid "NKit Warning" msgstr "NKit-advarsel" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7514,7 +7516,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7722,7 +7724,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Ingen feil har blitt oppdaget." @@ -7786,7 +7788,7 @@ msgstr "Ingen" msgid "North America" msgstr "Nord-Amerika" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Ikke satt" @@ -7908,7 +7910,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Nettbasert &dokumentasjon" @@ -7916,7 +7918,7 @@ msgstr "Nettbasert &dokumentasjon" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -7924,7 +7926,7 @@ msgstr "" "Legg til kun symboler med prefiks:\n" "(Blank for alle symboler)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7941,7 +7943,7 @@ msgstr "Åpne" msgid "Open &Containing Folder" msgstr "Åpne &inneholdende mappe" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -8047,11 +8049,11 @@ msgstr "Andre spill..." msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Spi&ll av inndataopptak…" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8154,7 +8156,7 @@ msgstr "Baner" msgid "Pause" msgstr "Pause" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pause på slutten av filmen" @@ -8192,7 +8194,7 @@ msgstr "Høyeste fart for utgående svingbevegelser." msgid "Per-Pixel Lighting" msgstr "Belysning per piksel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Utfør pålogget systemoppdatering" @@ -8226,7 +8228,7 @@ msgstr "" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Velg en debug-font" @@ -8243,7 +8245,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Plattform" @@ -8483,7 +8485,7 @@ msgstr "Fremdrift" msgid "Public" msgstr "Offentlig" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Tøm spillistehurtiglager" @@ -8539,11 +8541,11 @@ msgstr "Høyre-analog" msgid "READY" msgstr "KLAR" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO-moduler" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO-autooppdaging" @@ -8697,7 +8699,7 @@ msgid "Refreshing..." msgstr "Gjennoppfrisker..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Region" @@ -8795,7 +8797,7 @@ msgstr "Nullstill" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -9027,11 +9029,11 @@ msgstr "SSL-sammenheng" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Lag&ringskode" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Lagre &stadie" @@ -9054,7 +9056,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Lagringsfil Eksport" @@ -9075,11 +9077,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Lagre import" @@ -9141,23 +9143,23 @@ msgstr "Hurtiglagringsplass nr. 8" msgid "Save State Slot 9" msgstr "Hurtiglagringsplass nr. 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Lagre tilstand til fil" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Lagre tilstand til eldste kortplass" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Lagre tilstand til valgt kortplass" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Lagre tilstand til kortplass" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "&Lagre symbolkart som..." @@ -9177,11 +9179,11 @@ msgstr "" msgid "Save as..." msgstr "Lagre som …" -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Lagre kombinert utdatafil som" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9195,11 +9197,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Lagre kartfil" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Lagre signaturfil" @@ -9207,7 +9209,7 @@ msgstr "Lagre signaturfil" msgid "Save to Selected Slot" msgstr "Lagre til valgt kortplass" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Lagre til kortplass %1 - %2" @@ -9242,7 +9244,7 @@ msgstr "SkjDump" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Søk" @@ -9269,7 +9271,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Søk etter en instruks" @@ -9277,7 +9279,7 @@ msgstr "Søk etter en instruks" msgid "Search games..." msgstr "Søk spill..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Søk instruksjon" @@ -9315,7 +9317,7 @@ msgid "Select Dump Path" msgstr "Velg dumpens filbane" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Velg eksportmappe" @@ -9359,7 +9361,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Velg inngang %1 - %2" @@ -9367,7 +9369,7 @@ msgstr "Velg inngang %1 - %2" msgid "Select State" msgstr "Velg tilstand" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Velg kortplass for lagringsstadie" @@ -9453,7 +9455,7 @@ msgstr "" msgid "Select a game" msgstr "Velg et spill" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Velg en tittel å installere til NAND" @@ -9461,7 +9463,7 @@ msgstr "Velg en tittel å installere til NAND" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Velg RSO-moduladressen:" @@ -9478,7 +9480,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Velg nøkkelfil (OTP/SEEPROM dump)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Velg lagringsfil" @@ -9688,11 +9690,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Vis &logg" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Vis &verktøylinje" @@ -9700,11 +9702,11 @@ msgstr "Vis &verktøylinje" msgid "Show Active Title in Window Title" msgstr "Vis aktiv tittel i vindustittel" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Vis Australia" @@ -9717,7 +9719,7 @@ msgstr "Vis nåværende spill på Discord" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Vis ELF/DOL" @@ -9730,7 +9732,7 @@ msgstr "" msgid "Show FPS" msgstr "Vis bildefrekvens (FPS)" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Vis bildeteller" @@ -9738,15 +9740,15 @@ msgstr "Vis bildeteller" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Vis Frankrike" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Vis GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Vis Tyskland" @@ -9758,23 +9760,23 @@ msgstr "Vis golfmodusoverlegg" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Vis inndataskjerm" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Vis Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Vis Korea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Vis lagteller" @@ -9782,7 +9784,7 @@ msgstr "Vis lagteller" msgid "Show Language:" msgstr "Vis språk:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Vis logg&oppsett" @@ -9794,7 +9796,7 @@ msgstr "Vis NetPlay-meldinger" msgid "Show NetPlay Ping" msgstr "Vis NetPlay-ping" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Vis Nederland" @@ -9802,7 +9804,7 @@ msgstr "Vis Nederland" msgid "Show On-Screen Display Messages" msgstr "Vis Skjerm-meldinger" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Vis PAL" @@ -9815,19 +9817,19 @@ msgstr "Vis PC" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Vis plattformer" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Vis regioner" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Vis Russland" @@ -9835,7 +9837,7 @@ msgstr "Vis Russland" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Vis Spania" @@ -9847,19 +9849,19 @@ msgstr "" msgid "Show Statistics" msgstr "Vis statistikker" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Vis systemklokke" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Vis Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Vis USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Vis ukjent" @@ -9871,15 +9873,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Vis WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Vis Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Vis verden" @@ -9988,7 +9990,7 @@ msgstr "Sideveisveksling" msgid "Sideways Wii Remote" msgstr "Sideveis Wii Remote" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Signaturdatabase" @@ -10232,7 +10234,7 @@ msgstr "Forvalgt kontroller" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Start &NetPlay…" @@ -10240,7 +10242,7 @@ msgstr "Start &NetPlay…" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Start inn&dataopptak" @@ -10334,7 +10336,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Stereoskopisk 3D-modus:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopi" @@ -10356,7 +10358,7 @@ msgstr "Joystick" msgid "Stop" msgstr "Stopp" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Stopp avspilling/opptak av inndata" @@ -10427,8 +10429,8 @@ msgstr "Penn" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Vellykket" @@ -10455,7 +10457,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "Eksportering av lagringsfiler var vellykket" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Ekstrahering av sertifikat fra NAND vellykket" @@ -10467,12 +10469,12 @@ msgstr "Ekstrahering av fil vellykket." msgid "Successfully extracted system data." msgstr "Ekstrahering av systemdata vellykket." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Installering av tittelen til NAND var vellykket." @@ -10565,7 +10567,7 @@ msgstr "Symbolnavn:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symboler" @@ -10585,7 +10587,7 @@ msgstr "Synkroniser virkelige Wii-kontrollere og koble dem til" msgid "Synchronize GPU thread" msgstr "Synkroniser GPU-tråd" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10616,7 +10618,7 @@ msgstr "Synkroniserer lagringsdata..." msgid "System Language:" msgstr "Systemspråk:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS-inndata" @@ -10629,7 +10631,7 @@ msgstr "TAS-verktøy" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Etiketter" @@ -10647,7 +10649,7 @@ msgstr "Hale" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Ta skjermbilde" @@ -10729,7 +10731,7 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "Mesterverk-partisjonene mangler." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -10737,7 +10739,7 @@ msgstr "" "NAND kunne ikke repareres. Det er anbefalt å sikkerhetskopiere dine " "nåværende data for deretter å starte med en blank NAND." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND er blitt reparert." @@ -11022,6 +11024,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -11057,6 +11065,12 @@ msgstr "Oppdateringspartisjonen mangler." msgid "The update partition is not at its normal position." msgstr "Oppdateringspartisjonen er ikke ved sin normale posisjon." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -11085,7 +11099,7 @@ msgstr "Det er ingenting å angre!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11309,14 +11323,14 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" "Denne verdien er lagt til konvergeringsverdien satt under grafikkoppsett." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11372,7 +11386,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Tittel" @@ -11386,7 +11400,7 @@ msgstr "Til" msgid "To:" msgstr "Til:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Bruk &fullskjerm" @@ -11634,7 +11648,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11701,11 +11715,11 @@ msgstr "Ukomprimerte GC/Wii bildefiler (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Angre åpning av hurtiglagring" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Angre hurtiglagring" @@ -11725,7 +11739,7 @@ msgstr "" "Å avinstallere WAD-filen vil fjerne den nåværende installerte versjonen av " "denne tittelen fra NAND, uten å slette dens lagringsdata. Fortsett?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "USA" @@ -11978,7 +11992,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "Bruk kun én dybdebuffer for begge øyne. Trengs for noen få spill." @@ -12016,7 +12030,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Brukeroppsett" @@ -12210,7 +12224,7 @@ msgstr "Volum opp" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD-filer (*.wad)" @@ -12311,7 +12325,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Advarsel" @@ -12496,11 +12510,11 @@ msgstr "Wii og Wii-kontroll" msgid "Wii data is not public yet" msgstr "Wii-data er ikke offentlige enda" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii-lagringsfiler (*.bin);;Alle filer (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12723,6 +12737,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12759,7 +12779,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "auto" @@ -12792,7 +12812,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "falsk-utførrelse" @@ -12836,7 +12856,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "ingen" diff --git a/Languages/po/nl.po b/Languages/po/nl.po index ced5d7a3fa..861da4b42c 100644 --- a/Languages/po/nl.po +++ b/Languages/po/nl.po @@ -28,7 +28,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Mike van der Kuijl , 2020-2023\n" "Language-Team: Dutch (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -209,10 +209,12 @@ msgid "" "%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " "hardcore)" msgstr "" +"%1 heeft %2/%3 prestaties ontgrendeld (%4 hardcore) die %5/%6 punten waard " +"zijn (%7 hardcore)" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" -msgstr "" +msgstr "%1 heeft %2/%3 prestaties ontgrendeld die %4/%5 punten waard zijn" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" @@ -234,7 +236,7 @@ msgstr "%1 ms" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 msgid "%1 points" -msgstr "" +msgstr "%1 punten" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" @@ -345,7 +347,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Over" @@ -366,7 +368,7 @@ msgstr "&Functie toevoegen" msgid "&Add..." msgstr "&Toevoegen..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Geluidsinstellingen" @@ -374,7 +376,7 @@ msgstr "&Geluidsinstellingen" msgid "&Auto Update:" msgstr "&Automatisch Bijwerken:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automatische Start" @@ -382,11 +384,11 @@ msgstr "&Automatische Start" msgid "&Borderless Window" msgstr "&Randloos venster" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Breekpunten" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Bug-tracker" @@ -394,15 +396,15 @@ msgstr "&Bug-tracker" msgid "&Cancel" msgstr "&Annuleren" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Cheats Beheer" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Controleer op updates..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "Symbolen &wissen" @@ -410,7 +412,7 @@ msgstr "Symbolen &wissen" msgid "&Clone..." msgstr "&Klonen…" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Code" @@ -418,7 +420,7 @@ msgstr "&Code" msgid "&Connected" msgstr "&Verbonden" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Controllerinstellingen" @@ -457,11 +459,11 @@ msgstr "Code &bewerken…" msgid "&Edit..." msgstr "&Bewerken…" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "Schijf &uitwerpen" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulatie" @@ -481,27 +483,27 @@ msgstr "State &exporteren…" msgid "&Export as .gci..." msgstr "Als .gci exporteren…" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Bestand" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Lettertype..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Frame Voorwaarts" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "&Vrije-kijk-instellingen" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "Symbolen &genereren van" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub-repository" @@ -509,15 +511,15 @@ msgstr "&GitHub-repository" msgid "&Go to start of function" msgstr "&Ga naar het begin van de functie" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Grafische instellingen" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Hulp" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Sneltoetsinstellingen" @@ -537,7 +539,7 @@ msgstr "State &importeren…" msgid "&Import..." msgstr "&Importeren…" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "&Infinity Base" @@ -549,7 +551,7 @@ msgstr "Blr …invoegen" msgid "&Interframe Blending" msgstr "&Interframe Menging" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -557,11 +559,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Taal:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "State &laden" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "Symbol-map &laden" @@ -575,15 +577,15 @@ msgstr "&Laad bestand naar huidig adres" msgid "&Lock Watches" msgstr "&Vergrendel Watches" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&Vergrendel Widgets op hun Plaats" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Geheugen" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Opname" @@ -591,7 +593,7 @@ msgstr "&Opname" msgid "&Mute" msgstr "&Dempen" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Netwerk" @@ -600,23 +602,23 @@ msgid "&No" msgstr "&Nee" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Openen…" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opties" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Patch HLE Functies" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pauze" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Spelen" @@ -624,7 +626,7 @@ msgstr "&Spelen" msgid "&Properties" msgstr "&Eigenschappen" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Alleen-lezen-modus" @@ -632,7 +634,7 @@ msgstr "&Alleen-lezen-modus" msgid "&Refresh List" msgstr "Lijst &verversen" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registers" @@ -650,15 +652,15 @@ msgid "&Rename symbol" msgstr "&Symbool hernoemen" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Resetten" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Resource Pack Beheer" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Symbol-map opslaan" @@ -666,7 +668,7 @@ msgstr "&Symbol-map opslaan" msgid "&Scan e-Reader Card(s)..." msgstr "&Scan e-Reader Kaart(en)..." -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "&Skylanders Portal" @@ -674,7 +676,7 @@ msgstr "&Skylanders Portal" msgid "&Speed Limit:" msgstr "&Snelheidslimiet:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Stoppen" @@ -682,11 +684,11 @@ msgstr "&Stoppen" msgid "&Theme:" msgstr "&Thema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Threads" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Gereedschap" @@ -700,17 +702,17 @@ msgstr "&ROM ontladen" msgid "&Unlock Watches" msgstr "Watches &ontgrendelen" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Weergave" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Watch" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Website" @@ -722,11 +724,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Ja" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' niet gevonden, geen symboolnamen gegenereerd" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' niet gevonden, in plaats daarvan zoeken naar algemene functies" @@ -1176,7 +1178,7 @@ msgid "Accuracy:" msgstr "Nauwkeurigheid:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "Prestaties" @@ -1367,7 +1369,7 @@ msgstr "Toevoegen..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adres" @@ -1623,15 +1625,15 @@ msgstr "Anti-Aliasing:" msgid "Any Region" msgstr "Elke Regio" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Voeg Signatuur toe aan" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Toevoegen aan &Bestaand Signatuurbestand..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "P&as Signatuur Toe..." @@ -1651,7 +1653,7 @@ msgstr "Apploader Datum:" msgid "Apply" msgstr "Toepassen" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Pas signatuurbestand toe..." @@ -1764,7 +1766,7 @@ msgstr "Venstergrootte automatisch aanpassen" msgid "Auto-Hide" msgstr "Automatisch Verbergen" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Auto-detect RSO module?" @@ -1872,7 +1874,7 @@ msgstr "Verkeerde waarde opgegeven." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1946,7 +1948,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Blokgrootte" @@ -1984,7 +1986,7 @@ msgstr "" "Bluetooth passthrough modus staat aan, maar Dolphin is gecompileerd zonder " "libusb. Passthrough mode kan niet gebruikt worden." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Opstarten naar Pauze" @@ -2061,7 +2063,7 @@ msgstr "Breedbandadapterfout" msgid "Broadband Adapter MAC Address" msgstr "Breedbandadapter-MAC-adres" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Blader &NetPlay Sessies...." @@ -2126,7 +2128,7 @@ msgstr "Door:" msgid "C Stick" msgstr "C Stick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "M&aak Signatuurbestand aan..." @@ -2231,7 +2233,7 @@ msgstr "Kan geen NetPlay-sessie starten als spel nog draait!" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2304,7 +2306,7 @@ msgstr "Centreer en Kalibreer" msgid "Change &Disc" msgstr "&Schijf wisselen" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "&Schijf wisselen…" @@ -2380,7 +2382,7 @@ msgstr "Cheat Zoeken" msgid "Cheats Manager" msgstr "Cheats Beheer" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Controleer NAND..." @@ -2420,11 +2422,11 @@ msgstr "Kies een bestand om te openen" msgid "Choose a file to open or create" msgstr "Kies een bestand om te openen of te maken" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Kies een invoerbestand met prioriteit" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Kies een secundair invoerbestand" @@ -2459,7 +2461,7 @@ msgstr "Klassieke Controller" msgid "Clear" msgstr "Legen" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Cache legen" @@ -2480,7 +2482,7 @@ msgstr "Clone en &Wijzig Code..." msgid "Close" msgstr "Sluiten" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Co&nfiguratie" @@ -2527,7 +2529,7 @@ msgstr "Kleur Correctie:" msgid "Color Space" msgstr "Kleurruimte" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Combineer &Twee Signatuurbestanden..." @@ -2571,7 +2573,7 @@ msgstr "Shaders Compileren" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Compressie" @@ -2756,7 +2758,7 @@ msgstr "Backend-wijziging bevestigen" msgid "Confirm on Stop" msgstr "Bevestiging bij Stop" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2767,7 +2769,7 @@ msgstr "Bevestiging" msgid "Connect" msgstr "Verbind" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Verbind Balance Board" @@ -2775,7 +2777,7 @@ msgstr "Verbind Balance Board" msgid "Connect USB Keyboard" msgstr "USB-toetsenbord verbinden" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Verbind Wii-afstandsbediening %1" @@ -2795,7 +2797,7 @@ msgstr "Verbind Wii-afstandsbediening 3" msgid "Connect Wii Remote 4" msgstr "Verbind Wii-afstandsbediening 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Verbind Wii-afstandsbedieningen" @@ -2935,7 +2937,7 @@ msgstr "" msgid "Convergence" msgstr "Convergentie" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Convergentie:" @@ -3299,7 +3301,7 @@ msgstr "" "Kan de prestaties beïnvloeden.

In geval van twijfel " "leeg laten." -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Huidige Regio" @@ -3329,7 +3331,7 @@ msgstr "Aangepaste RTC Opties" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 msgid "Custom:" -msgstr "" +msgstr "Aangepast:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" @@ -3502,7 +3504,7 @@ msgstr "Verlaag Y" msgid "Default" msgstr "Standaard" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Standaardconfiguratie (Alleen-lezen)" @@ -3568,7 +3570,7 @@ msgstr "Verwijder het bestaande bestand '{0}'?" msgid "Depth" msgstr "Diepte" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Dieptepercentage:" @@ -3581,7 +3583,7 @@ msgstr "Diepte:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Beschrijving" @@ -3603,11 +3605,11 @@ msgstr "Ontkoppeld" msgid "Detect" msgstr "Detecteer" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "RSO Module Detecteren" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Deterministische dual-core:" @@ -3682,7 +3684,7 @@ msgstr "Schakel EFB VRAM Kopieën uit" msgid "Disable Emulation Speed Limit" msgstr "Schakel Emulatie Snelheidslimit uit" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Schakel Fastmem uit" @@ -3690,7 +3692,7 @@ msgstr "Schakel Fastmem uit" msgid "Disable Fog" msgstr "Schakel Mist uit" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "JIT-cache uitschakelen" @@ -3782,7 +3784,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Wilt u \"%1\" toevoegen aan de lijst met Spelpaden?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Wilt u de lijst met symboolnamen wissen?" @@ -3813,17 +3815,17 @@ msgstr "Dolphin FIFO Log (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Dolphin Spel Modificatie Voorinstelling " -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin Mapbestand (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Dolphin CSV Signatuurbestand" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Dolphin Signatuurbestand" @@ -3999,7 +4001,7 @@ msgstr "Dump &FakeVMEM" msgid "Dump &MRAM" msgstr "Dump &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Dump Audio" @@ -4011,7 +4013,7 @@ msgstr "Basistexturen dumpen" msgid "Dump EFB Target" msgstr "Dump EFB Doel" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Dump Frames" @@ -4096,7 +4098,7 @@ msgstr "Duur van Tubo-knop los Laten (frames):" msgid "Dutch" msgstr "Nederlands" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "Sl&uiten" @@ -4151,7 +4153,7 @@ msgid "Edit..." msgstr "Bewerk..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Bewerker" @@ -4220,7 +4222,7 @@ msgstr "" "Emuleert de schijfsnelheid van echte hardware. Uitschakelen kan " "instabiliteit veroorzaken. Staat standaard op Aan" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "Geëmuleerde USB Apparaten" @@ -4378,7 +4380,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4423,7 +4425,7 @@ msgstr "" "Activeert Dolby Pro Logic II emulatie met 5.1 surround. Alleen bij bepaalde " "backends." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4512,7 +4514,7 @@ msgstr "" "waarbij de CPU de bottleneck is.

In geval van " "twijfel leeg laten." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4611,7 +4613,7 @@ msgstr "Voer wachtwoord in" msgid "Enter the DNS server to use:" msgstr "Voer de te gebruiken DNS-server in:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Voer adres van de RSO-module in:" @@ -4658,18 +4660,18 @@ msgstr "Voer adres van de RSO-module in:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4816,7 +4818,7 @@ msgstr "Er zijn fouten gevonden in {0} ongebruikte blokken in de {1} partitie." msgid "Euphoria" msgstr "Euforie" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4913,7 +4915,7 @@ msgstr "Verwachtte naam van variabele." msgid "Experimental" msgstr "Experimenteel" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exporteer alle Wii Saves" @@ -4928,7 +4930,7 @@ msgstr "Exporteren Mislukt" msgid "Export Recording" msgstr "Exporteer Opname" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exporteer Opname..." @@ -4956,7 +4958,7 @@ msgstr "Exporteer als .&gcs..." msgid "Export as .&sav..." msgstr "Exporteer als .&sav..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4984,7 +4986,7 @@ msgstr "Extern" msgid "External Frame Buffer (XFB)" msgstr "Externe Frame Buffer (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Certificaten uitpakken van NAND" @@ -5022,7 +5024,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO Speler" @@ -5042,7 +5044,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Kon deze sessie niet aan de NetPlay index toe voegen: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Kon signatuurbestand niet toevoegen aan bestand '%1'" @@ -5142,7 +5144,7 @@ msgstr "Exporteren van %n van de %1 save bestand(en) is mislukt." msgid "Failed to export the following save files:" msgstr "Kon de volgende save bestanden niet exporteren:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Kon geen certificaten uitpakken van NAND" @@ -5172,14 +5174,14 @@ msgstr "Kon één of meerdere D3D symbolen niet vinden" msgid "Failed to import \"%1\"." msgstr "Kon \"%1\" niet importeren." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Save bestand importeren mislukt. Start het spel eerst en probeer het dan " "opnieuw." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5187,7 +5189,7 @@ msgstr "" "Save bestand importeren mislukt. Het bestand lijkt beschadigd te zijn of is " "geen geldige Wii-save." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5220,7 +5222,7 @@ msgid "Failed to install pack: %1" msgstr "Het is niet gelukt om het pakket te installeren: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Kon deze titel niet installeren op de NAND." @@ -5232,8 +5234,8 @@ msgstr "" "Luisteren naar poort %1 mislukt. Is er nog een exemplaar van de NetPlay-" "server actief?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Kon RSO-module op %1 niet laden" @@ -5245,7 +5247,7 @@ msgstr "Kon d3d11.dll niet laden" msgid "Failed to load dxgi.dll" msgstr "Kon dxgi.dll niet laden" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Kon mapbestand'%1' niet laden" @@ -5435,19 +5437,19 @@ msgstr "Kon NetPlay omleid map niet resetten. Controleer uw schrijfrechten." msgid "Failed to save FIFO log." msgstr "Kon FIFO log niet opslaan." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Kon code map niet opslaan naar pad '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Kon signatuurbestand '%1' niet opslaan" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Kon symbool map niet opslaan naar pad '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Kon niet opslaan naar signatuurbestand '%1'" @@ -5497,7 +5499,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Gefaald" @@ -5545,7 +5547,7 @@ msgstr "Bestand Details" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Bestandsformaat" @@ -5559,18 +5561,18 @@ msgstr "Bestandsinfo" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Bestandsnaam" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Bestandspad" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Bestandsgrootte" @@ -6114,7 +6116,7 @@ msgstr "Game Boy Advance aan Poort %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 msgid "Game Color Space:" -msgstr "" +msgstr "Kleurruimte Spel:" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 msgid "Game Config" @@ -6134,10 +6136,10 @@ msgstr "Spel Gamma" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 msgid "Game Gamma:" -msgstr "" +msgstr "Gamma Spel:" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Spel ID" @@ -6184,7 +6186,7 @@ msgstr "Spel overschreven door een andere save. Data corruptie {0:#x}, {1:#x}" msgid "Game region does not match" msgstr "Spel regio komt niet overeen" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Spelspecifieke instellingen" @@ -6255,7 +6257,7 @@ msgid "Gecko Codes" msgstr "Gecko Codes" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6281,7 +6283,7 @@ msgstr "Nieuwe statistiekidentiteit genereren" msgid "Generated AR code." msgstr "Gegenereerde AR code." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Gegenereerde symboolnamen van '%1'" @@ -6364,7 +6366,7 @@ msgstr "Groen Links" msgid "Green Right" msgstr "Groen Rechts" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Rasterweergave" @@ -6391,7 +6393,7 @@ msgstr "HDR Papier Wit Nits" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 msgid "HDR Paper White Nits:" -msgstr "" +msgstr "HDR Papier Wit Nits:" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" @@ -6439,7 +6441,7 @@ msgstr "Hexadecimaal" msgid "Hide" msgstr "Verbergen" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Alles verbergen" @@ -6779,7 +6781,7 @@ msgstr "" "vloeiend en vermindert prestaties enigszins.

In " "geval van twijfel leeg laten." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "BootMii-NAND-back-up importeren…" @@ -6794,7 +6796,7 @@ msgstr "Importeren mislukt" msgid "Import Save File(s)" msgstr "Save-bestand(en) importeren" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Wii-save importeren…" @@ -6908,8 +6910,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informatie" @@ -6918,10 +6920,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Schermbeveiliging blokkeren tijdens emulatie" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Invoer" @@ -6962,7 +6964,7 @@ msgstr "Installatiepartitie (%1)" msgid "Install Update" msgstr "Update installeren" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "WAD installeren…" @@ -6982,7 +6984,7 @@ msgstr "Instructie" msgid "Instruction Breakpoint" msgstr "Instructiebreekpunt" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instructie:" @@ -7051,7 +7053,7 @@ msgstr "Interne fout bij het genereren van AR code." msgid "Interpreter (slowest)" msgstr "Interpreter (traagst)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Interpreter-kern" @@ -7076,7 +7078,7 @@ msgstr "Ongeldige Pakket %1 ingevoerd: %2" msgid "Invalid Player ID" msgstr "Ongeldige Speler-ID" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Ongeldig RSO-moduleadres: %1" @@ -7152,11 +7154,11 @@ msgstr "Italiaans" msgid "Italy" msgstr "Italië" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT Block Linking Uit" @@ -7164,47 +7166,47 @@ msgstr "JIT Block Linking Uit" msgid "JIT Blocks" msgstr "JIT Blokken" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "Jit Branch Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FloatingPoint Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Integer Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LoadStore Floating Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LoadStore Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LoadStore Paired Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LoadStore lXz Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT LoadStore lbzx Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LoadStore lwz Uit" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Uit (JIT Core)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Paired Uit" @@ -7216,11 +7218,11 @@ msgstr "JIT Recompiler voor ARM64 (aanbevolen)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "JIT Recompiler voor x86-64 (aanbevolen)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "JIT-registercache uitgeschakld" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT SysteemRegisters Uit" @@ -7234,7 +7236,7 @@ msgstr "" "nooit moeten gebeuren. Meld dit incident alstublieft via de bugtracker. " "Dolphin zal nu afsluiten." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japan" @@ -7293,7 +7295,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Speler kicken" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -7444,11 +7446,11 @@ msgstr "Licht" msgid "Limit Chunked Upload Speed:" msgstr "Beperk chunked-uploadsnelheid:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Lijstkolommen" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Lijstweergave" @@ -7464,11 +7466,11 @@ msgstr "Luisteren" msgid "Load" msgstr "Laden" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Laad &Slechte Mapbestand..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Laad &Ander Mapbestand..." @@ -7480,7 +7482,7 @@ msgstr "Laad Aangepaste Textures" msgid "Load File" msgstr "Laad Bestand" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "GameCube Hoofdmenu Laden" @@ -7590,19 +7592,19 @@ msgstr "Laad State Slot 8" msgid "Load State Slot 9" msgstr "Laad State Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Laad State van Bestand" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Laad State van Geselecteerde Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Laad State van Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Wii-systeemmenu %1 laden" @@ -7614,16 +7616,16 @@ msgstr "Laad en Schrijf Alleen Host Save Data" msgid "Load from Selected Slot" msgstr "Laden van Geselecteerde Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Laad van Slot Slot %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Laad mapbestand" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "Laad vWii Systeem Menu %1" @@ -7631,7 +7633,7 @@ msgstr "Laad vWii Systeem Menu %1" msgid "Load..." msgstr "Laden..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Symbolen geladen van '%1'" @@ -7675,7 +7677,7 @@ msgstr "Log" msgid "Log Configuration" msgstr "Logconfiguratie" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "JIT-instructiedekking loggen" @@ -7758,7 +7760,7 @@ msgstr "Hoofd Stick" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Maker" @@ -7779,10 +7781,11 @@ msgstr "" "mist emulatie rekent.

In geval van twijfel leeg " "laten." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Beheer NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "Handmatige Texture Sampling" @@ -7833,7 +7836,7 @@ msgstr "Geheugenbreekpunt" msgid "Memory Card" msgstr "Geheugenkaart" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Geheugenkaart Beheer" @@ -7934,8 +7937,8 @@ msgstr "" "

Vereist in de meeste gevallen een emulatie reset." "

In geval van twijfel leeg laten." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Module gevonden: %1" @@ -7943,7 +7946,7 @@ msgstr "Module gevonden: %1" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoscopische Schaduwen" @@ -8010,9 +8013,10 @@ msgstr "Vermenigvuldiger" msgid "N&o to All" msgstr "N&ee op Alles" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND-controle" @@ -8021,7 +8025,7 @@ msgstr "NAND-controle" msgid "NKit Warning" msgstr "NKit-waarschuwing" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -8047,7 +8051,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8263,7 +8267,7 @@ msgstr "Er draait geen spel." msgid "No game running." msgstr "Er draait geen spel." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Er zijn geen problemen gedetecteerd." @@ -8327,7 +8331,7 @@ msgstr "Geen" msgid "North America" msgstr "Noord-Amerika" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Niet ingesteld" @@ -8458,7 +8462,7 @@ msgstr "" "voor het uitbreiden van punten en lijnen, selecteert de vertex shader voor " "de taak. Kan de prestatie beïnvloeden.

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Online &Documentatie" @@ -8466,7 +8470,7 @@ msgstr "Online &Documentatie" msgid "Only Show Collection" msgstr "Alleen Collectie Tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8474,7 +8478,7 @@ msgstr "" "Alleen symbolen toevoegen die beginnen met:\n" "(Leeg voor alle symbolen)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8491,7 +8495,7 @@ msgstr "Openen" msgid "Open &Containing Folder" msgstr "&Bijbehorende map openen" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "&Gebruikersmap openen" @@ -8597,11 +8601,11 @@ msgstr "Ander spel..." msgid "Overwritten" msgstr "Overschrijven" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "O&pname Invoer Afspelen..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8703,7 +8707,7 @@ msgstr "Paden" msgid "Pause" msgstr "Pauze" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pauzeer aan het Einde van de Opname" @@ -8745,7 +8749,7 @@ msgstr "Top snelheid van buitenwaartse zwaai beweging." msgid "Per-Pixel Lighting" msgstr "Per-Pixel Belichting" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Voer Online Systeemupdate Uit" @@ -8779,7 +8783,7 @@ msgstr "Fysieke adresruimte" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Kies een debug-lettertype" @@ -8796,7 +8800,7 @@ msgid "Pitch Up" msgstr "Stamp Omhoog" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Platform" @@ -9045,7 +9049,7 @@ msgstr "Voortgang" msgid "Public" msgstr "Openbaar" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Gamelijstcache opschonen" @@ -9102,11 +9106,11 @@ msgstr "R-Analoog" msgid "READY" msgstr "GEREED" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO Modules" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO autodetectie" @@ -9268,7 +9272,7 @@ msgid "Refreshing..." msgstr "Verversen..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Regio" @@ -9371,7 +9375,7 @@ msgstr "Reset" msgid "Reset All" msgstr "Reset Alles" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Reset Negeer Panic Handler" @@ -9579,7 +9583,7 @@ msgstr "SD Sync Map:" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 msgid "SDR Display Gamma Target" -msgstr "" +msgstr "SDR Beeldscherm Gamma Doel" #: Source/Core/Core/HW/GBAPadEmu.h:43 #: Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp:42 @@ -9608,11 +9612,11 @@ msgstr "SSL context" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Code Op&slaan" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "S&la State Op" @@ -9635,7 +9639,7 @@ msgstr "Sla Alles op" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Export Opslaan" @@ -9656,11 +9660,11 @@ msgstr "Spel Opslag" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "Spel Save Bestanden (*.sav);;All Files (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Import Opslaan" @@ -9722,23 +9726,23 @@ msgstr "Save State Slot 8" msgid "Save State Slot 9" msgstr "Save State Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Save State naar Bestand" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Save State naar Oudste Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Save State naar Geselecteerde Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Save State naar Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Sla Symbol Map Op &Als..." @@ -9758,11 +9762,11 @@ msgstr "Opslaan als voorinstelling..." msgid "Save as..." msgstr "Opslaan als..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Gecombineerde uitvoerbestand opslaan als" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9776,11 +9780,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Save in de Zelfde Map als de ROM" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Sla mapbestand op" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Sla signatuurbestand op" @@ -9788,7 +9792,7 @@ msgstr "Sla signatuurbestand op" msgid "Save to Selected Slot" msgstr "Opslaan naar Geselecteerde Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Opslaan naar Slot %1 - %2" @@ -9824,7 +9828,7 @@ msgstr "Schermafdruk" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Zoeken" @@ -9853,7 +9857,7 @@ msgstr "" "Zoeken is momenteel niet mogelijk in de virtuele adresruimte. Laat het spel " "een tijdje draaien en probeer het opnieuw." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Zoek naar Instructie" @@ -9861,7 +9865,7 @@ msgstr "Zoek naar Instructie" msgid "Search games..." msgstr "Zoek Spellen..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Zoek instructie" @@ -9898,7 +9902,7 @@ msgid "Select Dump Path" msgstr "Selecteer Dump Pad" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Selecteer Export Map" @@ -9942,7 +9946,7 @@ msgstr "Selecteer Skylander Collectie" msgid "Select Skylander File" msgstr "Selecteer Skylander Bestand" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Selecteer Slot %1 - %2" @@ -9950,7 +9954,7 @@ msgstr "Selecteer Slot %1 - %2" msgid "Select State" msgstr "Selecteer State" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Selecteer State Slot" @@ -10036,7 +10040,7 @@ msgstr "Selecteer een bestand" msgid "Select a game" msgstr "Selecteer een Spel" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Selecteer een titel om te installeren op de NAND" @@ -10044,7 +10048,7 @@ msgstr "Selecteer een titel om te installeren op de NAND" msgid "Select e-Reader Cards" msgstr "Selecteer e-Reader Kaarten" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Selecteer het RSO module adres:" @@ -10061,7 +10065,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Selecteer het sleutelbestand (OTP/SEEPROM dump)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Selecteer het save bestand" @@ -10306,11 +10310,11 @@ msgstr "Shinkansen Controller" msgid "Show % Speed" msgstr "Snelheidspercentage tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "&Log tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "&Werkbalk tonen" @@ -10318,11 +10322,11 @@ msgstr "&Werkbalk tonen" msgid "Show Active Title in Window Title" msgstr "Actieve game in venstertitel weergeven" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Alles tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Australië tonen" @@ -10335,7 +10339,7 @@ msgstr "Huidig spel op Discord tonen" msgid "Show Disabled Codes First" msgstr "Toon Eerst de Uitgeschakelde Codes" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL tonen" @@ -10348,7 +10352,7 @@ msgstr "Toon Eerst de Ingeschakelde Codes" msgid "Show FPS" msgstr "FPS tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Frameteller tonen" @@ -10356,15 +10360,15 @@ msgstr "Frameteller tonen" msgid "Show Frame Times" msgstr "Frametijden tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Frankrijk tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "GameCube tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Duitsland tonen" @@ -10376,23 +10380,23 @@ msgstr "Golfmodus-overlay tonen" msgid "Show Infinity Base" msgstr "Toon Infinity Base" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Invoerweergave tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Italië tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "JPN tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Korea tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Vertragingsteller tonen" @@ -10400,7 +10404,7 @@ msgstr "Vertragingsteller tonen" msgid "Show Language:" msgstr "Taal tonen:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Log&configuratie tonen" @@ -10412,7 +10416,7 @@ msgstr "NetPlay-berichten tonen" msgid "Show NetPlay Ping" msgstr "NetPlay-ping tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Nederland tonen" @@ -10420,7 +10424,7 @@ msgstr "Nederland tonen" msgid "Show On-Screen Display Messages" msgstr "On-screen-berichtgevingen tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "PAL tonen" @@ -10433,19 +10437,19 @@ msgstr "PC weergeven" msgid "Show Performance Graphs" msgstr "Prestatiegrafieken tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Platforms tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Regio's tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Heropnameteller tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Rusland tonen" @@ -10453,7 +10457,7 @@ msgstr "Rusland tonen" msgid "Show Skylanders Portal" msgstr "Toon Skylanders Portal" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Spanje tonen" @@ -10465,19 +10469,19 @@ msgstr "Snelheidskleuren tonen" msgid "Show Statistics" msgstr "Statistieken tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Systeemklok tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Taiwan tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "VS tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Onbekend tonen" @@ -10489,15 +10493,15 @@ msgstr "VBlank-tijden tonen" msgid "Show VPS" msgstr "VPS tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii tonen" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Wereld tonen" @@ -10631,7 +10635,7 @@ msgstr " Schakel Zijwaarts" msgid "Sideways Wii Remote" msgstr "Wii-afstandsbediening Zijwaarts" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Signatuurdatabase" @@ -10897,7 +10901,7 @@ msgstr "Standaardcontroller" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Start &NetPlay..." @@ -10905,7 +10909,7 @@ msgstr "Start &NetPlay..." msgid "Start New Cheat Search" msgstr "Start Nieuwe Cheat Zoekopdracht" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Start Invoer Op&name" @@ -10999,7 +11003,7 @@ msgstr "Stereoscopische 3D Modus" msgid "Stereoscopic 3D Mode:" msgstr "Stereoscopische 3D Modus:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoscopie" @@ -11021,7 +11025,7 @@ msgstr "Stick" msgid "Stop" msgstr "Stoppen" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Afspelen/opnemen van invoer stoppen" @@ -11102,8 +11106,8 @@ msgstr "Stylus" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Geslaagd" @@ -11130,7 +11134,7 @@ msgstr "Exporteren van %n van de %1 save bestand(en) gelukt." msgid "Successfully exported save files" msgstr "Save bestanden succesvol geëxporteerd" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Certificaten succesvol uitgepakt van NAND" @@ -11142,12 +11146,12 @@ msgstr "Bestand succesvol uitgepakt." msgid "Successfully extracted system data." msgstr "Systeemdata succesvol uitgepakt." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Save bestand succesvol geïmporteerd." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Titel succesvol geïnstalleerd op de NAND." @@ -11248,7 +11252,7 @@ msgstr "Symboolnaam:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symbolen" @@ -11268,7 +11272,7 @@ msgstr "Echte Wii-afstandsbedieningen synchroniseren en paren" msgid "Synchronize GPU thread" msgstr "Synchroniseer GPU thread" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11301,7 +11305,7 @@ msgstr "Synchroniseren van save data..." msgid "System Language:" msgstr "Systeemtaal:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS-invoer" @@ -11314,7 +11318,7 @@ msgstr "TAS-gereedschap" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Tags" @@ -11332,7 +11336,7 @@ msgstr "Staart" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Maak Screenshot" @@ -11418,7 +11422,7 @@ msgstr "Het IPL bestand is geen bekende goede dump. (CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "De Masterpiece partities ontbreken." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11426,7 +11430,7 @@ msgstr "" "De NAND kon niet worden gerepareerd. Het wordt aanbevolen om een back-up te " "maken van uw huidige gegevens en opnieuw te beginnen met een nieuwe NAND." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "De NAND is gerepareerd." @@ -11766,6 +11770,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "Het opgegeven bestand \"{0}\" bestaat niet" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "De doelgeheugenkaart bevat al een bestand \"% 1\"." @@ -11799,6 +11809,12 @@ msgstr "De updatepartitie ontbreekt." msgid "The update partition is not at its normal position." msgstr "De updatepartitie staat niet op zijn normale positie." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "De {0} partitie heeft geen geldig bestandssysteem. " @@ -11829,7 +11845,7 @@ msgstr "" "Er is een probleem opgetreden bij het toevoegen van een snelkoppeling aan " "het bureaublad." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -12077,7 +12093,7 @@ msgstr "" "\n" "Onbekende ucode (CRC = {0:08x}) - AXWii wordt geforceerd." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -12085,7 +12101,7 @@ msgstr "" "Deze waarde wordt toegevoegd aan de gekozen convergentie waarde in de " "grafische instellingen." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -12148,7 +12164,7 @@ msgstr "Timed Out" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Titel" @@ -12162,7 +12178,7 @@ msgstr "Naar" msgid "To:" msgstr "Naar:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "&Volledig scherm omschakelen" @@ -12423,7 +12439,7 @@ msgstr "" "het shadercompilatie met minimale impact op de prestaties, maar de " "resultaten zijn afhankelijk van het gedrag van video-stuurprogramma's." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Kan RSO-module niet automatisch detecteren" @@ -12491,11 +12507,11 @@ msgstr "Ongecomprimeerde GC/Wii-afbeeldingen (*.iso *.gcm)" msgid "Undead" msgstr "Ondood" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Laad State Ongedaan Maken" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Save State Ongedaan Maken" @@ -12516,7 +12532,7 @@ msgstr "" "van deze titel uit de NAND, zonder dat zijn save data wordt verwijderd. " "Doorgaan?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Verenigde Staten" @@ -12624,19 +12640,19 @@ msgstr "Ontgrendel Cursor" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 msgid "Unlocked" -msgstr "" +msgstr "Ontgrendeld" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 msgid "Unlocked %1 times this session" -msgstr "" +msgstr "%1 keer ontgrendeld deze sessie" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 msgid "Unlocked (Casual)" -msgstr "" +msgstr "Ontgrendeld (Casual)" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 msgid "Unlocked this session" -msgstr "" +msgstr "Deze sessie ontgrendeld" #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" @@ -12786,7 +12802,7 @@ msgstr "" "compatibel met handmatige texturesampling.

In geval " "van twijfel leeg laten." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "Gebruik één dieptebuffer voor beide ogen. Nodig voor een paar spellen." @@ -12845,7 +12861,7 @@ msgstr "" "U kunt gebruik blijven maken van 'Code is niet uitgevoerd'/ 'Code is " "uitgevoerd' om de resultaten te beperken." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Gebruikersconfiguratie" @@ -13053,7 +13069,7 @@ msgstr "Volume Omhoog" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD bestanden (*.wad)" @@ -13184,7 +13200,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Waarschuwing" @@ -13409,11 +13425,11 @@ msgstr "Wii en Wii-afstandsbediening" msgid "Wii data is not public yet" msgstr "Wii data is nog niet publiek" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii save bestanden (*.bin);;All Files (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "WiiTools Signatuur MEGA Bestand" @@ -13679,6 +13695,12 @@ msgstr "" "Wilt u nu stoppen om het probleem op te lossen?\n" "Als u \"Nee\" kiest, kan het geluid vervormd zijn." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13715,7 +13737,7 @@ msgstr "uitgelijnd" msgid "any value" msgstr "elke waarde" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "automatisch" @@ -13748,7 +13770,7 @@ msgstr "e-Reader Kaarten (*.raw);;Alle Bestanden (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "fake-completion" @@ -13794,7 +13816,7 @@ msgstr "" "mGBA Save States (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *.ss8 *." "ss9);;Alle Bestanden (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "geen" @@ -13819,7 +13841,7 @@ msgstr "s" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 msgid "sRGB" -msgstr "" +msgstr "sRGB" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" diff --git a/Languages/po/pl.po b/Languages/po/pl.po index 9ca7b87409..0954719bcd 100644 --- a/Languages/po/pl.po +++ b/Languages/po/pl.po @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: FlexBy, 2021,2023\n" "Language-Team: Polish (http://app.transifex.com/delroth/dolphin-emu/language/" @@ -337,7 +337,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&O programie" @@ -358,7 +358,7 @@ msgstr "&Dodaj funkcję" msgid "&Add..." msgstr "&Dodaj..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Ustawienia &audio" @@ -366,7 +366,7 @@ msgstr "Ustawienia &audio" msgid "&Auto Update:" msgstr "&Automatyczna aktualizacja:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automatyczny Start" @@ -374,11 +374,11 @@ msgstr "&Automatyczny Start" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Punkty przerwania" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -386,15 +386,15 @@ msgstr "" msgid "&Cancel" msgstr "&Anuluj" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Sprawdź aktualizacje..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "Wy&czyść Symbole" @@ -402,7 +402,7 @@ msgstr "Wy&czyść Symbole" msgid "&Clone..." msgstr "&Klonuj..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -410,7 +410,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "Ustawienia &kontrolerów" @@ -449,11 +449,11 @@ msgstr "&Edytuj kod..." msgid "&Edit..." msgstr "&Edytuj..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulacja" @@ -473,27 +473,27 @@ msgstr "&Eksportuj Stan..." msgid "&Export as .gci..." msgstr "&Eksportuj jako .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Plik" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Czcionka..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "Wyprzedzanie &klatek" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Generuj Symbole Z" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&Repozytorium GitHub" @@ -501,15 +501,15 @@ msgstr "&Repozytorium GitHub" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Ustawienia &graficzne" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "Po&moc" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Ustawienia &skrótów klawiaturowych" @@ -529,7 +529,7 @@ msgstr "&Importuj Stan..." msgid "&Import..." msgstr "&Importuj..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -541,7 +541,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -549,11 +549,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Język:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Wczytaj stan" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -567,15 +567,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "Pa&mięć" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Film" @@ -583,7 +583,7 @@ msgstr "&Film" msgid "&Mute" msgstr "&Wycisz" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Sieć" @@ -592,23 +592,23 @@ msgid "&No" msgstr "&Nie" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Otwórz..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opcje" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "W&strzymaj" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Graj" @@ -616,7 +616,7 @@ msgstr "&Graj" msgid "&Properties" msgstr "&Właściwości" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Tryb tylko do odczytu" @@ -624,7 +624,7 @@ msgstr "&Tryb tylko do odczytu" msgid "&Refresh List" msgstr "&Odśwież listę" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Rejestry" @@ -642,15 +642,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "Z&resetuj" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -658,7 +658,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -666,7 +666,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "Limit &szybkości:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Zatrzymaj" @@ -674,11 +674,11 @@ msgstr "&Zatrzymaj" msgid "&Theme:" msgstr "&Motyw:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Wątków" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Narzędzia" @@ -692,17 +692,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Widok" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Obejrz" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Strona internetowa" @@ -714,11 +714,11 @@ msgstr "Wi&ki" msgid "&Yes" msgstr "&Tak" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1143,7 +1143,7 @@ msgid "Accuracy:" msgstr "Dokładność:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1317,7 +1317,7 @@ msgstr "Dodaj..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adres" @@ -1557,15 +1557,15 @@ msgstr "Antyaliasing:" msgid "Any Region" msgstr "Jakikolwiek region" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1583,7 +1583,7 @@ msgstr "Data Apploadera:" msgid "Apply" msgstr "Zastosuj" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1690,7 +1690,7 @@ msgstr "Automatycznie dopasuj rozmiar okna" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1793,7 +1793,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Baner" @@ -1865,7 +1865,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1901,7 +1901,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1978,7 +1978,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -2040,7 +2040,7 @@ msgstr "" msgid "C Stick" msgstr "C Gałka" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2137,7 +2137,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2208,7 +2208,7 @@ msgstr "" msgid "Change &Disc" msgstr "Zmień &dysk" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Zmień &dysk..." @@ -2272,7 +2272,7 @@ msgstr "Szukaj cheatów" msgid "Cheats Manager" msgstr "Menadżer cheatów" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2310,11 +2310,11 @@ msgstr "Wybierz plik do otwarcia" msgid "Choose a file to open or create" msgstr "Wybierz plik do otwarcia lub utworzenia" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2349,7 +2349,7 @@ msgstr "Kontroler Klasyczny" msgid "Clear" msgstr "Wyczyść" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Wyczyść pamięć podręczną" @@ -2370,7 +2370,7 @@ msgstr "Sklonuj i &edytuj kod..." msgid "Close" msgstr "Zamknij" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Ko&nfiguracja" @@ -2417,7 +2417,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2454,7 +2454,7 @@ msgstr "Kompilowanie shaderów" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2590,7 +2590,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Potwierdź przy zatrzymaniu" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2601,7 +2601,7 @@ msgstr "Potwierdzenie" msgid "Connect" msgstr "Połącz" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Podłącz Balance Board" @@ -2609,7 +2609,7 @@ msgstr "Podłącz Balance Board" msgid "Connect USB Keyboard" msgstr "Podłącz klawiaturę USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2629,7 +2629,7 @@ msgstr "Połącz Wiilot 3" msgid "Connect Wii Remote 4" msgstr "Połącz Wiilot 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Połącz Wiiloty" @@ -2752,7 +2752,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Konwergencja:" @@ -3076,7 +3076,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Aktualny region" @@ -3272,7 +3272,7 @@ msgstr "" msgid "Default" msgstr "Domyślne" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3332,7 +3332,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3345,7 +3345,7 @@ msgstr "Głębia:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Opis" @@ -3367,11 +3367,11 @@ msgstr "" msgid "Detect" msgstr "Wykryj" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Deterministyczna dwurdzeniowość:" @@ -3446,7 +3446,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "Wyłącz limit szybkości emulacji" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3454,7 +3454,7 @@ msgstr "" msgid "Disable Fog" msgstr "Wyłącz mgłę" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3528,7 +3528,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Czy chcesz wyczyścić listę nazw symboli?" @@ -3559,17 +3559,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3732,7 +3732,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Zrzucaj audio" @@ -3744,7 +3744,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Zrzucaj docelowy EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Zrzucaj klatki" @@ -3822,7 +3822,7 @@ msgstr "" msgid "Dutch" msgstr "Holenderski" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Wyjście" @@ -3870,7 +3870,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Edytor" @@ -3937,7 +3937,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4090,7 +4090,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4132,7 +4132,7 @@ msgstr "" "Włącza emulację Dolby Pro Logic II używając przestrzennego 5.1. Tylko " "niektóre silniki." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4195,7 +4195,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4280,7 +4280,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4327,18 +4327,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4480,7 +4480,7 @@ msgstr "" msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4561,7 +4561,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Eksportuj wszystkie zapisy Wii" @@ -4576,7 +4576,7 @@ msgstr "" msgid "Export Recording" msgstr "Eksportuj nagranie" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Eksportuj nagranie..." @@ -4604,7 +4604,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4632,7 +4632,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "Zewnętrzny bufor klatki (External Frame Buffer - XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Wypakuj certyfikaty z NAND" @@ -4670,7 +4670,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Odtwarzacz FIFO" @@ -4688,7 +4688,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4782,7 +4782,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4809,18 +4809,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4847,7 +4847,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4859,8 +4859,8 @@ msgstr "" "Nasłuch na porcie %1 zakończony niepowodzeniem. Czy jest uruchomiony jakiś " "inny serwer NetPlay?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4872,7 +4872,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -5044,19 +5044,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Nie udało się zapisać log FIFO." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5104,7 +5104,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5150,7 +5150,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5164,18 +5164,18 @@ msgstr "Informacje o pliku" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Nazwa pliku" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Rozmiar pliku" @@ -5688,7 +5688,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID gry" @@ -5732,7 +5732,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Specyficzne ustawienia gry" @@ -5803,7 +5803,7 @@ msgid "Gecko Codes" msgstr "Kody Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5829,7 +5829,7 @@ msgstr "Generuj nową tożsamość" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5906,7 +5906,7 @@ msgstr "Zielony lewo" msgid "Green Right" msgstr "Zielony prawo" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Widok kafelków" @@ -5981,7 +5981,7 @@ msgstr "Heksadecymalne" msgid "Hide" msgstr "Ukryj" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6264,7 +6264,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6279,7 +6279,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importuj zapis Wii..." @@ -6384,8 +6384,8 @@ msgstr "Informacje" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informacja" @@ -6394,10 +6394,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Wejście" @@ -6438,7 +6438,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Zainstaluj WAD..." @@ -6458,7 +6458,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6521,7 +6521,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Interpreter (najwolniejszy)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6546,7 +6546,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6623,11 +6623,11 @@ msgstr "Włoski" msgid "Italy" msgstr "Włochy" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6635,47 +6635,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6687,11 +6687,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6702,7 +6702,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japonia" @@ -6761,7 +6761,7 @@ msgstr "" msgid "Kick Player" msgstr "Wyrzuć gracza" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -6906,11 +6906,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Pokaż kolumny" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Widok listy" @@ -6926,11 +6926,11 @@ msgstr "" msgid "Load" msgstr "Wczytaj" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6942,7 +6942,7 @@ msgstr "Wczytuj dostosowane tekstury" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -7052,19 +7052,19 @@ msgstr "Wczytaj stan Slot 8" msgid "Load State Slot 9" msgstr "Wczytaj stan Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Wczytaj stan z pliku" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Wczytaj stan z wybranego slotu" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Wczytaj stan ze slotu" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -7076,16 +7076,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "Wczytaj z wybranego slotu" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Wczytaj ze slotu Slot %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Wczytaj plik map" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7093,7 +7093,7 @@ msgstr "" msgid "Load..." msgstr "Wczytaj..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7132,7 +7132,7 @@ msgstr "Log" msgid "Log Configuration" msgstr "Konfiguracja logu" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7212,7 +7212,7 @@ msgstr "Główna gałka" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Producent" @@ -7229,10 +7229,11 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7283,7 +7284,7 @@ msgstr "" msgid "Memory Card" msgstr "Karta pamięci" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7368,8 +7369,8 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7377,7 +7378,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskopowe cienie" @@ -7440,9 +7441,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7451,7 +7453,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7477,7 +7479,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7685,7 +7687,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Nie wykryto żadnych problemów" @@ -7744,7 +7746,7 @@ msgstr "Brak" msgid "North America" msgstr "Ameryka Północna" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Nieokreślona" @@ -7866,7 +7868,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Dokumentacja online" @@ -7874,13 +7876,13 @@ msgstr "&Dokumentacja online" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7897,7 +7899,7 @@ msgstr "Otwórz" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -8003,11 +8005,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Odtwórz nagranie wejścia..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8109,7 +8111,7 @@ msgstr "Ścieżki" msgid "Pause" msgstr "Wstrzymaj" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Wstrzymaj na końcu filmu" @@ -8147,7 +8149,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Oświetlenie na piksel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8181,7 +8183,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8198,7 +8200,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Platforma" @@ -8431,7 +8433,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8487,11 +8489,11 @@ msgstr "R-Analog" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8645,7 +8647,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Region" @@ -8743,7 +8745,7 @@ msgstr "Zresetuj" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8975,11 +8977,11 @@ msgstr "" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Z&apisz stan" @@ -9002,7 +9004,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -9023,11 +9025,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9089,23 +9091,23 @@ msgstr "Zapisz stan Slot 8" msgid "Save State Slot 9" msgstr "Zapisz stan Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Zapisz stan do pliku" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Zapisz stan w najstarszym slocie" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Zapisz stan we wybranym slocie" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Zapisz stan w slocie" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9125,11 +9127,11 @@ msgstr "" msgid "Save as..." msgstr "Zapisz jako..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9140,11 +9142,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9152,7 +9154,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "Zapisz we wybranym slocie" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Zapisz w slocie %1 - %2" @@ -9186,7 +9188,7 @@ msgstr "Zrzut ekranu" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Szukaj" @@ -9213,7 +9215,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9221,7 +9223,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9258,7 +9260,7 @@ msgid "Select Dump Path" msgstr "Wybierz ścieżkę zrzutu" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9302,7 +9304,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Wybierz slot %1 - %2" @@ -9310,7 +9312,7 @@ msgstr "Wybierz slot %1 - %2" msgid "Select State" msgstr "Wybierz stan" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Wybierz slot stanu" @@ -9396,7 +9398,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9404,7 +9406,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9421,7 +9423,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Wybierz plik do zapisu" @@ -9631,11 +9633,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Pokaż &log" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Pokaż pasek &narzędzi" @@ -9643,11 +9645,11 @@ msgstr "Pokaż pasek &narzędzi" msgid "Show Active Title in Window Title" msgstr "Pokazuj aktywny tytuł w tytule okna" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Pokaż Australię" @@ -9660,7 +9662,7 @@ msgstr "Pokazuj aktualną grę w programie Discord" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Pokaż ELF/DOL" @@ -9673,7 +9675,7 @@ msgstr "" msgid "Show FPS" msgstr "Pokazuj kl./s" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Pokazuj licznik klatek" @@ -9681,15 +9683,15 @@ msgstr "Pokazuj licznik klatek" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Pokaż Francję" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Pokaż GameCube'a" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Pokaż Niemcy" @@ -9701,23 +9703,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Pokaż wejścia ekranu" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Pokaż Włochy" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Pokaż Koreę" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Pokaż licznik lagów" @@ -9725,7 +9727,7 @@ msgstr "Pokaż licznik lagów" msgid "Show Language:" msgstr "Pokaż język:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Pokaż &konfigurację logu" @@ -9737,7 +9739,7 @@ msgstr "Pokazuj wiadomości NetPlay" msgid "Show NetPlay Ping" msgstr "Pokazuj ping NetPlay" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Pokaż Holandię" @@ -9745,7 +9747,7 @@ msgstr "Pokaż Holandię" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Pokaż PAL" @@ -9758,19 +9760,19 @@ msgstr "Pokaż PC" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Pokaż platformy" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Pokaż regiony" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Pokaż Rosję" @@ -9778,7 +9780,7 @@ msgstr "Pokaż Rosję" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Pokaż Hiszpanię" @@ -9790,19 +9792,19 @@ msgstr "" msgid "Show Statistics" msgstr "Pokazuj statystyki" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Pokaż zegar systemowy" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Pokaż Tajwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Pokaż USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Pokaż nieznane" @@ -9814,15 +9816,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Pokaż WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Pokaż Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Pokaż świat" @@ -9931,7 +9933,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "Wiilot trzymany poziomo" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10173,7 +10175,7 @@ msgstr "Standardowy kontroler" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Uruchom &NetPlay..." @@ -10181,7 +10183,7 @@ msgstr "Uruchom &NetPlay..." msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Rozpocznij nagrywanie wejścia" @@ -10275,7 +10277,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Tryb 3D stereoskopii:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopia" @@ -10297,7 +10299,7 @@ msgstr "Gałka" msgid "Stop" msgstr "Zatrzymaj" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10368,8 +10370,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Powodzenie" @@ -10396,7 +10398,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "Pliki zapisów zostały pomyślnie wyeksportowane" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Certyfikaty z NAND zostały pomyślnie wyodrębnione" @@ -10408,12 +10410,12 @@ msgstr "Plik został pomyślnie wyodrębniony." msgid "Successfully extracted system data." msgstr "Dane systemowe zostały pomyślnie wyodrębnione." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Ten tytuł został pomyślnie zainstalowany do NAND." @@ -10506,7 +10508,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symbole" @@ -10526,7 +10528,7 @@ msgstr "Zsynchronizuj prawdziwe Wiiloty i je sparuj" msgid "Synchronize GPU thread" msgstr "Synchronizuj wątek GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10555,7 +10557,7 @@ msgstr "" msgid "System Language:" msgstr "Język systemu:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Wejście TAS" @@ -10568,7 +10570,7 @@ msgstr "Narzędzia TAS" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10586,7 +10588,7 @@ msgstr "" msgid "Taiwan" msgstr "Tajwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Zrób zrzut ekranu" @@ -10668,13 +10670,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND został naprawiony." @@ -10944,6 +10946,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10975,6 +10983,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -11003,7 +11017,7 @@ msgstr "Nie ma nic do cofnięcia!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11203,7 +11217,7 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -11211,7 +11225,7 @@ msgstr "" "Ta wartość jest dodana do wartości konwergencji ustawionej w konfiguracji " "graficznej." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11265,7 +11279,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Tytuł" @@ -11279,7 +11293,7 @@ msgstr "Do" msgid "To:" msgstr "Do:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Przełącz pełny &ekran" @@ -11525,7 +11539,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11584,11 +11598,11 @@ msgstr "Nieskompresowane obrazy gier GC/Wii (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Cofnij wczytywanie stanu" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Cofnij zapisywanie stanu" @@ -11606,7 +11620,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Stany Zjednoczone" @@ -11857,7 +11871,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "Użyj jednego buforu głębi dla obu oczu. Wymagane dla niektórych gier." @@ -11895,7 +11909,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -12089,7 +12103,7 @@ msgstr "Zwiększ głośność" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "Pliki WAD (*.wad)" @@ -12190,7 +12204,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Ostrzeżenie" @@ -12373,11 +12387,11 @@ msgstr "Wii i Wiilot" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Pliki zapisu Wii (*.bin);Wszystkie pliki (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12594,6 +12608,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12630,7 +12650,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "automatyczna" @@ -12663,7 +12683,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "fałszywe-ukończenie‭‭" @@ -12707,7 +12727,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "żadna" diff --git a/Languages/po/pt.po b/Languages/po/pt.po index e8d1a79000..90160d418d 100644 --- a/Languages/po/pt.po +++ b/Languages/po/pt.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Zilaan , 2011\n" "Language-Team: Portuguese (http://app.transifex.com/delroth/dolphin-emu/" @@ -309,7 +309,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -330,7 +330,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "" @@ -338,7 +338,7 @@ msgstr "" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -346,11 +346,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Pontos de partida" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -358,15 +358,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -374,7 +374,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -382,7 +382,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "" @@ -421,11 +421,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulação" @@ -445,27 +445,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Ficheiro" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Avançar Quadro" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -473,15 +473,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Definições Gráficas" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Ajuda" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Definições de Teclas de Atalho" @@ -501,7 +501,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -513,7 +513,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -521,11 +521,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Carregar Estado" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -539,15 +539,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memória" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "" @@ -555,7 +555,7 @@ msgstr "" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -564,23 +564,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Abrir..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opções" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Começar" @@ -588,7 +588,7 @@ msgstr "&Começar" msgid "&Properties" msgstr "&Propriedades" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "" @@ -596,7 +596,7 @@ msgstr "" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registos" @@ -614,15 +614,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Reset" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -630,7 +630,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -638,7 +638,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Parar" @@ -646,11 +646,11 @@ msgstr "&Parar" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Ferramentas" @@ -664,17 +664,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Ver" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "" @@ -686,11 +686,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1107,7 +1107,7 @@ msgid "Accuracy:" msgstr "Precisão:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1281,7 +1281,7 @@ msgstr "Adicionar..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "" @@ -1510,15 +1510,15 @@ msgstr "Anti-Serrilhamento" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1536,7 +1536,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1643,7 +1643,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1746,7 +1746,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1818,7 +1818,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1854,7 +1854,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1931,7 +1931,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1993,7 +1993,7 @@ msgstr "" msgid "C Stick" msgstr "C Stick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2089,7 +2089,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2160,7 +2160,7 @@ msgstr "" msgid "Change &Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Mudar &Disco..." @@ -2222,7 +2222,7 @@ msgstr "Procura de Cheats" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2260,11 +2260,11 @@ msgstr "Escolha um ficheiro para abrir" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2299,7 +2299,7 @@ msgstr "" msgid "Clear" msgstr "Limpar" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2320,7 +2320,7 @@ msgstr "" msgid "Close" msgstr "Fechar" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2367,7 +2367,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2404,7 +2404,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2540,7 +2540,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Confirmar Ao Parar" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2551,7 +2551,7 @@ msgstr "" msgid "Connect" msgstr "Conectar" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "" @@ -2559,7 +2559,7 @@ msgstr "" msgid "Connect USB Keyboard" msgstr "Conectar Teclado USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2579,7 +2579,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2702,7 +2702,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3022,7 +3022,7 @@ msgid "" "leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3218,7 +3218,7 @@ msgstr "" msgid "Default" msgstr "Padrão" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3278,7 +3278,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3291,7 +3291,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Descrição" @@ -3313,11 +3313,11 @@ msgstr "" msgid "Detect" msgstr "Detectar" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3392,7 +3392,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3400,7 +3400,7 @@ msgstr "" msgid "Disable Fog" msgstr "Desactivar Nevoeiro" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3473,7 +3473,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3504,17 +3504,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3675,7 +3675,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Depositar Áudio" @@ -3687,7 +3687,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Depositar Alvo EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Depositar Quadros" @@ -3765,7 +3765,7 @@ msgstr "" msgid "Dutch" msgstr "Holandês" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "S&air" @@ -3813,7 +3813,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3880,7 +3880,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4033,7 +4033,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4073,7 +4073,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4134,7 +4134,7 @@ msgid "" "" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4219,7 +4219,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4266,18 +4266,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4416,7 +4416,7 @@ msgstr "" msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4497,7 +4497,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exportar Todos os Jogos Guardados Wii" @@ -4512,7 +4512,7 @@ msgstr "" msgid "Export Recording" msgstr "Exportar Gravação" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exportar Gravação..." @@ -4540,7 +4540,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4568,7 +4568,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4606,7 +4606,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Reprodutor FIFO" @@ -4624,7 +4624,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4718,7 +4718,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4745,18 +4745,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4783,7 +4783,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4793,8 +4793,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4806,7 +4806,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4978,19 +4978,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5038,7 +5038,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5084,7 +5084,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5098,18 +5098,18 @@ msgstr "Informação de Ficheiro" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "" @@ -5622,7 +5622,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "" @@ -5666,7 +5666,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Definições específicas por jogo" @@ -5737,7 +5737,7 @@ msgid "Gecko Codes" msgstr "Códigos Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5763,7 +5763,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5840,7 +5840,7 @@ msgstr "Verde Esquerda" msgid "Green Right" msgstr "Verde Direita" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5915,7 +5915,7 @@ msgstr "" msgid "Hide" msgstr "Esconder" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6189,7 +6189,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6204,7 +6204,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6309,8 +6309,8 @@ msgstr "Informação" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informação" @@ -6319,10 +6319,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Entrada" @@ -6363,7 +6363,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6383,7 +6383,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6446,7 +6446,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6471,7 +6471,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6546,11 +6546,11 @@ msgstr "Italiano" msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6558,47 +6558,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6610,11 +6610,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6625,7 +6625,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6684,7 +6684,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6829,11 +6829,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6849,11 +6849,11 @@ msgstr "" msgid "Load" msgstr "Carregar" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6865,7 +6865,7 @@ msgstr "Carregar Texturas Personalizadas" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6975,19 +6975,19 @@ msgstr "Carregar Estado Slot 8" msgid "Load State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6999,16 +6999,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7016,7 +7016,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7055,7 +7055,7 @@ msgstr "Relatório" msgid "Log Configuration" msgstr "Configuração de Relatório" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7135,7 +7135,7 @@ msgstr "Stick Principal" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7152,10 +7152,11 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7206,7 +7207,7 @@ msgstr "" msgid "Memory Card" msgstr "Cartão de memória" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7291,8 +7292,8 @@ msgid "" "unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7300,7 +7301,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7363,9 +7364,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7374,7 +7376,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7400,7 +7402,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7608,7 +7610,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7667,7 +7669,7 @@ msgstr "Nenhum" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Não definido" @@ -7789,7 +7791,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Online e documentação" @@ -7797,13 +7799,13 @@ msgstr "Online e documentação" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7818,7 +7820,7 @@ msgstr "Abrir" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7924,11 +7926,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8030,7 +8032,7 @@ msgstr "Caminhos" msgid "Pause" msgstr "Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8068,7 +8070,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Iluminação por Pixel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8102,7 +8104,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8119,7 +8121,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8350,7 +8352,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8406,11 +8408,11 @@ msgstr "R-Analógico" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8564,7 +8566,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8662,7 +8664,7 @@ msgstr "Reset" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8894,11 +8896,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Gua&rdar Estado" @@ -8921,7 +8923,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8942,11 +8944,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9008,23 +9010,23 @@ msgstr "Guardar Estado Slot 8" msgid "Save State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9044,11 +9046,11 @@ msgstr "" msgid "Save as..." msgstr "Guardar como..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9059,11 +9061,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9071,7 +9073,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9105,7 +9107,7 @@ msgstr "ScrShot" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "" @@ -9132,7 +9134,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9140,7 +9142,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9177,7 +9179,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9221,7 +9223,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9229,7 +9231,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "" @@ -9315,7 +9317,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9323,7 +9325,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9340,7 +9342,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Seleccione o ficheiro de jogo guardado" @@ -9547,11 +9549,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Mostrar &Relatório" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Mostrar Barra de Ferramen&tas" @@ -9559,11 +9561,11 @@ msgstr "Mostrar Barra de Ferramen&tas" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9576,7 +9578,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9589,7 +9591,7 @@ msgstr "" msgid "Show FPS" msgstr "Mostrar FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9597,15 +9599,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Mostrar França" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Mostrar GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9617,23 +9619,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Mostrar visualização de Entradas" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Mostrar Itália" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Mostrar Coreia" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9641,7 +9643,7 @@ msgstr "" msgid "Show Language:" msgstr "Mostrar Idioma:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Mostrar &Configuração de Relatório" @@ -9653,7 +9655,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9661,7 +9663,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Mostrar Pal" @@ -9674,19 +9676,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Mostrar Plataformas" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Mostrar Regiões" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9694,7 +9696,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9706,19 +9708,19 @@ msgstr "" msgid "Show Statistics" msgstr "Mostrar Estatísticas" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Mostrar Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Mostrar EUA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9730,15 +9732,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Mostrar Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9847,7 +9849,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10087,7 +10089,7 @@ msgstr "Comando padrão" msgid "Start" msgstr "Começar" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10095,7 +10097,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10189,7 +10191,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10211,7 +10213,7 @@ msgstr "Stick" msgid "Stop" msgstr "Parar" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10282,8 +10284,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10310,7 +10312,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10322,12 +10324,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10420,7 +10422,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10440,7 +10442,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10469,7 +10471,7 @@ msgstr "" msgid "System Language:" msgstr "Idioma do sistema:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Entrada TAS" @@ -10482,7 +10484,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10500,7 +10502,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Tirar Screenshot" @@ -10582,13 +10584,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10858,6 +10860,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10889,6 +10897,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10917,7 +10931,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11111,13 +11125,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11170,7 +11184,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Título" @@ -11184,7 +11198,7 @@ msgstr "Para" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11430,7 +11444,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11489,11 +11503,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Retroceder Carregamento de Estado" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "" @@ -11511,7 +11525,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11762,7 +11776,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11800,7 +11814,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11994,7 +12008,7 @@ msgstr "" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12095,7 +12109,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Aviso" @@ -12278,11 +12292,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12499,6 +12513,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12535,7 +12555,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12568,7 +12588,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12612,7 +12632,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" diff --git a/Languages/po/pt_BR.po b/Languages/po/pt_BR.po index 0becf1cd41..931289695e 100644 --- a/Languages/po/pt_BR.po +++ b/Languages/po/pt_BR.po @@ -46,7 +46,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Runo , 2013\n" "Language-Team: Portuguese (Brazil) (http://app.transifex.com/delroth/dolphin-" @@ -228,10 +228,12 @@ msgid "" "%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " "hardcore)" msgstr "" +"%1 desbloqueou %2 de %3 conquistas (%4 hardcore) valendo %5 de %6 pontos (%7 " +"hardcore)" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" -msgstr "" +msgstr "%1 desbloqueou %2 de %3 conquistas valendo %4 de %5 pontos" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" @@ -253,7 +255,7 @@ msgstr "%1 ms" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 msgid "%1 points" -msgstr "" +msgstr "%1 pontos" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" @@ -363,7 +365,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Sobre" @@ -384,7 +386,7 @@ msgstr "&Adicionar função" msgid "&Add..." msgstr "&Adicionar..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Configurações de &Som" @@ -392,7 +394,7 @@ msgstr "Configurações de &Som" msgid "&Auto Update:" msgstr "C&anal:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "Início &Automático" @@ -400,11 +402,11 @@ msgstr "Início &Automático" msgid "&Borderless Window" msgstr "Janela Sem &Bordas" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Pontos de Interrupção" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Bug Tracker" @@ -412,15 +414,15 @@ msgstr "&Bug Tracker" msgid "&Cancel" msgstr "&Cancelar" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "Gerenciador de &Cheats" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "Verificar &Atualizações..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Limpar Símbolos" @@ -428,7 +430,7 @@ msgstr "&Limpar Símbolos" msgid "&Clone..." msgstr "&Duplicar..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Código" @@ -436,7 +438,7 @@ msgstr "&Código" msgid "&Connected" msgstr "&Conectado" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "Configurações de &Controles" @@ -475,11 +477,11 @@ msgstr "&Editar Código..." msgid "&Edit..." msgstr "&Editar..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Ejetar Disco" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulação" @@ -499,27 +501,27 @@ msgstr "&Exportar Estado Salvo..." msgid "&Export as .gci..." msgstr "&Exportar como .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Arquivo" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Fonte..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "A&vançar Quadro" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "&Configurações do Olhar Livre" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Gerar Símbolos De" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "Repositório no &GitHub" @@ -527,15 +529,15 @@ msgstr "Repositório no &GitHub" msgid "&Go to start of function" msgstr "&Ir pro início da função" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Configurações de &Gráficos" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "Aj&uda" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Configurações das &Teclas de Atalho" @@ -555,7 +557,7 @@ msgstr "&Importar Estado Salvo..." msgid "&Import..." msgstr "&Importar..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "Base &Infinity" @@ -567,7 +569,7 @@ msgstr "&Inserir blr" msgid "&Interframe Blending" msgstr "&Mistura do Interframe" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -575,11 +577,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Idioma:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "Carregar Estado Salvo" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Carregar o Mapa dos Símbolos" @@ -593,15 +595,15 @@ msgstr "&Carregar o arquivo no endereço atual" msgid "&Lock Watches" msgstr "&Trancar Relógios" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "B&loquear Widgets" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memória" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Gravação" @@ -609,7 +611,7 @@ msgstr "&Gravação" msgid "&Mute" msgstr "Ativar &Mudo" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Rede" @@ -618,23 +620,23 @@ msgid "&No" msgstr "&Não" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "A&brir..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opções" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Funções HLE do Patch" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "P&ausar" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "Inici&ar" @@ -642,7 +644,7 @@ msgstr "Inici&ar" msgid "&Properties" msgstr "&Propriedades" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "Modo &Somente Leitura" @@ -650,7 +652,7 @@ msgstr "Modo &Somente Leitura" msgid "&Refresh List" msgstr "&Atualizar Lista" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registradores" @@ -668,15 +670,15 @@ msgid "&Rename symbol" msgstr "&Renomear Símbolo" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Reiniciar" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "Gerenciador de Pacotes de &Recursos" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Salvar Mapa de Símbolos" @@ -684,7 +686,7 @@ msgstr "&Salvar Mapa de Símbolos" msgid "&Scan e-Reader Card(s)..." msgstr "&Escanear Cartões do e-Reader..." -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "Portal &Skylanders" @@ -692,7 +694,7 @@ msgstr "Portal &Skylanders" msgid "&Speed Limit:" msgstr "&Limite de Velocidade:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Parar" @@ -700,11 +702,11 @@ msgstr "&Parar" msgid "&Theme:" msgstr "&Tema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Threads" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Ferramentas" @@ -718,17 +720,17 @@ msgstr "&Fechar ROM" msgid "&Unlock Watches" msgstr "&Destrancar Relógios" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Visualizar" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "A&ssistir" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Website" @@ -740,11 +742,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Sim" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1\" não foi encontrado, nenhum nome de símbolo foi gerado" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' não foi encontrado, ao invés disto escaneando por funções comuns" @@ -1196,7 +1198,7 @@ msgid "Accuracy:" msgstr "Precisão:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "Conquistas" @@ -1390,7 +1392,7 @@ msgstr "Adicionar..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Endereço" @@ -1648,15 +1650,15 @@ msgstr "Anti-Aliasing:" msgid "Any Region" msgstr "Qualquer Região" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Anexar assinatura a" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Anexar ao &Arquivo de Assinatura Existente..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Apl&icar Arquivo de Assinatura..." @@ -1676,7 +1678,7 @@ msgstr "Data do Apploader:" msgid "Apply" msgstr "Aplicar" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Aplicar arquivo de assinatura" @@ -1789,7 +1791,7 @@ msgstr "Auto-Ajustar o Tamanho da Janela" msgid "Auto-Hide" msgstr "Ocultar Automaticamente" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Auto-detectar os módulos do RSO?" @@ -1898,7 +1900,7 @@ msgstr "Valor ruim fornecido." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1974,7 +1976,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Tamanho do Bloco" @@ -2013,7 +2015,7 @@ msgstr "" "foi compilada sem o libusb. O modo de redirecionamento não pode ser " "utilizado." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Do Início até a Pausa" @@ -2090,7 +2092,7 @@ msgstr "Erro no Adaptador de Banda Larga" msgid "Broadband Adapter MAC Address" msgstr "Endereço MAC do Adaptador de Banda Larga" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Navegar pelas &Sessões do NetPlay..." @@ -2155,7 +2157,7 @@ msgstr "Autor: " msgid "C Stick" msgstr "Eixo C" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "C&riar Arquivo de Assinatura..." @@ -2263,7 +2265,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2337,7 +2339,7 @@ msgstr "Centralizar e Calibrar" msgid "Change &Disc" msgstr "Trocar &Disco" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "&Trocar Disco..." @@ -2411,7 +2413,7 @@ msgstr "Pesquisa de Cheats" msgid "Cheats Manager" msgstr "Gerenciador de Cheats" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Verificar NAND..." @@ -2451,11 +2453,11 @@ msgstr "Abrir" msgid "Choose a file to open or create" msgstr "Escolha um arquivo pra abrir ou criar" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Escolha a prioridade do arquivo de entrada dos dados" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Escolha o arquivo secundário de entrada dos dados" @@ -2490,7 +2492,7 @@ msgstr "Classic Controller" msgid "Clear" msgstr "Limpar" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Limpar Cache" @@ -2511,7 +2513,7 @@ msgstr "Duplicar e &Editar Código..." msgid "Close" msgstr "Fechar" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Co&nfigurações" @@ -2558,7 +2560,7 @@ msgstr "Correção de Cores:" msgid "Color Space" msgstr "Espaço de Cores" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Combinar &Dois Arquivos de Assinatura..." @@ -2602,7 +2604,7 @@ msgstr "Compilando Shaders" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Compressão" @@ -2786,7 +2788,7 @@ msgstr "Confirmar mudança de backend" msgid "Confirm on Stop" msgstr "Confirmar ao Parar" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2797,7 +2799,7 @@ msgstr "Confirmação" msgid "Connect" msgstr "Conectar" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Conectar/Desconectar Balance Board" @@ -2805,7 +2807,7 @@ msgstr "Conectar/Desconectar Balance Board" msgid "Connect USB Keyboard" msgstr "Conectar Teclado USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Wii Remote %1" @@ -2825,7 +2827,7 @@ msgstr "Conectar/Desconectar Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Conectar/Desconectar Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Conectar Wii Remotes" @@ -2901,6 +2903,11 @@ msgid "" "display.

HDR output is required for this setting to take effect." "

If unsure, leave this at 200." msgstr "" +"Controla a luminância de base de uma superfície branca de papel em nits. " +"Útil para se adaptar à diferentes condições de iluminação ambiente ao " +"utilizar uma tela HDR.

'Pós-Processamento HDR' precisa estar ativado " +"para que essa opção tenha efeito.

Na dúvida, " +"mantenha essa opção em 200." #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" @@ -2966,7 +2973,7 @@ msgstr "" msgid "Convergence" msgstr "Convergência" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Convergência:" @@ -3039,6 +3046,17 @@ msgid "" "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" +"Converte as cores dos espaços de cores originalmente utilizados pelo " +"GameCube/Wii para cores correspondentes no espaço sRGB/Rec.709.

Não é " +"possível determinar um espaço de cores exato para todos os jogos, pois " +"diversos padrões existiam na época e muitos jogos não especificavam para " +"qual padrão foram desenvolvidos, logo não é correto assumir um espaço de " +"cores baseado apenas na região do disco. Recomenda-se escolher o espaço de " +"cores que pareça mais natural para você, ou que corresponda à região na qual " +"o jogo foi desenvolvido.

'Pós-Processamento HDR' precisa estar " +"ativado para exibir todo o espaço de cores PAL e NTSC-J." +"

Na dúvida, mantenha essa opção desativada." #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" @@ -3341,7 +3359,7 @@ msgstr "" "

Na dúvida, mantenha essa opção desativada." -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Região Atual" @@ -3371,7 +3389,7 @@ msgstr "Opções do RTC Personalizado" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 msgid "Custom:" -msgstr "" +msgstr "Personalizado:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" @@ -3541,7 +3559,7 @@ msgstr "Diminuir Y" msgid "Default" msgstr "Padrão" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Configuração Padrão (Somente Leitura)" @@ -3607,7 +3625,7 @@ msgstr "Excluir o arquivo existente '{0}'?" msgid "Depth" msgstr "Profundidade" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Porcentagem da Profundidade:" @@ -3620,7 +3638,7 @@ msgstr "Profundidade:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Descrição" @@ -3642,11 +3660,11 @@ msgstr "Separado" msgid "Detect" msgstr "Detectar" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Detectando os Módulos do RSO" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Dual core determinístico:" @@ -3723,7 +3741,7 @@ msgstr "Desativar Cópias VRAM do EFB" msgid "Disable Emulation Speed Limit" msgstr "Desativar Limite de Velocidade" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Desativar Fastmem" @@ -3731,7 +3749,7 @@ msgstr "Desativar Fastmem" msgid "Disable Fog" msgstr "Desativar Névoa" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Desativar Cache do JIT" @@ -3824,7 +3842,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Você quer adicionar '%1' a lista de caminhos dos jogos?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Você quer limpar a lista dos nomes do símbolos?" @@ -3855,17 +3873,17 @@ msgstr "Registro FIFO do Dolphin (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Pré-definição do Mod do Jogo no Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Arquivo do Mapa do Dolphin (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Arquivo CSV de Assinatura do Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Arquivo de Assinatura do Dolphin" @@ -4041,7 +4059,7 @@ msgstr "Exportar &FakeVMEM" msgid "Dump &MRAM" msgstr "Exportar &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Exportar Áudio" @@ -4053,7 +4071,7 @@ msgstr "Exportar Texturas de Base" msgid "Dump EFB Target" msgstr "Exportar Alvo EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Exportar Quadros" @@ -4140,7 +4158,7 @@ msgstr "Duração do Soltar do Botão Turbo (frames):" msgid "Dutch" msgstr "Holandês" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "S&air" @@ -4196,7 +4214,7 @@ msgid "Edit..." msgstr "Editar..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Editor" @@ -4265,7 +4283,7 @@ msgstr "" "Emula a velocidade do disco do hardware original. Desativar essa opção pode " "causar instabilidade. Valor padrão:Ativado" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "Dispositivos USB Emulados" @@ -4323,7 +4341,7 @@ msgstr "Ativar RTC Personalizado" #: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 msgid "Enable Debugging UI" -msgstr "" +msgstr "Ativar Interface de Depuração" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" @@ -4428,7 +4446,7 @@ msgstr "" "jogo está em execução.

Essa opção não tem relação com o status de " "atividade do Discord." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4485,7 +4503,7 @@ msgstr "" "Ativa a emulação do Dolby Pro Logic II utilizando surround de 5.1 canais.\n" "Disponível somente em alguns backends." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4581,7 +4599,7 @@ msgstr "" "de CPU.

Na dúvida, mantenha essa opção desativada." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4681,7 +4699,7 @@ msgstr "Inserir senha" msgid "Enter the DNS server to use:" msgstr "Informe o endereço do servidor DNS:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Insira o endereço do módulo do RSO:" @@ -4728,18 +4746,18 @@ msgstr "Insira o endereço do módulo do RSO:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4882,7 +4900,7 @@ msgstr "Erros foram encontrados em {0} blocos não utilizados da partição {1}. msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4980,7 +4998,7 @@ msgstr "Nome esperado da variável." msgid "Experimental" msgstr "Experimental" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exportar Todos os Dados Salvos do Wii" @@ -4995,7 +5013,7 @@ msgstr "Falha ao Exportar" msgid "Export Recording" msgstr "Exportar Gravação" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exportar Gravação..." @@ -5023,7 +5041,7 @@ msgstr "Exportar como .&gcs..." msgid "Export as .&sav..." msgstr "Exportar como .&sav..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -5051,7 +5069,7 @@ msgstr "IP Externo" msgid "External Frame Buffer (XFB)" msgstr "Frame Buffer Externo (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Extrair Certificados da NAND" @@ -5089,7 +5107,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO Player" @@ -5109,7 +5127,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Falha ao adicionar essa sessão ao indexador do NetPlay: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Falha ao anexar ao arquivo de assinatura '%1'" @@ -5213,7 +5231,7 @@ msgstr "Falha ao exportar %n de %1 arquivo(s) de jogo(s) salvo(s)." msgid "Failed to export the following save files:" msgstr "Falha ao exportar os seguintes dados salvos:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Falha ao extrair os certificados da NAND" @@ -5243,14 +5261,14 @@ msgstr "Falha ao localizar um ou mais símbolos do Direct3D" msgid "Failed to import \"%1\"." msgstr "Falha ao importar \"%1\"." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Falha ao importar o arquivo de dados salvos. Por favor, inicie o jogo " "correspondente pelo menos uma vez, depois tente novamente." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5258,7 +5276,7 @@ msgstr "" "Falha ao importar o arquivo de dados salvos. O arquivo fornecido pode estar " "corrompido ou não contém dados salvos válidos do Wii." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5292,7 +5310,7 @@ msgid "Failed to install pack: %1" msgstr "Falha ao instalar pacote: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Falha ao instalar esse software na NAND." @@ -5304,8 +5322,8 @@ msgstr "" "Falha ao acessar a porta %1. Existe outra instância do servidor NetPlay em " "execução?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Falha ao carregar o módulo RSO em %1" @@ -5317,7 +5335,7 @@ msgstr "Falha ao carregar d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "Falha ao carregar dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Falha ao carregar o arquivo de mapa '%1'" @@ -5516,19 +5534,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Falha ao salvar o log FIFO." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Falha ao salvar o mapa de códigos no local '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Falha ao salvar o arquivo de assinatura '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Falha ao salvar o mapa de símbolos no local '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Falha ao salvar no arquivo de assinatura '%1'" @@ -5578,7 +5596,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Falha" @@ -5626,7 +5644,7 @@ msgstr "Detalhes do Arquivo" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Formato" @@ -5640,18 +5658,18 @@ msgstr "Informações do Arquivo" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Nome do Arquivo" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Local" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Tamanho" @@ -6203,7 +6221,7 @@ msgstr "Game Boy Advance na Porta %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 msgid "Game Color Space:" -msgstr "" +msgstr "Espaço de Cores do Jogo:" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 msgid "Game Config" @@ -6223,10 +6241,10 @@ msgstr "Gama do Jogo" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 msgid "Game Gamma:" -msgstr "" +msgstr "Gama do Jogo:" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID do Jogo" @@ -6275,7 +6293,7 @@ msgstr "" msgid "Game region does not match" msgstr "A região do jogo é diferente" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Configurações Específicas do Jogo" @@ -6346,7 +6364,7 @@ msgid "Gecko Codes" msgstr "Códigos Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6372,7 +6390,7 @@ msgstr "Gerar uma Nova ID de Estatísticas " msgid "Generated AR code." msgstr "Código AR gerado com sucesso." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Nomes de símbolos gerados a partir de '%1'" @@ -6454,7 +6472,7 @@ msgstr "Verde Esquerdo" msgid "Green Right" msgstr "Verde Direito" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Exibição em Grade" @@ -6481,7 +6499,7 @@ msgstr "Branco de Papel HDR (nits)" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 msgid "HDR Paper White Nits:" -msgstr "" +msgstr "Branco do Papel HDR (nits):" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" @@ -6529,7 +6547,7 @@ msgstr "Hexadecimal" msgid "Hide" msgstr "Ocultar" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Ocultar Tudo" @@ -6876,7 +6894,7 @@ msgstr "" "levemente o desempenho.

Na dúvida, mantenha essa " "opção desativada." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Importar Backup da NAND do BootMii..." @@ -6891,7 +6909,7 @@ msgstr "Falha ao Importar" msgid "Import Save File(s)" msgstr "Importar Arquivo(s) de Jogo Salvo" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importar Dados Salvos do Wii..." @@ -7005,8 +7023,8 @@ msgstr "Informações" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informação" @@ -7015,10 +7033,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Desativar Proteção de Tela Durante a Emulação" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Entrada de Dados" @@ -7059,7 +7077,7 @@ msgstr "Partição de Instalação (%1)" msgid "Install Update" msgstr "Instalar Atualização" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Instalar WAD..." @@ -7079,7 +7097,7 @@ msgstr "Instrução" msgid "Instruction Breakpoint" msgstr "Ponto de Interrupção da Instrução" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instrução:" @@ -7148,7 +7166,7 @@ msgstr "Erro interno enquanto gera o código AR." msgid "Interpreter (slowest)" msgstr "Interpretador (muito lento)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Núcleo do Interpretador" @@ -7173,7 +7191,7 @@ msgstr "O pacote %1 fornecido é inválido: %2" msgid "Invalid Player ID" msgstr "ID de Jogador Inválida" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Endereço do módulo do RSO inválido: %1" @@ -7250,11 +7268,11 @@ msgstr "Italiano" msgid "Italy" msgstr "Itália" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "Ligação dos Blocos do JIT Desligado" @@ -7262,47 +7280,47 @@ msgstr "Ligação dos Blocos do JIT Desligado" msgid "JIT Blocks" msgstr "Blocos do JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "Vertente do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "Ponto Flutuante do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "Inteiro do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "LoadStore Flutuante do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "LoadStore do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "LoadStore Emparelhado do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "LoadStore lXz do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "LoadStore lbzx do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "LoadStore lwz do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT Desligado (Núcleo do JIT)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "Emparelhamento do JIT Desligado" @@ -7314,11 +7332,11 @@ msgstr "Recompilador JIT ARM64 (recomendado)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "Recompilador JIT x86-64 (recomendado)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "Registro do Cache do JIT Desligado" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "Registros do Sistema do JIT Desligado" @@ -7332,7 +7350,7 @@ msgstr "" "nunca deveria acontecer. Por favor relate este incidente no bug tracker. O " "Dolphin irá fechar agora." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japão" @@ -7391,7 +7409,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Remover Jogador" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Coréia" @@ -7542,11 +7560,11 @@ msgstr "Luzes" msgid "Limit Chunked Upload Speed:" msgstr "Limitar Velocidade de Envio de Fragmentos:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Selecionar Colunas" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Exibição em Lista" @@ -7562,11 +7580,11 @@ msgstr "Escutando" msgid "Load" msgstr "Carregar" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Carregar o &Arquivo do Mapa Ruim..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Carregar o &Outro Arquivo do Mapa..." @@ -7578,7 +7596,7 @@ msgstr "Carregar Texturas Personalizadas" msgid "Load File" msgstr "Carregar Arquivo" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Carregar Menu Principal do GameCube" @@ -7688,19 +7706,19 @@ msgstr "Carregar do Slot 8" msgid "Load State Slot 9" msgstr "Carregar do Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Carregar do Arquivo..." -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Carregar do Slot Selecionado" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Carregar do Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Carregar Wii System Menu %1" @@ -7712,16 +7730,16 @@ msgstr "Carregar e Armazenar Dados Salvos do Host" msgid "Load from Selected Slot" msgstr "Carregar do Slot Selecionado" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Slot %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Carregar o arquivo do mapa" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "Carregar vWii System Menu %1" @@ -7729,7 +7747,7 @@ msgstr "Carregar vWii System Menu %1" msgid "Load..." msgstr "Carregar..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Símbolos carregados do '%1'" @@ -7775,7 +7793,7 @@ msgstr "Log" msgid "Log Configuration" msgstr "Configurações" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Registrar Cobertura das Instruções do JIT" @@ -7859,7 +7877,7 @@ msgstr "Eixo Principal" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Fabricante" @@ -7881,10 +7899,11 @@ msgstr "" "

Na dúvida, mantenha essa opção desativada." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Gerenciar NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "Amostragem Manual de Texturas" @@ -7935,7 +7954,7 @@ msgstr "Pontos de Interrupção da Memória" msgid "Memory Card" msgstr "Memory Card" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Gerenciador de Memory Cards" @@ -8037,8 +8056,8 @@ msgstr "" "efeito.

Na dúvida, mantenha essa opção desativada." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Módulos achados: %1" @@ -8046,7 +8065,7 @@ msgstr "Módulos achados: %1" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Sombras Monoscópicas" @@ -8115,9 +8134,10 @@ msgstr "Multiplicador" msgid "N&o to All" msgstr "Não para T&odos" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "Verificação da NAND" @@ -8126,7 +8146,7 @@ msgstr "Verificação da NAND" msgid "NKit Warning" msgstr "Aviso sobre o NKit" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -8151,8 +8171,14 @@ msgid "" "match it here.

If unsure, leave this at 2.35." msgstr "" +"NTSC-M e NTSC-J definem o alvo de gama em ~2.2. PAL define o alvo de gama em " +"~2.8.
Nenhum dos dois foi necessariamente seguido pelos jogos, nem pelas " +"TVs.
O alvo 2.35 costuma ser um bom valor genérico para todas as regiões." +"

Se o jogo permite que você escolha o alvo de gama, especifique o " +"mesmo valor aqui.

Na dúvida, mantenha essa opção em " +"2.35." -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8367,7 +8393,7 @@ msgstr "Nenhum jogo está em execução." msgid "No game running." msgstr "Nenhum jogo em execução" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Não foram detectados problemas." @@ -8431,7 +8457,7 @@ msgstr "Nenhum" msgid "North America" msgstr "América do Norte" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Desconhecido" @@ -8562,7 +8588,7 @@ msgstr "" "vértices para expansão de pontos e linhas, utiliza shaders de vértices para " "o trabalho. Pode afetar o desempenho.

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Documentação Online" @@ -8570,7 +8596,7 @@ msgstr "&Documentação Online" msgid "Only Show Collection" msgstr "Mostrar Apenas Coleção" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8578,7 +8604,7 @@ msgstr "" "Só anexar símbolos com o prefixo:\n" "(Em branco pra todos os símbolos)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8595,7 +8621,7 @@ msgstr "Abrir" msgid "Open &Containing Folder" msgstr "Abrir &Local do Arquivo" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "Abrir Pasta do &Usuário" @@ -8701,11 +8727,11 @@ msgstr "Outro jogo..." msgid "Overwritten" msgstr "Sobrescrito" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Reproduzir Gravação de Replay..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8807,7 +8833,7 @@ msgstr "Locais" msgid "Pause" msgstr "Pausar" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "&Pausar no Fim do Replay" @@ -8849,7 +8875,7 @@ msgstr "Velocidade pico dos movimentos de balanço externos." msgid "Per-Pixel Lighting" msgstr "Iluminação Por Pixel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Executar Atualização do Sistema Online" @@ -8883,7 +8909,7 @@ msgstr "Espaço do endereço físico" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Escolha a fonte de depuração" @@ -8900,7 +8926,7 @@ msgid "Pitch Up" msgstr "Pra cima" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Plataforma" @@ -9149,7 +9175,7 @@ msgstr "Progresso" msgid "Public" msgstr "Público" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Limpar Cache da Lista de Jogos" @@ -9207,11 +9233,11 @@ msgstr "R (analógico)" msgid "READY" msgstr "PRONTO" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "Módulos do RSO" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "Auto-detecção do RSO" @@ -9373,7 +9399,7 @@ msgid "Refreshing..." msgstr "Atualizando..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Região" @@ -9476,7 +9502,7 @@ msgstr "Redefinir" msgid "Reset All" msgstr "Resetar Tudo" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Redefinir Ignorar Gerenciadores de Pânico" @@ -9684,7 +9710,7 @@ msgstr "Pasta de Sincronização do SD:" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 msgid "SDR Display Gamma Target" -msgstr "" +msgstr "Alvo de Gama da Tela SDR" #: Source/Core/Core/HW/GBAPadEmu.h:43 #: Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp:42 @@ -9713,11 +9739,11 @@ msgstr "Contexto do SSL" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Sa&lvar Código" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Salvar Estado Salvo" @@ -9740,7 +9766,7 @@ msgstr "Salvar Todos" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Exportar Dados Salvos" @@ -9761,11 +9787,11 @@ msgstr "Jogo Salvo" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "Arquivo de jogo salvo (*.sav);;Todos os arquivos (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Importar Dados Salvos" @@ -9827,23 +9853,23 @@ msgstr "Salvar no Slot 8" msgid "Save State Slot 9" msgstr "Salvar no Slot 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Salvar no Arquivo..." -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Salvar no Slot Mais Antigo" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Salvar no Slot Selecionado" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Salvar no Slot" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Salvar o Mapa dos Símbolos &Como..." @@ -9863,11 +9889,11 @@ msgstr "Salvar como Predefinição..." msgid "Save as..." msgstr "Salvar como..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Salvar o arquivo de saída combinada dos dados como" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9881,11 +9907,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Salvar na Mesma Pasta da ROM" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Salvar o arquivo do mapa" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Salvar o arquivo de assinatura" @@ -9893,7 +9919,7 @@ msgstr "Salvar o arquivo de assinatura" msgid "Save to Selected Slot" msgstr "Salvar no Slot Selecionado" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Slot %1 - %2" @@ -9929,7 +9955,7 @@ msgstr "Screenshot" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Pesquisar" @@ -9958,7 +9984,7 @@ msgstr "" "A busca atualmente não é possível no espaço do endereço virtual. Por favor " "execute o jogo um pouco e tente de novo." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Procurar uma Instrução" @@ -9966,7 +9992,7 @@ msgstr "Procurar uma Instrução" msgid "Search games..." msgstr "Pesquisar jogos..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Procurar instrução" @@ -10005,7 +10031,7 @@ msgid "Select Dump Path" msgstr "Selecione o Caminho do Dump" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Selecione o Diretório de Exportação" @@ -10049,7 +10075,7 @@ msgstr "Selecione a Correção do Skylander" msgid "Select Skylander File" msgstr "Selecione o arquivo do Skylander" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Slot %1 - %2" @@ -10057,7 +10083,7 @@ msgstr "Slot %1 - %2" msgid "Select State" msgstr "Selecionar" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Slot de Estado Salvo" @@ -10143,7 +10169,7 @@ msgstr "Selecione um arquivo" msgid "Select a game" msgstr "Selecione um jogo" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Selecione um título pra instalar no NAND" @@ -10151,7 +10177,7 @@ msgstr "Selecione um título pra instalar no NAND" msgid "Select e-Reader Cards" msgstr "Selecione os Cartões do e-Reader" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Selecione o endereço do módulo do RSO:" @@ -10168,7 +10194,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Selecione o arquivo das chaves (dump do OTP/SEEPROM)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Importar" @@ -10413,11 +10439,11 @@ msgstr "Controle Shinkansen" msgid "Show % Speed" msgstr "Mostrar Velocidade em %" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Mostrar &Log" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Mostrar Barra de &Ferramentas" @@ -10425,11 +10451,11 @@ msgstr "Mostrar Barra de &Ferramentas" msgid "Show Active Title in Window Title" msgstr "Mostrar Software em Execução no Título da Janela" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Mostrar Tudo" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Austrália" @@ -10442,7 +10468,7 @@ msgstr "Mostrar Jogo em Execução no Discord" msgid "Show Disabled Codes First" msgstr "Mostrar Códigos Desativados Primeiro" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL" @@ -10455,7 +10481,7 @@ msgstr "Mostrar Códigos Ativados Primeiro" msgid "Show FPS" msgstr "Mostrar FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Mostrar Contador de Quadros" @@ -10463,15 +10489,15 @@ msgstr "Mostrar Contador de Quadros" msgid "Show Frame Times" msgstr "Mostrar Duração dos Quadros" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "França" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Alemanha" @@ -10483,23 +10509,23 @@ msgstr "Mostrar Sobreposição do Modo Golfe" msgid "Show Infinity Base" msgstr "Mostrar Base Infinity" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Mostrar Entrada de Dados" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Itália" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "Japão" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Coréia" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Mostrar Contador de Lag" @@ -10507,7 +10533,7 @@ msgstr "Mostrar Contador de Lag" msgid "Show Language:" msgstr "Idioma:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Mostrar &Configurações do Log" @@ -10519,7 +10545,7 @@ msgstr "Mostrar Mensagens do NetPlay" msgid "Show NetPlay Ping" msgstr "Mostrar Ping do NetPlay" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Holanda" @@ -10527,7 +10553,7 @@ msgstr "Holanda" msgid "Show On-Screen Display Messages" msgstr "Mostrar Mensagens na Tela" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Europa" @@ -10540,19 +10566,19 @@ msgstr "Mostrar PC" msgid "Show Performance Graphs" msgstr "Mostrar Gráfico de Desempenho" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Mostrar Plataformas" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Mostrar Regiões" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Mostrar Contador de Regravações" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Rússia" @@ -10560,7 +10586,7 @@ msgstr "Rússia" msgid "Show Skylanders Portal" msgstr "Mostrar Portal Skylanders" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Espanha" @@ -10572,19 +10598,19 @@ msgstr "Mostrar Velocidade em Cores" msgid "Show Statistics" msgstr "Exibir Estatísticas" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Mostrar Relógio do Sistema" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Estados Unidos" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Desconhecido" @@ -10596,15 +10622,15 @@ msgstr "Mostrar Duração do VBlank" msgid "Show VPS" msgstr "Mostrar VPS" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Global" @@ -10739,7 +10765,7 @@ msgstr "Alternar Horizontal" msgid "Sideways Wii Remote" msgstr "Wii Remote na Horizontal" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Base de Dados da Assinatura" @@ -11005,7 +11031,7 @@ msgstr "Controle Padrão" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Iniciar &NetPlay..." @@ -11013,7 +11039,7 @@ msgstr "Iniciar &NetPlay..." msgid "Start New Cheat Search" msgstr "Iniciar Nova Pesquisa" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Iniciar Gravação de Replay" @@ -11107,7 +11133,7 @@ msgstr "Modo de Estereoscopia 3D:" msgid "Stereoscopic 3D Mode:" msgstr "Modo de Estereoscopia 3D:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Estereoscopia" @@ -11129,7 +11155,7 @@ msgstr "Eixo" msgid "Stop" msgstr "Parar" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Parar a Reprodução/Gravação de Replay" @@ -11210,8 +11236,8 @@ msgstr "Stylus" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Sucesso" @@ -11238,7 +11264,7 @@ msgstr "%n de %1 arquivo(s) de jogo salvo exportados com sucesso." msgid "Successfully exported save files" msgstr "Arquivos dos saves exportados com sucesso" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Certificados da NAND extraídos com sucesso" @@ -11250,12 +11276,12 @@ msgstr "Arquivo extraído com sucesso." msgid "Successfully extracted system data." msgstr "Dados extraídos do sistema com sucesso." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Arquivo de dados salvos importado com sucesso." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Software instalado na NAND com sucesso." @@ -11356,7 +11382,7 @@ msgstr "Nome do símbolo:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Símbolos" @@ -11376,7 +11402,7 @@ msgstr "Sincronizar os Wii Remotes reais e emparelhá-los" msgid "Synchronize GPU thread" msgstr "Sincronizar thread da GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11409,7 +11435,7 @@ msgstr "Sincronizando dados salvos..." msgid "System Language:" msgstr "Idioma do Sistema:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Entrada de Dados TAS" @@ -11422,7 +11448,7 @@ msgstr "Ferramentas de TAS" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Etiquetas" @@ -11440,7 +11466,7 @@ msgstr "Cauda" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Capturar Tela" @@ -11507,6 +11533,12 @@ msgid "" "\n" "Do you really want to switch to Direct3D 11? If unsure, select 'No'." msgstr "" +"O renderizador do Direct3D 11 exige o suporte de alguns recursos não " +"compatíveis com a configuração do seu sistema. Você ainda pode utilizar este " +"backend, mas encontrará defeitos gráficos em alguns jogos.\n" +"\n" +"Tem certeza de que deseja trocar para o Direct3D 11? Na dúvida, selecione " +"'Não'." #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." @@ -11528,7 +11560,7 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "As partições das Masterpieces estão ausentes." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11536,7 +11568,7 @@ msgstr "" "A NAND não pôde ser reparada. É recomendável fazer backup dos dados salvos " "atuais e recomeçar do zero com uma NAND limpa." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "A NAND foi reparada." @@ -11872,6 +11904,12 @@ msgstr "O índice de chave comum especificado é {0}, mas deveria ser {1}." msgid "The specified file \"{0}\" does not exist" msgstr "O arquivo especificado \"{0}\" não existe" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "O memory card alvo já contém um arquivo: \"%1\"." @@ -11905,6 +11943,12 @@ msgstr "A partição de atualização está ausente." msgid "The update partition is not at its normal position." msgstr "A partição de atualização não está em sua posição normal." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "A partição {0} não contém um sistema de arquivos válido." @@ -11933,7 +11977,7 @@ msgstr "Nào há nada para desfazer!" msgid "There was an issue adding a shortcut to the desktop" msgstr "Houve um problema ao adicionar um atalho na área de trabalho" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -12184,7 +12228,7 @@ msgstr "" "\n" "DSPHLE: uCode desconhecido (CRC = {0:08x}) - forçando AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -12192,7 +12236,7 @@ msgstr "" "Esse valor é somado com o valor de convergência definido nas configurações " "gráficas." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -12255,7 +12299,7 @@ msgstr "Tempo Esgotado" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Título" @@ -12269,7 +12313,7 @@ msgstr "Até" msgid "To:" msgstr "Até:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "Alternar &Tela Cheia" @@ -12531,7 +12575,7 @@ msgstr "" "compilação de shaders com um impacto mínimo no desempenho, mas os resultados " "dependem do comportamento do driver de vídeo." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Incapaz de auto-detectar o módulo do RSO" @@ -12599,11 +12643,11 @@ msgstr "Imagens do GC/Wii sem compressão (*.iso *.gcm)" msgid "Undead" msgstr "Morto-Vivo" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Desfazer Carregamento" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Desfazer Estado Salvo" @@ -12623,7 +12667,7 @@ msgstr "" "Desinstalar o WAD removerá a versão atualmente instalada desse software da " "NAND, sem excluir seus dados salvos. Continuar?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "Estados Unidos" @@ -12730,19 +12774,19 @@ msgstr "Destravar Cursor" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 msgid "Unlocked" -msgstr "" +msgstr "Desbloqueada" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 msgid "Unlocked %1 times this session" -msgstr "" +msgstr "Desbloqueada %1 vezes nesta sessão" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 msgid "Unlocked (Casual)" -msgstr "" +msgstr "Desbloqueada (Casual)" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 msgid "Unlocked this session" -msgstr "" +msgstr "Desbloqueada nesta sessão" #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" @@ -12894,7 +12938,7 @@ msgstr "" "de texturas.

Na dúvida, mantenha essa opção " "desativada." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Usar um único buffer de profundidade para os dois olhos. Necessário em " @@ -12953,7 +12997,7 @@ msgstr "" "Você pode continuar a usar 'O código não foi executado'/'O código foi " "executado' pra reduzir os resultados." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Configuração do Usuário" @@ -13161,7 +13205,7 @@ msgstr "Aumentar Volume" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "Arquivos WAD (*.wad)" @@ -13298,7 +13342,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Aviso" @@ -13526,11 +13570,11 @@ msgstr "Wii e Wii Remote" msgid "Wii data is not public yet" msgstr "Dados do Wii ainda não são públicos" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Arquivo de dados salvos do Wii (*.bin);;Todos os arquivos (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "MEGA Arquivo de Assinatura do WiiTools" @@ -13802,6 +13846,12 @@ msgstr "" "Gostaria de interromper a emulação para corrigir o problema?\n" "Se optar por continuar, o áudio pode não funcionar corretamente." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13838,7 +13888,7 @@ msgstr "alinhado" msgid "any value" msgstr "qualquer valor" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "Automático" @@ -13871,7 +13921,7 @@ msgstr "Cartões do e-Reader (*.raw);;Todos os arquivos (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "Falsa conclusão" @@ -13917,7 +13967,7 @@ msgstr "" "Estados Salvos do mGBA (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *." "ss8 *.ss9);;Todos os arquivos (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "Nenhum" @@ -13942,7 +13992,7 @@ msgstr "s" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 msgid "sRGB" -msgstr "" +msgstr "sRGB" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" diff --git a/Languages/po/ro.po b/Languages/po/ro.po index 508cba5f50..79c0799469 100644 --- a/Languages/po/ro.po +++ b/Languages/po/ro.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Arian - Cazare Muncitori , 2014\n" "Language-Team: Romanian (http://app.transifex.com/delroth/dolphin-emu/" @@ -308,7 +308,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -329,7 +329,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "" @@ -337,7 +337,7 @@ msgstr "" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -345,11 +345,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Puncte de întrerupere" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -357,15 +357,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -373,7 +373,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -381,7 +381,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "" @@ -420,11 +420,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulare" @@ -444,27 +444,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fișier" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Avans Cadru" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -472,15 +472,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Configurări Grafică" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Ajutor" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Configurări Tastă Rapidă" @@ -500,7 +500,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -512,7 +512,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -520,11 +520,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "&Status de Încărcare" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -538,15 +538,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memorie" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "" @@ -554,7 +554,7 @@ msgstr "" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -563,23 +563,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Deschide..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opțiuni" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pauză" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Redare" @@ -587,7 +587,7 @@ msgstr "&Redare" msgid "&Properties" msgstr "&Proprietăți" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "" @@ -595,7 +595,7 @@ msgstr "" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Înregistrări" @@ -613,15 +613,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Resetează" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -629,7 +629,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -637,7 +637,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Stop" @@ -645,11 +645,11 @@ msgstr "&Stop" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Instrumente" @@ -663,17 +663,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Vizualizează" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "" @@ -685,11 +685,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1106,7 +1106,7 @@ msgid "Accuracy:" msgstr "Precizie:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1280,7 +1280,7 @@ msgstr "Adaugă..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "" @@ -1509,15 +1509,15 @@ msgstr "Antialias:" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1535,7 +1535,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1642,7 +1642,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1745,7 +1745,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1817,7 +1817,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1853,7 +1853,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1930,7 +1930,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1992,7 +1992,7 @@ msgstr "" msgid "C Stick" msgstr "C Stick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2088,7 +2088,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2159,7 +2159,7 @@ msgstr "" msgid "Change &Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Schimbă &Discul..." @@ -2221,7 +2221,7 @@ msgstr "Căutare Trișări" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2259,11 +2259,11 @@ msgstr "Alege un fișier pentru a-l deschide" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2298,7 +2298,7 @@ msgstr "" msgid "Clear" msgstr "Curăță" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2319,7 +2319,7 @@ msgstr "" msgid "Close" msgstr "Închide" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2366,7 +2366,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2403,7 +2403,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2539,7 +2539,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Confirmă la Oprire" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2550,7 +2550,7 @@ msgstr "" msgid "Connect" msgstr "Conectare" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Conectează Placa de Echilibru" @@ -2558,7 +2558,7 @@ msgstr "Conectează Placa de Echilibru" msgid "Connect USB Keyboard" msgstr "Conectează Tastatura USB" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2578,7 +2578,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2701,7 +2701,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3021,7 +3021,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3217,7 +3217,7 @@ msgstr "" msgid "Default" msgstr "Implicit" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3277,7 +3277,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3290,7 +3290,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Descriere" @@ -3312,11 +3312,11 @@ msgstr "" msgid "Detect" msgstr "Detectare" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3391,7 +3391,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3399,7 +3399,7 @@ msgstr "" msgid "Disable Fog" msgstr "Dezactivează Ceața" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3472,7 +3472,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3503,17 +3503,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3674,7 +3674,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Dump Audio" @@ -3686,7 +3686,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "Dump Destinație EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Dump Cadre" @@ -3764,7 +3764,7 @@ msgstr "" msgid "Dutch" msgstr "Olandeză" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "I&sire" @@ -3812,7 +3812,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3879,7 +3879,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4032,7 +4032,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4072,7 +4072,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4133,7 +4133,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4218,7 +4218,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4265,18 +4265,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4415,7 +4415,7 @@ msgstr "" msgid "Euphoria" msgstr "Euforia" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4496,7 +4496,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exportă Toate Salvările Wii" @@ -4511,7 +4511,7 @@ msgstr "" msgid "Export Recording" msgstr "Export Înregistrare" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Export Înregistrare..." @@ -4539,7 +4539,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4567,7 +4567,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4605,7 +4605,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Jucător FIFO" @@ -4623,7 +4623,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4717,7 +4717,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4744,18 +4744,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4782,7 +4782,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4792,8 +4792,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4805,7 +4805,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4977,19 +4977,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5037,7 +5037,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5083,7 +5083,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5097,18 +5097,18 @@ msgstr "Info Fişier " #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "" @@ -5621,7 +5621,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "" @@ -5665,7 +5665,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Configurări Specifice-Jocului" @@ -5736,7 +5736,7 @@ msgid "Gecko Codes" msgstr "Coduri Gecko" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5762,7 +5762,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5839,7 +5839,7 @@ msgstr "Verde Stânga" msgid "Green Right" msgstr "Verde Dreapta" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5914,7 +5914,7 @@ msgstr "" msgid "Hide" msgstr "Ascunde" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6188,7 +6188,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6203,7 +6203,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6308,8 +6308,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informații" @@ -6318,10 +6318,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Intrare" @@ -6362,7 +6362,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6382,7 +6382,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6445,7 +6445,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6470,7 +6470,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6547,11 +6547,11 @@ msgstr "Italiană" msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6559,47 +6559,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6611,11 +6611,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6626,7 +6626,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6685,7 +6685,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6830,11 +6830,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6850,11 +6850,11 @@ msgstr "" msgid "Load" msgstr "Încarcă" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6866,7 +6866,7 @@ msgstr "Încarcă Texturi Personalizate" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6976,19 +6976,19 @@ msgstr "Încarcă Status din Slotul 8" msgid "Load State Slot 9" msgstr "Încarcă Status din Slotul 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -7000,16 +7000,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7017,7 +7017,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7056,7 +7056,7 @@ msgstr "Jurnal" msgid "Log Configuration" msgstr "Configurare Jurnal" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7136,7 +7136,7 @@ msgstr "Stick Principal" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7153,10 +7153,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7207,7 +7208,7 @@ msgstr "" msgid "Memory Card" msgstr "Card de memorie" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7292,8 +7293,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7301,7 +7302,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7364,9 +7365,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7375,7 +7377,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7401,7 +7403,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7609,7 +7611,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7668,7 +7670,7 @@ msgstr "Nimic" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Nestabilit" @@ -7790,7 +7792,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Documentație Online" @@ -7798,13 +7800,13 @@ msgstr "&Documentație Online" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7819,7 +7821,7 @@ msgstr "Deschide" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7925,11 +7927,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8031,7 +8033,7 @@ msgstr "Căi" msgid "Pause" msgstr "Pauză" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8069,7 +8071,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Iluminare Per-Pixel" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8103,7 +8105,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8120,7 +8122,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8351,7 +8353,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8407,11 +8409,11 @@ msgstr "R-Analog" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8565,7 +8567,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8663,7 +8665,7 @@ msgstr "Resetare" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8895,11 +8897,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Sal&vează Status" @@ -8922,7 +8924,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8943,11 +8945,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9009,23 +9011,23 @@ msgstr "Salvează Status din Slotul 8" msgid "Save State Slot 9" msgstr "Salvează Status din Slotul 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9045,11 +9047,11 @@ msgstr "" msgid "Save as..." msgstr "Salvează ca..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9060,11 +9062,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9072,7 +9074,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9106,7 +9108,7 @@ msgstr "ScrShot" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Căutare" @@ -9133,7 +9135,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9141,7 +9143,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9178,7 +9180,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9222,7 +9224,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9230,7 +9232,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "" @@ -9316,7 +9318,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9324,7 +9326,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9341,7 +9343,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Selectează fișierul salvat" @@ -9548,11 +9550,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Afișare &Jurnal" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Afișare &Bară de Instrumente" @@ -9560,11 +9562,11 @@ msgstr "Afișare &Bară de Instrumente" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9577,7 +9579,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9590,7 +9592,7 @@ msgstr "" msgid "Show FPS" msgstr "Afișare FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9598,15 +9600,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Afișare Franța" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Afișare GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9618,23 +9620,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Afișare Ecran Conectat" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Afișare Italia" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Afișare Coreea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9642,7 +9644,7 @@ msgstr "" msgid "Show Language:" msgstr "Afișare Limbă:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Afișare Jurnal &Configurare" @@ -9654,7 +9656,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9662,7 +9664,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Afișare PAL" @@ -9675,19 +9677,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Afișare Platforme" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Afișare Regiuni" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9695,7 +9697,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9707,19 +9709,19 @@ msgstr "" msgid "Show Statistics" msgstr "Afișare Statistici" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Afișare Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Afișare SUA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9731,15 +9733,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Afișare Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9848,7 +9850,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10088,7 +10090,7 @@ msgstr "Controler Standard" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10096,7 +10098,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10190,7 +10192,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10212,7 +10214,7 @@ msgstr "Joystick" msgid "Stop" msgstr "Stop" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10283,8 +10285,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10311,7 +10313,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10323,12 +10325,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10421,7 +10423,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10441,7 +10443,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "Sincronizare thread GPU" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10470,7 +10472,7 @@ msgstr "" msgid "System Language:" msgstr "Limbă Sistem" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Intrare TAS" @@ -10483,7 +10485,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10501,7 +10503,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Realizează CapturăEcran" @@ -10583,13 +10585,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10859,6 +10861,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10890,6 +10898,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10918,7 +10932,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11112,13 +11126,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11171,7 +11185,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Titlu" @@ -11185,7 +11199,7 @@ msgstr "Către" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11431,7 +11445,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11490,11 +11504,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Anulare Status Încărcare" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Anulare Status Salvare" @@ -11512,7 +11526,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11763,7 +11777,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11801,7 +11815,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11995,7 +12009,7 @@ msgstr "" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12096,7 +12110,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Atenție" @@ -12279,11 +12293,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12500,6 +12514,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12536,7 +12556,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12569,7 +12589,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12613,7 +12633,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" diff --git a/Languages/po/ru.po b/Languages/po/ru.po index e4d8a0e1dc..8ae384c16e 100644 --- a/Languages/po/ru.po +++ b/Languages/po/ru.po @@ -19,7 +19,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Sukharev Andrey , 2015-2022\n" "Language-Team: Russian (http://app.transifex.com/delroth/dolphin-emu/" @@ -333,7 +333,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Об эмуляторе" @@ -354,7 +354,7 @@ msgstr "&Добавить функцию" msgid "&Add..." msgstr "&Добавить..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "Настройки &звука" @@ -362,7 +362,7 @@ msgstr "Настройки &звука" msgid "&Auto Update:" msgstr "&Автообновление:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Автоматический запуск" @@ -370,11 +370,11 @@ msgstr "&Автоматический запуск" msgid "&Borderless Window" msgstr "&Окно без рамок" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Точки останова" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Баг-трекер" @@ -382,15 +382,15 @@ msgstr "&Баг-трекер" msgid "&Cancel" msgstr "&Отмена" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Менеджер читов" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Проверить обновления..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Очистить символы" @@ -398,7 +398,7 @@ msgstr "&Очистить символы" msgid "&Clone..." msgstr "&Клонировать..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Код" @@ -406,7 +406,7 @@ msgstr "&Код" msgid "&Connected" msgstr "&Подключен" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "Настройки &управления" @@ -445,11 +445,11 @@ msgstr "&Изменить код..." msgid "&Edit..." msgstr "&Изменить..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Извлечь диск" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Эмуляция" @@ -469,27 +469,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "&Экспорт в .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Файл" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Шрифт..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "Перемотка &кадров" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "Настройки &свободного обзора" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Создать символы из" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "Репозиторий на &GitHub" @@ -497,15 +497,15 @@ msgstr "Репозиторий на &GitHub" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "Настройки &графики" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Помощь" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "Горячие &клавиши" @@ -525,7 +525,7 @@ msgstr "" msgid "&Import..." msgstr "&Импортировать..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -537,7 +537,7 @@ msgstr "&Вставить blr" msgid "&Interframe Blending" msgstr "&Межкадровый блендинг" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -545,11 +545,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Язык:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "Быстрая &загрузка" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Загрузить карту символов" @@ -563,15 +563,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&Зафиксировать виджеты" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Память" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Запись" @@ -579,7 +579,7 @@ msgstr "&Запись" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Сеть" @@ -588,23 +588,23 @@ msgid "&No" msgstr "&Нет" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Открыть..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Опции" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Патчить HLE-функции" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Пауза" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Запустить" @@ -612,7 +612,7 @@ msgstr "&Запустить" msgid "&Properties" msgstr "&Свойства" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "Режим \"Только для &чтения\"" @@ -620,7 +620,7 @@ msgstr "Режим \"Только для &чтения\"" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Регистры" @@ -638,15 +638,15 @@ msgid "&Rename symbol" msgstr "&Переименовать символ" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Сбросить" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Менеджер наборов ресурсов" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Сохранить карту символов" @@ -654,7 +654,7 @@ msgstr "&Сохранить карту символов" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -662,7 +662,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&Ограничение скорости:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Остановить" @@ -670,11 +670,11 @@ msgstr "&Остановить" msgid "&Theme:" msgstr "&Тема:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Потоки" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Инструменты" @@ -688,17 +688,17 @@ msgstr "&Выгрузить образ игры" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Вид" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Наблюдение" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Сайт" @@ -710,11 +710,11 @@ msgstr "&Вики" msgid "&Yes" msgstr "&Да" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' не найден, имена символов не созданы" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' не найден, ищем на замену распространенные функции" @@ -1154,7 +1154,7 @@ msgid "Accuracy:" msgstr "Точность:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1343,7 +1343,7 @@ msgstr "Добавить..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Адрес" @@ -1593,15 +1593,15 @@ msgstr "Сглаживание:" msgid "Any Region" msgstr "Любой регион" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Добавить сигнатуру к" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Добавить к &имеющемуся файлу с сигнатурами..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Примени&ть файл с сигнатурами..." @@ -1621,7 +1621,7 @@ msgstr "Дата загрузчика:" msgid "Apply" msgstr "Применить" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Применить файл с сигнатурами" @@ -1734,7 +1734,7 @@ msgstr "Автонастройка размера окна" msgid "Auto-Hide" msgstr "Автоскрытие" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Обнаруживать RSO автоматически?" @@ -1843,7 +1843,7 @@ msgstr "Указано некорректное значение." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Логотип" @@ -1915,7 +1915,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Размер блока" @@ -1953,7 +1953,7 @@ msgstr "" "Включён режим проброса Bluetooth, но Dolphin собран без поддержки libusb. " "Невозможно использовать режим проброса." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Пауза после запуска" @@ -2030,7 +2030,7 @@ msgstr "Ошибка широкополосного адаптера" msgid "Broadband Adapter MAC Address" msgstr "MAC-адрес широкополосного адаптера" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Просмотр &сессий сетевой игры..." @@ -2094,7 +2094,7 @@ msgstr "" msgid "C Stick" msgstr "C Stick" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "С&оздать файл с сигнатурами..." @@ -2199,7 +2199,7 @@ msgstr "Невозможно создать сессию сетевой игры #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2272,7 +2272,7 @@ msgstr "Центрировать и откалибровать" msgid "Change &Disc" msgstr "Сменить &диск" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Сменить &диск..." @@ -2344,7 +2344,7 @@ msgstr "Поиск чит-кодов" msgid "Cheats Manager" msgstr "Менеджер читов" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Проверить NAND..." @@ -2384,11 +2384,11 @@ msgstr "Выберите открываемый файл" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Выберите основной входной файл" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Выберите вторичный входной файл" @@ -2423,7 +2423,7 @@ msgstr "Контроллер Classic" msgid "Clear" msgstr "Очистить" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Очистить кэш" @@ -2444,7 +2444,7 @@ msgstr "Скопировать и &изменить код..." msgid "Close" msgstr "Закрыть" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "&Настройка" @@ -2491,7 +2491,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Объединить &два файла с сигнатурами..." @@ -2528,7 +2528,7 @@ msgstr "Компиляция шейдеров" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Сжатие" @@ -2664,7 +2664,7 @@ msgstr "Подтвердите смену бэкенда" msgid "Confirm on Stop" msgstr "Подтверждать остановку" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2675,7 +2675,7 @@ msgstr "Подтверждение" msgid "Connect" msgstr "Подключиться" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Подключить Balance Board" @@ -2683,7 +2683,7 @@ msgstr "Подключить Balance Board" msgid "Connect USB Keyboard" msgstr "Подключить USB-клавиатуру" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Подключить Wii Remote %1" @@ -2703,7 +2703,7 @@ msgstr "Подключить Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "Подключить Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Подключить Wii Remote" @@ -2843,7 +2843,7 @@ msgstr "" msgid "Convergence" msgstr "Сведение" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Сведение:" @@ -3204,7 +3204,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Текущий регион" @@ -3406,7 +3406,7 @@ msgstr "Уменьшить по Y" msgid "Default" msgstr "По умолчанию" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Конфигурация по умолчанию (только для чтения)" @@ -3472,7 +3472,7 @@ msgstr "Удалить существующий файл '{0}'?" msgid "Depth" msgstr "Глубина" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Процент глубины:" @@ -3485,7 +3485,7 @@ msgstr "Глубина:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Описание" @@ -3507,11 +3507,11 @@ msgstr "Отсоединён" msgid "Detect" msgstr "Считать" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Обнаружение модулей RSO" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Детерминированная двухядерность:" @@ -3586,7 +3586,7 @@ msgstr "Отключить копии EFB в VRAM" msgid "Disable Emulation Speed Limit" msgstr "Отключить огр. скорости эмуляции" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Отключить быструю память" @@ -3594,7 +3594,7 @@ msgstr "Отключить быструю память" msgid "Disable Fog" msgstr "Отключить туман" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Отключить кэш JIT" @@ -3685,7 +3685,7 @@ msgstr "Вы разрешаете отправку данной информац msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Вы хотите добавить \"%1\" в список путей к играм?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Вы хотите очистить список имён символов?" @@ -3716,17 +3716,17 @@ msgstr "Лог Dolphin FIFO (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Файл карты Dolphin (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "CSV-файл с сигнатурами Dolphin" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Файл с сигнатурами Dolphin" @@ -3894,7 +3894,7 @@ msgstr "Дампить &FakeVMEM" msgid "Dump &MRAM" msgstr "Дампить &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Дампить звук" @@ -3906,7 +3906,7 @@ msgstr "Дампить основные текстуры" msgid "Dump EFB Target" msgstr "Дампить конечный EFB" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Дампить кадры" @@ -3993,7 +3993,7 @@ msgstr "Длительность отпускания турбо-кнопки ( msgid "Dutch" msgstr "Голландский" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Закрыть" @@ -4048,7 +4048,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Редактор" @@ -4115,7 +4115,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4271,7 +4271,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4313,7 +4313,7 @@ msgstr "" "Включить эмуляцию Dolby Pro Logic II с использованием 5.1 канального звука. " "Только для некоторых бэкендов." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4399,7 +4399,7 @@ msgstr "" "

Если не уверены – оставьте выключенным." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4496,7 +4496,7 @@ msgstr "Введите пароль" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Введите адрес модуля RSO:" @@ -4543,18 +4543,18 @@ msgstr "Введите адрес модуля RSO:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4698,7 +4698,7 @@ msgstr "В {0} неиспользуемых блоках раздела {1} на msgid "Euphoria" msgstr "Эйфория" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Европа" @@ -4779,7 +4779,7 @@ msgstr "Ожидалось название переменной." msgid "Experimental" msgstr "Экспериментальные" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Экспортировать все сохранения Wii" @@ -4794,7 +4794,7 @@ msgstr "Не удалось экспортировать" msgid "Export Recording" msgstr "Экспорт записи" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Экспорт записи..." @@ -4822,7 +4822,7 @@ msgstr "Экспорт в .&gcs..." msgid "Export as .&sav..." msgstr "Экспорт в .&sav..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4850,7 +4850,7 @@ msgstr "Внешний адрес" msgid "External Frame Buffer (XFB)" msgstr "Внешний буфер кадров (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Извлечь сертификаты из NAND" @@ -4888,7 +4888,7 @@ msgid "FD" msgstr "ФД" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "Проигрыватель FIFO" @@ -4908,7 +4908,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Не удалось добавить сессию в индекс сетевой игры: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Не удалось добавить данные в файл с сигнатурами '%1'" @@ -5004,7 +5004,7 @@ msgstr "Не удалось экспортировать %n из %1 сохран msgid "Failed to export the following save files:" msgstr "Не удалось экспортировать следующие файлы сохранений:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Не удалось извлечь сертификаты из NAND" @@ -5034,14 +5034,14 @@ msgstr "Не удалось найти один или более символ D msgid "Failed to import \"%1\"." msgstr "Не удалось импортировать \"%1\"." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Не удалось импортировать файл сохранения. Пожалуйста, запустите игру, а " "потом попробуйте ещё раз." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5049,7 +5049,7 @@ msgstr "" "Не удалось импортировать файл сохранения. Похоже, что данный файл повреждён " "или не является корректным сохранением Wii." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5080,7 +5080,7 @@ msgid "Failed to install pack: %1" msgstr "Не удалось установить набор: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Не удалось установить этот продукт в NAND." @@ -5092,8 +5092,8 @@ msgstr "" "Не удалось инициализировать прослушивание порта %1. У вас запущен ещё один " "сервер сетевой игры?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Не удалось загрузить модуль RSO на %1" @@ -5105,7 +5105,7 @@ msgstr "Не удалось загрузить d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "Не удалось загрузить dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Не удалось загрузить файл с картой '%1'" @@ -5293,19 +5293,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Не удалось сохранить лог FIFO." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Не удалось сохранить карту кода по пути '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Не удалось сохранить файл сигнатуры '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Не удалось сохранить карту символов по пути '%1'" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Не удалось сохранить файл с сигнатурами '%1'" @@ -5355,7 +5355,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Ошибка" @@ -5403,7 +5403,7 @@ msgstr "Информация о файле" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Формат файла" @@ -5417,18 +5417,18 @@ msgstr "Информация о файле" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Имя файла" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Путь к файлу" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Размер файла" @@ -5985,7 +5985,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "ID игры" @@ -6031,7 +6031,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Настройки конкретной игры" @@ -6102,7 +6102,7 @@ msgid "Gecko Codes" msgstr "Gecko-коды" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6128,7 +6128,7 @@ msgstr "Сгенерировать новый ID сбора статистики msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Созданы имена символов из '%1'" @@ -6211,7 +6211,7 @@ msgstr "Зеленая слева" msgid "Green Right" msgstr "Зеленая справа" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "В виде сетки" @@ -6286,7 +6286,7 @@ msgstr "Шестнадцатеричный" msgid "Hide" msgstr "Спрятать" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Скрыть все" @@ -6616,7 +6616,7 @@ msgstr "" "

Если не уверены – оставьте выключенным." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Импортировать бэкап BootMii NAND..." @@ -6631,7 +6631,7 @@ msgstr "Не удалось импортировать" msgid "Import Save File(s)" msgstr "Импорт файлов сохранений" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Импортировать сохранение Wii..." @@ -6743,8 +6743,8 @@ msgstr "Информация" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Информация" @@ -6753,10 +6753,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Запретить скринсейвер во время эмуляции" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Ввод" @@ -6797,7 +6797,7 @@ msgstr "Установить раздел (%1)" msgid "Install Update" msgstr "Установить обновление" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Установить WAD..." @@ -6817,7 +6817,7 @@ msgstr "Инструкция" msgid "Instruction Breakpoint" msgstr "Точка останова инструкции" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Инструкция:" @@ -6882,7 +6882,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Интерпретатор (самый медленный)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Ядро интерпретатора" @@ -6907,7 +6907,7 @@ msgstr "Некорректный набор %1 указан: %2" msgid "Invalid Player ID" msgstr "Некорректный ID игрока" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Некорректный адрес модуля RSO: %1" @@ -6982,11 +6982,11 @@ msgstr "Итальянский" msgid "Italy" msgstr "Италия" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "Отключить линковку блоков JIT" @@ -6994,47 +6994,47 @@ msgstr "Отключить линковку блоков JIT" msgid "JIT Blocks" msgstr "Блоки JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "Отключить JIT Branch" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "Отключить JIT для FloatingPoint" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "Отключить JIT для Integer" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "Отключить JIT LoadStore Floating" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "Отключить JIT LoadStore" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "Отключить JIT LoadStore Paired" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "Отключить JIT LoadStore lXz" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "Отключить JIT LoadStore lbzx" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "Отключить JIT LoadStore lwz" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "Отключить JIT (ядро JIT)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "Отключить JIT Paired" @@ -7046,11 +7046,11 @@ msgstr "JIT-рекомпилятор для ARM64 (рекомендуется)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "JIT-рекомпилятор для x86-64 (рекомендуется)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "Отключить кэш регистров JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "Отключить JIT SystemRegisters" @@ -7064,7 +7064,7 @@ msgstr "" "происходить. Пожалуйста, сообщите об этой ошибке в багтрекере. Dolphin " "завершит работу." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Япония" @@ -7123,7 +7123,7 @@ msgstr "КиБ" msgid "Kick Player" msgstr "Исключить игрока" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Корея" @@ -7274,11 +7274,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "Ограничить скорость закачки:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Столбцы в списке" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "В виде списка" @@ -7294,11 +7294,11 @@ msgstr "Прослушивание" msgid "Load" msgstr "Загр." -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Загрузить файл с &плохими картами..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Загрузить &другой файл с картой..." @@ -7310,7 +7310,7 @@ msgstr "Загружать свои текстуры" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Загрузить главное меню GameCube" @@ -7420,19 +7420,19 @@ msgstr "Быстрая загрузка 8" msgid "Load State Slot 9" msgstr "Быстрая загрузка 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Быстрая загрузка из файла" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Быстрая загрузка из выбранного слота" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Быстрая загрузка из слота" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Загрузить системное меню Wii %1" @@ -7444,16 +7444,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "Загрузить из выбранного слота" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Быстрая загрузка из слота %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Загрузить файл с картой" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7461,7 +7461,7 @@ msgstr "" msgid "Load..." msgstr "Загрузить..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Загружены символы из '%1'" @@ -7503,7 +7503,7 @@ msgstr "Лог" msgid "Log Configuration" msgstr "Настройка логирования" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Логировать покрытие инструкций JIT" @@ -7587,7 +7587,7 @@ msgstr "Основной стик" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Создатель" @@ -7609,10 +7609,11 @@ msgstr "" "

Если не уверены – оставьте выключенным." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Управлять NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7663,7 +7664,7 @@ msgstr "Точка останова в памяти" msgid "Memory Card" msgstr "Карта памяти" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Менеджер карт памяти" @@ -7764,8 +7765,8 @@ msgstr "" "

Если не уверены – оставьте выключенным." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Найдено модулей: %1" @@ -7773,7 +7774,7 @@ msgstr "Найдено модулей: %1" msgid "Mono" msgstr "Моно" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Моноскопические тени" @@ -7836,9 +7837,10 @@ msgstr "" msgid "N&o to All" msgstr "&Нет для всех" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "Проверка NAND" @@ -7847,7 +7849,7 @@ msgstr "Проверка NAND" msgid "NKit Warning" msgstr "Предупреждение NKit" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7873,7 +7875,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8081,7 +8083,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Проблем не обнаружено." @@ -8146,7 +8148,7 @@ msgstr "Отсутствует" msgid "North America" msgstr "Северная Америка" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Не установлено" @@ -8274,7 +8276,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Онлайн-&документация" @@ -8282,7 +8284,7 @@ msgstr "Онлайн-&документация" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8290,7 +8292,7 @@ msgstr "" "Добавлять только символы с префиксом:\n" "(Пусто - все символы)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8307,7 +8309,7 @@ msgstr "Открыть" msgid "Open &Containing Folder" msgstr "Открыть &папку с образом" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -8413,11 +8415,11 @@ msgstr "Другой игры..." msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "&Проиграть записанный ввод..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8519,7 +8521,7 @@ msgstr "Пути" msgid "Pause" msgstr "Пауза" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Пауза в конце ролика" @@ -8557,7 +8559,7 @@ msgstr "Пиковая скорость взмаха." msgid "Per-Pixel Lighting" msgstr "Попискельное освещение" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Обновить систему через интернет" @@ -8591,7 +8593,7 @@ msgstr "" msgid "PiB" msgstr "ПиБ" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Выбрать шрифт для отладки" @@ -8608,7 +8610,7 @@ msgid "Pitch Up" msgstr "Тангаж вверх" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Платформа" @@ -8854,7 +8856,7 @@ msgstr "Ход выполнения" msgid "Public" msgstr "Открытые" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Очистить кэш списка игр" @@ -8911,11 +8913,11 @@ msgstr "R-аналог" msgid "READY" msgstr "ГОТОВ" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "Модули RSO" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "Автообнаружение RSO" @@ -9078,7 +9080,7 @@ msgid "Refreshing..." msgstr "Обновление..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Регион" @@ -9181,7 +9183,7 @@ msgstr "Сбросить" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -9413,11 +9415,11 @@ msgstr "Контекст SSL" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "Со&хранить код" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Быстрое &сохранение" @@ -9440,7 +9442,7 @@ msgstr "Сохранить все" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Экспортировать сохранение" @@ -9461,11 +9463,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Импортировать сохранение" @@ -9527,23 +9529,23 @@ msgstr "Быстрое сохранение 8" msgid "Save State Slot 9" msgstr "Быстрое сохранение 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Быстрое сохранение в файл" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Быстрое сохранение в старый слот" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Быстрое сохранение в выбранный слот" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Быстрое сохранение в слот" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Сохранить карту символов &как..." @@ -9563,11 +9565,11 @@ msgstr "" msgid "Save as..." msgstr "Сохранить как..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Сохранить объединённый файл как" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9582,11 +9584,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Сохранение в той же папке, где и образ" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Сохранить файл с картой" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Сохранить файл сигнатуры" @@ -9594,7 +9596,7 @@ msgstr "Сохранить файл сигнатуры" msgid "Save to Selected Slot" msgstr "Сохранить в выбранный слот" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Сохранить в слот %1 - %2" @@ -9630,7 +9632,7 @@ msgstr "Скриншот" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Поиск" @@ -9659,7 +9661,7 @@ msgstr "" "Поиск в виртуальном адресном пространстве пока невозможен. Пожалуйста, " "запустите игру на некоторое время и попробуйте снова." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Найти инструкцию" @@ -9667,7 +9669,7 @@ msgstr "Найти инструкцию" msgid "Search games..." msgstr "Искать игры..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Поиск инструкции" @@ -9706,7 +9708,7 @@ msgid "Select Dump Path" msgstr "Выберите путь к дампам" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Выберите папку для экспорта" @@ -9750,7 +9752,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Выбрать слот %1 - %2" @@ -9758,7 +9760,7 @@ msgstr "Выбрать слот %1 - %2" msgid "Select State" msgstr "Выбор сохранения" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Выбрать слот сохранения" @@ -9844,7 +9846,7 @@ msgstr "" msgid "Select a game" msgstr "Выберите игру" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Выберите продукт для установки в NAND" @@ -9852,7 +9854,7 @@ msgstr "Выберите продукт для установки в NAND" msgid "Select e-Reader Cards" msgstr "Выбрать e-карточки" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Выберите адрес модуля RSO:" @@ -9869,7 +9871,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Выберите файл с ключами (дамп OTP/SEEPROM)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Выберите файл сохранения" @@ -10108,11 +10110,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Показать &лог" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Отображать панель &инструментов" @@ -10120,11 +10122,11 @@ msgstr "Отображать панель &инструментов" msgid "Show Active Title in Window Title" msgstr "Показывать название запущенной игры в заголовке окна" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Показать все" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Австралия" @@ -10137,7 +10139,7 @@ msgstr "Показывать текущую игру в Discord" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL-файлы" @@ -10150,7 +10152,7 @@ msgstr "" msgid "Show FPS" msgstr "Показывать FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Показывать счётчик кадров" @@ -10158,15 +10160,15 @@ msgstr "Показывать счётчик кадров" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Франция" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Германия" @@ -10178,23 +10180,23 @@ msgstr "Показывать оверлей режима гольфа" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Показывать ввод экрана" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Италия" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Корея" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Показывать счётчик лагов" @@ -10202,7 +10204,7 @@ msgstr "Показывать счётчик лагов" msgid "Show Language:" msgstr "Язык отображения:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Показать &настройки логирования" @@ -10214,7 +10216,7 @@ msgstr "Показывать сообщения в сетевой игре" msgid "Show NetPlay Ping" msgstr "Показывать пинг в сетевой игре" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Голландия" @@ -10222,7 +10224,7 @@ msgstr "Голландия" msgid "Show On-Screen Display Messages" msgstr "Показывать наэкранные сообщения" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "PAL" @@ -10235,19 +10237,19 @@ msgstr "Показать СК" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Отображать игры платформ" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Отображать игры регионов" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Россия" @@ -10255,7 +10257,7 @@ msgstr "Россия" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Испания" @@ -10267,19 +10269,19 @@ msgstr "" msgid "Show Statistics" msgstr "Показывать статистику" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Показывать системное время" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Тайвань" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Неизвестный" @@ -10291,15 +10293,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD-файлы" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Мир" @@ -10419,7 +10421,7 @@ msgstr "Положить на бок" msgid "Sideways Wii Remote" msgstr "Wii Remote на боку" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "База данных сигнатур" @@ -10671,7 +10673,7 @@ msgstr "Стандартный контроллер" msgid "Start" msgstr "Старт" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Начать &сетевую игру..." @@ -10679,7 +10681,7 @@ msgstr "Начать &сетевую игру..." msgid "Start New Cheat Search" msgstr "Новый поиск читов" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "&Начать запись ввода" @@ -10773,7 +10775,7 @@ msgstr "Стереоскопический 3D-режим" msgid "Stereoscopic 3D Mode:" msgstr "Стереоскопический 3D-режим:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Стереоизображение" @@ -10795,7 +10797,7 @@ msgstr "Стик" msgid "Stop" msgstr "Стоп" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Остановить проигр./запись ввода" @@ -10876,8 +10878,8 @@ msgstr "Стилус" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Успешно" @@ -10904,7 +10906,7 @@ msgstr "Файлы сохранений (%n из %1 шт.) успешно экс msgid "Successfully exported save files" msgstr "Файлы сохранений успешно экспортированы" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Сертификаты успешно извлечены из NAND" @@ -10916,12 +10918,12 @@ msgstr "Файл успешно извлечён." msgid "Successfully extracted system data." msgstr "Системные данные успешно извлечены." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Файл сохранения успешно импортирован." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Данный продукт успешно установлен в NAND." @@ -11018,7 +11020,7 @@ msgstr "Имя символа:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Символы" @@ -11038,7 +11040,7 @@ msgstr "Синхронизировать и спарить Wii Remote" msgid "Synchronize GPU thread" msgstr "Синхронизировать поток ГП" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11069,7 +11071,7 @@ msgstr "Синхронизация сохранений..." msgid "System Language:" msgstr "Язык системы:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "Ввод TAS" @@ -11082,7 +11084,7 @@ msgstr "Управление TAS" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Метки" @@ -11100,7 +11102,7 @@ msgstr "Хвост" msgid "Taiwan" msgstr "Тайвань" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Сделать скриншот" @@ -11184,7 +11186,7 @@ msgstr "IPL-файла нет в списке известных коррект msgid "The Masterpiece partitions are missing." msgstr "Отсутствуют разделы Masterpiece." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11192,7 +11194,7 @@ msgstr "" "Не получается исправить NAND. Рекомендуется создать резервную копию текущих " "данных и поставить NAND с нуля." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND успешно исправлен." @@ -11492,6 +11494,12 @@ msgstr "Указанный общий ключевой индекс: {0}, а д msgid "The specified file \"{0}\" does not exist" msgstr "Указанный файл \"{0}\" не существует" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "Выбранная карта памяти уже содержит файл \"%1\"." @@ -11526,6 +11534,12 @@ msgstr "Отсутствует раздел с обновлением." msgid "The update partition is not at its normal position." msgstr "Раздел с обновлением находится не на своей обычной позиции." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "В разделе {0} некорректная файловая система." @@ -11554,7 +11568,7 @@ msgstr "Нет действий для отмены!" msgid "There was an issue adding a shortcut to the desktop" msgstr "При добавлении ярлыка на рабочий стол произошла ошибка" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11793,7 +11807,7 @@ msgstr "" "\n" "Неизвестный ucode (CRC = {0:08x}) - принудительное AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -11801,7 +11815,7 @@ msgstr "" "Данное значение добавляется к значению сведения, указанному в графических " "настройках." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11862,7 +11876,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Название" @@ -11876,7 +11890,7 @@ msgstr "до" msgid "To:" msgstr "До:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "&Полноэкранный режим" @@ -12138,7 +12152,7 @@ msgstr "" "подтормаживания при компиляции шейдеров с минимальным влиянием на " "производительность, но конечный результат зависит от поведения драйвера ГП." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Не удалось автоматически обнаружить модуль RSO" @@ -12205,11 +12219,11 @@ msgstr "Несжатые образы GC/Wii (*.iso *.gcm)" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Отменить быструю загрузку" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Отменить быстрое сохранение" @@ -12229,7 +12243,7 @@ msgstr "" "Удаление WAD приведет к удалению текущей версии этого продукта из NAND без " "удаления его сохраненных данных. Продолжить?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "США" @@ -12486,7 +12500,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Использовать один буфер глубины для обоих глаз. Необходимо для нескольких " @@ -12526,7 +12540,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Пользовательская конфигурация" @@ -12730,7 +12744,7 @@ msgstr "Увеличить громкость" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD-файлы (*.wad)" @@ -12858,7 +12872,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Предупреждение" @@ -13081,11 +13095,11 @@ msgstr "Wii и Wii Remote" msgid "Wii data is not public yet" msgstr "Данные Wii ещё не опубликованы" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Файлы сохранений Wii (*.bin);;Все файлы (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "MEGA-файл с сигнатурами WiiTools" @@ -13323,6 +13337,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13359,7 +13379,7 @@ msgstr "" msgid "any value" msgstr "любое значение" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "автоматически" @@ -13392,7 +13412,7 @@ msgstr "e-карточки (*.raw);;Все файлы (*)" msgid "errno" msgstr "номер ошибки" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "ложное дополнение" @@ -13438,7 +13458,7 @@ msgstr "" "Быстрые сохранения mGBA (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *." "ss8 *.ss9);;Все файлы (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "отсутствует" diff --git a/Languages/po/sr.po b/Languages/po/sr.po index 3fb4debbf8..4c968a7c33 100644 --- a/Languages/po/sr.po +++ b/Languages/po/sr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: nikolassj, 2011\n" "Language-Team: Serbian (http://app.transifex.com/delroth/dolphin-emu/" @@ -308,7 +308,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "" @@ -329,7 +329,7 @@ msgstr "" msgid "&Add..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "" @@ -337,7 +337,7 @@ msgstr "" msgid "&Auto Update:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "" @@ -345,11 +345,11 @@ msgstr "" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -357,15 +357,15 @@ msgstr "" msgid "&Cancel" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -373,7 +373,7 @@ msgstr "" msgid "&Clone..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "" @@ -381,7 +381,7 @@ msgstr "" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "" @@ -420,11 +420,11 @@ msgstr "" msgid "&Edit..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulacija" @@ -444,27 +444,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Fajl" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -472,15 +472,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Graficke Opcije" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Pomoc" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Hotkey Opcije" @@ -500,7 +500,7 @@ msgstr "" msgid "&Import..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -512,7 +512,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -520,11 +520,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "Loaduj Savestate" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -538,15 +538,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Memorija" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "" @@ -554,7 +554,7 @@ msgstr "" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -563,23 +563,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Otvori..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Opcije" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pauza" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Pokreni" @@ -587,7 +587,7 @@ msgstr "&Pokreni" msgid "&Properties" msgstr "&Pribor/Opcije" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "" @@ -595,7 +595,7 @@ msgstr "" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Registri" @@ -613,15 +613,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Reset" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -629,7 +629,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -637,7 +637,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Stop" @@ -645,11 +645,11 @@ msgstr "&Stop" msgid "&Theme:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Alat" @@ -663,17 +663,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Pogledaj" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "" @@ -685,11 +685,11 @@ msgstr "" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1106,7 +1106,7 @@ msgid "Accuracy:" msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1280,7 +1280,7 @@ msgstr "Dodaj..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "" @@ -1509,15 +1509,15 @@ msgstr "" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1535,7 +1535,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1642,7 +1642,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1745,7 +1745,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Baner" @@ -1817,7 +1817,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1853,7 +1853,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1930,7 +1930,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1992,7 +1992,7 @@ msgstr "" msgid "C Stick" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2088,7 +2088,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2159,7 +2159,7 @@ msgstr "" msgid "Change &Disc" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Promeni &Disk..." @@ -2221,7 +2221,7 @@ msgstr "Trazi Chit" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2259,11 +2259,11 @@ msgstr "Biraj fajl da otvoris " msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2298,7 +2298,7 @@ msgstr "" msgid "Clear" msgstr "Ocisti" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2319,7 +2319,7 @@ msgstr "" msgid "Close" msgstr "Zatvori" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2366,7 +2366,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2403,7 +2403,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2539,7 +2539,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2550,7 +2550,7 @@ msgstr "" msgid "Connect" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "" @@ -2558,7 +2558,7 @@ msgstr "" msgid "Connect USB Keyboard" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2578,7 +2578,7 @@ msgstr "" msgid "Connect Wii Remote 4" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "" @@ -2701,7 +2701,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3021,7 +3021,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3217,7 +3217,7 @@ msgstr "" msgid "Default" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3277,7 +3277,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3290,7 +3290,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "" @@ -3312,11 +3312,11 @@ msgstr "" msgid "Detect" msgstr "Detekuj" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3391,7 +3391,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3399,7 +3399,7 @@ msgstr "" msgid "Disable Fog" msgstr "Onemoguci \"Fog\"" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3472,7 +3472,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3503,17 +3503,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3674,7 +3674,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "" @@ -3686,7 +3686,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "" @@ -3764,7 +3764,7 @@ msgstr "" msgid "Dutch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "" @@ -3812,7 +3812,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3879,7 +3879,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4032,7 +4032,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4072,7 +4072,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4133,7 +4133,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4216,7 +4216,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4263,18 +4263,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4411,7 +4411,7 @@ msgstr "" msgid "Euphoria" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4492,7 +4492,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "" @@ -4507,7 +4507,7 @@ msgstr "" msgid "Export Recording" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "" @@ -4535,7 +4535,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4563,7 +4563,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4601,7 +4601,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "" @@ -4619,7 +4619,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4713,7 +4713,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4740,18 +4740,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4778,7 +4778,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4788,8 +4788,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4801,7 +4801,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4973,19 +4973,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5033,7 +5033,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5079,7 +5079,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5093,18 +5093,18 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "" @@ -5617,7 +5617,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "" @@ -5661,7 +5661,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "" @@ -5732,7 +5732,7 @@ msgid "Gecko Codes" msgstr "" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5758,7 +5758,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5835,7 +5835,7 @@ msgstr "" msgid "Green Right" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5910,7 +5910,7 @@ msgstr "" msgid "Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6184,7 +6184,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6199,7 +6199,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6304,8 +6304,8 @@ msgstr "Info " #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Informacija " @@ -6314,10 +6314,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "" @@ -6358,7 +6358,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6378,7 +6378,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6441,7 +6441,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6466,7 +6466,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6541,11 +6541,11 @@ msgstr "Italianski " msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6553,47 +6553,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6605,11 +6605,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6620,7 +6620,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6679,7 +6679,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6821,11 +6821,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6841,11 +6841,11 @@ msgstr "" msgid "Load" msgstr "Ucitaj " -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6857,7 +6857,7 @@ msgstr "" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6967,19 +6967,19 @@ msgstr "Ucitaj State Slot 8" msgid "Load State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6991,16 +6991,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7008,7 +7008,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7047,7 +7047,7 @@ msgstr "" msgid "Log Configuration" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7127,7 +7127,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7144,10 +7144,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7198,7 +7199,7 @@ msgstr "" msgid "Memory Card" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7283,8 +7284,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7292,7 +7293,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7355,9 +7356,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7366,7 +7368,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7392,7 +7394,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7600,7 +7602,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7659,7 +7661,7 @@ msgstr "" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "" @@ -7781,7 +7783,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "" @@ -7789,13 +7791,13 @@ msgstr "" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7810,7 +7812,7 @@ msgstr "Otvori " msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7916,11 +7918,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8022,7 +8024,7 @@ msgstr "" msgid "Pause" msgstr "Pauza " -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8060,7 +8062,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8094,7 +8096,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8111,7 +8113,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8342,7 +8344,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8398,11 +8400,11 @@ msgstr "" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8556,7 +8558,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8654,7 +8656,7 @@ msgstr "Reset/Restart " msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8886,11 +8888,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "" @@ -8913,7 +8915,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8934,11 +8936,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9000,23 +9002,23 @@ msgstr "Snimaj State Slot 8" msgid "Save State Slot 9" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9036,11 +9038,11 @@ msgstr "" msgid "Save as..." msgstr "Snimaj kao..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9051,11 +9053,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9063,7 +9065,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9097,7 +9099,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "" @@ -9124,7 +9126,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9132,7 +9134,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9169,7 +9171,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9213,7 +9215,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9221,7 +9223,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "" @@ -9307,7 +9309,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9315,7 +9317,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9332,7 +9334,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Izaberi \"snimani fajl/the save state\"" @@ -9539,11 +9541,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "" @@ -9551,11 +9553,11 @@ msgstr "" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9568,7 +9570,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9581,7 +9583,7 @@ msgstr "" msgid "Show FPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9589,15 +9591,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9609,23 +9611,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9633,7 +9635,7 @@ msgstr "" msgid "Show Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "" @@ -9645,7 +9647,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9653,7 +9655,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "" @@ -9666,19 +9668,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9686,7 +9688,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9698,19 +9700,19 @@ msgstr "" msgid "Show Statistics" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9722,15 +9724,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9839,7 +9841,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10079,7 +10081,7 @@ msgstr "" msgid "Start" msgstr "Pokreni " -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10087,7 +10089,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10181,7 +10183,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10203,7 +10205,7 @@ msgstr "" msgid "Stop" msgstr " Zaustavi" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10274,8 +10276,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10302,7 +10304,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10314,12 +10316,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10412,7 +10414,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10432,7 +10434,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10461,7 +10463,7 @@ msgstr "" msgid "System Language:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "" @@ -10474,7 +10476,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10492,7 +10494,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "" @@ -10574,13 +10576,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10850,6 +10852,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10881,6 +10889,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10909,7 +10923,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11099,13 +11113,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11158,7 +11172,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "" @@ -11172,7 +11186,7 @@ msgstr "" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11418,7 +11432,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11477,11 +11491,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "" @@ -11499,7 +11513,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11750,7 +11764,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11788,7 +11802,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11982,7 +11996,7 @@ msgstr "" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12083,7 +12097,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Upozorenje " @@ -12266,11 +12280,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12487,6 +12501,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12523,7 +12543,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12556,7 +12576,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12600,7 +12620,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" diff --git a/Languages/po/sv.po b/Languages/po/sv.po index 3fecd9bf70..5542b40a37 100644 --- a/Languages/po/sv.po +++ b/Languages/po/sv.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: JosJuice, 2015-2023\n" "Language-Team: Swedish (http://app.transifex.com/delroth/dolphin-emu/" @@ -195,10 +195,12 @@ msgid "" "%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " "hardcore)" msgstr "" +"%1 har låst upp %2/%3 prestationer (%4 hardcore) värda %5/%6 poäng (%7 " +"hardcore)" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" -msgstr "" +msgstr "%1 har låst upp %2/%3 prestationer värda %4/%5 poäng" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" @@ -220,7 +222,7 @@ msgstr "%1 ms" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 msgid "%1 points" -msgstr "" +msgstr "%1 poäng" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" @@ -330,7 +332,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Om" @@ -351,7 +353,7 @@ msgstr "&Lägg till funktion" msgid "&Add..." msgstr "&Lägg till..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Ljudinställningar" @@ -359,7 +361,7 @@ msgstr "&Ljudinställningar" msgid "&Auto Update:" msgstr "&Uppdatera automatiskt:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Automatisk start" @@ -367,11 +369,11 @@ msgstr "&Automatisk start" msgid "&Borderless Window" msgstr "&Kantlöst fönster" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Brytpunkter" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Bugghanterare" @@ -379,15 +381,15 @@ msgstr "&Bugghanterare" msgid "&Cancel" msgstr "&Avbryt" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Fuskhanterare" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Leta efter uppdateringar..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Rensa symboler" @@ -395,7 +397,7 @@ msgstr "&Rensa symboler" msgid "&Clone..." msgstr "&Klona..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Kod" @@ -403,7 +405,7 @@ msgstr "&Kod" msgid "&Connected" msgstr "&Inkopplad" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Kontrollinställningar" @@ -442,11 +444,11 @@ msgstr "&Redigera kod…" msgid "&Edit..." msgstr "&Redigera..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Mata ut skiva" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emulering" @@ -466,27 +468,27 @@ msgstr "&Exportera snabbsparning..." msgid "&Export as .gci..." msgstr "&Exportera som .gci..." -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Arkiv" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Teckensnitt…" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "Gå fram en &bildruta" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "&Fri vy-inställningar" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Generera symboler från" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "Källkoden på &GitHub" @@ -494,15 +496,15 @@ msgstr "Källkoden på &GitHub" msgid "&Go to start of function" msgstr "&Gå till början av funktionen" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "G&rafikinställningar" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Hjälp" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Kortkommandoinställningar" @@ -522,9 +524,9 @@ msgstr "&Importera snabbsparning..." msgid "&Import..." msgstr "&Importera..." -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" -msgstr "" +msgstr "&Infinitybas" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:595 msgid "&Insert blr" @@ -534,7 +536,7 @@ msgstr "&Infoga blr" msgid "&Interframe Blending" msgstr "Tidsut&jämning" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -542,11 +544,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Språk:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "L&äs in snabbsparning" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Ladda symbol-map" @@ -560,15 +562,15 @@ msgstr "&Ladda fil till nuvarande adress" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&Lås fast gränssnittselement" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Minne" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Inspelning" @@ -576,7 +578,7 @@ msgstr "&Inspelning" msgid "&Mute" msgstr "&Tyst" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Nätverk" @@ -585,23 +587,23 @@ msgid "&No" msgstr "&Nej" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Öppna..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "A<ernativ" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&Patcha HLE-funktioner" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Spela" @@ -609,7 +611,7 @@ msgstr "&Spela" msgid "&Properties" msgstr "&Egenskaper" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "S&krivskyddat läge" @@ -617,7 +619,7 @@ msgstr "S&krivskyddat läge" msgid "&Refresh List" msgstr "&Uppdatera lista" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Register" @@ -635,15 +637,15 @@ msgid "&Rename symbol" msgstr "&Byt namn på symbol" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Återställ" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Resurspaketshanterare" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Spara symbol-map" @@ -651,15 +653,15 @@ msgstr "&Spara symbol-map" msgid "&Scan e-Reader Card(s)..." msgstr "&Skanna e-Readerkort..." -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" -msgstr "" +msgstr "&Skylandersportal" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:175 msgid "&Speed Limit:" msgstr "&Hastighetsbegränsning:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "S&toppa" @@ -667,11 +669,11 @@ msgstr "S&toppa" msgid "&Theme:" msgstr "&Tema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "&Trådar" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Verktyg" @@ -685,17 +687,17 @@ msgstr "Ladda &ur ROM" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Visa" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&Bevakning" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Webbplats" @@ -707,11 +709,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Ja" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "'%1' hittades inte, inga symbolnamn genererade" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "'%1' hittades inte, skannar efter vanliga funktioner istället" @@ -773,7 +775,7 @@ msgstr "0" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:79 msgid "1 GiB" -msgstr "" +msgstr "1 GiB" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:31 msgid "128 Mbit (2043 blocks)" @@ -781,7 +783,7 @@ msgstr "128 Mbit (2043 block)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:76 msgid "128 MiB" -msgstr "" +msgstr "128 MiB" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:209 msgid "16 Bytes" @@ -789,7 +791,7 @@ msgstr "16 byte" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:83 msgid "16 GiB (SDHC)" -msgstr "" +msgstr "16 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:28 msgid "16 Mbit (251 blocks)" @@ -815,7 +817,7 @@ msgstr "16:9" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:94 msgid "16x Anisotropic" -msgstr "" +msgstr "16x anisotropisk" #: Source/Core/Core/HotkeyManager.cpp:193 msgid "1x" @@ -823,11 +825,11 @@ msgstr "1x" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:80 msgid "2 GiB" -msgstr "" +msgstr "2 GiB" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:77 msgid "256 MiB" -msgstr "" +msgstr "256 MiB" #: Source/Core/Core/HotkeyManager.cpp:194 msgid "2x" @@ -835,7 +837,7 @@ msgstr "2x" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:91 msgid "2x Anisotropic" -msgstr "" +msgstr "2x anisotropisk" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:66 msgid "2x Native (1280x1056) for 720p" @@ -843,7 +845,7 @@ msgstr "2x ursprunglig (1280x1056) för 720p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:84 msgid "32 GiB (SDHC)" -msgstr "" +msgstr "32 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:29 msgid "32 Mbit (507 blocks)" @@ -895,7 +897,7 @@ msgstr "4 byte" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:81 msgid "4 GiB (SDHC)" -msgstr "" +msgstr "4 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:26 msgid "4 Mbit (59 blocks)" @@ -911,7 +913,7 @@ msgstr "4x" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:92 msgid "4x Anisotropic" -msgstr "" +msgstr "4x anisotropisk" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "4x Native (2560x2112) for 1440p" @@ -919,7 +921,7 @@ msgstr "4x ursprunglig (2560x2112) för 1440p" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:78 msgid "512 MiB" -msgstr "" +msgstr "512 MiB" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:67 msgid "5x Native (3200x2640)" @@ -931,7 +933,7 @@ msgstr "64 Mbit (1019 block)" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:75 msgid "64 MiB" -msgstr "" +msgstr "64 MiB" #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:111 #: Source/Core/DolphinQt/CheatSearchWidget.cpp:164 @@ -962,7 +964,7 @@ msgstr "8 byte" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:82 msgid "8 GiB (SDHC)" -msgstr "" +msgstr "8 GiB (SDHC)" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:27 msgid "8 Mbit (123 blocks)" @@ -984,7 +986,7 @@ msgstr "8-bitars osignerat heltal" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:93 msgid "8x Anisotropic" -msgstr "" +msgstr "8x anisotropisk" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:69 msgid "8x Native (5120x4224) for 5K" @@ -1062,6 +1064,8 @@ msgid "" "A group of features to make the colors more accurate, matching the color " "space Wii and GC games were meant for." msgstr "" +"En grupp funktioner som gör färgerna mer autentiska genom att matcha " +"färgrymden Wii- och GC-spel designades för." #: Source/Core/DolphinQt/Main.cpp:226 msgid "A save state cannot be loaded without specifying a game to launch." @@ -1081,6 +1085,8 @@ msgid "" "A supported Bluetooth device could not be found.\n" "You must manually connect your Wii Remote." msgstr "" +"Ingen Bluetooth-enhet som stöds hittades.\n" +"Du måste ansluta din Wii-fjärrkontroll manuellt." #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:232 msgid "A sync can only be triggered when a Wii game is running." @@ -1158,9 +1164,9 @@ msgid "Accuracy:" msgstr "Precision:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" -msgstr "" +msgstr "Prestationer" #: Source/Core/DolphinQt/Debugger/BreakpointDialog.cpp:172 msgid "Action" @@ -1256,7 +1262,7 @@ msgstr "Aktiv" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:74 msgid "Active Infinity Figures:" -msgstr "" +msgstr "Aktiva Infinityfigurer:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:161 msgid "Active thread queue" @@ -1348,7 +1354,7 @@ msgstr "Lägg till..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adress" @@ -1376,6 +1382,13 @@ msgid "" "textures and might cause issues in a small number of games." "

If unsure, select 'Default'." msgstr "" +"Justerar texturfiltreringen. Anisotropisk filtrering förbättrar den visuella " +"kvaliteten för texturer som ses från sneda vinklar. Tvinga närmsta och " +"tvinga linjär åsidosätter texturskalningsfiltret som spelet har valt." +"

Alla alternativ utom \"Standard\" förändrar hur spelets texturer ser " +"ut och kan orsaka problem i ett litet antal spel." +"

Om du är osäker kan du välja \"Default\"." #. i18n: Refers to plastic shell of game controller (stick gate) that limits stick movements. #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:107 @@ -1598,15 +1611,15 @@ msgstr "Kantutjämning:" msgid "Any Region" msgstr "Valfri region" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "Lägg till signatur i" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "Lägg till i &existerande signaturfil..." -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "Appli&cera signaturfil..." @@ -1626,7 +1639,7 @@ msgstr "Apploader-datum:" msgid "Apply" msgstr "Verkställ" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "Applicera signaturfil" @@ -1738,7 +1751,7 @@ msgstr "Autojustera fönsterstorlek" msgid "Auto-Hide" msgstr "Dölj automatiskt" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "Upptäck RSO-moduler automatiskt?" @@ -1847,7 +1860,7 @@ msgstr "Ogiltigt värde angivet." #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Banner" @@ -1916,10 +1929,12 @@ msgid "" "Blank figure creation failed at:\n" "%1, try again with a different character" msgstr "" +"Misslyckades att skapa en blank figur i \"%1\".\n" +"Prova igen med en annan karaktär." #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "Blockstorlek" @@ -1957,7 +1972,7 @@ msgstr "" "Bluetooth-genomsläppningsläge är påslaget, men Dolphin byggdes utan libusb. " "Genomsläppningsläge kan inte användas." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "Pausa vid start" @@ -2034,7 +2049,7 @@ msgstr "Fel i bredbandsadapter" msgid "Broadband Adapter MAC Address" msgstr "Bredbandsadapterns MAC-adress" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "Bläddra bland &nätspelssessioner..." @@ -2099,7 +2114,7 @@ msgstr "Av: " msgid "C Stick" msgstr "C-spak" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "S&kapa signaturfil..." @@ -2205,7 +2220,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2281,7 +2296,7 @@ msgstr "Centrera och kalibrera" msgid "Change &Disc" msgstr "Byt &skiva" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "Byt s&kiva..." @@ -2302,6 +2317,9 @@ msgid "" "Changes the color of the FPS counter depending on emulation speed." "

If unsure, leave this checked." msgstr "" +"Byter färg på FPS-räknaren baserat på emuleringshastigheten." +"

Om du är osäker kan du lämna detta markerat." #: Source/Core/DolphinQt/Config/FreeLookWidget.cpp:44 msgid "" @@ -2333,7 +2351,7 @@ msgstr "Kanalpartition (%1)" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:260 msgid "Character entered is invalid!" -msgstr "" +msgstr "Den angivna karaktären är ogiltig!" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:264 msgid "Chat" @@ -2351,7 +2369,7 @@ msgstr "Sök efter fusk" msgid "Cheats Manager" msgstr "Fuskhanterare" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "Kontrollera NAND-minne..." @@ -2391,11 +2409,11 @@ msgstr "Välj en fil att öppna" msgid "Choose a file to open or create" msgstr "Välj en fil att öppna eller skapa" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "Välj primär indatafil" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "Välj sekundär indatafil" @@ -2430,13 +2448,13 @@ msgstr "Classic Controller" msgid "Clear" msgstr "Rensa" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Rensa cache" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:119 msgid "Clear Slot" -msgstr "" +msgstr "Rensa plats" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:83 msgid "Clock Override" @@ -2451,7 +2469,7 @@ msgstr "Klona och &redigera kod…" msgid "Close" msgstr "Stäng" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Ko&nfiguration" @@ -2488,17 +2506,17 @@ msgstr "Koder mottagna!" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:24 msgid "Color Correction Configuration" -msgstr "" +msgstr "Färgkorrigering" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:137 msgid "Color Correction:" -msgstr "" +msgstr "Färgkorrigering:" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:58 msgid "Color Space" -msgstr "" +msgstr "Färgrymd" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "Kombinera &två signaturfiler..." @@ -2535,7 +2553,7 @@ msgstr "Kompilerar shaders" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "Komprimering" @@ -2671,7 +2689,7 @@ msgstr "Bekräfta byte av backend" msgid "Confirm on Stop" msgstr "Bekräfta vid stopp" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2682,7 +2700,7 @@ msgstr "Bekräftelse" msgid "Connect" msgstr "Anslut" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Anslut balansbräda" @@ -2690,7 +2708,7 @@ msgstr "Anslut balansbräda" msgid "Connect USB Keyboard" msgstr "Anslut USB-tangentbord" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "Anslut Wii-fjärrkontroll %1" @@ -2710,7 +2728,7 @@ msgstr "Anslut Wii-fjärrkontroll 3" msgid "Connect Wii Remote 4" msgstr "Anslut Wii-fjärrkontroll 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Anslut Wii-fjärrkontroller" @@ -2786,6 +2804,11 @@ msgid "" "display.

HDR output is required for this setting to take effect." "

If unsure, leave this at 200." msgstr "" +"Ställer in basluminansen för en pappersvit yta, mätt i cd/m². Användbart för " +"att anpassa en HDR-skärm till olika bakgrundsbelysningsförhållanden." +"

HDR-signal ut krävs för att den här inställningen ska ta effekt." +"

Om du är osäker kan du låta detta vara 200." #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" @@ -2851,7 +2874,7 @@ msgstr "" msgid "Convergence" msgstr "Konvergens" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Konvergens:" @@ -2924,6 +2947,15 @@ msgid "" "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" +"Omvandlar färger från färgrymderna GC/Wii gjordes för till sRGB/Rec.709." +"

Det går inte att veta exakt vilken färgrymd ett visst spel " +"designades för eftersom det fanns flera standarder och de flesta spel inte " +"tog hänsyn till dem, så det är inte korrekt att anta att ett spel använder " +"ett visst format för att spelskivan är för en viss region. Du kan helt " +"enkelt välja den som ser mer naturlig ut för dig, eller den som matchar " +"regionen där spelet utvecklades.

HDR-signal ut krävs för att visa " +"alla färger från PAL- och NTSC-J-färgrymderna.
Om du är " +"osäker kan du lämna detta omarkerat." #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" @@ -2987,11 +3019,11 @@ msgstr "Kärna" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:64 msgid "Correct Color Space" -msgstr "" +msgstr "Korrigera färgrymd" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:93 msgid "Correct SDR Gamma" -msgstr "" +msgstr "Korrigera SDR-gamma" #. i18n: Performance cost, not monetary cost #: Source/Core/DolphinQt/Debugger/JITWidget.cpp:91 @@ -3138,7 +3170,7 @@ msgstr "Skapa" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:279 msgid "Create Infinity File" -msgstr "" +msgstr "Skapa Infinityfil" #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:62 #: Source/Core/DolphinQt/GCMemcardCreateNewDialog.cpp:74 @@ -3152,7 +3184,7 @@ msgstr "Skapa Skylanderfil" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:80 msgid "Create Skylander Folder" -msgstr "" +msgstr "Skapa Skylandermapp" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:109 msgid "Create mappings for other devices" @@ -3215,7 +3247,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Nuvarande region" @@ -3245,11 +3277,11 @@ msgstr "Alternativ för egen realtidsklocka" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 msgid "Custom:" -msgstr "" +msgstr "Anpassad:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" -msgstr "" +msgstr "Anpassa" #: Source/Core/Core/HW/GBAPadEmu.h:37 Source/Core/Core/HW/GCPadEmu.h:57 #: Source/Core/Core/HW/WiimoteEmu/Extension/Classic.h:223 @@ -3400,7 +3432,7 @@ msgstr "Sänk intern upplösning" #: Source/Core/Core/HotkeyManager.cpp:183 msgid "Decrease Selected State Slot" -msgstr "" +msgstr "Sänk vald snabbsparningsplats" #: Source/Core/Core/FreeLookManager.cpp:108 msgid "Decrease X" @@ -3415,7 +3447,7 @@ msgstr "Minska Y" msgid "Default" msgstr "Standard" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "Standardinställningar (skrivskyddad)" @@ -3481,7 +3513,7 @@ msgstr "Radera den existerande filen '{0}'?" msgid "Depth" msgstr "Djup" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "Djupandel:" @@ -3494,7 +3526,7 @@ msgstr "Djup:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Beskrivning" @@ -3516,11 +3548,11 @@ msgstr "Frikopplad" msgid "Detect" msgstr "Sök" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "Upptäcker RSO-moduler" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "Deterministiska dubbla kärnor:" @@ -3595,7 +3627,7 @@ msgstr "Inaktivera EFB-VRAM-kopior" msgid "Disable Emulation Speed Limit" msgstr "Inaktivera emuleringshastighetsgräns" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "Inaktivera fastmem" @@ -3603,7 +3635,7 @@ msgstr "Inaktivera fastmem" msgid "Disable Fog" msgstr "Inaktivera dimma" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "Inaktivera JIT-cache" @@ -3693,7 +3725,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "Vill du lägga till \"%1\" i listan av spelsökvägar?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "Vill du tömma symbolnamnlistan?" @@ -3724,17 +3756,17 @@ msgstr "Dolphin-FIFO-logg (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Förinställd Dolphin-spelmod" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin-map-fil (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Dolphin-signatur-CSV-fil" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Dolphin-signaturfil" @@ -3883,7 +3915,7 @@ msgstr "Trumset" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:210 msgid "Dual Core" -msgstr "Dual Core" +msgstr "Dubbla kärnor" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:212 msgid "Dual View" @@ -3909,7 +3941,7 @@ msgstr "Dumpa &FakeVMEM" msgid "Dump &MRAM" msgstr "Dumpa &MRAM" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Dumpa ljud" @@ -3921,7 +3953,7 @@ msgstr "Dumpa bastexturer" msgid "Dump EFB Target" msgstr "Dumpa EFB-mål" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Dumpa bildrutor" @@ -4008,7 +4040,7 @@ msgstr "Varaktighet för turboknappsläppning (bildrutor):" msgid "Dutch" msgstr "Nederländska" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "A&vsluta" @@ -4064,7 +4096,7 @@ msgid "Edit..." msgstr "Redigera..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "Editor" @@ -4115,7 +4147,7 @@ msgstr "Emulera skivhastighet" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:60 msgid "Emulate Infinity Base" -msgstr "" +msgstr "Emulera Infinitybas" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:146 msgid "Emulate Skylander Portal" @@ -4131,9 +4163,9 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" -msgstr "" +msgstr "Emulerade USB-enheter" #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:141 msgid "Emulated Wii Remote" @@ -4173,7 +4205,7 @@ msgstr "Aktivera API-valideringslager" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:60 msgid "Enable Achievements" -msgstr "" +msgstr "Aktivera prestationer" #: Source/Core/DolphinQt/Settings/AudioPane.cpp:142 msgid "Enable Audio Stretching" @@ -4189,7 +4221,7 @@ msgstr "Aktivera egen realtidsklocka" #: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 msgid "Enable Debugging UI" -msgstr "" +msgstr "Aktivera felsökningsgränssnitt" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" @@ -4209,7 +4241,7 @@ msgstr "Åsidosätt den emulerade minnesstorleken" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:78 msgid "Enable Encore Achievements" -msgstr "" +msgstr "Aktivera reprisprestationer" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:89 msgid "Enable FPRF" @@ -4234,7 +4266,7 @@ msgstr "Aktivera Progressive scan" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:45 msgid "Enable RetroAchievements.org Integration" -msgstr "" +msgstr "Aktivera RetroAchievements.org-integrering" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:66 msgid "Enable Rich Presence" @@ -4255,7 +4287,7 @@ msgstr "Aktivera högtalardata" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:72 msgid "Enable Unofficial Achievements" -msgstr "" +msgstr "Aktivera inofficiella prestationer" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:230 msgid "Enable Usage Statistics Reporting" @@ -4263,7 +4295,7 @@ msgstr "Aktivera statistikrapportering" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:161 msgid "Enable WiiConnect24 via WiiLink" -msgstr "" +msgstr "Aktivera WiiConnect24 via WiiLink" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:81 msgid "Enable Wireframe" @@ -4271,7 +4303,7 @@ msgstr "Aktivera Wireframe" #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:77 msgid "Enable Write-Back Cache (slow)" -msgstr "" +msgstr "Aktivera cache för skrivningar (långsamt)" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:64 msgid "" @@ -4287,11 +4319,13 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" msgstr "" +"Aktiverar emulerad skivhastighet. Att stänga av detta kan leda till kraschar " +"och andra problem i vissa spel. (PÅ = kompatibel, AV = obegränsad)" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:47 msgid "" @@ -4308,6 +4342,10 @@ msgid "" "will be notified if they meet the unlock conditions again, useful for custom " "speedrun criteria or simply for fun." msgstr "" +"Aktiverar upplåsning av prestationer i reprisläge.

Reprisläge " +"återaktiverar prestationer som du redan har låst upp så att du får en notis " +"om du uppnår kraven för att låsa upp prestationen igen. Användbart för " +"anpassade speedrun-kriterier eller helt enkelt för skojs skull." #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:61 msgid "Enable unlocking achievements.
" @@ -4329,7 +4367,7 @@ msgstr "" "Aktiverar emulering av Dolby Pro Logic II med hjälp av 5.1 surround. Endast " "för vissa backends." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4362,6 +4400,9 @@ msgid "" "Enabling will have a significant impact on performance.\n" "This should be left disabled unless absolutely needed." msgstr "" +"Emulerar CPU:ns cache när data ska skrivas till minnet.\n" +"Att aktivera detta har stor påverkan på prestandan.\n" +"Aktivera bara detta om det absolut behövs." #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:365 msgid "" @@ -4395,6 +4436,13 @@ msgid "" "

Note that games still render in SDR internally." "

If unsure, leave this unchecked." msgstr "" +"Aktiverar scRGB-HDR-signal ut (om det stöds av din grafikbackend och skärm). " +"Det kan hända att helskärm krävs.

Detta ger efterbehandlingseffekter " +"mer utrymme att återskapa autentiska färger, gör det möjligt för \"AutoHDR\"-" +"efterbehandlingseffekter att fungera, och gör det möjligt att visa hela PAL- " +"och NTSC-J-färgrymderna.

Observera att spel fortfarande renderar med " +"SDR internt.

Om du är osäker kan du lämna detta " +"omarkerat." #: Source/Core/DolphinQt/Settings/AudioPane.cpp:151 msgid "Enables stretching of the audio to match emulation speed." @@ -4412,7 +4460,7 @@ msgstr "" "begränsas av CPU:n.

Om du är osäker kan du lämna " "detta omarkerat." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4428,6 +4476,10 @@ msgid "" "such as the Forecast and Nintendo Channels\n" "Read the Terms of Service at: https://www.wiilink24.com/tos" msgstr "" +"Aktiverar WiiLink-tjänsten för WiiConnect24-kanaler.\n" +"WiiLink är en alternativ operatör för nedstängda WiiConnect24-kanaler som " +"Forecast Channel och Nintendo Channel.\n" +"Läs användarvillkoren på: https://www.wiilink24.com/tos" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:298 msgid "" @@ -4508,7 +4560,7 @@ msgstr "Ange lösenord" msgid "Enter the DNS server to use:" msgstr "Ange DNS-server:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "Ange RSO-moduladressen:" @@ -4555,18 +4607,18 @@ msgstr "Ange RSO-moduladressen:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4596,13 +4648,13 @@ msgstr "Ett fel uppstod när adaptern skulle öppnas: %1" #: Source/Core/Core/NetPlayServer.cpp:1493 msgid "Error collecting save data!" -msgstr "" +msgstr "Fel uppstod när spardata samlades in!" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:260 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:526 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:533 msgid "Error converting value" -msgstr "" +msgstr "Misslyckades att konvertera värde" #: Source/Core/DolphinQt/Translation.cpp:323 msgid "Error loading selected language. Falling back to system default." @@ -4711,7 +4763,7 @@ msgstr "Fel hittades i {0} oanvända block i {1}-partitionen." msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Europa" @@ -4792,7 +4844,7 @@ msgstr "Variabelnamn förväntades." msgid "Experimental" msgstr "Experimentell" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Exportera alla Wii-sparningar" @@ -4807,7 +4859,7 @@ msgstr "Exportering misslyckades" msgid "Export Recording" msgstr "Exportera inspelning" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Exportera inspelning..." @@ -4835,7 +4887,7 @@ msgstr "Exportera som .&gcs..." msgid "Export as .&sav..." msgstr "Exportera som .&sav..." -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4863,7 +4915,7 @@ msgstr "Extern" msgid "External Frame Buffer (XFB)" msgstr "Extern bildrutebuffert (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "Extrahera certifikat från NAND-minne" @@ -4901,7 +4953,7 @@ msgid "FD" msgstr "FD" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO-spelare" @@ -4921,7 +4973,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "Misslyckades att lägga till denna session i nätspelsindex: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "Misslyckades att lägga till i signaturfilen \"%1\"" @@ -4931,11 +4983,11 @@ msgstr "Misslyckades att göra anspråk på interface för BT-genomsläpp: {0}" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:574 msgid "Failed to clear Skylander!" -msgstr "" +msgstr "Misslyckades att rensa Skylander!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:575 msgid "Failed to clear the Skylander from slot(%1)!" -msgstr "" +msgstr "Misslyckades att rensa Skylander från plats(%1)!" #: Source/Core/DiscIO/VolumeVerifier.cpp:108 msgid "Failed to connect to Redump.org" @@ -4964,11 +5016,11 @@ msgstr "Misslyckades att skapa DXGI-fabrik" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:289 msgid "Failed to create Infinity file" -msgstr "" +msgstr "Misslyckades att skapa Infinityfil" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:678 msgid "Failed to create Skylander file!" -msgstr "" +msgstr "Misslyckades att skapa Skylanderfil!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:679 msgid "" @@ -4976,6 +5028,9 @@ msgid "" "%1\n" "(Skylander may already be on the portal)" msgstr "" +"Misslyckades att skapa Skylanderfil:\n" +"%1\n" +"(Skylandern kanske redan är på portalen)" #: Source/Core/Core/NetPlayClient.cpp:1292 msgid "" @@ -5019,7 +5074,7 @@ msgstr "Misslyckades med att exportera %n av %1 sparfil(er)." msgid "Failed to export the following save files:" msgstr "Misslyckades att exportera följande sparfiler:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "Misslyckades att extrahera certifikat från NAND-minnet" @@ -5049,14 +5104,14 @@ msgstr "Misslyckades att hitta en eller flera D3D-symboler" msgid "Failed to import \"%1\"." msgstr "Misslyckades att importera \"%1\"." -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" "Misslyckades att importera sparfil. Starta spelet en gång och prova sedan " "igen." -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." @@ -5064,7 +5119,7 @@ msgstr "" "Misslyckades att importera sparfil. Den givna filen verkar vara skadad eller " "är inte en giltig Wii-sparfil." -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5098,7 +5153,7 @@ msgid "Failed to install pack: %1" msgstr "Misslyckades att installera paket: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "Misslyckades att installera denna titel till NAND-minnet." @@ -5108,8 +5163,8 @@ msgid "" "running?" msgstr "Misslyckades att lyssna på port %1. Körs nätspelsservern redan?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "Misslyckades att ladda RSO-model vid %1" @@ -5121,17 +5176,17 @@ msgstr "Misslyckades att ladda d3d11.dll" msgid "Failed to load dxgi.dll" msgstr "Misslyckades att ladda dxgi.dll" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "Misslyckades att läsa map-filen \"%1\"" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:720 msgid "Failed to load the Skylander file!" -msgstr "" +msgstr "Misslyckades att ladda Skylanderfilen!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:721 msgid "Failed to load the Skylander file(%1)!\n" -msgstr "" +msgstr "Misslyckades att ladda Skylanderfilen(%1)!\n" #: Source/Core/Core/Boot/Boot.cpp:560 msgid "Failed to load the executable to memory." @@ -5185,23 +5240,27 @@ msgstr "Misslyckades att öppna servern" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:164 msgid "Failed to open the Infinity file!" -msgstr "" +msgstr "Misslyckades att öppna Infinityfilen!" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:165 msgid "" "Failed to open the Infinity file(%1)!\n" "File may already be in use on the base." msgstr "" +"Misslyckades att öppna Infinityfilen(%1)!\n" +"Filen kanske redan används på basen." #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:696 msgid "Failed to open the Skylander file!" -msgstr "" +msgstr "Misslyckades att öppna Skylanderfilen!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:697 msgid "" "Failed to open the Skylander file(%1)!\n" "File may already be in use on the portal." msgstr "" +"Misslyckades att öppna Skylanderfilen(%1)!\n" +"Filen kanske redan används på portalen." #: Source/Core/DolphinQt/ConvertDialog.cpp:472 msgid "Failed to open the input file \"%1\"." @@ -5247,23 +5306,27 @@ msgstr "Kunde inte läsa vald(a) sparfil(er) från minneskort." #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:173 msgid "Failed to read the Infinity file!" -msgstr "" +msgstr "Misslyckades att läsa Infinityfilen!" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:174 msgid "" "Failed to read the Infinity file(%1)!\n" "File was too small." msgstr "" +"Misslyckades att läsa Infinityfilen(%1)!\n" +"Filen var för liten." #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:706 msgid "Failed to read the Skylander file!" -msgstr "" +msgstr "Misslyckades att läsa Skylanderfilen!" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:707 msgid "" "Failed to read the Skylander file(%1)!\n" "File was too small." msgstr "" +"Misslyckades att läsa Skylanderfilen(%1)!\n" +"Filen var för liten." #: Source/Core/Core/Movie.cpp:1037 msgid "Failed to read {0}" @@ -5309,19 +5372,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "Misslyckades att spara FIFO-logg." -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "Misslyckades att spara kod-map till sökvägen \"%1\"" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "Misslyckades att spara signaturfilen \"%1\"" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "Misslyckades att spara symbol-map till sökvägen \"%1\"" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "Misslyckades att spara till signaturfilen \"%1\"" @@ -5371,7 +5434,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "Misslyckades" @@ -5411,7 +5474,7 @@ msgstr "Synfält" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:233 msgid "Figure Number:" -msgstr "" +msgstr "Figurnummer:" #: Source/Core/DolphinQt/Config/InfoWidget.cpp:46 msgid "File Details" @@ -5419,7 +5482,7 @@ msgstr "Fildetaljer" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Filformat" @@ -5433,18 +5496,18 @@ msgstr "Filinformation" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Filnamn" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Sökväg" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Filstorlek" @@ -5584,23 +5647,23 @@ msgstr "Tvinga 4:3" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:96 msgid "Force Linear" -msgstr "" +msgstr "Tvinga linjär" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:103 msgid "Force Linear and 16x Anisotropic" -msgstr "" +msgstr "Tvinga linjär och 16x anisotropisk" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:97 msgid "Force Linear and 2x Anisotropic" -msgstr "" +msgstr "Tvinga linjär och 2x anisotropisk" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:99 msgid "Force Linear and 4x Anisotropic" -msgstr "" +msgstr "Tvinga linjär och 4x anisotropisk" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:101 msgid "Force Linear and 8x Anisotropic" -msgstr "" +msgstr "Tvinga linjär och 8x anisotropisk" #: Source/Core/DolphinQt/NetPlay/NetPlaySetupDialog.cpp:135 msgid "Force Listen Port:" @@ -5608,7 +5671,7 @@ msgstr "Lyssna på port:" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:95 msgid "Force Nearest" -msgstr "" +msgstr "Tvinga närmsta" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:444 msgid "Forced off because %1 doesn't support VS expansion." @@ -5805,7 +5868,7 @@ msgstr "GBA (TCP)" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:114 msgid "GBA Cartridge Path:" -msgstr "" +msgstr "GBA-kassettsökväg:" #: Source/Core/Core/HotkeyManager.cpp:358 msgid "GBA Core" @@ -5868,6 +5931,12 @@ msgid "" "Further errors will be sent to the Video Backend log and Dolphin will now " "likely crash or hang." msgstr "" +"Grafik-FIFO: Okänd opcode ({0:#04x} @ {1}, preprocess={2}).\n" +"\n" +"{3}\n" +"\n" +"Vidare fel kommer skickas till Video Backend-loggen, och Dolphin kommer nu " +"antagligen krascha eller frysa." #: Source/Core/VideoBackends/OGL/OGLMain.cpp:181 msgid "GL_MAX_TEXTURE_SIZE is {0} - must be at least 1024." @@ -5975,7 +6044,7 @@ msgstr "Game Boy Advance i uttag %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 msgid "Game Color Space:" -msgstr "" +msgstr "Spelets färgrymd:" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 msgid "Game Config" @@ -5991,14 +6060,14 @@ msgstr "Spelmappar" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:88 msgid "Game Gamma" -msgstr "" +msgstr "Spelets gamma" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 msgid "Game Gamma:" -msgstr "" +msgstr "Spelets gamma:" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Spel-ID" @@ -6046,7 +6115,7 @@ msgstr "" msgid "Game region does not match" msgstr "Spelets region matchar inte" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Spelspecifika inställningar" @@ -6105,7 +6174,7 @@ msgstr "GameCube-TAS-inmatning %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:80 msgid "Gamma" -msgstr "" +msgstr "Gamma" #: Source/Core/InputCommon/ControllerEmu/ControlGroup/AnalogStick.cpp:103 msgid "Gate Size" @@ -6117,7 +6186,7 @@ msgid "Gecko Codes" msgstr "Gecko-koder" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6143,7 +6212,7 @@ msgstr "Generera en ny statistikidentitet" msgid "Generated AR code." msgstr "Genererade AR-kod." -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "Genererade symbolnamn från '%1'" @@ -6225,7 +6294,7 @@ msgstr "Grön vänster" msgid "Green Right" msgstr "Grön höger" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Rutnätsvy" @@ -6244,19 +6313,19 @@ msgstr "HDMI-3D" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:130 msgid "HDR" -msgstr "" +msgstr "HDR" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:139 msgid "HDR Paper White Nits" -msgstr "" +msgstr "HDR pappersvit cd/m²" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 msgid "HDR Paper White Nits:" -msgstr "" +msgstr "HDR pappersvit cd/m²:" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" -msgstr "" +msgstr "HDR efterbehandling" #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:62 msgid "Hacks" @@ -6300,7 +6369,7 @@ msgstr "Hexadecimal" msgid "Hide" msgstr "Göm" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "Dölj alla" @@ -6549,6 +6618,9 @@ msgid "" "being started. Useful when switching games mid-session. Has no effect if No " "Save Data is selected." msgstr "" +"Om du markerar detta används alla Wii-sparfiler, inte bara sparfilen för " +"spelet som startas. Användbart om du vill byta spel mitt i en session. Har " +"ingen effekt om du väljer \"Ingen spardata\"." #: Source/Core/Core/HW/GCPadEmu.cpp:87 msgid "" @@ -6641,7 +6713,7 @@ msgstr "" "

Om du är osäker kan du lämna detta omarkerat." -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "Importera BootMii-NAND-kopia..." @@ -6656,7 +6728,7 @@ msgstr "Importering misslyckades" msgid "Import Save File(s)" msgstr "Importera sparfil(er)" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Importera Wii-sparning…" @@ -6722,7 +6794,7 @@ msgstr "Öka intern upplösning" #: Source/Core/Core/HotkeyManager.cpp:182 msgid "Increase Selected State Slot" -msgstr "" +msgstr "Höj vald snabbsparningsplats" #: Source/Core/Core/FreeLookManager.cpp:107 msgid "Increase X" @@ -6742,15 +6814,15 @@ msgstr "Inkrementell rotation (rad/sek)" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:188 msgid "Infinity Figure Creator" -msgstr "" +msgstr "Infinityfigurskapare" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:37 msgid "Infinity Manager" -msgstr "" +msgstr "Infinityhanterare" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:280 msgid "Infinity Object (*.bin);;" -msgstr "" +msgstr "Infinityobjekt (*.bin);;" #. i18n: Refers to a setting controling the influence of accelerometer data. #: Source/Core/InputCommon/ControllerEmu/ControlGroup/IMUCursor.cpp:48 @@ -6770,8 +6842,8 @@ msgstr "Info" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Information" @@ -6780,10 +6852,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "Blockera skärmsläckare under emulering" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Indata" @@ -6824,7 +6896,7 @@ msgstr "Installationspartition (%1)" msgid "Install Update" msgstr "Installera uppdatering" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "Installera WAD…" @@ -6844,7 +6916,7 @@ msgstr "Instruktion" msgid "Instruction Breakpoint" msgstr "Instruktionsbrytpunkt" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "Instruktion:" @@ -6909,7 +6981,7 @@ msgstr "Ett internt fel uppstod när AR-kod skulle genereras." msgid "Interpreter (slowest)" msgstr "Interpreterare (långsammast)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "Interpreterarkärna" @@ -6934,7 +7006,7 @@ msgstr "Ogiltigt paket %1: %2" msgid "Invalid Player ID" msgstr "Ogiltigt spelar-ID" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "Ogiltig RSO-moduladress: %1" @@ -7009,11 +7081,11 @@ msgstr "Italienska" msgid "Italy" msgstr "Italien" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "JIT-blocklänkning av" @@ -7021,47 +7093,47 @@ msgstr "JIT-blocklänkning av" msgid "JIT Blocks" msgstr "JIT-block" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "JIT Branch av" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "JIT FloatingPoint av" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "JIT Integer av" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "JIT LoadStore Floating av" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "JIT LoadStore av" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "JIT LoadStore Paired av" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "JIT LoadStore lXz av" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "JIT LoadStore lbzx av" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "JIT LoadStore lwz av" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "JIT av (JIT-kärna)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "JIT Paired av" @@ -7073,11 +7145,11 @@ msgstr "JIT-omkompilerare för ARM64 (rekommenderas)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "JIT-omkompilerare för x86-64 (rekommenderas)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "JIT Register Cache av" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "JIT SystemRegisters av" @@ -7091,7 +7163,7 @@ msgstr "" "aldrig hända. Rapportera gärna detta till utvecklarna. Dolphin kommer nu " "avslutas." -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japan" @@ -7131,7 +7203,7 @@ msgstr "Tangentbord" #: Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp:44 msgid "Keyboard Controller" -msgstr "" +msgstr "Tangentbordskontroll" #: Source/Core/Core/HW/GCKeyboardEmu.cpp:57 #: Source/Core/Core/HW/GCKeyboardEmu.cpp:61 @@ -7150,7 +7222,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "Sparka ut spelare" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Korea" @@ -7210,7 +7282,7 @@ msgstr "Latens: ~80 ms" #: Source/Core/DolphinQt/NANDRepairDialog.cpp:81 msgid "Launching these titles may also fix the issues." -msgstr "" +msgstr "Det är möjligt att problemen också kan fixas av att starta titlarna." #: Source/Core/Core/FreeLookManager.cpp:90 #: Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp:36 @@ -7301,11 +7373,11 @@ msgstr "Ljus" msgid "Limit Chunked Upload Speed:" msgstr "Begränsa segmentuppladdningshastighet:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "Listkolumner" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Listvy" @@ -7321,11 +7393,11 @@ msgstr "Lyssnar" msgid "Load" msgstr "Läs in" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "Ladda &felaktig map-fil..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "Ladda &annan map-fil..." @@ -7335,15 +7407,15 @@ msgstr "Läs in anpassade texturer" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:118 msgid "Load File" -msgstr "" +msgstr "Ladda fil" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "Ladda GameCube-huvudmeny" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:145 msgid "Load Host's Save Data Only" -msgstr "" +msgstr "Ladda bara värdens spardata" #: Source/Core/Core/HotkeyManager.cpp:356 #: Source/Core/DolphinQt/Config/Mapping/HotkeyStatesOther.cpp:22 @@ -7360,7 +7432,7 @@ msgstr "Ladda in ROM" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:120 msgid "Load Slot" -msgstr "" +msgstr "Ladda plats" #: Source/Core/Core/HotkeyManager.cpp:181 #: Source/Core/Core/HotkeyManager.cpp:353 @@ -7447,40 +7519,40 @@ msgstr "Läs in snabbsparningsplats 8" msgid "Load State Slot 9" msgstr "Läs in snabbsparningsplats 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Läs in snabbsparning från fil" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Läs in snabbsparning från vald plats" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Läs in snabbsparning från plats" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Starta Wii-systemmeny %1" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:150 msgid "Load and Write Host's Save Data" -msgstr "" +msgstr "Ladda och skriv värdens spardata" #: Source/Core/Core/HotkeyManager.cpp:141 msgid "Load from Selected Slot" msgstr "Ladda från vald plats" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "Läs in från plats %1 - %2" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "Ladda map-fil" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "Starta vWii-systemmeny %1" @@ -7488,7 +7560,7 @@ msgstr "Starta vWii-systemmeny %1" msgid "Load..." msgstr "Ladda..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "Laddade symboler från '%1'" @@ -7533,7 +7605,7 @@ msgstr "Logg" msgid "Log Configuration" msgstr "Loggkonfiguration" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "Logga JIT-instruktionstäckning" @@ -7551,15 +7623,15 @@ msgstr "Loggningsutdata" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:55 msgid "Login" -msgstr "" +msgstr "Logga in" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:57 msgid "Login Failed" -msgstr "" +msgstr "Inloggning misslyckades" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:56 msgid "Logout" -msgstr "" +msgstr "Logga ut" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:284 msgid "" @@ -7617,7 +7689,7 @@ msgstr "Huvudspak" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "Skapare" @@ -7639,10 +7711,11 @@ msgstr "" "

Om du är osäker kan du lämna detta omarkerat." -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "Hantera NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "Manuell textursampling" @@ -7693,7 +7766,7 @@ msgstr "Minnesbrytpunkt" msgid "Memory Card" msgstr "Minneskort" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "Minneskorthanterare" @@ -7794,8 +7867,8 @@ msgstr "" "

Om du är osäker kan du lämna detta omarkerat." -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "Moduler hittade: %1" @@ -7803,7 +7876,7 @@ msgstr "Moduler hittade: %1" msgid "Mono" msgstr "Mono" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskopiska skuggor" @@ -7868,9 +7941,10 @@ msgstr "Multiplikator" msgid "N&o to All" msgstr "N&ej till alla" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND-minneskontroll" @@ -7879,14 +7953,14 @@ msgstr "NAND-minneskontroll" msgid "NKit Warning" msgstr "NKit-varning" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-J (ARIB TR-B9)" -msgstr "" +msgstr "NTSC-J (ARIB TR-B9)" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-K" @@ -7894,7 +7968,7 @@ msgstr "NTSC-K" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:69 msgid "NTSC-M (SMPTE 170M)" -msgstr "" +msgstr "NTSC-M (SMPTE 170M)" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:42 msgid "" @@ -7905,7 +7979,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7970,6 +8044,8 @@ msgid "" "Netplay will start using the Host's save data, and any save data created or " "modified during the Netplay session will remain in the Host's local saves." msgstr "" +"Nätspel startar med värdens spardata, och spardata som skapas eller " +"förändras under nätspelssessionen sparas bland värdens lokala spardata." #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:147 msgid "" @@ -7977,12 +8053,16 @@ msgid "" "modified during the Netplay session will be discarded at the end of the " "session." msgstr "" +"Nätspel startar med värdens spardata, men spardata som skapas eller " +"förändras under nätspelssessionen slängs när sessionen tar slut." #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:142 msgid "" "Netplay will start without any save data, and any created save data will be " "discarded at the end of the Netplay session." msgstr "" +"Nätspel startar utan någon spardata, och all spardata som skapas slängs när " +"nätspelssessionen tar slut." #: Source/Core/DolphinQt/Debugger/NetworkWidget.cpp:147 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:181 @@ -8082,7 +8162,7 @@ msgstr "Ingen sökträff" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:140 msgid "No Save Data" -msgstr "" +msgstr "Ingen spardata" #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:542 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:559 @@ -8113,7 +8193,7 @@ msgstr "Inget spel körs." msgid "No game running." msgstr "Inget spel körs." -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "Inga problem upptäcktes." @@ -8177,7 +8257,7 @@ msgstr "Ingen" msgid "North America" msgstr "Nordamerika" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Inte angiven" @@ -8252,7 +8332,7 @@ msgstr "Nunchuk" #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:184 msgid "Nunchuk Accelerometer" -msgstr "" +msgstr "Nunchuk-accelerometer" #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:277 msgid "Nunchuk Buttons" @@ -8304,15 +8384,15 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "&Dokumentation online " #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:47 msgid "Only Show Collection" -msgstr "" +msgstr "Visa bara samling" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8320,7 +8400,7 @@ msgstr "" "Lägg endast till symboler med prefix:\n" "(Lämna tomt för att exportera alla symboler)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8337,7 +8417,7 @@ msgstr "Öppna" msgid "Open &Containing Folder" msgstr "Öppna &innehållande mapp" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "Öppna &användarmapp" @@ -8443,11 +8523,11 @@ msgstr "Annat spel..." msgid "Overwritten" msgstr "Överskrivet" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "Spe&la upp inspelning..." -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8549,7 +8629,7 @@ msgstr "Sökvägar" msgid "Pause" msgstr "Pausa" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Pausa vid slutet av inspelningar" @@ -8590,7 +8670,7 @@ msgstr "Topphastigheten för svingande utåt." msgid "Per-Pixel Lighting" msgstr "Ljus per bildpunkt" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "Uppdatera systemmjukvaran via internet" @@ -8624,7 +8704,7 @@ msgstr "Fysiskt adressutrymme" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "Välj ett teckensnitt för felsökning" @@ -8641,7 +8721,7 @@ msgid "Pitch Up" msgstr "Luta uppåt" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Plattform" @@ -8659,7 +8739,7 @@ msgstr "Spela upp inspelning" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:78 msgid "Play Set/Power Disc" -msgstr "" +msgstr "Play Set/Power Disc" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:120 msgid "Playback Options" @@ -8671,27 +8751,27 @@ msgstr "Spelare" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:80 msgid "Player One" -msgstr "" +msgstr "Spelare ett" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:82 msgid "Player One Ability One" -msgstr "" +msgstr "Spelare ett förmåga ett" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:84 msgid "Player One Ability Two" -msgstr "" +msgstr "Spelare ett förmåga två" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:86 msgid "Player Two" -msgstr "" +msgstr "Spelare två" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:88 msgid "Player Two Ability One" -msgstr "" +msgstr "Spelare två förmåga ett" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:90 msgid "Player Two Ability Two" -msgstr "" +msgstr "Spelare två förmåga två" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:224 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:287 @@ -8705,6 +8785,9 @@ msgid "" "Please change the \"SyncOnSkipIdle\" setting to \"True\"! It's currently " "disabled, which makes this problem very likely to happen." msgstr "" +"Ändra inställningen \"SyncOnSkipIdle\" till \"True\"! Den är just nu " +"avstängd, vilket leder till väldigt stor risk för det här problemet att " +"inträffa." #: Source/Core/DolphinQt/CheatSearchFactoryWidget.cpp:164 msgid "" @@ -8717,7 +8800,7 @@ msgstr "" #: Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp:227 #: Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp:232 msgid "Point" -msgstr "Pekning" +msgstr "Peka" #: Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp:83 #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:66 @@ -8735,7 +8818,7 @@ msgstr "Port:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:163 msgid "Portal Slots" -msgstr "" +msgstr "Portalplatser" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:967 msgid "Possible desync detected: %1 might have desynced at frame %2" @@ -8889,7 +8972,7 @@ msgstr "Förlopp" msgid "Public" msgstr "Offentlig" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "Töm cache för spellista" @@ -8946,11 +9029,11 @@ msgstr "R-analog" msgid "READY" msgstr "KLAR" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO-moduler" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO auto-upptäckt" @@ -9110,7 +9193,7 @@ msgid "Refreshing..." msgstr "Uppdaterar..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Region" @@ -9213,7 +9296,7 @@ msgstr "Återställ" msgid "Reset All" msgstr "Återställ alla" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "Nollställ ignorera panikhanterare" @@ -9397,7 +9480,7 @@ msgstr "SD-kort" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:266 msgid "SD Card File Size:" -msgstr "" +msgstr "Filstorlek för SD-kort:" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:506 msgid "SD Card Image (*.raw);;All Files (*)" @@ -9450,11 +9533,11 @@ msgstr "SSL-kontext" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "&Spara kod" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "Spa&ra snabbsparning" @@ -9477,7 +9560,7 @@ msgstr "Spara alla" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "Sparfilsexportering" @@ -9498,11 +9581,11 @@ msgstr "Sparfil" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "Sparfiler (*.sav);;Alla filer (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "Sparfilsimportering" @@ -9564,23 +9647,23 @@ msgstr "Spara snabbsparningsplats 8" msgid "Save State Slot 9" msgstr "Spara snabbsparningsplats 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "Spara snabbsparning till fil" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "Spara snabbsparning på äldsta platsen" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Snabbspara på vald plats" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "Spara snabbsparning på plats" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "Spara symbol-map so&m..." @@ -9600,11 +9683,11 @@ msgstr "Spara som förinställningar..." msgid "Save as..." msgstr "Spara som..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "Spara kombinerad utdatafil som" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9618,11 +9701,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "Spara i samma katalog som ROM-filen" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "Spara map-fil" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "Spara signaturfil" @@ -9630,7 +9713,7 @@ msgstr "Spara signaturfil" msgid "Save to Selected Slot" msgstr "Spara på vald plats" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "Spara på plats %1 - %2" @@ -9666,7 +9749,7 @@ msgstr "Skärmdump" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Sök" @@ -9695,7 +9778,7 @@ msgstr "" "Sökning är inte möjligt i virtuellt adressutrymme just nu. Kör spelet ett " "kort tag och prova igen." -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Sök efter en instruktion" @@ -9703,13 +9786,13 @@ msgstr "Sök efter en instruktion" msgid "Search games..." msgstr "Sök efter spel..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "Sök efter en instruktion" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:236 msgid "Search:" -msgstr "" +msgstr "Sök:" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:59 msgid "Section that contains all Action Replay cheat codes." @@ -9740,13 +9823,13 @@ msgid "Select Dump Path" msgstr "Välj dump-sökväg:" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "Välj exporteringskatalog" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:137 msgid "Select Figure File" -msgstr "" +msgstr "Välj figurfil" #: Source/Core/DolphinQt/Settings/GameCubePane.cpp:653 msgid "Select GBA BIOS" @@ -9778,13 +9861,13 @@ msgstr "Välj Riivolution-XML-fil" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:410 msgid "Select Skylander Collection" -msgstr "" +msgstr "Välj Skylandersamling" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:481 msgid "Select Skylander File" msgstr "Välj Skylanderfil" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "Välj plats %1 - %2" @@ -9792,7 +9875,7 @@ msgstr "Välj plats %1 - %2" msgid "Select State" msgstr "Välj snabbsparning" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Välj snabbsparningsplats" @@ -9878,7 +9961,7 @@ msgstr "Välj en fil" msgid "Select a game" msgstr "Välj ett spel" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "Välj en titel att installera till NAND-minnet" @@ -9886,7 +9969,7 @@ msgstr "Välj en titel att installera till NAND-minnet" msgid "Select e-Reader Cards" msgstr "Välj e-Readerkort" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "Välj RSO-modulens adress:" @@ -9903,7 +9986,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "Välj nyckelfil (OTP/SEEPROM-kopia)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Välj sparningsfilen" @@ -10131,7 +10214,7 @@ msgstr "Shaderkompilering" #: Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp:228 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp:29 msgid "Shake" -msgstr "Skakning" +msgstr "Skaka" #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:232 msgid "Shinkansen" @@ -10146,11 +10229,11 @@ msgstr "Shinkansenkontroll" msgid "Show % Speed" msgstr "Visa %-hastighet" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "Visa &logg" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Visa &verktygsfält" @@ -10158,11 +10241,11 @@ msgstr "Visa &verktygsfält" msgid "Show Active Title in Window Title" msgstr "Visa aktiv titel i fönstertitel" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "Visa alla" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Visa Australien" @@ -10173,38 +10256,38 @@ msgstr "Visa nuvarande spel på Discord" #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:118 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:262 msgid "Show Disabled Codes First" -msgstr "" +msgstr "Visa avstängda koder först" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "Visa ELF/DOL" #: Source/Core/DolphinQt/Config/ARCodeWidget.cpp:117 #: Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp:261 msgid "Show Enabled Codes First" -msgstr "" +msgstr "Visa påslagna koder först" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:53 msgid "Show FPS" msgstr "Visa bildfrekvens" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Visa bildruteräknare" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:54 msgid "Show Frame Times" -msgstr "" +msgstr "Visa bildrutetider" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Visa Frankrike" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "Visa GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Visa Tyskland" @@ -10214,25 +10297,25 @@ msgstr "Visa överlägg för golfläge" #: Source/Core/Core/HotkeyManager.cpp:199 msgid "Show Infinity Base" -msgstr "" +msgstr "Visa Infinitybas" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Visa indata" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "Visa Italien" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "Visa JPN" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Visa Korea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Visa laggräknare" @@ -10240,7 +10323,7 @@ msgstr "Visa laggräknare" msgid "Show Language:" msgstr "Visa språk:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Visa logg&konfiguration" @@ -10252,7 +10335,7 @@ msgstr "Visa nätspelsmeddelanden" msgid "Show NetPlay Ping" msgstr "Visa nätspelsping" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Visa Nederländerna" @@ -10260,7 +10343,7 @@ msgstr "Visa Nederländerna" msgid "Show On-Screen Display Messages" msgstr "Visa meddelanden på skärmen" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "Visa PAL" @@ -10271,29 +10354,29 @@ msgstr "Visa PC" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:57 msgid "Show Performance Graphs" -msgstr "" +msgstr "Visa prestandagrafer" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Visa plattformar" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Visa regioner" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "Visa ominspelningsräknare" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Visa Ryssland" #: Source/Core/Core/HotkeyManager.cpp:198 msgid "Show Skylanders Portal" -msgstr "" +msgstr "Visa Skylandersportal" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "Visa Spanien" @@ -10305,39 +10388,39 @@ msgstr "Visa hastighetsfärger" msgid "Show Statistics" msgstr "Visa statistik" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Visa systemklocka" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Visa Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Visa USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Visa okänd" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:56 msgid "Show VBlank Times" -msgstr "" +msgstr "Visa vblank-tider" #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:55 msgid "Show VPS" msgstr "Visa VPS" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "Visa WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Visa Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Visa världen" @@ -10456,7 +10539,7 @@ msgstr "Tryck för liggande läge" msgid "Sideways Wii Remote" msgstr "Liggande Wii-fjärrkontroll" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "Signaturdatabas" @@ -10533,6 +10616,11 @@ msgid "" "issues.


If unsure, leave this " "unchecked." msgstr "" +"Hoppar över vertikal blankning-avbrott när lagg upptäcks, vilket håller " +"ljuduppspelningen mjuk när emuleringshastigheten inte är 100%." +"

VARNING: Kan leda till att spel fryser och andra " +"kompatibilitetsproblem.

Om du är " +"osäker kan du lämna detta omarkerat." #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:258 msgid "" @@ -10556,15 +10644,15 @@ msgstr "Skylander %1" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:482 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:551 msgid "Skylander (*.sky);;All Files (*)" -msgstr "" +msgstr "Skylander (*.sky);;Alla filer(*)" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:217 msgid "Skylander Collection Path:" -msgstr "" +msgstr "Sökväg för Skylandersamling:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:448 msgid "Skylander not found in this collection. Create new file?" -msgstr "" +msgstr "Skylandern hittades inte i den här samlingen. Vill du skapa en ny fil?" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:42 msgid "Skylanders Manager" @@ -10573,6 +10661,8 @@ msgstr "Skylandershanterare" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:81 msgid "Skylanders folder not found for this user. Create new folder?" msgstr "" +"Ingen Skylandersmapp hittades för den här användaren. Vill du skapa en ny " +"mapp?" #: Source/Core/Core/HW/WiimoteEmu/Extension/Guitar.cpp:97 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtension.cpp:140 @@ -10717,7 +10807,7 @@ msgstr "Standardkontroll" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "Starta &nätspel..." @@ -10725,7 +10815,7 @@ msgstr "Starta &nätspel..." msgid "Start New Cheat Search" msgstr "Starta ny fusksökning" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "Starta &inspelning" @@ -10819,7 +10909,7 @@ msgstr "Läge för stereoskopisk 3D" msgid "Stereoscopic 3D Mode:" msgstr "Läge för stereoskopisk 3D:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopi" @@ -10841,7 +10931,7 @@ msgstr "Spak" msgid "Stop" msgstr "Stoppa" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "Avbryt uppspelning/inspelning" @@ -10922,8 +11012,8 @@ msgstr "Penna" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "Klar" @@ -10950,7 +11040,7 @@ msgstr "Exporterade %n av %1 sparfil(er)." msgid "Successfully exported save files" msgstr "Exporteringen av sparfiler lyckades" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "Certifikaten har extraherats från NAND-minnet" @@ -10962,12 +11052,12 @@ msgstr "Extraheringen av filen lyckades." msgid "Successfully extracted system data." msgstr "Extraheringen av systemdata lyckades." -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "Importeringen av sparfilen lyckades." #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "Titeln har installerats i NAND-minnet." @@ -11026,7 +11116,7 @@ msgstr "" #: Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp:230 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp:35 msgid "Swing" -msgstr "Svängning " +msgstr "Svinga" #: Source/Core/DolphinQt/GCMemcardManager.cpp:242 msgid "Switch to A" @@ -11063,7 +11153,7 @@ msgstr "Symbolnamn" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Symboler" @@ -11083,7 +11173,7 @@ msgstr "Synka riktiga Wii-fjärrkontroller och para dem" msgid "Synchronize GPU thread" msgstr "Synkronisera grafikprocessortråd" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11117,7 +11207,7 @@ msgstr "Synkroniserar spardata..." msgid "System Language:" msgstr "Systemspråk:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS-inmatning" @@ -11130,7 +11220,7 @@ msgstr "TAS-verktyg" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Etiketter" @@ -11148,7 +11238,7 @@ msgstr "Svans" msgid "Taiwan" msgstr "Taiwan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Ta en skärmdump" @@ -11213,6 +11303,11 @@ msgid "" "\n" "Do you really want to switch to Direct3D 11? If unsure, select 'No'." msgstr "" +"Direct3D 11-renderaren kräver stöd för funktioner som inte stöds av din " +"systemkonfiguration. Du kan använda Direct3D 11-renderaren ändå, men det " +"kommer uppstå grafiska problem i vissa spel.\n" +"\n" +"Vill du verkligen byta till Direct3D 11? Om du är osäker, välj 'Nej'." #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." @@ -11232,7 +11327,7 @@ msgstr "IPL-filen är inte en känd korrekt version. (CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "Masterpiecepartitionerna saknas." -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." @@ -11241,7 +11336,7 @@ msgstr "" "säkerhetskopia av ditt nuvarande NAND-minne och sedan börjar om med ett " "nyskapat NAND-minne." -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND-minnet har reparerats." @@ -11262,6 +11357,10 @@ msgid "" "slower it will be to update.

If unsure, leave this " "at 1000ms." msgstr "" +"Mängden tid FPS- och VPS-räknarna ska sampla över.

Ju högre värde, " +"desto mer stabila blir FPS- och VPS-räknarna, men desto långsammare reagerar " +"de på förändringar.

Om du är osäker kan du låta " +"detta vara 1000 ms." #: Source/Core/DiscIO/VolumeVerifier.cpp:467 msgid "The channel partition is missing." @@ -11320,6 +11419,8 @@ msgid "" "The emulated NAND is damaged. System titles such as the Wii Menu and the Wii " "Shop Channel may not work correctly." msgstr "" +"Det emulerade NAND-minnet är skadat. Systemtitlar som Wii-menyn och Wii Shop " +"Channel kommer kanske inte fungera korrekt." #: Source/Core/DolphinQt/WiiUpdate.cpp:33 msgid "The emulated Wii console has been updated." @@ -11399,6 +11500,9 @@ msgid "" "folders. Please rename this folder to either %2, %3, or %4, matching the " "region of the save files that are in it." msgstr "" +"Mappen %1 följer inte Dolphins regionkodsformat för GCI-mappar. Byt namn på " +"mappen till antingen %2, %3 eller %4 i enlighet med vilken regions sparfiler " +"som finns i mappen." #: Source/Core/DiscIO/VolumeVerifier.cpp:781 msgid "" @@ -11557,6 +11661,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "Den angivna filen \"{0}\" finns inte" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "Destinationsminneskortet innehåller redan en fil med namnet \"%1\"." @@ -11592,6 +11702,12 @@ msgstr "Uppdateringspartitionen saknas." msgid "The update partition is not at its normal position." msgstr "Uppdateringspartitionen är inte på sin normala position." +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "{0}-partitionen har inte ett giltigt filsystem." @@ -11620,7 +11736,7 @@ msgstr "Det finns inget att ångra!" msgid "There was an issue adding a shortcut to the desktop" msgstr "Ett problem uppstod med att skapa en genväg på skrivbordet" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11745,12 +11861,19 @@ msgid "" "CPU, but your current settings make this unlikely to happen. If this error " "is stopping the game from working, please report it to the developers." msgstr "" +"Det här felet orsakas oftast av att den emulerade GPU:n desynkroniseras med " +"den emulerade CPU:n, men med dina nuvarande inställningar är det osannolikt " +"att det händer. Om det här felet gör att spelet inte fungerar, rapportera " +"gärna det till utvecklarna." #: Source/Core/VideoCommon/CommandProcessor.cpp:724 msgid "" "This error is usually caused by the emulated GPU desyncing with the emulated " "CPU. Turn off the \"Dual Core\" setting to avoid this." msgstr "" +"Det här felet orsakas oftast av att den emulerade GPU:n desynkroniseras med " +"den emulerade CPU:n. Stäng av inställningen \"dubbla kärnor\" för att " +"åtgärda detta." #: Source/Core/DiscIO/NANDImporter.cpp:116 msgid "This file does not contain a valid Wii filesystem." @@ -11863,7 +11986,7 @@ msgstr "" "\n" "DSPHLE: Okänd µcode (CRC = {0:08x}) - AXWii kommer användas." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." @@ -11871,7 +11994,7 @@ msgstr "" "Det här värdet adderas med konvergensvärdet som har ställts in i " "grafikkonfigurationen." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11918,7 +12041,7 @@ msgstr "TiB" #: Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp:229 #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionSimulation.cpp:32 msgid "Tilt" -msgstr "Lutning" +msgstr "Luta" #. i18n: Refers to the "Calibration" setting of gyroscope input. #: Source/Core/InputCommon/ControllerEmu/ControlGroup/IMUGyroscope.cpp:49 @@ -11934,7 +12057,7 @@ msgstr "Timeout" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Titel" @@ -11948,7 +12071,7 @@ msgstr "till" msgid "To:" msgstr "Till:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "&Helskärm" @@ -12045,7 +12168,7 @@ msgstr "Topp-och-botten" #: Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp:144 #: Source/Core/DolphinQt/Debugger/CodeDiffDialog.cpp:375 msgid "Total Hits" -msgstr "" +msgstr "Totalt antal träffar" #. i18n: Refers to an amount of rotational movement about the "pitch" axis. #: Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp:55 @@ -12150,15 +12273,15 @@ msgstr "USA" #: Source/Core/DolphinQt/Config/Mapping/HotkeyUSBEmu.cpp:21 msgid "USB Device Emulation" -msgstr "" +msgstr "USB-enhetsemulering" #: Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp:454 msgid "USB Emulation" -msgstr "" +msgstr "USB-emulering" #: Source/Core/Core/HotkeyManager.cpp:361 msgid "USB Emulation Devices" -msgstr "" +msgstr "Emulerade USB-enheter" #: Source/Core/Core/HW/EXI/EXI_Device.h:103 msgid "USB Gecko" @@ -12209,7 +12332,7 @@ msgstr "" "prestandapåverkan, men resultaten varierar beroende på grafikdrivrutinernas " "beteende." -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "Kunde inte upptäcka RSO-modul automatiskt" @@ -12276,11 +12399,11 @@ msgstr "Okomprimerade GC/Wii-skivavbildningar (*.iso *.gcm)" msgid "Undead" msgstr "Odöd" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Ångra inläsning av snabbsparning" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Ångra snabbsparning" @@ -12301,7 +12424,7 @@ msgstr "" "av denna titel tas bort från NAND-minnet utan att dess spardata tas bort. " "Vill du fortsätta?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "USA" @@ -12318,7 +12441,7 @@ msgstr "Okänd" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:744 msgid "Unknown (Id:%1 Var:%2)" -msgstr "" +msgstr "Okänd (Id:%1 Var:%2)" #: Source/Core/Core/HW/DVD/DVDInterface.cpp:1168 msgid "Unknown DVD command {0:08x} - fatal error" @@ -12389,11 +12512,11 @@ msgstr "" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:462 #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:546 msgid "Unknown(%1 %2).sky" -msgstr "" +msgstr "Okänd(%1 %2).sky" #: Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp:275 msgid "Unknown(%1).bin" -msgstr "" +msgstr "Okänd(%1).bin" #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:163 msgid "Unlimited" @@ -12409,19 +12532,19 @@ msgstr "Lås upp muspekare" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 msgid "Unlocked" -msgstr "" +msgstr "Upplåst" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 msgid "Unlocked %1 times this session" -msgstr "" +msgstr "Upplåst %1 gånger denna session" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 msgid "Unlocked (Casual)" -msgstr "" +msgstr "Upplåst (casual)" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 msgid "Unlocked this session" -msgstr "" +msgstr "Upplåst denna session" #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" @@ -12524,7 +12647,7 @@ msgstr "Ange 8.8.8.8 för vanlig DNS, eller ange en egen" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:164 msgid "Use All Wii Save Data" -msgstr "" +msgstr "Använd all Wii-spardata" #: Source/Core/DolphinQt/Settings/InterfacePane.cpp:145 msgid "Use Built-In Database of Game Names" @@ -12572,7 +12695,7 @@ msgstr "" "

Om du är osäker kan du lämna detta omarkerat." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "Gör så att båda ögon använder samma djupbuffert. Vissa spel kräver detta." @@ -12612,7 +12735,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Användarinställningar" @@ -12640,7 +12763,7 @@ msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementSettingsWidget.cpp:50 msgid "Username" -msgstr "" +msgstr "Användarnamn" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:270 msgid "" @@ -12708,7 +12831,7 @@ msgstr "V-synk" #: Source/Core/DolphinQt/Config/Graphics/HacksWidget.cpp:109 msgid "VBI Skip" -msgstr "" +msgstr "Hoppa över VBI" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:125 msgid "Value" @@ -12819,7 +12942,7 @@ msgstr "Volym upp" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD-filer (*.wad)" @@ -12854,6 +12977,9 @@ msgid "" "incomplete data on the NAND, including all associated save data. By " "continuing, the following title(s) will be removed:" msgstr "" +"VARNING: För att fixa det här NAND-minnet måste titlar som har ofullständig " +"data på NAND-minnet tas bort, inklusive tillhörande spardata. Om du " +"fortsätter kommer följande titlar tas bort:" #: Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp:31 msgid "" @@ -12945,7 +13071,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Varning" @@ -13132,7 +13258,7 @@ msgstr "Wii-fjärrkontroll %1" #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:111 msgid "Wii Remote Accelerometer" -msgstr "" +msgstr "Wii-fjärrkontrollaccelerometer" #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:269 msgid "Wii Remote Buttons" @@ -13140,7 +13266,7 @@ msgstr "Wii-fjärrkontrollknappar" #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:144 msgid "Wii Remote Gyroscope" -msgstr "" +msgstr "Wii-fjärrkontrollgyroskop" #: Source/Core/DolphinQt/Settings/WiiPane.cpp:349 msgid "Wii Remote Settings" @@ -13170,11 +13296,11 @@ msgstr "Wii och Wii-fjärrkontroller" msgid "Wii data is not public yet" msgstr "Wii-data är inte offentlig än" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii-sparfiler (*.bin);;Alla filer (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "WiiTools-signaturmegafil" @@ -13356,6 +13482,9 @@ msgid "" "for \"Phantasy Star Online Episode I & II\". If you are unsure, turn back " "now and configure a \"Standard Controller\"." msgstr "" +"Du håller på att konfigurera en \"tangentbordskontroll\", som bara är till " +"för \"Phantasy Star Online Episode I & II\". Om du är osäker, vänd tillbaka " +"och byt till \"standardkontroll\"." #: Source/Core/UICommon/AutoUpdate.cpp:222 msgid "You are running the latest version available on this update track." @@ -13436,6 +13565,12 @@ msgstr "" "Vill du avbryta nu för att åtgärda problemet?\n" "Om du väljer \"Nej\" kan det uppstå problem med ljudet." +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13472,7 +13607,7 @@ msgstr "justerat" msgid "any value" msgstr "valfritt värde" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "auto" @@ -13505,7 +13640,7 @@ msgstr "e-Readerkort (*.raw);;Alla filer (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "fake-completion" @@ -13551,7 +13686,7 @@ msgstr "" "mGBA-snabbsparningar (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *.ss8 " "*.ss9);;Alla filer (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "ingen" @@ -13576,7 +13711,7 @@ msgstr "s" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 msgid "sRGB" -msgstr "" +msgstr "sRGB" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" diff --git a/Languages/po/tr.po b/Languages/po/tr.po index f232946a63..a0ee61371e 100644 --- a/Languages/po/tr.po +++ b/Languages/po/tr.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: i286, 2022\n" "Language-Team: Turkish (http://app.transifex.com/delroth/dolphin-emu/" @@ -322,7 +322,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "&Hakkında" @@ -343,7 +343,7 @@ msgstr "&Fonksiyon Ekle" msgid "&Add..." msgstr "&Ekle..." -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "&Ses Ayarları" @@ -351,7 +351,7 @@ msgstr "&Ses Ayarları" msgid "&Auto Update:" msgstr "&Otomatik Güncelle:" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "&Otomatik Başlangıç" @@ -359,11 +359,11 @@ msgstr "&Otomatik Başlangıç" msgid "&Borderless Window" msgstr "&Çerçevesiz pencere" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "&Kesme Noktaları" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "&Hata İzleyici" @@ -371,15 +371,15 @@ msgstr "&Hata İzleyici" msgid "&Cancel" msgstr "&İptal" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "&Hile Yöneticisi" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "&Güncellemeleri Denetle..." -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "&Sembolleri Temizle" @@ -387,7 +387,7 @@ msgstr "&Sembolleri Temizle" msgid "&Clone..." msgstr "&Çoğalt..." -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "&Kod" @@ -395,7 +395,7 @@ msgstr "&Kod" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "&Denetleyici Ayarları" @@ -434,11 +434,11 @@ msgstr "&Kodu Düzenle..." msgid "&Edit..." msgstr "&Düzenle..." -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "&Diski Çıkart" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "&Emülasyon" @@ -458,27 +458,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "&Dosya" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "&Yazı Tipi..." -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "&Kare İlerletme" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "&Sembolleri Şuradan Getir" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "&GitHub Repo'su" @@ -486,15 +486,15 @@ msgstr "&GitHub Repo'su" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "&Grafik Ayarları" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "&Yardım" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "&Kısayol Ayarları" @@ -514,7 +514,7 @@ msgstr "" msgid "&Import..." msgstr "&İçeri aktar" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -526,7 +526,7 @@ msgstr "&BLR yerleştir" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -534,11 +534,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "&Dil:" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "Durumu &Yükle" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "&Sembol Haritasını Yükle" @@ -552,15 +552,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "&Gereçleri Yerinde Kilitle" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "&Hafıza" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "&Film" @@ -568,7 +568,7 @@ msgstr "&Film" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "&Ağ" @@ -577,23 +577,23 @@ msgid "&No" msgstr "&Hayır" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "&Aç..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "&Seçenekler" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "&HLE Fonksiyonlarını Yamala" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "&Duraklat" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "&Oynat" @@ -601,7 +601,7 @@ msgstr "&Oynat" msgid "&Properties" msgstr "&Özellikler" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "&Salt-Okunur Mod" @@ -609,7 +609,7 @@ msgstr "&Salt-Okunur Mod" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "&Kayıtlar" @@ -627,15 +627,15 @@ msgid "&Rename symbol" msgstr "&Sembolü yeniden adlandır" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "&Sıfırla" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "&Kaynak Paketi Yöneticisi" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "&Sembol Haritasını Kaydet" @@ -643,7 +643,7 @@ msgstr "&Sembol Haritasını Kaydet" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -651,7 +651,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "&Hız Limiti:" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "&Durdur" @@ -659,11 +659,11 @@ msgstr "&Durdur" msgid "&Theme:" msgstr "&Tema:" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "&Araçlar" @@ -677,17 +677,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "&Görünüm" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "&İzle" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "&Website" @@ -699,11 +699,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "&Evet" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1132,7 +1132,7 @@ msgid "Accuracy:" msgstr "Doğruluk:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1306,7 +1306,7 @@ msgstr "Ekle..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "Adres" @@ -1535,15 +1535,15 @@ msgstr "Kenar Yumuşatma:" msgid "Any Region" msgstr "Herhangi Bir Bölge" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1561,7 +1561,7 @@ msgstr "Apploader Tarihi:" msgid "Apply" msgstr "Uygula" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1668,7 +1668,7 @@ msgstr "Pencere Boyutunu Otomatik Ayarla" msgid "Auto-Hide" msgstr "Otomatik Gizle" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1771,7 +1771,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "Afiş" @@ -1843,7 +1843,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1881,7 +1881,7 @@ msgstr "" "Bluetooth Geçişi Modu etkin, ancak Dolphin libusb olmadan oluşturuldu. Geçiş " "modu kullanılamaz." -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1958,7 +1958,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -2020,7 +2020,7 @@ msgstr "" msgid "C Stick" msgstr "C Çubuğu" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2116,7 +2116,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2188,7 +2188,7 @@ msgstr "" msgid "Change &Disc" msgstr "&Diski Değiştir" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "&Diski Değiştir..." @@ -2250,7 +2250,7 @@ msgstr "Hile Arama" msgid "Cheats Manager" msgstr "Hile Yöneticisi" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2288,11 +2288,11 @@ msgstr "Açmak için bir dosya seçin" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2327,7 +2327,7 @@ msgstr "" msgid "Clear" msgstr "Temizle" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "Önbelleği Temizle" @@ -2348,7 +2348,7 @@ msgstr "" msgid "Close" msgstr "Kapat" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "Ya&pılandırma" @@ -2395,7 +2395,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2432,7 +2432,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2568,7 +2568,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "Durdurmayı Onayla" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2579,7 +2579,7 @@ msgstr "" msgid "Connect" msgstr "Bağlan" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "Balance Board Bağla" @@ -2587,7 +2587,7 @@ msgstr "Balance Board Bağla" msgid "Connect USB Keyboard" msgstr "USB Klavye Bağla" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "" @@ -2607,7 +2607,7 @@ msgstr "3. Wii Remote'u Bağla" msgid "Connect Wii Remote 4" msgstr "4. Wii Remote'u Bağla" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "Wii Remote Bağla" @@ -2732,7 +2732,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "Yakınsama:" @@ -3060,7 +3060,7 @@ msgid "" "leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "Mevcut Bölge" @@ -3256,7 +3256,7 @@ msgstr "" msgid "Default" msgstr "Varsayılan" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3316,7 +3316,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3329,7 +3329,7 @@ msgstr "Derinlik:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "Açıklama" @@ -3351,11 +3351,11 @@ msgstr "" msgid "Detect" msgstr "Belirle" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3430,7 +3430,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "Emülasyon Hızı Limitini Kapat" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3438,7 +3438,7 @@ msgstr "" msgid "Disable Fog" msgstr "Sisi Devre Dışı Bırak" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3511,7 +3511,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3542,17 +3542,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin Harita Dosyası (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3715,7 +3715,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "Sesi Dök" @@ -3727,7 +3727,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "EFB Hedef Dökümü" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "Kareleri Dök" @@ -3805,7 +3805,7 @@ msgstr "" msgid "Dutch" msgstr "Flemenkçe" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "&Çıkış" @@ -3853,7 +3853,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3920,7 +3920,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4073,7 +4073,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4115,7 +4115,7 @@ msgstr "" "Dolby Pro Logic II emülasyonunu etkinleştirerek 5.1 çevresel ses alınmasını " "sağlar. Yalnızca bazı oyunlarda çalışır." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4178,7 +4178,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4263,7 +4263,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "RSO modül adresini girin:" @@ -4310,18 +4310,18 @@ msgstr "RSO modül adresini girin:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4458,7 +4458,7 @@ msgstr "" msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "Avrupa" @@ -4539,7 +4539,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "Tüm Wii Kayıtlarını Ver" @@ -4554,7 +4554,7 @@ msgstr "" msgid "Export Recording" msgstr "Çekimi Ver" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "Çekimi Ver..." @@ -4582,7 +4582,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4610,7 +4610,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "Harici Çerçeve Arabelleği (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4648,7 +4648,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO Oynatıcısı" @@ -4666,7 +4666,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4760,7 +4760,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4787,18 +4787,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4825,7 +4825,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4835,8 +4835,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4848,7 +4848,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -5020,19 +5020,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5080,7 +5080,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5126,7 +5126,7 @@ msgstr "Dosya Ayrıntıları" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "Dosya Biçimi" @@ -5140,18 +5140,18 @@ msgstr "Dosya Bilgisi" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "Dosya Adı" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "Dosya Yolu" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "Dosya Boyutu" @@ -5664,7 +5664,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "Oyun ID'si" @@ -5708,7 +5708,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "Oyuna Özel Ayarlar" @@ -5779,7 +5779,7 @@ msgid "Gecko Codes" msgstr "Gecko Kodları" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5805,7 +5805,7 @@ msgstr "Yeni bir İstatistik Kimliği Oluşturun" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5882,7 +5882,7 @@ msgstr "Yeşil Sol" msgid "Green Right" msgstr "Yeşil Sağ" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "Sütun Görünümü" @@ -5957,7 +5957,7 @@ msgstr "Hexadecimal" msgid "Hide" msgstr "Gizle" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6231,7 +6231,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6246,7 +6246,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "Wii Kayıtlarını Al..." @@ -6351,8 +6351,8 @@ msgstr "Bilgi" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "Bilgilendirme" @@ -6361,10 +6361,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "Giriş" @@ -6405,7 +6405,7 @@ msgstr "" msgid "Install Update" msgstr "Güncellemeyi Kur" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "WAD Kur..." @@ -6425,7 +6425,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6488,7 +6488,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "Yorumlayıcı (çok yavaş)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6513,7 +6513,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6588,11 +6588,11 @@ msgstr "İtalyanca" msgid "Italy" msgstr "İtalya" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6600,47 +6600,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6652,11 +6652,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6667,7 +6667,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "Japonya" @@ -6726,7 +6726,7 @@ msgstr "" msgid "Kick Player" msgstr "Oyuncuyu At" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "Kore" @@ -6871,11 +6871,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "Liste Görünümü" @@ -6891,11 +6891,11 @@ msgstr "" msgid "Load" msgstr "Yükle" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6907,7 +6907,7 @@ msgstr "Özel Dokuları Yükle" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "GameCube Ana Menüsü'nü Yükle" @@ -7017,19 +7017,19 @@ msgstr "8. Durumu Yükle" msgid "Load State Slot 9" msgstr "9. Durumu Yükle" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "Dosyadan Durum Yükle" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "Seçili Yuvadan Durum Yükle" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "Yuvadan Durum Yükle" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "Wii Sistem Menüsünü Yükle %1" @@ -7041,16 +7041,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "Seçili Yuvadan Yükle" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7058,7 +7058,7 @@ msgstr "" msgid "Load..." msgstr "Yükle..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7097,7 +7097,7 @@ msgstr "Günlük" msgid "Log Configuration" msgstr "Günlük Yapılandırması" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7177,7 +7177,7 @@ msgstr "Ana Çubuk" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7194,10 +7194,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7248,7 +7249,7 @@ msgstr "" msgid "Memory Card" msgstr "Hafıza Kartı" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7333,8 +7334,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7342,7 +7343,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "Monoskopik Gölgeler" @@ -7405,9 +7406,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7416,7 +7418,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7442,7 +7444,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -7650,7 +7652,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7709,7 +7711,7 @@ msgstr "Hiçbiri" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "Ayarlanmamış" @@ -7831,7 +7833,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "Çevrimiçi &Belgeler" @@ -7839,13 +7841,13 @@ msgstr "Çevrimiçi &Belgeler" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7860,7 +7862,7 @@ msgstr "Aç" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7966,11 +7968,11 @@ msgstr "Diğer oyun..." msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8072,7 +8074,7 @@ msgstr "Yollar" msgid "Pause" msgstr "Duraklat" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "Filmin Sonunda Duraklat" @@ -8110,7 +8112,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "Piksel Aydınlatması" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "İnternet Üzerinden Sistem Güncellemesi Yap" @@ -8144,7 +8146,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8161,7 +8163,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "Platform" @@ -8394,7 +8396,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8450,11 +8452,11 @@ msgstr "R-Analog" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8608,7 +8610,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "Bölge" @@ -8706,7 +8708,7 @@ msgstr "Sıfırla" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8938,11 +8940,11 @@ msgstr "" msgid "START" msgstr "START TUŞU" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "&Durumu Kaydet" @@ -8965,7 +8967,7 @@ msgstr "Tümünü Kaydet" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8986,11 +8988,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9052,23 +9054,23 @@ msgstr "8. Duruma Kaydet" msgid "Save State Slot 9" msgstr "9. Duruma Kaydet" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "Durumu Seçili Slot'a Kaydet" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9088,11 +9090,11 @@ msgstr "" msgid "Save as..." msgstr "Farklı kaydet..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9103,11 +9105,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9115,7 +9117,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9151,7 +9153,7 @@ msgstr "Ekran Görüntüsü" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "Ara" @@ -9178,7 +9180,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "Bir talimat ara" @@ -9186,7 +9188,7 @@ msgstr "Bir talimat ara" msgid "Search games..." msgstr "Oyun ara..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9223,7 +9225,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9267,7 +9269,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9275,7 +9277,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "Durum Yuvası Seç" @@ -9361,7 +9363,7 @@ msgstr "" msgid "Select a game" msgstr "Bir oyun seç" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9369,7 +9371,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9386,7 +9388,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "Kayıt dosyasını seçin" @@ -9596,11 +9598,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "&Günlüğü Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "Araç Çubuğunu Gös&ter" @@ -9608,11 +9610,11 @@ msgstr "Araç Çubuğunu Gös&ter" msgid "Show Active Title in Window Title" msgstr "Etkin Başlığı Pencere Başlığında Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "Avusturalya'yı Göster" @@ -9625,7 +9627,7 @@ msgstr "Discord'da Mevcut Oyunu Göster" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "ELF/DOL'u Göster" @@ -9638,7 +9640,7 @@ msgstr "" msgid "Show FPS" msgstr "FPS'yi Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "Kare Sayacını Göster" @@ -9646,15 +9648,15 @@ msgstr "Kare Sayacını Göster" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "Fransızları Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "GameCube'leri Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "Almanları göster" @@ -9666,23 +9668,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "Görüntü Girişini Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "İtalyanları Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "Korelileri Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "Takılma Sayacını Göster" @@ -9690,7 +9692,7 @@ msgstr "Takılma Sayacını Göster" msgid "Show Language:" msgstr "Dili Göster:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "Geçmiş &Yapılandırmasını Göster" @@ -9702,7 +9704,7 @@ msgstr "NetPlay Mesajlarını Göster" msgid "Show NetPlay Ping" msgstr "NetPlay Ping'ini Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "Hollanda'yı Göster" @@ -9710,7 +9712,7 @@ msgstr "Hollanda'yı Göster" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "PAL'ları Göster" @@ -9723,19 +9725,19 @@ msgstr "PC'yi Göster" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "Platformları Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "Bölgeleri Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "Rusya'yı Göster" @@ -9743,7 +9745,7 @@ msgstr "Rusya'yı Göster" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "İspanya'yı Göster" @@ -9755,19 +9757,19 @@ msgstr "" msgid "Show Statistics" msgstr "İstatistikleri Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "Sistem Saatini Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "Tayvanlıları Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "Amerikanları Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "Bilinmeyenleri Göster" @@ -9779,15 +9781,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "WAD'ları Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "Wii'leri Göster" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "Dünyayı Göster" @@ -9896,7 +9898,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10138,7 +10140,7 @@ msgstr "Standart Denetleyici" msgid "Start" msgstr "Başlat" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "&Netplay'i Başlat..." @@ -10146,7 +10148,7 @@ msgstr "&Netplay'i Başlat..." msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10240,7 +10242,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "Stereoskopik 3D Modu:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "Stereoskopi" @@ -10262,7 +10264,7 @@ msgstr "Çubuk" msgid "Stop" msgstr "Durdur" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10333,8 +10335,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10361,7 +10363,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10373,12 +10375,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10471,7 +10473,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "Semboller" @@ -10491,7 +10493,7 @@ msgstr "Gerçek Wii Remote'ları senkronize edin ve onları eşleştirin" msgid "Synchronize GPU thread" msgstr "GPU işlemini eşitle" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10520,7 +10522,7 @@ msgstr "" msgid "System Language:" msgstr "Sistem Dili:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS Girişi" @@ -10533,7 +10535,7 @@ msgstr "TAS Araçları" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "Etiketler" @@ -10551,7 +10553,7 @@ msgstr "" msgid "Taiwan" msgstr "Tayvan" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "Ekran Görüntüsü Al" @@ -10633,13 +10635,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10909,6 +10911,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10942,6 +10950,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10970,7 +10984,7 @@ msgstr "Geri alacak hiçbirşey yok!" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11170,14 +11184,14 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" "Bu değer, grafik yapılandırmasında ayarlanan yakınsama değerine eklenir." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "Bu değer, grafik yapılandırmasında ayarlanan derinlik ile çarpılır." @@ -11230,7 +11244,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "Başlık" @@ -11244,7 +11258,7 @@ msgstr "Buraya" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "&Tam Ekran Moduna Geç" @@ -11490,7 +11504,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11549,11 +11563,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "Durum Yüklemeyi Geri Al" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "Durum Kaydetmeyi Geri Al" @@ -11573,7 +11587,7 @@ msgstr "" "Yüklü olan WAD dosyası, herhangi bir kayıt verisi silinmeden NAND'dan " "kaldırılacaktır. Devam edilsin mi?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "ABD" @@ -11824,7 +11838,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" "İki göz için tek bir derinlik aralığı kullanır. Bazı oyunlar için gereklidir." @@ -11863,7 +11877,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "Kullanıcı Yapılandırması" @@ -12057,7 +12071,7 @@ msgstr "Sesi Yükselt" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD dosyaları (*.wad)" @@ -12160,7 +12174,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "Uyarı" @@ -12343,11 +12357,11 @@ msgstr "Wii ve Wii Remote" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12568,6 +12582,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12604,7 +12624,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "otomatik" @@ -12637,7 +12657,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "sahte-tamamlama" @@ -12681,7 +12701,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "hiçbiri" diff --git a/Languages/po/zh_CN.po b/Languages/po/zh_CN.po index f5e6a27aaf..3cdd34f280 100644 --- a/Languages/po/zh_CN.po +++ b/Languages/po/zh_CN.po @@ -21,9 +21,9 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" -"Last-Translator: 天绝星 , 2015-2023\n" +"Last-Translator: 陈 依云 , 2023\n" "Language-Team: Chinese (China) (http://app.transifex.com/delroth/dolphin-emu/" "language/zh_CN/)\n" "Language: zh_CN\n" @@ -201,10 +201,12 @@ msgid "" "%1 has unlocked %2/%3 achievements (%4 hardcore) worth %5/%6 points (%7 " "hardcore)" msgstr "" +"%1 已解锁 %2/%3 项成就 (包括 %4 项 Hardcore 成就) 折合 %5/%6 成就点数 (包括 " +"%7 Hardcore 点数)" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:131 msgid "%1 has unlocked %2/%3 achievements worth %4/%5 points" -msgstr "" +msgstr "%1 已解锁 %2/%3 项成就,折合 %4/%5 成就点数" #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:1108 msgid "%1 is not a valid ROM" @@ -226,7 +228,7 @@ msgstr "%1 毫秒" #: Source/Core/DolphinQt/Achievements/AchievementHeaderWidget.cpp:86 #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:55 msgid "%1 points" -msgstr "" +msgstr "%1 成就点数" #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:265 msgid "%1 session found" @@ -336,7 +338,7 @@ msgstr "&3x" msgid "&4x" msgstr "&4x" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "关于(&A)" @@ -357,7 +359,7 @@ msgstr "添加函数(&A)" msgid "&Add..." msgstr "添加...(&A)" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "音频设置(&A)" @@ -365,7 +367,7 @@ msgstr "音频设置(&A)" msgid "&Auto Update:" msgstr "自动更新(&A):" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "自动开始游戏(&A)" @@ -373,11 +375,11 @@ msgstr "自动开始游戏(&A)" msgid "&Borderless Window" msgstr "无边框窗口(&B)" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "断点(&B)" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "错误跟踪器(&B)" @@ -385,15 +387,15 @@ msgstr "错误跟踪器(&B)" msgid "&Cancel" msgstr "取消(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "金手指管理器(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "检查更新...(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "清除符号(&C)" @@ -401,7 +403,7 @@ msgstr "清除符号(&C)" msgid "&Clone..." msgstr "克隆...(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "代码(&C)" @@ -409,7 +411,7 @@ msgstr "代码(&C)" msgid "&Connected" msgstr "连接(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "控制器设置(&C)" @@ -448,11 +450,11 @@ msgstr "编辑代码...(&E)" msgid "&Edit..." msgstr "编辑...(&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "弹出光盘(&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "模拟(&E)" @@ -472,27 +474,27 @@ msgstr "导出状态...(&E)" msgid "&Export as .gci..." msgstr "导出为 .gci...(&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "文件(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "字体...(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "逐帧播放(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "自由视点设置(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "生成符号来自(&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "GitHub 资源库(&G)" @@ -500,15 +502,15 @@ msgstr "GitHub 资源库(&G)" msgid "&Go to start of function" msgstr "转到函数起始位置(&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "图形设置(&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "帮助(&H)" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "热键设置(&H)" @@ -528,7 +530,7 @@ msgstr "导入状态...(&I)" msgid "&Import..." msgstr "导入...(&I)" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "Infinity 底座(&I)" @@ -540,7 +542,7 @@ msgstr "插入 blr (&I)" msgid "&Interframe Blending" msgstr "帧间混合(&I)" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "即时编译器(&J)" @@ -548,11 +550,11 @@ msgstr "即时编译器(&J)" msgid "&Language:" msgstr "语言(&L):" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "载入状态(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "载入符号映射(&L)" @@ -566,15 +568,15 @@ msgstr "将文件加载到当前地址(&L)" msgid "&Lock Watches" msgstr "锁定监视(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "锁定部件位置(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "内存(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "影片(&M)" @@ -582,7 +584,7 @@ msgstr "影片(&M)" msgid "&Mute" msgstr "静音(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "网络(&N)" @@ -591,23 +593,23 @@ msgid "&No" msgstr "否(&N)" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "打开...(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "选项(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "修补 HLE 功能函数(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "暂停游戏(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "开始游戏(&P)" @@ -615,7 +617,7 @@ msgstr "开始游戏(&P)" msgid "&Properties" msgstr "属性(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "只读模式(&R)" @@ -623,7 +625,7 @@ msgstr "只读模式(&R)" msgid "&Refresh List" msgstr "刷新列表(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "寄存器(&R)" @@ -641,15 +643,15 @@ msgid "&Rename symbol" msgstr "重命名符号(&R)" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "重置游戏(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "资源包管理器(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "保存符号映射(&S)" @@ -657,7 +659,7 @@ msgstr "保存符号映射(&S)" msgid "&Scan e-Reader Card(s)..." msgstr "扫描 e-Reader 卡...(&S)" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "Skylanders 传送门(&S)" @@ -665,7 +667,7 @@ msgstr "Skylanders 传送门(&S)" msgid "&Speed Limit:" msgstr "速度限制(&S):" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "停止游戏(&S)" @@ -673,11 +675,11 @@ msgstr "停止游戏(&S)" msgid "&Theme:" msgstr "主题(&T):" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "线程(&T)" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "工具(&T)" @@ -691,17 +693,17 @@ msgstr "卸载 ROM (&U)" msgid "&Unlock Watches" msgstr "解锁监视(&U)" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "视图(&V)" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "监视(&W)" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "网站(&W)" @@ -713,11 +715,11 @@ msgstr "百科(&W)" msgid "&Yes" msgstr "是(&Y)" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "找不到 '%1',未生成符号名" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "找不到 '%1',改为扫描常用函数" @@ -1156,7 +1158,7 @@ msgid "Accuracy:" msgstr "精确度:" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "成就" @@ -1342,7 +1344,7 @@ msgstr "添加..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "地址" @@ -1591,15 +1593,15 @@ msgstr "抗锯齿:" msgid "Any Region" msgstr "任意区域" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "附加签名到" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "附加到现有签名文件...(&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "应用签名文件...(&Y)" @@ -1619,7 +1621,7 @@ msgstr "应用载入器时间:" msgid "Apply" msgstr "应用" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "应用签名文件" @@ -1729,7 +1731,7 @@ msgstr "自动调整窗口大小" msgid "Auto-Hide" msgstr "自动隐藏" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "自动检测 RSO 模块?" @@ -1836,7 +1838,7 @@ msgstr "值格式不正确。" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "标图" @@ -1910,7 +1912,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "区块大小" @@ -1947,7 +1949,7 @@ msgid "" msgstr "" "蓝牙直通模式已启用,但 Dolphin 构建没有加入 libusb 驱动。无法使用直通模式。" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "引导后暂停" @@ -2024,7 +2026,7 @@ msgstr "宽带适配器错误" msgid "Broadband Adapter MAC Address" msgstr "宽带适配器 MAC 地址" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "浏览联机会话...(&N)" @@ -2088,7 +2090,7 @@ msgstr "作者:" msgid "C Stick" msgstr "C 摇杆" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "创建签名文件...(&R)" @@ -2190,7 +2192,7 @@ msgstr "游戏运行时无法启动联机会话!" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2261,7 +2263,7 @@ msgstr "中心和校准" msgid "Change &Disc" msgstr "切换光盘(&D)" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "切换光盘...(&D)" @@ -2330,7 +2332,7 @@ msgstr "金手指搜索" msgid "Cheats Manager" msgstr "金手指管理器" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "校验 NAND..." @@ -2368,11 +2370,11 @@ msgstr "选择要打开的文件" msgid "Choose a file to open or create" msgstr "选择要打开或创建的文件" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "选择优先输入文件" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "选择次要输入文件" @@ -2407,7 +2409,7 @@ msgstr "传统控制器" msgid "Clear" msgstr "清除" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "清除缓存" @@ -2428,7 +2430,7 @@ msgstr "复制并编辑代码...(&E)" msgid "Close" msgstr "关闭" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "程序设置(&N)" @@ -2475,7 +2477,7 @@ msgstr "色彩校正:" msgid "Color Space" msgstr "色彩空间" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "合并两个签名文件...(&T)" @@ -2516,7 +2518,7 @@ msgstr "正在编译着色器" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "压缩" @@ -2692,7 +2694,7 @@ msgstr "确认改变后端" msgid "Confirm on Stop" msgstr "停止游戏时确认" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2703,7 +2705,7 @@ msgstr "确认" msgid "Connect" msgstr "连接" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "连接平衡板" @@ -2711,7 +2713,7 @@ msgstr "连接平衡板" msgid "Connect USB Keyboard" msgstr "连接 USB 键盘" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "连接 Wii 遥控器 %1" @@ -2731,7 +2733,7 @@ msgstr "连接 Wii 遥控器 3" msgid "Connect Wii Remote 4" msgstr "连接 Wii 遥控器 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "连接 Wii 遥控器" @@ -2807,6 +2809,9 @@ msgid "" "display.

HDR output is required for this setting to take effect." "

If unsure, leave this at 200." msgstr "" +"控制 HDR 白色亮度(单位:尼特)。用于在使用 HDR 显示器时根据不同的环境照明条件" +"进行亮度调整。

此设置需要 HDR 输出才能生效。

" +"如果不确定,请将其保持为 200。" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:496 msgid "" @@ -2862,7 +2867,7 @@ msgstr "控制使用高级还是低级 DSP 模拟。默认值为 True" msgid "Convergence" msgstr "会聚" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "会聚:" @@ -2934,6 +2939,11 @@ msgid "" "required to show all the colors from the PAL and NTSC-J color spaces." "

If unsure, leave this unchecked." msgstr "" +"将颜色转换为 GC/Wii 所能使用的 sRGB/Rec.709 色彩空间。

考虑到存在多种" +"标准并且大多数游戏不认可,因此无法知道游戏的确切色彩空间是什么 ,所以从游戏光" +"盘区域假设一种格式是不正确的。只需选择对您来说更自然的格式,或将其与游戏开发" +"地的区域相匹配。

需要 HDR 输出才能显示 PAL 和 NTSC-J 色彩空间的所有颜" +"色。

如果不确定,请不要选中此项。" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:47 msgid "" @@ -3216,7 +3226,7 @@ msgstr "" "清除 CPU 上的顶点以减少所需的绘制调用数。可能影响性能和绘制统计数据。" "

如不确定,请不要选中此项。" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "当前区域" @@ -3246,7 +3256,7 @@ msgstr "自定义 RTC 选项" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:102 msgid "Custom:" -msgstr "" +msgstr "自定义:" #: Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp:117 msgid "Customize" @@ -3415,7 +3425,7 @@ msgstr "减小 Y" msgid "Default" msgstr "默认" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "默认配置 (只读)" @@ -3478,7 +3488,7 @@ msgstr "删除已经存在的文件 ‘{0}’ 吗?" msgid "Depth" msgstr "深度" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "深度百分比:" @@ -3491,7 +3501,7 @@ msgstr "深度:" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "说明" @@ -3513,11 +3523,11 @@ msgstr "分离的" msgid "Detect" msgstr "检测" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "正在检测 RSO 模块" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "确定性双核:" @@ -3592,7 +3602,7 @@ msgstr "禁用 EFB VRAM 副本" msgid "Disable Emulation Speed Limit" msgstr "禁用模拟速度限制" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "禁用快速内存" @@ -3600,7 +3610,7 @@ msgstr "禁用快速内存" msgid "Disable Fog" msgstr "禁用雾化" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "禁用 JIT 缓存" @@ -3683,7 +3693,7 @@ msgstr "是否授权 Dolphin 向开发者报告信息?" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "是否要添加 \"%1\" 到游戏路径列表?" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "你是否要清除符号名称列表?" @@ -3714,17 +3724,17 @@ msgstr "Dolphin FIFO 日志 (*.dff)" msgid "Dolphin Game Mod Preset" msgstr "Dolphin 游戏模组预设" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "Dolphin 映射文件 (*.map)" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "Dolphin 签名 CSV 文件" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "Dolphin 签名文件" @@ -3894,7 +3904,7 @@ msgstr "转储伪显存(&F)" msgid "Dump &MRAM" msgstr "转储主内存(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "转储音频" @@ -3906,7 +3916,7 @@ msgstr "转储基本纹理" msgid "Dump EFB Target" msgstr "转储 EFB 目标" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "转储帧" @@ -3990,7 +4000,7 @@ msgstr "连发按键的松开持续时间(帧):" msgid "Dutch" msgstr "荷兰语" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "退出模拟(&X)" @@ -4042,7 +4052,7 @@ msgid "Edit..." msgstr "编辑..." #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "编辑器" @@ -4109,7 +4119,7 @@ msgid "" "Defaults to True" msgstr "模拟实机的光盘速度。禁用可能会导致不稳定。默认启用" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "模拟 USB 设备" @@ -4167,7 +4177,7 @@ msgstr "启用自定义 RTC" #: Source/Core/DolphinQt/Settings/InterfacePane.cpp:149 msgid "Enable Debugging UI" -msgstr "" +msgstr "启用调试页面" #: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:87 msgid "Enable Dual Core" @@ -4269,7 +4279,7 @@ msgstr "" "戏中所做操作的详细描述。如果禁用此功能,网站将仅报告正在玩的游戏。

这" "对 Discord 的详细状态没有影响。" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4319,7 +4329,7 @@ msgid "" "only." msgstr "启用杜比定向逻辑II模拟5.1环绕声。仅适用于某些后端。" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4400,7 +4410,7 @@ msgstr "" "统中带来性能提升。

如果不确定,请不要选中此项。" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4496,7 +4506,7 @@ msgstr "输入密码" msgid "Enter the DNS server to use:" msgstr "输入要使用的 DNS 服务器:" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "请输入 RSO 模块地址:" @@ -4543,18 +4553,18 @@ msgstr "请输入 RSO 模块地址:" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4697,7 +4707,7 @@ msgstr "在 {1} 分区未使用的 {0} 区块中发现错误。" msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "欧洲" @@ -4790,7 +4800,7 @@ msgstr "建议使用的变量名称。" msgid "Experimental" msgstr "实验性" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "导出所有 Wii 存档" @@ -4805,7 +4815,7 @@ msgstr "导出失败" msgid "Export Recording" msgstr "导出录制" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "导出录制..." @@ -4833,7 +4843,7 @@ msgstr "导出为 .gcs...(&G)" msgid "Export as .&sav..." msgstr "导出为 .sav...(&S)" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4861,7 +4871,7 @@ msgstr "外部" msgid "External Frame Buffer (XFB)" msgstr "外部帧缓冲 (XFB)" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "从 NAND 中提取证书" @@ -4899,7 +4909,7 @@ msgid "FD" msgstr "文件描述符" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "FIFO 回放器" @@ -4919,7 +4929,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "无法将此会话添加到联机索引: %1" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "附加到签名文件 '%1' 失败" @@ -5016,7 +5026,7 @@ msgstr "在 %1 个存档文件中 %n 个导出失败。" msgid "Failed to export the following save files:" msgstr "导出以下存档文件失败:" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "从 NAND 中提取证书失败" @@ -5046,18 +5056,18 @@ msgstr "无法找到一个或多个 D3D 符号" msgid "Failed to import \"%1\"." msgstr "导入 \"%1\" 失败。" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "导入存档文件失败。请运行一次游戏,然后重试。" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "导入存档文件失败。给定的文件似乎已损坏或不是有效的 Wii 存档。" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -5089,7 +5099,7 @@ msgid "Failed to install pack: %1" msgstr "安装包失败: %1" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "无法将该游戏安装到 NAND。" @@ -5099,8 +5109,8 @@ msgid "" "running?" msgstr "监听端口 %1 失败。是否有另一个联机服务器的实例正在运行?" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "无法在 %1 处加载 RSO 模块" @@ -5112,7 +5122,7 @@ msgstr "载入 d3d11.dll 失败" msgid "Failed to load dxgi.dll" msgstr "载入 dxgi.dll 失败" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "载入映射文件 '%1' 失败" @@ -5299,19 +5309,19 @@ msgstr "重置联机重定向文件夹失败。请验证你的写入权限。" msgid "Failed to save FIFO log." msgstr "保存 FIFO 日志失败。" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "保存代码映射到路径 '%1' 失败" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "保存签名文件 '%1' 失败" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "保存符号映射到路径 '%1' 失败" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "保存到签名文件 '%1' 失败" @@ -5361,7 +5371,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "失败" @@ -5408,7 +5418,7 @@ msgstr "文件详细信息" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "文件格式" @@ -5422,18 +5432,18 @@ msgstr "文件信息" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "文件名" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "文件路径" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "文件大小" @@ -5965,7 +5975,7 @@ msgstr "GameBoy Advance 连至端口 %1" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:73 msgid "Game Color Space:" -msgstr "" +msgstr "游戏色彩空间:" #: Source/Core/DolphinQt/Config/PropertiesDialog.cpp:61 msgid "Game Config" @@ -5985,10 +5995,10 @@ msgstr "游戏伽玛" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:86 msgid "Game Gamma:" -msgstr "" +msgstr "游戏伽玛:" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "游戏 ID" @@ -6034,7 +6044,7 @@ msgstr "游戏覆盖了其他的游戏存档,将会破坏数据 {0:#x}, {1:#x} msgid "Game region does not match" msgstr "游戏区域不匹配" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "特定游戏设置" @@ -6105,7 +6115,7 @@ msgid "Gecko Codes" msgstr "Gecko 代码" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -6131,7 +6141,7 @@ msgstr "生成一个新的统计标识" msgid "Generated AR code." msgstr "已生成 AR 代码。" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "从 '%1' 中生成符号名" @@ -6211,7 +6221,7 @@ msgstr "绿 左" msgid "Green Right" msgstr "绿 右" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "网格视图" @@ -6238,7 +6248,7 @@ msgstr "HDR 白色亮度尼特数" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:137 msgid "HDR Paper White Nits:" -msgstr "" +msgstr "HDR 白色亮度尼特数:" #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:122 msgid "HDR Post-Processing" @@ -6286,7 +6296,7 @@ msgstr "十六进制" msgid "Hide" msgstr "隐藏" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "隐藏全部" @@ -6608,7 +6618,7 @@ msgstr "" "能也会略微降低。

如果不确定,请不要选中此项。" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "导入 BootMii NAND 备份..." @@ -6623,7 +6633,7 @@ msgstr "导入失败" msgid "Import Save File(s)" msgstr "导入存档文件" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "导入 Wii 存档..." @@ -6735,8 +6745,8 @@ msgstr "信息" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "信息" @@ -6745,10 +6755,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "在模拟过程中禁止屏幕保护程序" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "输入" @@ -6789,7 +6799,7 @@ msgstr "安装分区 (%1)" msgid "Install Update" msgstr "安装更新" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "安装 WAD..." @@ -6809,7 +6819,7 @@ msgstr "指令" msgid "Instruction Breakpoint" msgstr "指令断点" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "指令:" @@ -6878,7 +6888,7 @@ msgstr "生成 AR 代码时出现内部错误。" msgid "Interpreter (slowest)" msgstr "解释器(最慢)" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "解释器核心" @@ -6903,7 +6913,7 @@ msgstr "包 %1 无效: %2" msgid "Invalid Player ID" msgstr "无效玩家 ID" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "无效 RSO 模块地址: %1" @@ -6978,11 +6988,11 @@ msgstr "意大利语" msgid "Italy" msgstr "意大利" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "JIT" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "关闭 JIT 区块链接" @@ -6990,47 +7000,47 @@ msgstr "关闭 JIT 区块链接" msgid "JIT Blocks" msgstr "JIT 区块" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "关闭 JIT 分支" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "关闭 JIT 浮点" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "关闭 JIT 整数" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "关闭 JIT 加载存储浮动" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "关闭 JIT 加载存储" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "关闭 JIT 加载存储配对" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "关闭 JIT 加载存储 IXz" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "关闭 JIT 加载存储 Ibzx" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "关闭 JIT 加载存储 Iwz" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "关闭 JIT (JIT 核心)" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "关闭 JIT 配对" @@ -7042,11 +7052,11 @@ msgstr "适用于 ARM64 的 JIT 重编译器(推荐)" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "适用于 x86-64 的 JIT 重编译器(推荐)" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "关闭 JIT 寄存器缓存" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "关闭 JIT 系统寄存器" @@ -7059,7 +7069,7 @@ msgstr "" "清除缓存后,JIT 无法找到代码空间。这应该从不会出现。请在错误跟踪器中上报此事" "件。 Dolphin 即将退出。" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "日本" @@ -7118,7 +7128,7 @@ msgstr "KiB" msgid "Kick Player" msgstr "踢除玩家" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "韩国" @@ -7269,11 +7279,11 @@ msgstr "标识灯" msgid "Limit Chunked Upload Speed:" msgstr "限制数据块上传速度:" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "表单列" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "列表视图" @@ -7289,11 +7299,11 @@ msgstr "正在监听" msgid "Load" msgstr "载入" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "载入损坏映射文件(&B)..." -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "载入其他映射文件(&O)..." @@ -7305,7 +7315,7 @@ msgstr "加载自定义纹理" msgid "Load File" msgstr "载入文件" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "载入 GameCube 主菜单" @@ -7415,19 +7425,19 @@ msgstr "载入状态 8" msgid "Load State Slot 9" msgstr "载入状态 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "从文件中载入状态" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "从选择的插槽中加载状态" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "从插槽中载入状态" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "加载 Wii 系统菜单 %1" @@ -7439,16 +7449,16 @@ msgstr "加载和写入主机的存档数据" msgid "Load from Selected Slot" msgstr "从选择的插槽中加载" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "从插槽 %1 - %2 载入" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "载入映射文件" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "加载 vWii 系统菜单 %1" @@ -7456,7 +7466,7 @@ msgstr "加载 vWii 系统菜单 %1" msgid "Load..." msgstr "载入..." -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "已从 '%1' 中加载符号" @@ -7500,7 +7510,7 @@ msgstr "日志" msgid "Log Configuration" msgstr "日志设置" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "记录 JIT 指令范围" @@ -7583,7 +7593,7 @@ msgstr "主摇杆" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "制作者" @@ -7603,10 +7613,11 @@ msgstr "" "雾模拟,禁用雾将破坏其游戏性。

如果不确定,请不要选" "中此项。" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "管理 NAND" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "手动纹理采样" @@ -7657,7 +7668,7 @@ msgstr "内存断点" msgid "Memory Card" msgstr "存储卡" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "存储卡管理器" @@ -7753,8 +7764,8 @@ msgstr "" "修改纹理以显示以其编码格式。

可能需要重置模拟才能生效。" "

如果不确定,请不要选中此项。" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "已找到模块: %1" @@ -7762,7 +7773,7 @@ msgstr "已找到模块: %1" msgid "Mono" msgstr "单声道" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "单视场阴影" @@ -7825,9 +7836,10 @@ msgstr "多重分插器" msgid "N&o to All" msgstr "全部选否(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "NAND 校验" @@ -7836,7 +7848,7 @@ msgstr "NAND 校验" msgid "NKit Warning" msgstr "NKit 警告" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "NTSC-J" @@ -7861,8 +7873,12 @@ msgid "" "match it here.

If unsure, leave this at 2.35." msgstr "" +"NTSC-M 和 NTSC-J 标准伽玛值约为 2.2。PAL 的标准伽玛值约为 2.8。
游戏或电视" +"不一定遵循这两者。
2.35 是一个很好的通用值。

如果游戏允许您选择伽玛" +"值,请在此处进行设置。

如果不确定,请保持为 2.35。" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "NTSC-U" @@ -8076,7 +8092,7 @@ msgstr "没有游戏在运行。" msgid "No game running." msgstr "没有游戏运行。" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "没有发现问题。" @@ -8137,7 +8153,7 @@ msgstr "无" msgid "North America" msgstr "北美" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "未设置" @@ -8261,7 +8277,7 @@ msgstr "" "在同时支持使用几何着色器和顶点着色器来扩展点和线的后端上,为任务选择顶点着色" "器。可能会影响性能。

%1" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "在线文档(&D)" @@ -8269,7 +8285,7 @@ msgstr "在线文档(&D)" msgid "Only Show Collection" msgstr "只显示合集" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" @@ -8277,7 +8293,7 @@ msgstr "" "仅附加有此前缀的符号:\n" "(留空表示全部)" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -8294,7 +8310,7 @@ msgstr "打开" msgid "Open &Containing Folder" msgstr "打开所在目录(&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "打开用户目录(&U)" @@ -8400,11 +8416,11 @@ msgstr "其他游戏..." msgid "Overwritten" msgstr "覆盖" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "播放录制...(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "PAL" @@ -8506,7 +8522,7 @@ msgstr "路径" msgid "Pause" msgstr "暂停" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "在影片末尾暂停" @@ -8547,7 +8563,7 @@ msgstr "向外挥舞的峰值速度。" msgid "Per-Pixel Lighting" msgstr "逐像素光照" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "执行在线系统更新" @@ -8581,7 +8597,7 @@ msgstr "物理地址空间" msgid "PiB" msgstr "PiB" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "选择调试字体" @@ -8598,7 +8614,7 @@ msgid "Pitch Up" msgstr "上仰" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "平台" @@ -8835,7 +8851,7 @@ msgstr "进度" msgid "Public" msgstr "公开" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "清除游戏列表缓存" @@ -8891,11 +8907,11 @@ msgstr "R-模拟" msgid "READY" msgstr "就绪" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "RSO 模块" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "RSO 自动检测" @@ -9053,7 +9069,7 @@ msgid "Refreshing..." msgstr "正在刷新..." #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "地区" @@ -9155,7 +9171,7 @@ msgstr "重置" msgid "Reset All" msgstr "全部重置" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "重置忽略警告程序" @@ -9361,7 +9377,7 @@ msgstr "SD 同步文件夹:" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:97 msgid "SDR Display Gamma Target" -msgstr "" +msgstr "SDR 显示目标伽玛值" #: Source/Core/Core/HW/GBAPadEmu.h:43 #: Source/Core/Core/HW/WiimoteEmu/Extension/Shinkansen.cpp:42 @@ -9390,11 +9406,11 @@ msgstr "SSL 上下文" msgid "START" msgstr "START" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "保存代码(&V)" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "保存状态(&V)" @@ -9417,7 +9433,7 @@ msgstr "保存全部" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "存档导出" @@ -9438,11 +9454,11 @@ msgstr "游戏存档" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "游戏存档文件 (*.sav);;所有文件 (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "存档导入" @@ -9504,23 +9520,23 @@ msgstr "保存状态 8" msgid "Save State Slot 9" msgstr "保存状态 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "保存状态到文件" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "保存状态到最早的插槽" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "向选中的插槽保存状态" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "保存状态到插槽" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "保存符号映射为...(&A)" @@ -9540,11 +9556,11 @@ msgstr "另存为预设..." msgid "Save as..." msgstr "另存为..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "将组合输出文件另存为" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9557,11 +9573,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "保存在与 ROM 相同的目录中" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "保存映射文件" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "保存签名文件" @@ -9569,7 +9585,7 @@ msgstr "保存签名文件" msgid "Save to Selected Slot" msgstr "保存至所选插槽" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "保存到插槽 %1 - %2" @@ -9603,7 +9619,7 @@ msgstr "截图" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "搜索" @@ -9630,7 +9646,7 @@ msgid "" "for a bit and try again." msgstr "当前无法在虚拟地址空间中进行搜索。请运行一会儿游戏,然后重试。" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "搜索一个指令" @@ -9638,7 +9654,7 @@ msgstr "搜索一个指令" msgid "Search games..." msgstr "搜索游戏..." -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "搜索指令" @@ -9675,7 +9691,7 @@ msgid "Select Dump Path" msgstr "选择转储路径" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "选择导出目录" @@ -9719,7 +9735,7 @@ msgstr "选择 Skylander 合集" msgid "Select Skylander File" msgstr "选择 Skylander 文件" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "选择插槽 %1 - %2" @@ -9727,7 +9743,7 @@ msgstr "选择插槽 %1 - %2" msgid "Select State" msgstr "选择状态" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "选择状态插槽" @@ -9813,7 +9829,7 @@ msgstr "选择文件" msgid "Select a game" msgstr "选择游戏" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "选择要安装到 NAND 的软件" @@ -9821,7 +9837,7 @@ msgstr "选择要安装到 NAND 的软件" msgid "Select e-Reader Cards" msgstr "选择 e-Reader 卡" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "选择 RSO 模块地址:" @@ -9838,7 +9854,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "选择密钥文件 (OTP/SEEPROM 转储)" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "选择一个存档文件" @@ -10069,11 +10085,11 @@ msgstr "新干线控制器" msgid "Show % Speed" msgstr "显示百分比速度" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "显示日志(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "显示工具栏(&T)" @@ -10081,11 +10097,11 @@ msgstr "显示工具栏(&T)" msgid "Show Active Title in Window Title" msgstr "在标题栏显示当前游戏名" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "显示全部" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "显示澳大利亚" @@ -10098,7 +10114,7 @@ msgstr "在 Discord 软件中显示当前游戏" msgid "Show Disabled Codes First" msgstr "优先显示禁用的代码" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "显示 ELF/DOL" @@ -10111,7 +10127,7 @@ msgstr "优先显示启用的代码" msgid "Show FPS" msgstr "显示 FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "显示帧计数器" @@ -10119,15 +10135,15 @@ msgstr "显示帧计数器" msgid "Show Frame Times" msgstr "显示帧生成时间" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "显示法国" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "显示 GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "显示德国" @@ -10139,23 +10155,23 @@ msgstr "叠加显示高尔夫模式" msgid "Show Infinity Base" msgstr "显示 Infinity 底座" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "显示输入回显" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "显示意大利" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "显示日本" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "显示韩国" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "显示延迟计数器" @@ -10163,7 +10179,7 @@ msgstr "显示延迟计数器" msgid "Show Language:" msgstr "显示语言:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "显示日志设置(&C)" @@ -10175,7 +10191,7 @@ msgstr "显示联机信息" msgid "Show NetPlay Ping" msgstr "显示联机延迟" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "显示荷兰" @@ -10183,7 +10199,7 @@ msgstr "显示荷兰" msgid "Show On-Screen Display Messages" msgstr "显示屏显消息" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "显示 PAL" @@ -10196,19 +10212,19 @@ msgstr "显示 PC" msgid "Show Performance Graphs" msgstr "显示性能图表" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "显示平台" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "显示地区" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "显示重录计数器" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "显示俄罗斯" @@ -10216,7 +10232,7 @@ msgstr "显示俄罗斯" msgid "Show Skylanders Portal" msgstr "显示 Skylanders 传送门" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "显示西班牙" @@ -10228,19 +10244,19 @@ msgstr "显示速度颜色" msgid "Show Statistics" msgstr "显示统计数据" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "显示系统频率" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "显示台湾" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "显示美国" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "显示未知" @@ -10252,15 +10268,15 @@ msgstr "显示垂直消隐时间" msgid "Show VPS" msgstr "显示 VPS" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "显示 WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "显示 Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "显示全球" @@ -10387,7 +10403,7 @@ msgstr "切换横握" msgid "Sideways Wii Remote" msgstr "横握 Wii 遥控器" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "签名数据库" @@ -10643,7 +10659,7 @@ msgstr "标准控制器" msgid "Start" msgstr "开始" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "开始联机...(&N)" @@ -10651,7 +10667,7 @@ msgstr "开始联机...(&N)" msgid "Start New Cheat Search" msgstr "开始新的金手指搜索" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "开始录制输入(&C)" @@ -10745,7 +10761,7 @@ msgstr "立体 3D 模式" msgid "Stereoscopic 3D Mode:" msgstr "立体 3D 模式:" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "立体 3D" @@ -10767,7 +10783,7 @@ msgstr "摇杆" msgid "Stop" msgstr "停止" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "停止播放/录制输入" @@ -10844,8 +10860,8 @@ msgstr "手写笔" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "成功" @@ -10872,7 +10888,7 @@ msgstr "在 %1 个存档文件中 %n 个导出成功。" msgid "Successfully exported save files" msgstr "成功导出存档文件" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "已成功从 NAND 中提取证书" @@ -10884,12 +10900,12 @@ msgstr "提取文件成功。" msgid "Successfully extracted system data." msgstr "提取系统数据成功。" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "导入存档文件成功。" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "成功将此软件安装到 NAND。" @@ -10989,7 +11005,7 @@ msgstr "符号名:" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "符号" @@ -11009,7 +11025,7 @@ msgstr "同步并配对真实 Wii 遥控器" msgid "Synchronize GPU thread" msgstr "同步 GPU 线程" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -11039,7 +11055,7 @@ msgstr "正在同步存档数据..." msgid "System Language:" msgstr "系统语言:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "TAS 输入" @@ -11052,7 +11068,7 @@ msgstr "TAS 工具" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "标签" @@ -11070,7 +11086,7 @@ msgstr "尾" msgid "Taiwan" msgstr "台湾" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "屏幕截图" @@ -11135,6 +11151,10 @@ msgid "" "\n" "Do you really want to switch to Direct3D 11? If unsure, select 'No'." msgstr "" +"Direct3D 11 渲染器需要某些您的系统配置所不支持的特性。您仍然可以使用此后端," +"但您可能会在某些游戏中遇到图像错误。\n" +"\n" +"您真的想要切换到 Direct3D 11 吗?如果不确定,请选择“否”。" #: Source/Core/DiscIO/VolumeVerifier.cpp:601 msgid "The H3 hash table for the {0} partition is not correct." @@ -11154,13 +11174,13 @@ msgstr "此 IPL 文件不是已知的正确转储。(CRC32: {0:x})" msgid "The Masterpiece partitions are missing." msgstr "缺少杰作分区。" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "该 NAND 无法修复。建议备份您当前的数据并使用新的 NAND 启动。" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "NAND 已修复。" @@ -11468,6 +11488,12 @@ msgstr "指定的公用密钥索引是 {0} ,但应该为 {1} 。" msgid "The specified file \"{0}\" does not exist" msgstr "指定的文件 “{0}” 不存在" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "目标存储卡已包含文件 “%1”。" @@ -11499,6 +11525,12 @@ msgstr "缺少更新分区。" msgid "The update partition is not at its normal position." msgstr "更新分区未处于正常位置。" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "分区 {0} 无有效的文件系统。" @@ -11527,7 +11559,7 @@ msgstr "没有需要撤销的操作。" msgid "There was an issue adding a shortcut to the desktop" msgstr "向桌面添加快捷方式时出现问题" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11752,13 +11784,13 @@ msgstr "" "\n" "未知 Ucode (CRC = {0:08x}) - 强制 AXWii." -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "该数值将与图像设置中设定的会聚值相加。" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "该数值将与图像设置中设定的深度值相乘。" @@ -11814,7 +11846,7 @@ msgstr "超时" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "标题" @@ -11828,7 +11860,7 @@ msgstr "至" msgid "To:" msgstr "至:" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "切换全屏(&F)" @@ -12083,7 +12115,7 @@ msgstr "" "

在理想情况下将在消除着色器编译卡顿的同时尽可能减小性能影响,但效果因" "视频驱动的行为而异。" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "无法自动检测 RSO 模块" @@ -12149,11 +12181,11 @@ msgstr "未压缩的 GC/Wii 镜像 (*.iso *.gcm)" msgid "Undead" msgstr "亡灵" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "撤销载入状态" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "撤销保存状态" @@ -12173,7 +12205,7 @@ msgstr "" "卸载 WAD 会将该游戏的当前已安装版本从 NAND 中移除,而不会删除其存档。是否继" "续?" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "美国" @@ -12275,19 +12307,19 @@ msgstr "解锁光标" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:119 msgid "Unlocked" -msgstr "" +msgstr "已解锁" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:108 msgid "Unlocked %1 times this session" -msgstr "" +msgstr "本次会话期间解锁 %1 次" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:117 msgid "Unlocked (Casual)" -msgstr "" +msgstr "已解锁 (临时)" #: Source/Core/DolphinQt/Achievements/AchievementProgressWidget.cpp:110 msgid "Unlocked this session" -msgstr "" +msgstr "本次会话期间解锁" #: Source/Core/DiscIO/FileBlob.cpp:82 msgid "Unpacking" @@ -12432,7 +12464,7 @@ msgstr "" "其是在更高的内部分辨率下;此外,各向异性过滤目前与手动纹理采样不兼容。" "

如果不确定,请不要选中此项。" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "双眼使用同一个深度缓冲,部分游戏需要。" @@ -12483,7 +12515,7 @@ msgstr "" "在你同时使用排除和包含一次后,将从包含列表中减去排除列表,并显示任意剩余的包" "含数。你可以继续使用“代码未执行”/“代码已执行”来缩小结果范围。" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "用户配置" @@ -12687,7 +12719,7 @@ msgstr "增大音量" msgid "Vulkan" msgstr "Vulkan" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "WAD 文件 (*.wad)" @@ -12804,7 +12836,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "警告" @@ -13017,11 +13049,11 @@ msgstr "Wii 和 Wii 遥控器" msgid "Wii data is not public yet" msgstr "Wii 数据尚未公开" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "Wii 存档文件 (*.bin);; 所有文件 (*)" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "WiiTools 签名 MEGA 文件" @@ -13273,6 +13305,12 @@ msgstr "" "您想现在停下来修复此问题吗?\n" "如果选择“否”,音频可能会嘈杂混乱。" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -13309,7 +13347,7 @@ msgstr "已对齐" msgid "any value" msgstr "任意值" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "自动" @@ -13342,7 +13380,7 @@ msgstr "e-Reader 卡 (*.raw);;所有文件 (*)" msgid "errno" msgstr "errno" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "伪完成" @@ -13388,7 +13426,7 @@ msgstr "" "mGBA 即时存档 (*.ss0 *.ss1 *.ss2 *.ss3 *.ss4 *.ss5 *.ss6 *.ss7 *.ss8 *.ss9);;" "所有文件 (*)" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "无" @@ -13413,7 +13451,7 @@ msgstr "秒" #: Source/Core/DolphinQt/Config/Graphics/ColorCorrectionConfigWindow.cpp:101 msgid "sRGB" -msgstr "" +msgstr "sRGB" #: Source/Core/DolphinQt/CheatSearchWidget.cpp:199 msgid "this value:" diff --git a/Languages/po/zh_TW.po b/Languages/po/zh_TW.po index 159effb0e3..71bc255705 100644 --- a/Languages/po/zh_TW.po +++ b/Languages/po/zh_TW.po @@ -14,7 +14,7 @@ msgid "" msgstr "" "Project-Id-Version: Dolphin Emulator\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-26 15:31+0200\n" +"POT-Creation-Date: 2023-08-01 21:06+0200\n" "PO-Revision-Date: 2013-01-23 13:48+0000\n" "Last-Translator: Narusawa Yui , 2016,2018\n" "Language-Team: Chinese (Taiwan) (http://app.transifex.com/delroth/dolphin-" @@ -313,7 +313,7 @@ msgstr "" msgid "&4x" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:614 +#: Source/Core/DolphinQt/MenuBar.cpp:616 msgid "&About" msgstr "關於(&A)" @@ -334,7 +334,7 @@ msgstr "新增功能 (&A)" msgid "&Add..." msgstr "新增... (&A)" -#: Source/Core/DolphinQt/MenuBar.cpp:540 +#: Source/Core/DolphinQt/MenuBar.cpp:542 msgid "&Audio Settings" msgstr "聲音設定 (&A)" @@ -342,7 +342,7 @@ msgstr "聲音設定 (&A)" msgid "&Auto Update:" msgstr "自動更新 (&A)" -#: Source/Core/DolphinQt/MenuBar.cpp:556 +#: Source/Core/DolphinQt/MenuBar.cpp:558 msgid "&Automatic Start" msgstr "自動啟動 (&A)" @@ -350,11 +350,11 @@ msgstr "自動啟動 (&A)" msgid "&Borderless Window" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:472 +#: Source/Core/DolphinQt/MenuBar.cpp:474 msgid "&Breakpoints" msgstr "中斷點(&B)" -#: Source/Core/DolphinQt/MenuBar.cpp:597 +#: Source/Core/DolphinQt/MenuBar.cpp:599 msgid "&Bug Tracker" msgstr "" @@ -362,15 +362,15 @@ msgstr "" msgid "&Cancel" msgstr "取消 (&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:224 +#: Source/Core/DolphinQt/MenuBar.cpp:226 msgid "&Cheats Manager" msgstr "作弊碼管理器 (&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:607 +#: Source/Core/DolphinQt/MenuBar.cpp:609 msgid "&Check for Updates..." msgstr "檢查更新 (&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:980 +#: Source/Core/DolphinQt/MenuBar.cpp:982 msgid "&Clear Symbols" msgstr "" @@ -378,7 +378,7 @@ msgstr "" msgid "&Clone..." msgstr "相容版 (&C)" -#: Source/Core/DolphinQt/MenuBar.cpp:437 +#: Source/Core/DolphinQt/MenuBar.cpp:439 msgid "&Code" msgstr "代碼 (&C)" @@ -386,7 +386,7 @@ msgstr "代碼 (&C)" msgid "&Connected" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:542 +#: Source/Core/DolphinQt/MenuBar.cpp:544 msgid "&Controller Settings" msgstr "控制器設定(&C)" @@ -425,11 +425,11 @@ msgstr "編輯代碼 (&E)" msgid "&Edit..." msgstr "編輯 (&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:204 +#: Source/Core/DolphinQt/MenuBar.cpp:206 msgid "&Eject Disc" msgstr "退出碟片 (&E)" -#: Source/Core/DolphinQt/MenuBar.cpp:315 +#: Source/Core/DolphinQt/MenuBar.cpp:317 msgid "&Emulation" msgstr "模擬 (&E)" @@ -449,27 +449,27 @@ msgstr "" msgid "&Export as .gci..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:194 +#: Source/Core/DolphinQt/MenuBar.cpp:196 msgid "&File" msgstr "檔案 (&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:569 +#: Source/Core/DolphinQt/MenuBar.cpp:571 msgid "&Font..." msgstr "字體... (&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:321 +#: Source/Core/DolphinQt/MenuBar.cpp:323 msgid "&Frame Advance" msgstr "畫格步進(&F)" -#: Source/Core/DolphinQt/MenuBar.cpp:544 +#: Source/Core/DolphinQt/MenuBar.cpp:546 msgid "&Free Look Settings" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:982 +#: Source/Core/DolphinQt/MenuBar.cpp:984 msgid "&Generate Symbols From" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:593 +#: Source/Core/DolphinQt/MenuBar.cpp:595 msgid "&GitHub Repository" msgstr "" @@ -477,15 +477,15 @@ msgstr "" msgid "&Go to start of function" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:539 +#: Source/Core/DolphinQt/MenuBar.cpp:541 msgid "&Graphics Settings" msgstr "影像設定(&G)" -#: Source/Core/DolphinQt/MenuBar.cpp:584 +#: Source/Core/DolphinQt/MenuBar.cpp:586 msgid "&Help" msgstr "說明(&H)" -#: Source/Core/DolphinQt/MenuBar.cpp:543 +#: Source/Core/DolphinQt/MenuBar.cpp:545 msgid "&Hotkey Settings" msgstr "快捷鍵設定(&D)" @@ -505,7 +505,7 @@ msgstr "" msgid "&Import..." msgstr "匯入... (&I)" -#: Source/Core/DolphinQt/MenuBar.cpp:230 +#: Source/Core/DolphinQt/MenuBar.cpp:232 msgid "&Infinity Base" msgstr "" @@ -517,7 +517,7 @@ msgstr "" msgid "&Interframe Blending" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:497 +#: Source/Core/DolphinQt/MenuBar.cpp:499 msgid "&JIT" msgstr "&JIT" @@ -525,11 +525,11 @@ msgstr "&JIT" msgid "&Language:" msgstr "語言 (&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:338 +#: Source/Core/DolphinQt/MenuBar.cpp:340 msgid "&Load State" msgstr "讀取進度(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:988 +#: Source/Core/DolphinQt/MenuBar.cpp:990 msgid "&Load Symbol Map" msgstr "" @@ -543,15 +543,15 @@ msgstr "" msgid "&Lock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:429 +#: Source/Core/DolphinQt/MenuBar.cpp:431 msgid "&Lock Widgets In Place" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:481 +#: Source/Core/DolphinQt/MenuBar.cpp:483 msgid "&Memory" msgstr "記憶卡(&M)" -#: Source/Core/DolphinQt/MenuBar.cpp:743 +#: Source/Core/DolphinQt/MenuBar.cpp:745 msgid "&Movie" msgstr "影片(&M)" @@ -559,7 +559,7 @@ msgstr "影片(&M)" msgid "&Mute" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:489 +#: Source/Core/DolphinQt/MenuBar.cpp:491 msgid "&Network" msgstr "" @@ -568,23 +568,23 @@ msgid "&No" msgstr "" #: Source/Core/DolphinQt/GCMemcardManager.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:196 Source/Core/DolphinQt/MenuBar.cpp:198 +#: Source/Core/DolphinQt/MenuBar.cpp:198 Source/Core/DolphinQt/MenuBar.cpp:200 msgid "&Open..." msgstr "開啟(&O)..." -#: Source/Core/DolphinQt/MenuBar.cpp:530 +#: Source/Core/DolphinQt/MenuBar.cpp:532 msgid "&Options" msgstr "選項(&O)" -#: Source/Core/DolphinQt/MenuBar.cpp:1008 +#: Source/Core/DolphinQt/MenuBar.cpp:1010 msgid "&Patch HLE Functions" msgstr "修正 HLE 功能 (&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:317 +#: Source/Core/DolphinQt/MenuBar.cpp:319 msgid "&Pause" msgstr "暫停(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:316 +#: Source/Core/DolphinQt/MenuBar.cpp:318 msgid "&Play" msgstr "執行(&P)" @@ -592,7 +592,7 @@ msgstr "執行(&P)" msgid "&Properties" msgstr "屬性(&P)" -#: Source/Core/DolphinQt/MenuBar.cpp:758 +#: Source/Core/DolphinQt/MenuBar.cpp:760 msgid "&Read-Only Mode" msgstr "唯讀模式(&R)" @@ -600,7 +600,7 @@ msgstr "唯讀模式(&R)" msgid "&Refresh List" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:445 +#: Source/Core/DolphinQt/MenuBar.cpp:447 msgid "&Registers" msgstr "寄存器(&R)" @@ -618,15 +618,15 @@ msgid "&Rename symbol" msgstr "" #: Source/Core/DolphinQt/GBAWidget.cpp:404 -#: Source/Core/DolphinQt/MenuBar.cpp:319 +#: Source/Core/DolphinQt/MenuBar.cpp:321 msgid "&Reset" msgstr "重新啟動(&R)" -#: Source/Core/DolphinQt/MenuBar.cpp:221 +#: Source/Core/DolphinQt/MenuBar.cpp:223 msgid "&Resource Pack Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:989 +#: Source/Core/DolphinQt/MenuBar.cpp:991 msgid "&Save Symbol Map" msgstr "" @@ -634,7 +634,7 @@ msgstr "" msgid "&Scan e-Reader Card(s)..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:229 +#: Source/Core/DolphinQt/MenuBar.cpp:231 msgid "&Skylanders Portal" msgstr "" @@ -642,7 +642,7 @@ msgstr "" msgid "&Speed Limit:" msgstr "限制速度 (&S)" -#: Source/Core/DolphinQt/MenuBar.cpp:318 +#: Source/Core/DolphinQt/MenuBar.cpp:320 msgid "&Stop" msgstr "停止(&S)" @@ -650,11 +650,11 @@ msgstr "停止(&S)" msgid "&Theme:" msgstr "主題 (&T)" -#: Source/Core/DolphinQt/MenuBar.cpp:454 +#: Source/Core/DolphinQt/MenuBar.cpp:456 msgid "&Threads" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:219 +#: Source/Core/DolphinQt/MenuBar.cpp:221 msgid "&Tools" msgstr "工具(&T)" @@ -668,17 +668,17 @@ msgstr "" msgid "&Unlock Watches" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:403 +#: Source/Core/DolphinQt/MenuBar.cpp:405 msgid "&View" msgstr "檢視(&V)" #. i18n: This kind of "watch" is used for watching emulated memory. #. It's not related to timekeeping devices. -#: Source/Core/DolphinQt/MenuBar.cpp:464 +#: Source/Core/DolphinQt/MenuBar.cpp:466 msgid "&Watch" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:586 +#: Source/Core/DolphinQt/MenuBar.cpp:588 msgid "&Website" msgstr "網站(&W)" @@ -690,11 +690,11 @@ msgstr "&Wiki" msgid "&Yes" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1248 +#: Source/Core/DolphinQt/MenuBar.cpp:1285 msgid "'%1' not found, no symbol names generated" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1469 +#: Source/Core/DolphinQt/MenuBar.cpp:1506 msgid "'%1' not found, scanning for common functions instead" msgstr "" @@ -1111,7 +1111,7 @@ msgid "Accuracy:" msgstr "" #: Source/Core/DolphinQt/Achievements/AchievementsWindow.cpp:21 -#: Source/Core/DolphinQt/MenuBar.cpp:243 +#: Source/Core/DolphinQt/MenuBar.cpp:245 msgid "Achievements" msgstr "" @@ -1285,7 +1285,7 @@ msgstr "新增..." #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:181 #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:91 -#: Source/Core/DolphinQt/MenuBar.cpp:983 +#: Source/Core/DolphinQt/MenuBar.cpp:985 msgid "Address" msgstr "位址" @@ -1514,15 +1514,15 @@ msgstr "邊緣抗鋸齒:" msgid "Any Region" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1618 +#: Source/Core/DolphinQt/MenuBar.cpp:1655 msgid "Append signature to" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1001 +#: Source/Core/DolphinQt/MenuBar.cpp:1003 msgid "Append to &Existing Signature File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1005 +#: Source/Core/DolphinQt/MenuBar.cpp:1007 msgid "Appl&y Signature File..." msgstr "" @@ -1540,7 +1540,7 @@ msgstr "" msgid "Apply" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1641 +#: Source/Core/DolphinQt/MenuBar.cpp:1678 msgid "Apply signature file" msgstr "" @@ -1647,7 +1647,7 @@ msgstr "" msgid "Auto-Hide" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "Auto-detect RSO modules?" msgstr "" @@ -1750,7 +1750,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:982 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:217 #: Source/Core/DolphinQt/GCMemcardManager.cpp:151 -#: Source/Core/DolphinQt/MenuBar.cpp:641 +#: Source/Core/DolphinQt/MenuBar.cpp:643 msgid "Banner" msgstr "橫幅" @@ -1822,7 +1822,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:992 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:651 +#: Source/Core/DolphinQt/MenuBar.cpp:653 msgid "Block Size" msgstr "" @@ -1858,7 +1858,7 @@ msgid "" "Passthrough mode cannot be used." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:549 +#: Source/Core/DolphinQt/MenuBar.cpp:551 msgid "Boot to Pause" msgstr "" @@ -1935,7 +1935,7 @@ msgstr "" msgid "Broadband Adapter MAC Address" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:236 +#: Source/Core/DolphinQt/MenuBar.cpp:238 msgid "Browse &NetPlay Sessions...." msgstr "" @@ -1997,7 +1997,7 @@ msgstr "" msgid "C Stick" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1000 +#: Source/Core/DolphinQt/MenuBar.cpp:1002 msgid "C&reate Signature File..." msgstr "" @@ -2093,7 +2093,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.cpp:57 #: Source/Core/DolphinQt/Config/VerifyWidget.cpp:157 -#: Source/Core/DolphinQt/MenuBar.cpp:1290 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 #: Source/Core/DolphinQt/NKitWarningDialog.cpp:59 #: Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp:50 #: Source/Core/DolphinQt/Settings/WiiPane.cpp:282 @@ -2164,7 +2164,7 @@ msgstr "" msgid "Change &Disc" msgstr "更換光碟(&D)" -#: Source/Core/DolphinQt/MenuBar.cpp:203 +#: Source/Core/DolphinQt/MenuBar.cpp:205 msgid "Change &Disc..." msgstr "更換光碟(&D)..." @@ -2226,7 +2226,7 @@ msgstr "尋找作弊代碼" msgid "Cheats Manager" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:268 +#: Source/Core/DolphinQt/MenuBar.cpp:270 msgid "Check NAND..." msgstr "" @@ -2264,11 +2264,11 @@ msgstr "選擇一個要開啟的檔案" msgid "Choose a file to open or create" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1663 +#: Source/Core/DolphinQt/MenuBar.cpp:1700 msgid "Choose priority input file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1705 msgid "Choose secondary input file" msgstr "" @@ -2303,7 +2303,7 @@ msgstr "" msgid "Clear" msgstr "清除" -#: Source/Core/DolphinQt/MenuBar.cpp:859 +#: Source/Core/DolphinQt/MenuBar.cpp:861 msgid "Clear Cache" msgstr "" @@ -2324,7 +2324,7 @@ msgstr "" msgid "Close" msgstr "關閉" -#: Source/Core/DolphinQt/MenuBar.cpp:532 Source/Core/DolphinQt/MenuBar.cpp:535 +#: Source/Core/DolphinQt/MenuBar.cpp:534 Source/Core/DolphinQt/MenuBar.cpp:537 msgid "Co&nfiguration" msgstr "" @@ -2371,7 +2371,7 @@ msgstr "" msgid "Color Space" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1003 +#: Source/Core/DolphinQt/MenuBar.cpp:1005 msgid "Combine &Two Signature Files..." msgstr "" @@ -2408,7 +2408,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:993 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:233 -#: Source/Core/DolphinQt/MenuBar.cpp:652 +#: Source/Core/DolphinQt/MenuBar.cpp:654 msgid "Compression" msgstr "" @@ -2544,7 +2544,7 @@ msgstr "" msgid "Confirm on Stop" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1203 +#: Source/Core/DolphinQt/MenuBar.cpp:1240 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:496 #: Source/Core/DolphinQt/ResourcePackManager.cpp:239 msgid "Confirmation" @@ -2555,7 +2555,7 @@ msgstr "" msgid "Connect" msgstr "連接" -#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:309 +#: Source/Core/Core/HotkeyManager.cpp:85 Source/Core/DolphinQt/MenuBar.cpp:311 msgid "Connect Balance Board" msgstr "連接平衡板" @@ -2563,7 +2563,7 @@ msgstr "連接平衡板" msgid "Connect USB Keyboard" msgstr "連接 USB 鍵盤" -#: Source/Core/DolphinQt/MenuBar.cpp:301 +#: Source/Core/DolphinQt/MenuBar.cpp:303 msgid "Connect Wii Remote %1" msgstr "連接 Wii Remote %1" @@ -2583,7 +2583,7 @@ msgstr "連接 Wii Remote 3" msgid "Connect Wii Remote 4" msgstr "連接 Wii Remote 4" -#: Source/Core/DolphinQt/MenuBar.cpp:294 +#: Source/Core/DolphinQt/MenuBar.cpp:296 msgid "Connect Wii Remotes" msgstr "連接 Wii Remote" @@ -2706,7 +2706,7 @@ msgstr "" msgid "Convergence" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:142 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:145 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:179 msgid "Convergence:" msgstr "" @@ -3026,7 +3026,7 @@ msgid "" "leave this unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:278 +#: Source/Core/DolphinQt/MenuBar.cpp:280 msgid "Current Region" msgstr "" @@ -3222,7 +3222,7 @@ msgstr "" msgid "Default" msgstr "預設值" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:172 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:176 msgid "Default Config (Read Only)" msgstr "" @@ -3282,7 +3282,7 @@ msgstr "" msgid "Depth" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:140 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:143 msgid "Depth Percentage:" msgstr "" @@ -3295,7 +3295,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/ThreadWidget.cpp:233 #: Source/Core/DolphinQt/GameList/GameList.cpp:984 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:219 -#: Source/Core/DolphinQt/MenuBar.cpp:643 +#: Source/Core/DolphinQt/MenuBar.cpp:645 #: Source/Core/DolphinQt/ResourcePackManager.cpp:91 msgid "Description" msgstr "描述" @@ -3317,11 +3317,11 @@ msgstr "" msgid "Detect" msgstr "檢測" -#: Source/Core/DolphinQt/MenuBar.cpp:1291 +#: Source/Core/DolphinQt/MenuBar.cpp:1328 msgid "Detecting RSO Modules" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:115 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:118 msgid "Deterministic dual core:" msgstr "" @@ -3396,7 +3396,7 @@ msgstr "" msgid "Disable Emulation Speed Limit" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:851 +#: Source/Core/DolphinQt/MenuBar.cpp:853 msgid "Disable Fastmem" msgstr "" @@ -3404,7 +3404,7 @@ msgstr "" msgid "Disable Fog" msgstr "關閉霧化" -#: Source/Core/DolphinQt/MenuBar.cpp:843 +#: Source/Core/DolphinQt/MenuBar.cpp:845 msgid "Disable JIT Cache" msgstr "" @@ -3477,7 +3477,7 @@ msgstr "" msgid "Do you want to add \"%1\" to the list of Game Paths?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1204 +#: Source/Core/DolphinQt/MenuBar.cpp:1241 msgid "Do you want to clear the list of symbol names?" msgstr "" @@ -3508,17 +3508,17 @@ msgstr "" msgid "Dolphin Game Mod Preset" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1499 -#: Source/Core/DolphinQt/MenuBar.cpp:1516 -#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1536 +#: Source/Core/DolphinQt/MenuBar.cpp:1553 +#: Source/Core/DolphinQt/MenuBar.cpp:1572 msgid "Dolphin Map File (*.map)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature CSV File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:71 +#: Source/Core/DolphinQt/MenuBar.cpp:73 msgid "Dolphin Signature File" msgstr "" @@ -3679,7 +3679,7 @@ msgstr "" msgid "Dump &MRAM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:812 +#: Source/Core/DolphinQt/MenuBar.cpp:814 msgid "Dump Audio" msgstr "轉儲聲音" @@ -3691,7 +3691,7 @@ msgstr "" msgid "Dump EFB Target" msgstr "轉儲 EFB 目標" -#: Source/Core/DolphinQt/MenuBar.cpp:806 +#: Source/Core/DolphinQt/MenuBar.cpp:808 msgid "Dump Frames" msgstr "轉儲畫格" @@ -3769,7 +3769,7 @@ msgstr "" msgid "Dutch" msgstr "Dutch" -#: Source/Core/DolphinQt/MenuBar.cpp:213 +#: Source/Core/DolphinQt/MenuBar.cpp:215 msgid "E&xit" msgstr "離開(&X)" @@ -3817,7 +3817,7 @@ msgid "Edit..." msgstr "" #: Source/Core/DolphinQt/Config/GameConfigEdit.cpp:200 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:197 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:201 msgid "Editor" msgstr "" @@ -3884,7 +3884,7 @@ msgid "" "Defaults to True" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:228 +#: Source/Core/DolphinQt/MenuBar.cpp:230 msgid "Emulated USB Devices" msgstr "" @@ -4037,7 +4037,7 @@ msgid "" "being played.

This has no bearing on Discord rich presence." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:105 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:107 msgid "" "Enable emulated disc speed. Disabling this can cause crashes and other " "problems in some games. (ON = Compatible, OFF = Unlocked)" @@ -4077,7 +4077,7 @@ msgid "" "only." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:101 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:102 msgid "" "Enables Floating Point Result Flag calculation, needed for a few games. (ON " "= Compatible, OFF = Fast)" @@ -4138,7 +4138,7 @@ msgid "" "
" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:99 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:100 #: Source/Core/DolphinQt/Settings/AdvancedPane.cpp:68 msgid "" "Enables the Memory Management Unit, needed for some games. (ON = Compatible, " @@ -4221,7 +4221,7 @@ msgstr "" msgid "Enter the DNS server to use:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1263 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 msgid "Enter the RSO module address:" msgstr "" @@ -4268,18 +4268,18 @@ msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1561 #: Source/Core/DolphinQt/MainWindow.cpp:1568 #: Source/Core/DolphinQt/MainWindow.cpp:1670 -#: Source/Core/DolphinQt/MenuBar.cpp:1167 -#: Source/Core/DolphinQt/MenuBar.cpp:1247 -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 #: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1315 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 -#: Source/Core/DolphinQt/MenuBar.cpp:1560 -#: Source/Core/DolphinQt/MenuBar.cpp:1571 -#: Source/Core/DolphinQt/MenuBar.cpp:1583 -#: Source/Core/DolphinQt/MenuBar.cpp:1605 -#: Source/Core/DolphinQt/MenuBar.cpp:1631 -#: Source/Core/DolphinQt/MenuBar.cpp:1685 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 +#: Source/Core/DolphinQt/MenuBar.cpp:1597 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 +#: Source/Core/DolphinQt/MenuBar.cpp:1620 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 +#: Source/Core/DolphinQt/MenuBar.cpp:1668 +#: Source/Core/DolphinQt/MenuBar.cpp:1722 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:315 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:477 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:738 @@ -4416,7 +4416,7 @@ msgstr "" msgid "Euphoria" msgstr "Euphoria" -#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:280 +#: Source/Core/DiscIO/Enums.cpp:24 Source/Core/DolphinQt/MenuBar.cpp:282 #: Source/Core/UICommon/NetPlayIndex.cpp:249 msgid "Europe" msgstr "" @@ -4497,7 +4497,7 @@ msgstr "" msgid "Experimental" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:292 +#: Source/Core/DolphinQt/MenuBar.cpp:294 msgid "Export All Wii Saves" msgstr "匯出全部 Wii 存檔" @@ -4512,7 +4512,7 @@ msgstr "" msgid "Export Recording" msgstr "匯出錄像" -#: Source/Core/DolphinQt/MenuBar.cpp:751 +#: Source/Core/DolphinQt/MenuBar.cpp:753 msgid "Export Recording..." msgstr "匯出錄像..." @@ -4540,7 +4540,7 @@ msgstr "" msgid "Export as .&sav..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1131 +#: Source/Core/DolphinQt/MenuBar.cpp:1133 #, c-format msgctxt "" msgid "Exported %n save(s)" @@ -4568,7 +4568,7 @@ msgstr "" msgid "External Frame Buffer (XFB)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:269 +#: Source/Core/DolphinQt/MenuBar.cpp:271 msgid "Extract Certificates from NAND" msgstr "" @@ -4606,7 +4606,7 @@ msgid "FD" msgstr "" #: Source/Core/DolphinQt/FIFO/FIFOPlayerWindow.cpp:37 -#: Source/Core/DolphinQt/MenuBar.cpp:226 +#: Source/Core/DolphinQt/MenuBar.cpp:228 msgid "FIFO Player" msgstr "" @@ -4624,7 +4624,7 @@ msgstr "" msgid "Failed to add this session to the NetPlay index: %1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1632 +#: Source/Core/DolphinQt/MenuBar.cpp:1669 msgid "Failed to append to signature file '%1'" msgstr "" @@ -4718,7 +4718,7 @@ msgstr "" msgid "Failed to export the following save files:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1167 +#: Source/Core/DolphinQt/MenuBar.cpp:1204 msgid "Failed to extract certificates from NAND" msgstr "" @@ -4745,18 +4745,18 @@ msgstr "" msgid "Failed to import \"%1\"." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1107 +#: Source/Core/DolphinQt/MenuBar.cpp:1109 msgid "" "Failed to import save file. Please launch the game once, then try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1101 +#: Source/Core/DolphinQt/MenuBar.cpp:1103 msgid "" "Failed to import save file. The given file appears to be corrupted or is not " "a valid Wii save." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1114 +#: Source/Core/DolphinQt/MenuBar.cpp:1116 msgid "" "Failed to import save file. Your NAND may be corrupt, or something is " "preventing access to files within it. Try repairing your NAND (Tools -> " @@ -4783,7 +4783,7 @@ msgid "Failed to install pack: %1" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:619 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failed to install this title to the NAND." msgstr "" @@ -4793,8 +4793,8 @@ msgid "" "running?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1284 -#: Source/Core/DolphinQt/MenuBar.cpp:1339 +#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1376 msgid "Failed to load RSO module at %1" msgstr "" @@ -4806,7 +4806,7 @@ msgstr "" msgid "Failed to load dxgi.dll" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1571 +#: Source/Core/DolphinQt/MenuBar.cpp:1608 msgid "Failed to load map file '%1'" msgstr "" @@ -4978,19 +4978,19 @@ msgstr "" msgid "Failed to save FIFO log." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1561 +#: Source/Core/DolphinQt/MenuBar.cpp:1598 msgid "Failed to save code map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1605 +#: Source/Core/DolphinQt/MenuBar.cpp:1642 msgid "Failed to save signature file '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1584 +#: Source/Core/DolphinQt/MenuBar.cpp:1621 msgid "Failed to save symbol map to path '%1'" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1686 +#: Source/Core/DolphinQt/MenuBar.cpp:1723 msgid "Failed to save to signature file '%1'" msgstr "" @@ -5038,7 +5038,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 #: Source/Core/DolphinQt/GameList/GameList.cpp:840 -#: Source/Core/DolphinQt/MenuBar.cpp:1072 +#: Source/Core/DolphinQt/MenuBar.cpp:1074 msgid "Failure" msgstr "" @@ -5084,7 +5084,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:991 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:229 -#: Source/Core/DolphinQt/MenuBar.cpp:650 +#: Source/Core/DolphinQt/MenuBar.cpp:652 msgid "File Format" msgstr "" @@ -5098,18 +5098,18 @@ msgstr "檔案資訊" #: Source/Core/DolphinQt/GameList/GameList.cpp:986 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:223 -#: Source/Core/DolphinQt/MenuBar.cpp:645 +#: Source/Core/DolphinQt/MenuBar.cpp:647 msgid "File Name" msgstr "檔案名稱" #: Source/Core/DolphinQt/GameList/GameList.cpp:987 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:225 -#: Source/Core/DolphinQt/MenuBar.cpp:646 +#: Source/Core/DolphinQt/MenuBar.cpp:648 msgid "File Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:990 -#: Source/Core/DolphinQt/MenuBar.cpp:649 +#: Source/Core/DolphinQt/MenuBar.cpp:651 msgid "File Size" msgstr "檔案大小" @@ -5622,7 +5622,7 @@ msgid "Game Gamma:" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:988 -#: Source/Core/DolphinQt/MenuBar.cpp:647 +#: Source/Core/DolphinQt/MenuBar.cpp:649 msgid "Game ID" msgstr "遊戲 ID" @@ -5666,7 +5666,7 @@ msgstr "" msgid "Game region does not match" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:146 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:149 msgid "Game-Specific Settings" msgstr "遊戲規格設定" @@ -5737,7 +5737,7 @@ msgid "Gecko Codes" msgstr "Gecko 代碼" #: Source/Core/Core/HotkeyManager.cpp:333 -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:196 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:200 #: Source/Core/DolphinQt/Config/Graphics/GraphicsWindow.cpp:60 #: Source/Core/DolphinQt/Config/Graphics/PostProcessingConfigWindow.cpp:120 #: Source/Core/DolphinQt/Config/Mapping/HotkeyGeneral.cpp:21 @@ -5763,7 +5763,7 @@ msgstr "" msgid "Generated AR code." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1241 +#: Source/Core/DolphinQt/MenuBar.cpp:1278 msgid "Generated symbol names from '%1'" msgstr "" @@ -5840,7 +5840,7 @@ msgstr "綠 左" msgid "Green Right" msgstr "綠 右" -#: Source/Core/DolphinQt/MenuBar.cpp:622 +#: Source/Core/DolphinQt/MenuBar.cpp:624 msgid "Grid View" msgstr "" @@ -5915,7 +5915,7 @@ msgstr "" msgid "Hide" msgstr "隱藏" -#: Source/Core/DolphinQt/MenuBar.cpp:717 +#: Source/Core/DolphinQt/MenuBar.cpp:719 msgid "Hide All" msgstr "" @@ -6189,7 +6189,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:266 +#: Source/Core/DolphinQt/MenuBar.cpp:268 msgid "Import BootMii NAND Backup..." msgstr "" @@ -6204,7 +6204,7 @@ msgstr "" msgid "Import Save File(s)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:291 +#: Source/Core/DolphinQt/MenuBar.cpp:293 msgid "Import Wii Save..." msgstr "" @@ -6309,8 +6309,8 @@ msgstr "訊息" #: Source/Core/Common/MsgHandler.cpp:59 #: Source/Core/DolphinQt/GameList/GameList.cpp:700 #: Source/Core/DolphinQt/GameList/GameList.cpp:762 -#: Source/Core/DolphinQt/MenuBar.cpp:1240 -#: Source/Core/DolphinQt/MenuBar.cpp:1479 +#: Source/Core/DolphinQt/MenuBar.cpp:1277 +#: Source/Core/DolphinQt/MenuBar.cpp:1516 msgid "Information" msgstr "訊息" @@ -6319,10 +6319,10 @@ msgid "Inhibit Screensaver During Emulation" msgstr "" #: Source/Core/DolphinQt/Debugger/WatchWidget.cpp:275 -#: Source/Core/DolphinQt/MenuBar.cpp:1263 -#: Source/Core/DolphinQt/MenuBar.cpp:1321 -#: Source/Core/DolphinQt/MenuBar.cpp:1590 -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1300 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "Input" msgstr "輸入" @@ -6363,7 +6363,7 @@ msgstr "" msgid "Install Update" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:264 +#: Source/Core/DolphinQt/MenuBar.cpp:266 msgid "Install WAD..." msgstr "" @@ -6383,7 +6383,7 @@ msgstr "" msgid "Instruction Breakpoint" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Instruction:" msgstr "" @@ -6446,7 +6446,7 @@ msgstr "" msgid "Interpreter (slowest)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:823 +#: Source/Core/DolphinQt/MenuBar.cpp:825 msgid "Interpreter Core" msgstr "" @@ -6471,7 +6471,7 @@ msgstr "" msgid "Invalid Player ID" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1270 +#: Source/Core/DolphinQt/MenuBar.cpp:1307 msgid "Invalid RSO module address: %1" msgstr "" @@ -6546,11 +6546,11 @@ msgstr "Italian" msgid "Italy" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:821 +#: Source/Core/DolphinQt/MenuBar.cpp:823 msgid "JIT" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:835 +#: Source/Core/DolphinQt/MenuBar.cpp:837 msgid "JIT Block Linking Off" msgstr "" @@ -6558,47 +6558,47 @@ msgstr "" msgid "JIT Blocks" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:959 +#: Source/Core/DolphinQt/MenuBar.cpp:961 msgid "JIT Branch Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:927 +#: Source/Core/DolphinQt/MenuBar.cpp:929 msgid "JIT FloatingPoint Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:935 +#: Source/Core/DolphinQt/MenuBar.cpp:937 msgid "JIT Integer Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:910 +#: Source/Core/DolphinQt/MenuBar.cpp:912 msgid "JIT LoadStore Floating Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:878 +#: Source/Core/DolphinQt/MenuBar.cpp:880 msgid "JIT LoadStore Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:919 +#: Source/Core/DolphinQt/MenuBar.cpp:921 msgid "JIT LoadStore Paired Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:894 +#: Source/Core/DolphinQt/MenuBar.cpp:896 msgid "JIT LoadStore lXz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:886 +#: Source/Core/DolphinQt/MenuBar.cpp:888 msgid "JIT LoadStore lbzx Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:902 +#: Source/Core/DolphinQt/MenuBar.cpp:904 msgid "JIT LoadStore lwz Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:870 +#: Source/Core/DolphinQt/MenuBar.cpp:872 msgid "JIT Off (JIT Core)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:943 +#: Source/Core/DolphinQt/MenuBar.cpp:945 msgid "JIT Paired Off" msgstr "" @@ -6610,11 +6610,11 @@ msgstr "" msgid "JIT Recompiler for x86-64 (recommended)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:967 +#: Source/Core/DolphinQt/MenuBar.cpp:969 msgid "JIT Register Cache Off" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:951 +#: Source/Core/DolphinQt/MenuBar.cpp:953 msgid "JIT SystemRegisters Off" msgstr "" @@ -6625,7 +6625,7 @@ msgid "" "Please report this incident on the bug tracker. Dolphin will now exit." msgstr "" -#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:282 +#: Source/Core/DiscIO/Enums.cpp:27 Source/Core/DolphinQt/MenuBar.cpp:284 msgid "Japan" msgstr "" @@ -6684,7 +6684,7 @@ msgstr "" msgid "Kick Player" msgstr "" -#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:284 +#: Source/Core/DiscIO/Enums.cpp:45 Source/Core/DolphinQt/MenuBar.cpp:286 msgid "Korea" msgstr "" @@ -6829,11 +6829,11 @@ msgstr "" msgid "Limit Chunked Upload Speed:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:656 +#: Source/Core/DolphinQt/MenuBar.cpp:658 msgid "List Columns" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:619 +#: Source/Core/DolphinQt/MenuBar.cpp:621 msgid "List View" msgstr "" @@ -6849,11 +6849,11 @@ msgstr "" msgid "Load" msgstr "讀取" -#: Source/Core/DolphinQt/MenuBar.cpp:993 +#: Source/Core/DolphinQt/MenuBar.cpp:995 msgid "Load &Bad Map File..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:992 +#: Source/Core/DolphinQt/MenuBar.cpp:994 msgid "Load &Other Map File..." msgstr "" @@ -6865,7 +6865,7 @@ msgstr "" msgid "Load File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:249 +#: Source/Core/DolphinQt/MenuBar.cpp:251 msgid "Load GameCube Main Menu" msgstr "" @@ -6975,19 +6975,19 @@ msgstr "讀取儲存格 8" msgid "Load State Slot 9" msgstr "讀取儲存格 9" -#: Source/Core/DolphinQt/MenuBar.cpp:339 +#: Source/Core/DolphinQt/MenuBar.cpp:341 msgid "Load State from File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:340 +#: Source/Core/DolphinQt/MenuBar.cpp:342 msgid "Load State from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:341 +#: Source/Core/DolphinQt/MenuBar.cpp:343 msgid "Load State from Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1032 +#: Source/Core/DolphinQt/MenuBar.cpp:1034 msgid "Load Wii System Menu %1" msgstr "" @@ -6999,16 +6999,16 @@ msgstr "" msgid "Load from Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:395 +#: Source/Core/DolphinQt/MenuBar.cpp:397 msgid "Load from Slot %1 - %2" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1498 -#: Source/Core/DolphinQt/MenuBar.cpp:1515 +#: Source/Core/DolphinQt/MenuBar.cpp:1535 +#: Source/Core/DolphinQt/MenuBar.cpp:1552 msgid "Load map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1031 +#: Source/Core/DolphinQt/MenuBar.cpp:1033 msgid "Load vWii System Menu %1" msgstr "" @@ -7016,7 +7016,7 @@ msgstr "" msgid "Load..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1480 +#: Source/Core/DolphinQt/MenuBar.cpp:1517 msgid "Loaded symbols from '%1'" msgstr "" @@ -7055,7 +7055,7 @@ msgstr "記錄" msgid "Log Configuration" msgstr "記錄設定" -#: Source/Core/DolphinQt/MenuBar.cpp:864 +#: Source/Core/DolphinQt/MenuBar.cpp:866 msgid "Log JIT Instruction Coverage" msgstr "" @@ -7135,7 +7135,7 @@ msgstr "主搖桿" #: Source/Core/DolphinQt/GameList/GameList.cpp:985 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:221 -#: Source/Core/DolphinQt/MenuBar.cpp:644 +#: Source/Core/DolphinQt/MenuBar.cpp:646 msgid "Maker" msgstr "" @@ -7152,10 +7152,11 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:265 +#: Source/Core/DolphinQt/MenuBar.cpp:267 msgid "Manage NAND" msgstr "" +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:93 #: Source/Core/DolphinQt/Config/Graphics/AdvancedWidget.cpp:184 msgid "Manual Texture Sampling" msgstr "" @@ -7206,7 +7207,7 @@ msgstr "" msgid "Memory Card" msgstr "記憶卡" -#: Source/Core/DolphinQt/MenuBar.cpp:258 +#: Source/Core/DolphinQt/MenuBar.cpp:260 msgid "Memory Card Manager" msgstr "" @@ -7291,8 +7292,8 @@ msgid "" "unchecked.
" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1290 -#: Source/Core/DolphinQt/MenuBar.cpp:1439 +#: Source/Core/DolphinQt/MenuBar.cpp:1327 +#: Source/Core/DolphinQt/MenuBar.cpp:1476 msgid "Modules found: %1" msgstr "" @@ -7300,7 +7301,7 @@ msgstr "" msgid "Mono" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:131 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 msgid "Monoscopic Shadows" msgstr "" @@ -7363,9 +7364,10 @@ msgstr "" msgid "N&o to All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 -#: Source/Core/DolphinQt/MenuBar.cpp:1149 -#: Source/Core/DolphinQt/MenuBar.cpp:1153 +#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1172 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 +#: Source/Core/DolphinQt/MenuBar.cpp:1190 #: Source/Core/DolphinQt/NANDRepairDialog.cpp:29 msgid "NAND Check" msgstr "" @@ -7374,7 +7376,7 @@ msgstr "" msgid "NKit Warning" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:251 +#: Source/Core/DolphinQt/MenuBar.cpp:253 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-J" msgstr "" @@ -7400,7 +7402,7 @@ msgid "" "dolphin_emphasis>" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:253 +#: Source/Core/DolphinQt/MenuBar.cpp:255 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "NTSC-U" msgstr "" @@ -7608,7 +7610,7 @@ msgstr "" msgid "No game running." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1140 +#: Source/Core/DolphinQt/MenuBar.cpp:1174 msgid "No issues have been detected." msgstr "" @@ -7667,7 +7669,7 @@ msgstr "無" msgid "North America" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "Not Set" msgstr "未設定" @@ -7789,7 +7791,7 @@ msgid "" "job. May affect performance.

%1" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:589 +#: Source/Core/DolphinQt/MenuBar.cpp:591 msgid "Online &Documentation" msgstr "" @@ -7797,13 +7799,13 @@ msgstr "" msgid "Only Show Collection" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1615 +#: Source/Core/DolphinQt/MenuBar.cpp:1652 msgid "" "Only append symbols with prefix:\n" "(Blank for all symbols)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1590 +#: Source/Core/DolphinQt/MenuBar.cpp:1627 msgid "" "Only export symbols with prefix:\n" "(Blank for all symbols)" @@ -7818,7 +7820,7 @@ msgstr "開啟" msgid "Open &Containing Folder" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:209 +#: Source/Core/DolphinQt/MenuBar.cpp:211 msgid "Open &User Folder" msgstr "" @@ -7924,11 +7926,11 @@ msgstr "" msgid "Overwritten" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:747 +#: Source/Core/DolphinQt/MenuBar.cpp:749 msgid "P&lay Input Recording..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:256 +#: Source/Core/DolphinQt/MenuBar.cpp:258 #: Source/Core/DolphinQt/Settings/GeneralPane.cpp:212 msgid "PAL" msgstr "" @@ -8030,7 +8032,7 @@ msgstr "路徑" msgid "Pause" msgstr "暫停" -#: Source/Core/DolphinQt/MenuBar.cpp:767 +#: Source/Core/DolphinQt/MenuBar.cpp:769 msgid "Pause at End of Movie" msgstr "" @@ -8068,7 +8070,7 @@ msgstr "" msgid "Per-Pixel Lighting" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:276 +#: Source/Core/DolphinQt/MenuBar.cpp:278 msgid "Perform Online System Update" msgstr "" @@ -8102,7 +8104,7 @@ msgstr "" msgid "PiB" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1195 +#: Source/Core/DolphinQt/MenuBar.cpp:1232 msgid "Pick a debug font" msgstr "" @@ -8119,7 +8121,7 @@ msgid "Pitch Up" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:981 -#: Source/Core/DolphinQt/MenuBar.cpp:640 +#: Source/Core/DolphinQt/MenuBar.cpp:642 msgid "Platform" msgstr "" @@ -8350,7 +8352,7 @@ msgstr "" msgid "Public" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:514 +#: Source/Core/DolphinQt/MenuBar.cpp:516 msgid "Purge Game List Cache" msgstr "" @@ -8406,11 +8408,11 @@ msgstr "R-類比" msgid "READY" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:985 +#: Source/Core/DolphinQt/MenuBar.cpp:987 msgid "RSO Modules" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1258 +#: Source/Core/DolphinQt/MenuBar.cpp:1295 msgid "RSO auto-detection" msgstr "" @@ -8564,7 +8566,7 @@ msgid "Refreshing..." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:989 -#: Source/Core/DolphinQt/MenuBar.cpp:648 +#: Source/Core/DolphinQt/MenuBar.cpp:650 #: Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp:223 msgid "Region" msgstr "" @@ -8662,7 +8664,7 @@ msgstr "重置" msgid "Reset All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:563 +#: Source/Core/DolphinQt/MenuBar.cpp:565 msgid "Reset Ignore Panic Handler" msgstr "" @@ -8894,11 +8896,11 @@ msgstr "" msgid "START" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:997 +#: Source/Core/DolphinQt/MenuBar.cpp:999 msgid "Sa&ve Code" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:354 +#: Source/Core/DolphinQt/MenuBar.cpp:356 msgid "Sa&ve State" msgstr "儲存進度(&V)" @@ -8921,7 +8923,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:575 #: Source/Core/DolphinQt/GameList/GameList.cpp:580 -#: Source/Core/DolphinQt/MenuBar.cpp:1130 +#: Source/Core/DolphinQt/MenuBar.cpp:1132 msgid "Save Export" msgstr "" @@ -8942,11 +8944,11 @@ msgstr "" msgid "Save Game Files (*.sav);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1088 -#: Source/Core/DolphinQt/MenuBar.cpp:1097 -#: Source/Core/DolphinQt/MenuBar.cpp:1100 -#: Source/Core/DolphinQt/MenuBar.cpp:1106 -#: Source/Core/DolphinQt/MenuBar.cpp:1113 +#: Source/Core/DolphinQt/MenuBar.cpp:1090 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 +#: Source/Core/DolphinQt/MenuBar.cpp:1102 +#: Source/Core/DolphinQt/MenuBar.cpp:1108 +#: Source/Core/DolphinQt/MenuBar.cpp:1115 msgid "Save Import" msgstr "" @@ -9008,23 +9010,23 @@ msgstr "儲存至儲存格 8" msgid "Save State Slot 9" msgstr "儲存至儲存格 9" -#: Source/Core/DolphinQt/MenuBar.cpp:355 +#: Source/Core/DolphinQt/MenuBar.cpp:357 msgid "Save State to File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:357 +#: Source/Core/DolphinQt/MenuBar.cpp:359 msgid "Save State to Oldest Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:356 +#: Source/Core/DolphinQt/MenuBar.cpp:358 msgid "Save State to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:358 +#: Source/Core/DolphinQt/MenuBar.cpp:360 msgid "Save State to Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:994 +#: Source/Core/DolphinQt/MenuBar.cpp:996 msgid "Save Symbol Map &As..." msgstr "" @@ -9044,11 +9046,11 @@ msgstr "" msgid "Save as..." msgstr "另存為..." -#: Source/Core/DolphinQt/MenuBar.cpp:1673 +#: Source/Core/DolphinQt/MenuBar.cpp:1710 msgid "Save combined output file as" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1089 +#: Source/Core/DolphinQt/MenuBar.cpp:1091 msgid "" "Save data for this title already exists in the NAND. Consider backing up the " "current data before overwriting.\n" @@ -9059,11 +9061,11 @@ msgstr "" msgid "Save in Same Directory as the ROM" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1533 +#: Source/Core/DolphinQt/MenuBar.cpp:1570 msgid "Save map file" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1593 +#: Source/Core/DolphinQt/MenuBar.cpp:1630 msgid "Save signature file" msgstr "" @@ -9071,7 +9073,7 @@ msgstr "" msgid "Save to Selected Slot" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:396 +#: Source/Core/DolphinQt/MenuBar.cpp:398 msgid "Save to Slot %1 - %2" msgstr "" @@ -9105,7 +9107,7 @@ msgstr "截圖" #: Source/Core/DolphinQt/Debugger/MemoryWidget.cpp:148 #: Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp:86 -#: Source/Core/DolphinQt/MenuBar.cpp:522 Source/Core/DolphinQt/MenuBar.cpp:524 +#: Source/Core/DolphinQt/MenuBar.cpp:524 Source/Core/DolphinQt/MenuBar.cpp:526 msgid "Search" msgstr "" @@ -9132,7 +9134,7 @@ msgid "" "for a bit and try again." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:866 +#: Source/Core/DolphinQt/MenuBar.cpp:868 msgid "Search for an Instruction" msgstr "" @@ -9140,7 +9142,7 @@ msgstr "" msgid "Search games..." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1713 +#: Source/Core/DolphinQt/MenuBar.cpp:1750 msgid "Search instruction" msgstr "" @@ -9177,7 +9179,7 @@ msgid "Select Dump Path" msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:555 -#: Source/Core/DolphinQt/MenuBar.cpp:1124 +#: Source/Core/DolphinQt/MenuBar.cpp:1126 msgid "Select Export Directory" msgstr "" @@ -9221,7 +9223,7 @@ msgstr "" msgid "Select Skylander File" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:397 +#: Source/Core/DolphinQt/MenuBar.cpp:399 msgid "Select Slot %1 - %2" msgstr "" @@ -9229,7 +9231,7 @@ msgstr "" msgid "Select State" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:371 +#: Source/Core/DolphinQt/MenuBar.cpp:373 msgid "Select State Slot" msgstr "選擇儲存格" @@ -9315,7 +9317,7 @@ msgstr "" msgid "Select a game" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "Select a title to install to NAND" msgstr "" @@ -9323,7 +9325,7 @@ msgstr "" msgid "Select e-Reader Cards" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1321 +#: Source/Core/DolphinQt/MenuBar.cpp:1358 msgid "Select the RSO module address:" msgstr "" @@ -9340,7 +9342,7 @@ msgid "Select the keys file (OTP/SEEPROM dump)" msgstr "" #: Source/Core/DolphinQt/MainWindow.cpp:1724 -#: Source/Core/DolphinQt/MenuBar.cpp:1079 +#: Source/Core/DolphinQt/MenuBar.cpp:1081 msgid "Select the save file" msgstr "選擇存檔" @@ -9547,11 +9549,11 @@ msgstr "" msgid "Show % Speed" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:404 +#: Source/Core/DolphinQt/MenuBar.cpp:406 msgid "Show &Log" msgstr "顯示日誌視窗(&L)" -#: Source/Core/DolphinQt/MenuBar.cpp:417 +#: Source/Core/DolphinQt/MenuBar.cpp:419 msgid "Show &Toolbar" msgstr "顯示工具列(&T)" @@ -9559,11 +9561,11 @@ msgstr "顯示工具列(&T)" msgid "Show Active Title in Window Title" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:716 +#: Source/Core/DolphinQt/MenuBar.cpp:718 msgid "Show All" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:703 +#: Source/Core/DolphinQt/MenuBar.cpp:705 msgid "Show Australia" msgstr "" @@ -9576,7 +9578,7 @@ msgstr "" msgid "Show Disabled Codes First" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:678 +#: Source/Core/DolphinQt/MenuBar.cpp:680 msgid "Show ELF/DOL" msgstr "" @@ -9589,7 +9591,7 @@ msgstr "" msgid "Show FPS" msgstr "顯示 FPS" -#: Source/Core/DolphinQt/MenuBar.cpp:785 +#: Source/Core/DolphinQt/MenuBar.cpp:787 msgid "Show Frame Counter" msgstr "" @@ -9597,15 +9599,15 @@ msgstr "" msgid "Show Frame Times" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:704 +#: Source/Core/DolphinQt/MenuBar.cpp:706 msgid "Show France" msgstr "顯示 France" -#: Source/Core/DolphinQt/MenuBar.cpp:676 +#: Source/Core/DolphinQt/MenuBar.cpp:678 msgid "Show GameCube" msgstr "顯示 GameCube" -#: Source/Core/DolphinQt/MenuBar.cpp:705 +#: Source/Core/DolphinQt/MenuBar.cpp:707 msgid "Show Germany" msgstr "" @@ -9617,23 +9619,23 @@ msgstr "" msgid "Show Infinity Base" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:791 +#: Source/Core/DolphinQt/MenuBar.cpp:793 msgid "Show Input Display" msgstr "輸入顯示" -#: Source/Core/DolphinQt/MenuBar.cpp:706 +#: Source/Core/DolphinQt/MenuBar.cpp:708 msgid "Show Italy" msgstr "顯示 Italy" -#: Source/Core/DolphinQt/MenuBar.cpp:700 +#: Source/Core/DolphinQt/MenuBar.cpp:702 msgid "Show JPN" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:707 +#: Source/Core/DolphinQt/MenuBar.cpp:709 msgid "Show Korea" msgstr "顯示 Korea" -#: Source/Core/DolphinQt/MenuBar.cpp:779 +#: Source/Core/DolphinQt/MenuBar.cpp:781 msgid "Show Lag Counter" msgstr "" @@ -9641,7 +9643,7 @@ msgstr "" msgid "Show Language:" msgstr "顯示語系:" -#: Source/Core/DolphinQt/MenuBar.cpp:410 +#: Source/Core/DolphinQt/MenuBar.cpp:412 msgid "Show Log &Configuration" msgstr "日誌記錄設定(&C)" @@ -9653,7 +9655,7 @@ msgstr "" msgid "Show NetPlay Ping" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:708 +#: Source/Core/DolphinQt/MenuBar.cpp:710 msgid "Show Netherlands" msgstr "" @@ -9661,7 +9663,7 @@ msgstr "" msgid "Show On-Screen Display Messages" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:701 +#: Source/Core/DolphinQt/MenuBar.cpp:703 msgid "Show PAL" msgstr "顯示 PAL" @@ -9674,19 +9676,19 @@ msgstr "" msgid "Show Performance Graphs" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:681 +#: Source/Core/DolphinQt/MenuBar.cpp:683 msgid "Show Platforms" msgstr "顯示平台" -#: Source/Core/DolphinQt/MenuBar.cpp:715 +#: Source/Core/DolphinQt/MenuBar.cpp:717 msgid "Show Regions" msgstr "顯示區域" -#: Source/Core/DolphinQt/MenuBar.cpp:773 +#: Source/Core/DolphinQt/MenuBar.cpp:775 msgid "Show Rerecord Counter" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:709 +#: Source/Core/DolphinQt/MenuBar.cpp:711 msgid "Show Russia" msgstr "" @@ -9694,7 +9696,7 @@ msgstr "" msgid "Show Skylanders Portal" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:710 +#: Source/Core/DolphinQt/MenuBar.cpp:712 msgid "Show Spain" msgstr "" @@ -9706,19 +9708,19 @@ msgstr "" msgid "Show Statistics" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:798 +#: Source/Core/DolphinQt/MenuBar.cpp:800 msgid "Show System Clock" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:711 +#: Source/Core/DolphinQt/MenuBar.cpp:713 msgid "Show Taiwan" msgstr "顯示 Taiwan" -#: Source/Core/DolphinQt/MenuBar.cpp:702 +#: Source/Core/DolphinQt/MenuBar.cpp:704 msgid "Show USA" msgstr "顯示 USA" -#: Source/Core/DolphinQt/MenuBar.cpp:713 +#: Source/Core/DolphinQt/MenuBar.cpp:715 msgid "Show Unknown" msgstr "" @@ -9730,15 +9732,15 @@ msgstr "" msgid "Show VPS" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:677 +#: Source/Core/DolphinQt/MenuBar.cpp:679 msgid "Show WAD" msgstr "顯示 WAD" -#: Source/Core/DolphinQt/MenuBar.cpp:675 +#: Source/Core/DolphinQt/MenuBar.cpp:677 msgid "Show Wii" msgstr "顯示 Wii" -#: Source/Core/DolphinQt/MenuBar.cpp:712 +#: Source/Core/DolphinQt/MenuBar.cpp:714 msgid "Show World" msgstr "" @@ -9847,7 +9849,7 @@ msgstr "" msgid "Sideways Wii Remote" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:984 +#: Source/Core/DolphinQt/MenuBar.cpp:986 msgid "Signature Database" msgstr "" @@ -10087,7 +10089,7 @@ msgstr "標準控制器" msgid "Start" msgstr "Start" -#: Source/Core/DolphinQt/MenuBar.cpp:235 +#: Source/Core/DolphinQt/MenuBar.cpp:237 msgid "Start &NetPlay..." msgstr "" @@ -10095,7 +10097,7 @@ msgstr "" msgid "Start New Cheat Search" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:745 +#: Source/Core/DolphinQt/MenuBar.cpp:747 msgid "Start Re&cording Input" msgstr "" @@ -10189,7 +10191,7 @@ msgstr "" msgid "Stereoscopic 3D Mode:" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:119 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:122 #: Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp:163 msgid "Stereoscopy" msgstr "" @@ -10211,7 +10213,7 @@ msgstr "搖桿" msgid "Stop" msgstr "停止" -#: Source/Core/DolphinQt/MenuBar.cpp:748 +#: Source/Core/DolphinQt/MenuBar.cpp:750 msgid "Stop Playing/Recording Input" msgstr "" @@ -10282,8 +10284,8 @@ msgstr "" #: Source/Core/DolphinQt/ConvertDialog.cpp:534 #: Source/Core/DolphinQt/GameList/GameList.cpp:617 #: Source/Core/DolphinQt/GameList/GameList.cpp:645 -#: Source/Core/DolphinQt/MenuBar.cpp:1067 -#: Source/Core/DolphinQt/MenuBar.cpp:1162 +#: Source/Core/DolphinQt/MenuBar.cpp:1069 +#: Source/Core/DolphinQt/MenuBar.cpp:1199 msgid "Success" msgstr "" @@ -10310,7 +10312,7 @@ msgstr "" msgid "Successfully exported save files" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1163 +#: Source/Core/DolphinQt/MenuBar.cpp:1200 msgid "Successfully extracted certificates from NAND" msgstr "" @@ -10322,12 +10324,12 @@ msgstr "" msgid "Successfully extracted system data." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1097 +#: Source/Core/DolphinQt/MenuBar.cpp:1099 msgid "Successfully imported save file." msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:618 -#: Source/Core/DolphinQt/MenuBar.cpp:1068 +#: Source/Core/DolphinQt/MenuBar.cpp:1070 msgid "Successfully installed this title to the NAND." msgstr "" @@ -10420,7 +10422,7 @@ msgstr "" #: Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp:157 #: Source/Core/DolphinQt/Debugger/CodeWidget.cpp:135 -#: Source/Core/DolphinQt/MenuBar.cpp:978 +#: Source/Core/DolphinQt/MenuBar.cpp:980 msgid "Symbols" msgstr "" @@ -10440,7 +10442,7 @@ msgstr "" msgid "Synchronize GPU thread" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:103 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:104 msgid "" "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual " "core mode. (ON = Compatible, OFF = Fast)" @@ -10469,7 +10471,7 @@ msgstr "" msgid "System Language:" msgstr "系統語系:" -#: Source/Core/DolphinQt/MenuBar.cpp:763 +#: Source/Core/DolphinQt/MenuBar.cpp:765 msgid "TAS Input" msgstr "" @@ -10482,7 +10484,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:494 #: Source/Core/DolphinQt/GameList/GameList.cpp:994 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:235 -#: Source/Core/DolphinQt/MenuBar.cpp:653 +#: Source/Core/DolphinQt/MenuBar.cpp:655 msgid "Tags" msgstr "" @@ -10500,7 +10502,7 @@ msgstr "" msgid "Taiwan" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:323 +#: Source/Core/Core/HotkeyManager.cpp:35 Source/Core/DolphinQt/MenuBar.cpp:325 msgid "Take Screenshot" msgstr "截取畫面" @@ -10582,13 +10584,13 @@ msgstr "" msgid "The Masterpiece partitions are missing." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1154 +#: Source/Core/DolphinQt/MenuBar.cpp:1191 msgid "" "The NAND could not be repaired. It is recommended to back up your current " "data and start over with a fresh NAND." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1149 +#: Source/Core/DolphinQt/MenuBar.cpp:1186 msgid "The NAND has been repaired." msgstr "" @@ -10858,6 +10860,12 @@ msgstr "" msgid "The specified file \"{0}\" does not exist" msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1153 +msgid "" +"The system-reserved part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DolphinQt/GCMemcardManager.cpp:543 msgid "The target memory card already contains a file \"%1\"." msgstr "" @@ -10889,6 +10897,12 @@ msgstr "" msgid "The update partition is not at its normal position." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1145 +msgid "" +"The user-accessible part of your NAND contains %1 blocks (%2 KiB) of data, " +"out of an allowed maximum of %3 blocks (%4 KiB)." +msgstr "" + #: Source/Core/DiscIO/VolumeVerifier.cpp:643 msgid "The {0} partition does not have a valid file system." msgstr "" @@ -10917,7 +10931,7 @@ msgstr "" msgid "There was an issue adding a shortcut to the desktop" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:151 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:154 msgid "" "These settings override core Dolphin settings.\n" "Undetermined means the game uses Dolphin's setting." @@ -11109,13 +11123,13 @@ msgid "" "Unknown ucode (CRC = {0:08x}) - forcing AXWii." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:136 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:139 msgid "" "This value is added to the convergence value set in the graphics " "configuration." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:134 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:137 msgid "" "This value is multiplied with the depth set in the graphics configuration." msgstr "" @@ -11168,7 +11182,7 @@ msgstr "" #: Source/Core/DolphinQt/GameList/GameList.cpp:983 #: Source/Core/DolphinQt/GameList/GameListModel.cpp:213 #: Source/Core/DolphinQt/GCMemcardManager.cpp:153 -#: Source/Core/DolphinQt/MenuBar.cpp:642 +#: Source/Core/DolphinQt/MenuBar.cpp:644 msgid "Title" msgstr "標題" @@ -11182,7 +11196,7 @@ msgstr "" msgid "To:" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:320 +#: Source/Core/DolphinQt/MenuBar.cpp:322 msgid "Toggle &Fullscreen" msgstr "" @@ -11428,7 +11442,7 @@ msgid "" "behavior." msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1315 +#: Source/Core/DolphinQt/MenuBar.cpp:1352 msgid "Unable to auto-detect RSO module" msgstr "" @@ -11487,11 +11501,11 @@ msgstr "" msgid "Undead" msgstr "" -#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:342 +#: Source/Core/Core/HotkeyManager.cpp:178 Source/Core/DolphinQt/MenuBar.cpp:344 msgid "Undo Load State" msgstr "取消讀取進度" -#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:359 +#: Source/Core/Core/HotkeyManager.cpp:179 Source/Core/DolphinQt/MenuBar.cpp:361 msgid "Undo Save State" msgstr "取消儲存進度" @@ -11509,7 +11523,7 @@ msgid "" "title from the NAND without deleting its save data. Continue?" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:286 +#: Source/Core/DolphinQt/MenuBar.cpp:288 msgid "United States" msgstr "" @@ -11760,7 +11774,7 @@ msgid "" "

If unsure, leave this unchecked." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:138 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:141 msgid "Use a single depth buffer for both eyes. Needed for a few games." msgstr "" @@ -11798,7 +11812,7 @@ msgid "" "to narrow down the results." msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:179 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:183 msgid "User Config" msgstr "" @@ -11992,7 +12006,7 @@ msgstr "提高音量" msgid "Vulkan" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1059 +#: Source/Core/DolphinQt/MenuBar.cpp:1061 msgid "WAD files (*.wad)" msgstr "" @@ -12093,7 +12107,7 @@ msgstr "" #: Source/Core/DolphinQt/Config/LogConfigWidget.cpp:47 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:215 #: Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp:231 -#: Source/Core/DolphinQt/MenuBar.cpp:1468 +#: Source/Core/DolphinQt/MenuBar.cpp:1505 #: Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp:469 msgid "Warning" msgstr "警告" @@ -12276,11 +12290,11 @@ msgstr "" msgid "Wii data is not public yet" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:1080 +#: Source/Core/DolphinQt/MenuBar.cpp:1082 msgid "Wii save files (*.bin);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/MenuBar.cpp:72 +#: Source/Core/DolphinQt/MenuBar.cpp:74 msgid "WiiTools Signature MEGA File" msgstr "" @@ -12497,6 +12511,12 @@ msgid "" "If you select \"No\", audio might be garbled." msgstr "" +#: Source/Core/DolphinQt/MenuBar.cpp:1165 +msgid "" +"Your NAND contains more data than allowed. Wii software may behave " +"incorrectly or not allow saving." +msgstr "" + #. i18n: Refers to a 3D axis (used when mapping motion controls) #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:133 #: Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp:173 @@ -12533,7 +12553,7 @@ msgstr "" msgid "any value" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "auto" msgstr "" @@ -12566,7 +12586,7 @@ msgstr "" msgid "errno" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "fake-completion" msgstr "" @@ -12610,7 +12630,7 @@ msgid "" "ss9);;All Files (*)" msgstr "" -#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:95 +#: Source/Core/DolphinQt/Config/GameConfigWidget.cpp:96 msgid "none" msgstr "" From 83f307ec7ec77b2af13ed06d601e03a9d274bae8 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Fri, 4 Aug 2023 11:53:06 -0700 Subject: [PATCH 71/99] D3D12: Only use framebuffer integer descriptor if allocated Verify that DXFramebuffer's integer RTV descriptor's cpu_handle has been allocated before using it, and if it hasn't use the non-integer RTV descriptor instead. This fixes a Dolphin crash in Twilight Princess, and possibly other games (Issue 13312). As an optimization to save space in the descriptor heap, DXFramebuffer's integer descriptor is only initialized if the given abstract texture format has different integer and non-integer RTV formats. This previously wasn't accounted for by GetIntRTVDescriptorArray, which could cause DX12::Gfx::BindFramebuffer to call OMSetRenderTargets with an invalid descriptor which would lead to a crash. Triggering the bug was fortunately rare because integer formats are only used when blending is disabled and logic ops are enabled. Furthermore, the standard integer abstract format is RGBA8 which has different integer and non-integer RTV formats, causing the integer descriptor to be initialized and avoiding the bug. The crash started appearing in a2702c6 because it changed the swapchain's abstract texture format from RGBA8 to RGB10_A2. Unlike RGBA8, RGB10_A2 has the same integer and non-integer RTV formats and so the bug can be triggered if the other requirements are met. --- .../Core/VideoBackends/D3D12/DX12Texture.cpp | 21 +++++++++++++++++++ Source/Core/VideoBackends/D3D12/DX12Texture.h | 5 +---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoBackends/D3D12/DX12Texture.cpp b/Source/Core/VideoBackends/D3D12/DX12Texture.cpp index f20c37354b..e040d0483d 100644 --- a/Source/Core/VideoBackends/D3D12/DX12Texture.cpp +++ b/Source/Core/VideoBackends/D3D12/DX12Texture.cpp @@ -422,6 +422,23 @@ DXFramebuffer::~DXFramebuffer() } } +const D3D12_CPU_DESCRIPTOR_HANDLE* DXFramebuffer::GetIntRTVDescriptorArray() const +{ + if (m_color_attachment == nullptr) + return nullptr; + + const auto& handle = m_int_rtv_descriptor.cpu_handle; + + // To save space in the descriptor heap, m_int_rtv_descriptor.cpu_handle.ptr is only allocated + // when the integer RTV format corresponding to the current abstract format differs from the + // non-integer RTV format. Only use the integer handle if it has been allocated. + if (handle.ptr != 0) + return &handle; + + // The integer and non-integer RTV formats are the same, so use the non-integer descriptor. + return GetRTVDescriptorArray(); +} + void DXFramebuffer::Unbind() { static const D3D12_DISCARD_REGION dr = {0, nullptr, 0, 1}; @@ -556,6 +573,10 @@ bool DXFramebuffer::CreateIRTVDescriptor() const bool multisampled = m_samples > 1; DXGI_FORMAT non_int_format = D3DCommon::GetRTVFormatForAbstractFormat(m_color_format, false); DXGI_FORMAT int_format = D3DCommon::GetRTVFormatForAbstractFormat(m_color_format, true); + + // If the integer and non-integer RTV formats are the same for a given abstract format we can save + // space in the descriptor heap by only allocating the non-integer descriptor and using it for + // the integer RTV too. if (int_format != non_int_format) { if (!g_dx_context->GetRTVHeapManager().Allocate(&m_int_rtv_descriptor)) diff --git a/Source/Core/VideoBackends/D3D12/DX12Texture.h b/Source/Core/VideoBackends/D3D12/DX12Texture.h index ea781fd899..2054b195b2 100644 --- a/Source/Core/VideoBackends/D3D12/DX12Texture.h +++ b/Source/Core/VideoBackends/D3D12/DX12Texture.h @@ -75,10 +75,7 @@ public: { return m_render_targets_raw.data(); } - const D3D12_CPU_DESCRIPTOR_HANDLE* GetIntRTVDescriptorArray() const - { - return m_color_attachment ? &m_int_rtv_descriptor.cpu_handle : nullptr; - } + const D3D12_CPU_DESCRIPTOR_HANDLE* GetIntRTVDescriptorArray() const; const D3D12_CPU_DESCRIPTOR_HANDLE* GetDSVDescriptorArray() const { return m_depth_attachment ? &m_dsv_descriptor.cpu_handle : nullptr; From 1ebec40e4d4c473bc717b1d5836b8320f4851388 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 6 Aug 2023 11:52:25 +0200 Subject: [PATCH 72/99] JitArm64: Prefer MOVI with 64-bit elements for zeroing The Cortex-X2 and Cortex-X3 (and possibly others) recognize MOVI with 64-bit elements as a zeroing idiom, but not MOVI with other sizes. --- Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp | 2 +- Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp index c5624ee6d4..54ba054bce 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp @@ -832,7 +832,7 @@ void JitArm64::ConvertSingleToDoublePair(size_t guest_reg, ARM64Reg dest_reg, AR { // Set each 32-bit element of scratch_reg to 0x0000'0000 or 0xFFFF'FFFF depending on whether // the absolute value of the corresponding element in src_reg compares greater than 0 - m_float_emit.MOVI(8, EncodeRegToDouble(scratch_reg), 0); + m_float_emit.MOVI(64, EncodeRegToDouble(scratch_reg), 0); m_float_emit.FACGT(32, EncodeRegToDouble(scratch_reg), EncodeRegToDouble(src_reg), EncodeRegToDouble(scratch_reg)); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp index 4c0730f9d0..a79bf83cb0 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Paired.cpp @@ -254,7 +254,7 @@ void JitArm64::ps_arith(UGeckoInstruction inst) // Pick the right NaNs - m_float_emit.MOVI(8, zero_reg, 0); + m_float_emit.MOVI(64, zero_reg, 0); const auto check_input = [&](ARM64Reg input) { m_float_emit.FACGE(size, nan_temp_reg_paired, input, zero_reg); From 246b7c5bdb7e87704ab13448f1579f3f95d92444 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Fri, 11 Aug 2023 00:36:41 -0500 Subject: [PATCH 73/99] VideoCommon: fix regression with texture load order where the custom texture code was always updating the asset map for each texture with each entry, making it so the last value actually would be loaded instead of the first --- Source/Core/VideoCommon/HiresTextures.cpp | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp index c70e5523f8..f9f3134e35 100644 --- a/Source/Core/VideoCommon/HiresTextures.cpp +++ b/Source/Core/VideoCommon/HiresTextures.cpp @@ -120,24 +120,27 @@ void HiresTexture::Update() if (has_arbitrary_mipmaps) filename.erase(arb_index, 4); - // Since this is just a texture (single file) the mapper doesn't really matter - // just provide a string - s_file_library->SetAssetIDMapData(filename, - std::map{{"", path}}); - - if (g_ActiveConfig.bCacheHiresTextures) - { - auto hires_texture = std::make_shared( - has_arbitrary_mipmaps, - system.GetCustomAssetLoader().LoadGameTexture(filename, s_file_library)); - s_hires_texture_cache.try_emplace(filename, std::move(hires_texture)); - } const auto [it, inserted] = s_hires_texture_id_to_arbmipmap.try_emplace(filename, has_arbitrary_mipmaps); if (!inserted) { failed_insert = true; } + else + { + // Since this is just a texture (single file) the mapper doesn't really matter + // just provide a string + s_file_library->SetAssetIDMapData( + filename, std::map{{"", path}}); + + if (g_ActiveConfig.bCacheHiresTextures) + { + auto hires_texture = std::make_shared( + has_arbitrary_mipmaps, + system.GetCustomAssetLoader().LoadGameTexture(filename, s_file_library)); + s_hires_texture_cache.try_emplace(filename, std::move(hires_texture)); + } + } } } From 1f8f3840ac086c3047d19701b245132e74a65e5f Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 23 Jul 2023 15:13:47 -0700 Subject: [PATCH 74/99] Disable right-click menu on main window Before, right-clicking on the toolbar would allow toggling all dock widgets, including the debugger ones even when they are disabled. (See https://doc.qt.io/qt-5/qmainwindow.html#createPopupMenu for this behavior, and https://bugs.dolphin-emu.org/issues/13306 for an example of where it caused issues.) --- Source/Core/DolphinQt/MainWindow.cpp | 7 +++++++ Source/Core/DolphinQt/MainWindow.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 42a6a04603..c63fa1ae50 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -1645,6 +1645,13 @@ bool MainWindow::eventFilter(QObject* object, QEvent* event) return false; } +QMenu* MainWindow::createPopupMenu() +{ + // Disable the default popup menu as it exposes the debugger UI even when the debugger UI is + // disabled, which can lead to user confusion (see e.g. https://bugs.dolphin-emu.org/issues/13306) + return nullptr; +} + void MainWindow::dragEnterEvent(QDragEnterEvent* event) { if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index 4654202ed7..357dc5186e 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -13,6 +13,7 @@ #include "Core/Boot/Boot.h" +class QMenu; class QStackedWidget; class QString; @@ -80,6 +81,7 @@ public: WindowSystemInfo GetWindowSystemInfo() const; bool eventFilter(QObject* object, QEvent* event) override; + QMenu* createPopupMenu() override; signals: void ReadOnlyModeChanged(bool read_only); From a202d84570f510c2152591ef0b7e5f42bf5e043b Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 7 Mar 2023 18:39:26 -0800 Subject: [PATCH 75/99] msbuild: auto generate and embed qt rcc files --- Source/VSProps/QtCompile.props | 37 +- Source/VSProps/qtmoc.props | 83 --- Source/VSProps/{QtCompile.xml => qtmoc.xml} | 0 Source/VSProps/qtrcc.targets | 580 ++++++++++++++++++++ Source/VSProps/qtrcc.xml | 5 + 5 files changed, 619 insertions(+), 86 deletions(-) delete mode 100644 Source/VSProps/qtmoc.props rename Source/VSProps/{QtCompile.xml => qtmoc.xml} (100%) create mode 100644 Source/VSProps/qtrcc.targets create mode 100644 Source/VSProps/qtrcc.xml diff --git a/Source/VSProps/QtCompile.props b/Source/VSProps/QtCompile.props index 2b4ceed3c4..c42c823f88 100644 --- a/Source/VSProps/QtCompile.props +++ b/Source/VSProps/QtCompile.props @@ -51,9 +51,14 @@ but not the include paths, as passing include paths drastically slows down moc, and it doesn't appear to actually need them anyway. --> - + + + + moc %(Identity) + $(QtHostToolsDir) + %(FullPath) $(QtToolOutDir)moc_68\moc_%(Filename).cpp + $(QtToolOutDir)moc_68\ + moc_%(Filename).cpp + output + true + [AllOptions] [AdditionalOptions] + %(OutputFile) + false - - + + + + + rcc %(Identity) + $(QtHostToolsDir) + %(FullPath) + $(QtToolOutDir)rcc\qrc_%(Filename).cpp + $(QtToolOutDir)rcc\ + qrc_%(Filename).cpp + %(Filename) + default + false + output + true + [AllOptions] [AdditionalOptions] + %(OutputFile) + + + + diff --git a/Source/VSProps/qtmoc.props b/Source/VSProps/qtmoc.props deleted file mode 100644 index 18832a6e93..0000000000 --- a/Source/VSProps/qtmoc.props +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - - moc %(Identity) - - $(QtHostToolsDir) - $(QtInstallDir) - - %(FullPath) - - $(ProjectDir)GeneratedFiles\$(Configuration)\moc_%(Filename).cpp - - $(IntDir)moc\ - moc_%(Filename).cpp - - output - true - [AllOptions] [AdditionalOptions] - %(OutputFile) - false - - - - - - - diff --git a/Source/VSProps/QtCompile.xml b/Source/VSProps/qtmoc.xml similarity index 100% rename from Source/VSProps/QtCompile.xml rename to Source/VSProps/qtmoc.xml diff --git a/Source/VSProps/qtrcc.targets b/Source/VSProps/qtrcc.targets new file mode 100644 index 0000000000..3b60e5848c --- /dev/null +++ b/Source/VSProps/qtrcc.targets @@ -0,0 +1,580 @@ + + + + + + + + + + + QtRcc;$(QtBuildTargets) + + + + + + + + + + + + + + + + + + Qt;_ClCompile + + + + QtRule40_Rcc + + + + + + + + $([System.IO.Path]::Combine('%(QtRcc.QtRccDir)','%(QtRcc.QtRccFileName)')) + + + + + + + + + + + + + + + + + + + + + + @(res_file) + %(QtRcc.AdditionalDependencies);@(res_file->'%(FullPath)') + + + + + + + + + + + + + + + + + + + + + [@(selected_files->'%(Identity)','][')] + [@(QtRcc->'%(Identity)')] + @(QtRcc->'%(OutputFile)') + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(input_changed) + + + + + + + + + + + QtPrepare; + QtRccPrepare; + QtRccSetModified; + $(QtRccDependsOn) + + + + + + + + + + + + true + + + + + + + + + + + + + + + + $([System.String]::Copy('%(Value)').Replace('"', '')) + + + %(Value)\ + + + "%(Value)" + + + + + + %(Value) + + + + + -o %(Value) + + + + + + + + --temp %(Value) + + + + + --name %(Value) + + + + + --root %(Value) + + + + + --compress 1 + + + --compress 2 + + + --compress 3 + + + --compress 4 + + + --compress 5 + + + --compress 6 + + + --compress 7 + + + --compress 8 + + + --compress 9 + + + + + + + + + + + --no-compress + + + + + --threshold %(Value) + + + + + + + + --binary + + + + + + + + --no-zstd + + + + + --pass %(Value) + + + + + + + + --namespace + + + + + + + + --verbose + + + + + + + + --list + + + + + + + + --project + + + + + --format-version %(Value) + + + + @(options->'%(Value)', ' ') + + + + + + %(QtRcc.InputChanged) + true + + + true + + + true + + + $([MSBuild]::MakeRelative($(ProjectDir), %(QtRcc.OutputFile)).TrimStart('\')) + + + + + + rcc + $(QtToolsPath)/rcc + %(QtRcc.QTDIR)\bin\rcc.exe + $(options) + %(QtRcc.ExecutionDescription) + $(dependencies_changed) + $(input_changed) + true + false + + %(QtRcc.ExecutionDescription) [pass 1] + 1 + $(options) + $(options) -pass 1 -o "%(OutputFile)" + Disabled + + $(output_relative) + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + + + + + + + + + + + + + + + + + + + + + $(ComputeLinkInputsTargets); + ;QtRccPass2_Link; + + + $(ComputeLibInputsTargets); + ;QtRccPass2_Lib; + + + + + + + diff --git a/Source/VSProps/qtrcc.xml b/Source/VSProps/qtrcc.xml new file mode 100644 index 0000000000..d373d8b49e --- /dev/null +++ b/Source/VSProps/qtrcc.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From f2300d89cc88cd9720cbd7af603d66fee3ab4b41 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 00:22:25 +0200 Subject: [PATCH 76/99] CMake: Turn on rcc file embedding. --- Source/Core/DolphinQt/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 032f237eba..2f22853179 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -12,6 +12,7 @@ if (MSVC) endif() set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Svg) message(STATUS "Found Qt version ${Qt6_VERSION}") From 5d33f2abd1355e792566a51129a0df13db9a03c2 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 00:27:48 +0200 Subject: [PATCH 77/99] DolphinQt: On Windows, detect whether the system is using a dark theme. Co-authored-by: FearlessTobi --- Source/Core/DolphinQt/Main.cpp | 18 +++++++++++++++++- Source/Core/DolphinQt/Settings.cpp | 12 ++++++++++++ Source/Core/DolphinQt/Settings.h | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 1c658e8d62..a530f14f8d 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -2,11 +2,13 @@ // SPDX-License-Identifier: GPL-2.0-or-later #ifdef _WIN32 +#include #include #include #include -#include + +#include #endif #ifdef __linux__ @@ -244,6 +246,20 @@ int main(int argc, char* argv[]) DolphinAnalytics::Instance().ReportDolphinStart("qt"); MainWindow win{std::move(boot), static_cast(options.get("movie"))}; + +#ifdef _WIN32 + // Check if the system is set to dark mode so we can set the default theme and window + // decorations accordingly. + { + using namespace winrt::Windows::UI::ViewManagement; + const UISettings settings; + const auto& color = settings.GetColorValue(UIColorType::Foreground); + + const bool is_system_dark = 5 * color.G + 2 * color.R + color.B > 8 * 128; + Settings::Instance().SetSystemDark(is_system_dark); + } +#endif + Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle()); win.Show(); diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index c6a06336e2..4849ab4adb 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -47,6 +47,8 @@ #include "VideoCommon/NetPlayChatUI.h" #include "VideoCommon/NetPlayGolfUI.h" +static bool s_system_dark = false; + Settings::Settings() { qRegisterMetaType(); @@ -125,6 +127,16 @@ QString Settings::GetCurrentUserStyle() const return QFileInfo(GetQSettings().value(QStringLiteral("userstyle/path")).toString()).fileName(); } +void Settings::SetSystemDark(bool dark) +{ + s_system_dark = dark; +} + +bool Settings::IsSystemDark() +{ + return s_system_dark; +} + // Calling this before the main window has been created breaks the style of some widgets. void Settings::SetCurrentUserStyle(const QString& stylesheet_name) { diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index 30ab757753..ae58aca8a5 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -52,6 +52,8 @@ public: // UI void SetThemeName(const QString& theme_name); + void SetSystemDark(bool dark); + bool IsSystemDark(); void SetCurrentUserStyle(const QString& stylesheet_name); QString GetCurrentUserStyle() const; From ea30651cd73f2e74bc52c5138329a366c338962d Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 00:32:28 +0200 Subject: [PATCH 78/99] DolphinQt: Embed custom dark theme for Windows. --- Source/Core/DolphinQt/CMakeLists.txt | 6 + Source/Core/DolphinQt/DolphinQt.vcxproj | 4 + .../Styles/Dark/checkbox-checked-disabled.svg | 5 + .../Styles/Dark/checkbox-checked.svg | 5 + .../Styles/Dark/checkbox-empty-disabled.svg | 4 + .../DolphinQt/Styles/Dark/checkbox-empty.svg | 4 + .../Styles/Dark/checkbox-half-disabled.svg | 5 + .../DolphinQt/Styles/Dark/checkbox-half.svg | 5 + Source/Core/DolphinQt/Styles/Dark/dark.qrc | 30 ++ Source/Core/DolphinQt/Styles/Dark/dark.qss | 487 ++++++++++++++++++ .../Styles/Dark/dockwidget-close.svg | 5 + .../Styles/Dark/dockwidget-undock.svg | 5 + .../Styles/Dark/down-triangle-spinbox.svg | 4 + .../DolphinQt/Styles/Dark/down-triangle.svg | 4 + .../DolphinQt/Styles/Dark/dropdown-arrow.svg | 4 + .../Styles/Dark/left-triangle-tabbar.svg | 4 + .../Dark/radiobutton-checked-disabled.svg | 5 + .../Styles/Dark/radiobutton-checked.svg | 5 + .../Dark/radiobutton-empty-disabled.svg | 4 + .../Styles/Dark/radiobutton-empty.svg | 4 + .../Styles/Dark/right-triangle-tabbar.svg | 4 + .../Styles/Dark/scrollbar-arrow-down.svg | 4 + .../Styles/Dark/scrollbar-arrow-left.svg | 4 + .../Styles/Dark/scrollbar-arrow-right.svg | 4 + .../Styles/Dark/scrollbar-arrow-up.svg | 4 + .../Dark/table-header-sort-arrow-down.svg | 4 + .../Dark/table-header-sort-arrow-up.svg | 4 + .../Styles/Dark/up-triangle-spinbox.svg | 4 + .../DolphinQt/Styles/Dark/up-triangle.svg | 4 + 29 files changed, 635 insertions(+) create mode 100644 Source/Core/DolphinQt/Styles/Dark/checkbox-checked-disabled.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/checkbox-checked.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/checkbox-empty-disabled.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/checkbox-empty.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/checkbox-half-disabled.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/checkbox-half.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/dark.qrc create mode 100644 Source/Core/DolphinQt/Styles/Dark/dark.qss create mode 100644 Source/Core/DolphinQt/Styles/Dark/dockwidget-close.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/dockwidget-undock.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/down-triangle-spinbox.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/down-triangle.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/dropdown-arrow.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/left-triangle-tabbar.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/radiobutton-checked-disabled.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/radiobutton-checked.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/radiobutton-empty-disabled.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/radiobutton-empty.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/right-triangle-tabbar.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-down.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-left.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-right.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-up.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-down.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-up.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/up-triangle-spinbox.svg create mode 100644 Source/Core/DolphinQt/Styles/Dark/up-triangle.svg diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 2f22853179..50dbbbf57a 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -363,6 +363,12 @@ add_executable(dolphin-emu WiiUpdate.h ) +if (WIN32) + target_sources(dolphin-emu PRIVATE + Styles/Dark/dark.qrc + ) +endif() + if (NOT WIN32) target_sources(dolphin-emu PRIVATE QtUtils/SignalDaemon.cpp diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index ff17a0a4b1..5eaf14fa9f 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -415,6 +415,10 @@ + + + + {D79392F7-06D6-4B4B-A39F-4D587C215D3A} diff --git a/Source/Core/DolphinQt/Styles/Dark/checkbox-checked-disabled.svg b/Source/Core/DolphinQt/Styles/Dark/checkbox-checked-disabled.svg new file mode 100644 index 0000000000..2c630f0b8a --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/checkbox-checked-disabled.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/checkbox-checked.svg b/Source/Core/DolphinQt/Styles/Dark/checkbox-checked.svg new file mode 100644 index 0000000000..a9164e1c72 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/checkbox-checked.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/checkbox-empty-disabled.svg b/Source/Core/DolphinQt/Styles/Dark/checkbox-empty-disabled.svg new file mode 100644 index 0000000000..5e4660fd8a --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/checkbox-empty-disabled.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/checkbox-empty.svg b/Source/Core/DolphinQt/Styles/Dark/checkbox-empty.svg new file mode 100644 index 0000000000..43dd3887ce --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/checkbox-empty.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/checkbox-half-disabled.svg b/Source/Core/DolphinQt/Styles/Dark/checkbox-half-disabled.svg new file mode 100644 index 0000000000..ade83d8df5 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/checkbox-half-disabled.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/checkbox-half.svg b/Source/Core/DolphinQt/Styles/Dark/checkbox-half.svg new file mode 100644 index 0000000000..4f6aa9a032 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/checkbox-half.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/dark.qrc b/Source/Core/DolphinQt/Styles/Dark/dark.qrc new file mode 100644 index 0000000000..025d685de1 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/dark.qrc @@ -0,0 +1,30 @@ + + + dark.qss + checkbox-checked.svg + checkbox-checked-disabled.svg + checkbox-empty.svg + checkbox-empty-disabled.svg + checkbox-half.svg + checkbox-half-disabled.svg + dockwidget-close.svg + dockwidget-undock.svg + down-triangle.svg + down-triangle-spinbox.svg + dropdown-arrow.svg + left-triangle-tabbar.svg + radiobutton-checked.svg + radiobutton-checked-disabled.svg + radiobutton-empty.svg + radiobutton-empty-disabled.svg + right-triangle-tabbar.svg + scrollbar-arrow-down.svg + scrollbar-arrow-left.svg + scrollbar-arrow-right.svg + scrollbar-arrow-up.svg + table-header-sort-arrow-down.svg + table-header-sort-arrow-up.svg + up-triangle.svg + up-triangle-spinbox.svg + + diff --git a/Source/Core/DolphinQt/Styles/Dark/dark.qss b/Source/Core/DolphinQt/Styles/Dark/dark.qss new file mode 100644 index 0000000000..9d41736fdb --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/dark.qss @@ -0,0 +1,487 @@ +/* +Theme for a look and feel like our default Windows theme, but dark +*/ + +* { + color: #dcdcdc; +} +*:disabled { + color: #7e7e7e; +} + +/* +window title bars apparently can't be styled +would be #000000 for active, #2b2b2b for background +*/ + +QMenu { + border: 1px solid #7e7e7e; +} +QMenuBar { + background-color: #202020; + color: #dcdcdc; + border: 0px; +} +QMenu { + background-color: #202020; + color: #dcdcdc; + border: 1px solid #7e7e7e; +} +QMenuBar::item { + background-color: #202020; + color: #dcdcdc; + border: 0px; + padding-left: 8px; + padding-right: 8px; + padding-top: 3px; + padding-bottom: 2px; + margin: 0px; +} +QMenuBar { + border-color: #404040; +} +QMenu::item { + background-color: #202020; + color: #dcdcdc; + border: 0px; + padding-left: 8px; + padding-right: 32px; + padding-top: 4px; + padding-bottom: 4px; + margin: 0px; +} +QMenuBar::item:hover, QMenuBar::item:selected, QMenu::item:hover, QMenu::item:selected { + background-color: #404040; + color: #dcdcdc; +} +QMenuBar::item:disabled, QMenu::item:disabled { + color: #7e7e7e; +} +QMenu::separator { + height: 1px; + background-color: #7e7e7e; + margin-left: 2px; + margin-right: 2px; + margin-top: 5px; + margin-bottom: 5px; +} + +QWidget { + background-color: #202020; +} +QColumnView, QListView, QTableView, QTableWidget, QTreeView { + background-color: #202020; + alternate-background-color: #303030; + border: 1px solid #7e7e7e; + selection-background-color: #505050; /* #202050; */ + gridline-color: #606060; +} +/* +would be consistent with Explorer, but Qt keeps the focus color even if you click away from the item, which is confusing +QColumnView::item:focus, QListView::item:focus, QTableView::item:focus, QTableWidget::item:focus, QTreeView::item:focus { + background-color: #606060; +} +*/ +QHeaderView::section { + background-color: #202020; + border: 0px; + border-right: 1px solid #7e7e7e; + padding: 0px; + text-align: right; + + /* + this is a hack, Qt is extremely convinced that the sort arrow belongs on the right side + of the header and will reserve space for it there. so this applies that same space to the left + so the text is still centered correctly. + */ + padding-left: 10px; +} +QHeaderView::section:last { + border-right: 0px; +} +QHeaderView::section:hover, QHeaderView::section:checked { + background-color: #404040; +} +QHeaderView::down-arrow { + subcontrol-origin: margin; + subcontrol-position: top center; + image: url(:/dolphin_dark_win/table-header-sort-arrow-down.svg); + width: 10px; + height: 7px; + background: transparent; +} +QHeaderView::up-arrow { + subcontrol-origin: margin; + subcontrol-position: top center; + image: url(:/dolphin_dark_win/table-header-sort-arrow-up.svg); + width: 10px; + height: 7px; + background: transparent; +} + +QTabWidget::pane { + border: 1px solid #7e7e7e; + top: -1px; /* move border behind tabs */ +} +QTabWidget::tab-bar { + left: 2px; /* leave space on the side of the tabs */ +} + +QTabBar { + /* The outline on the focused tab has an incorrect position and as far as I can tell there's no way to move it. + So as a hack, remove it and apply an underline to the text instead. */ + outline: 0px; +} +QTabBar::tab { + background-color: #303030; + border-left: 1px solid #7e7e7e; + border-right: 1px solid #7e7e7e; + border-top: 1px solid #7e7e7e; + border-bottom: 1px solid #7e7e7e; + padding-top: 2px; + padding-bottom: 2px; + padding-left: 9px; + padding-right: 10px; + margin-right: -1px; /* so adjacent tab borders overlap */ +} +QTabBar::tab:only-one { + margin-right: 0px; +} +QTabBar::tab:last { + margin-right: 0px; +} +QTabBar::tab:hover { + background-color: #404040; +} +QTabBar::tab:selected { + border-bottom: 0px; + background-color: #202020; + padding-bottom: 1px; +} +QTabBar::tab:focus { + text-decoration: underline; +} +QTabBar::tab:!selected { + margin-top: 2px; +} + +QDockWidget { + background-color: #404040; + titlebar-close-icon: url(:/dolphin_dark_win/dockwidget-close.svg); + titlebar-normal-icon: url(:/dolphin_dark_win/dockwidget-undock.svg); +} + +QPushButton, QToolButton { + background-color: #303030; + border: 1px solid #7e7e7e; + padding: 2px; + min-width: 67px; +} +QPushButton:hover, QToolButton:hover { + background-color: #404040; +} +QPushButton:focus, QToolButton:focus { + background-color: #404040; +} +QPushButton:disabled, QToolButton:disabled { + background-color: #505050; +} + +/* the dropdownarrow on the right of the button in menu popup mode */ +QToolButton[popupMode="1"] { + padding-right: 19px; +} +QToolButton::menu-button { + border: 0px; + border-left: 1px solid #7e7e7e; + width: 18px; +} +QToolButton::menu-arrow { + image: url(:/dolphin_dark_win/down-triangle.svg); + width: 14px; +} + +/* the icon bar at the top of the main window */ +QToolBar { + border: 0px; +} +QToolBar QToolButton { + border: 0px; + padding: 0px; + padding-left: 3px; + padding-right: 2px; + min-width: 50px; + background-color: #202020; +} +QToolBar QToolButton:hover { + background-color: #404040; +} +QToolBar QToolButton:focus { + background-color: #404040; +} +QToolBar QToolButton:disabled { + background-color: #202020; +} +QToolBar::separator { + min-width: 0px; + width: 1px; + margin-left: 3px; + margin-right: 2px; + background-color: #7e7e7e; +} + +QGroupBox { + border: 1px solid #7e7e7e; + margin-top: 9px; + padding-top: 7px; + padding-bottom: 0px; + padding-left: 1px; + padding-right: 1px; +} +QGroupBox::title { + subcontrol-origin: margin; + subcontrol-position: top left; + left: 9px; + padding-top: 1px; + min-width: 0px; +} + +QLineEdit, QTextEdit { + border: 1px solid #7e7e7e; +} +QLineEdit:disabled, QTextEdit:disabled { + background-color: #505050; +} + +QComboBox { + background-color: #303030; + border: 1px solid #7e7e7e; + margin: 0px; + padding-left: 3px; + padding-right: 3px; + padding-top: 1px; + padding-bottom: 1px; +} +QComboBox:disabled { + background-color: #505050; +} +QComboBox:selected { + background-color: #404040; +} +QComboBox:editable { + background-color: #202020; +} +QComboBox::drop-down { + border: 0px; +} +QComboBox::down-arrow { + image: url(:/dolphin_dark_win/dropdown-arrow.svg); + height: 10px; + width: 15px; +} +QComboBox QAbstractItemView { + background-color: #303030; + selection-background-color: #404040; + border: 1px solid #7e7e7e; + padding: 0px; + margin: 0px; + outline: 0px; +} +QComboBox QAbstractItemView::item:selected { + color: #dcdcdc; + background-color: #404040; +} +QComboBox QAbstractItemView::item:last { + border: 0px; +} + +QScrollBar:vertical { + border: 0px; + background: #303030; + width: 15px; + margin: 15px 0px; +} +QScrollBar::handle:vertical { /* the bar in the middle */ + border: 0px; + background: #606060; + min-height: 20px; +} +QScrollBar::add-line:vertical { /* the down button at the bottom */ + border: 0px; + background: #303030; + height: 15px; + subcontrol-position: bottom; + subcontrol-origin: margin; +} +QScrollBar::sub-line:vertical { /* the up button at the top */ + border: 0px; + background: #303030; + height: 15px; + subcontrol-position: top; + subcontrol-origin: margin; +} +QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { /* the area between the bar and the up/down buttons */ + border: 0px; + background: none; +} +QScrollBar::up-arrow:vertical { + image: url(:/dolphin_dark_win/scrollbar-arrow-up.svg); + height: 15px; +} +QScrollBar::down-arrow:vertical { + image: url(:/dolphin_dark_win/scrollbar-arrow-down.svg); + height: 15px; +} +QScrollBar:horizontal { + border: 0px; + background: #303030; + height: 15px; + margin: 0px 15px; +} +QScrollBar::handle:horizontal { /* the bar in the middle */ + border: 0px; + background: #606060; + min-width: 20px; +} +QScrollBar::add-line:horizontal { /* the right button */ + border: 0px; + background: #303030; + width: 15px; + subcontrol-position: right; + subcontrol-origin: margin; +} +QScrollBar::sub-line:horizontal { /* the left button */ + border: 0px; + background: #303030; + width: 15px; + subcontrol-position: left; + subcontrol-origin: margin; +} +QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { /* the area between the bar and the left/right buttons */ + border: 0px; + background: none; +} +QScrollBar::left-arrow:horizontal { + image: url(:/dolphin_dark_win/scrollbar-arrow-left.svg); + width: 15px; +} +QScrollBar::right-arrow:horizontal { + image: url(:/dolphin_dark_win/scrollbar-arrow-right.svg); + width: 15px; +} + +QSpinBox, QDateEdit, QDateTimeEdit, QTimeEdit, QDoubleSpinBox { + border: 1px solid #7e7e7e; + padding-right: 15px; +} +QSpinBox:disabled, QDateEdit:disabled, QDateTimeEdit:disabled, QTimeEdit:disabled, QDoubleSpinBox:disabled { + background-color: #505050; +} +QSpinBox::up-button, QDateEdit::up-button, QDateTimeEdit::up-button, QTimeEdit::up-button, QDoubleSpinBox::up-button { + border: 1px transparent; + subcontrol-origin: border; + subcontrol-position: top right; + width: 16px; +} +QSpinBox::down-button, QDateEdit::down-button, QDateTimeEdit::down-button, QTimeEdit::down-button, QDoubleSpinBox::down-button { + border: 1px transparent; + subcontrol-origin: border; + subcontrol-position: bottom right; + width: 16px; +} +QSpinBox::up-arrow, QDateEdit::up-arrow, QDateTimeEdit::up-arrow, QTimeEdit::up-arrow, QDoubleSpinBox::up-arrow { + image: url(:/dolphin_dark_win/up-triangle-spinbox.svg); + width: 14px; + height: 7px; +} +QSpinBox::down-arrow, QDateEdit::down-arrow, QDateTimeEdit::down-arrow, QTimeEdit::down-arrow, QDoubleSpinBox::down-arrow { + image: url(:/dolphin_dark_win/down-triangle-spinbox.svg); + width: 14px; + height: 7px; +} + +/* +QSlider ticks break if you try to style the groove. +https://stackoverflow.com/questions/27531542/tick-marks-disappear-on-styled-qslider +https://bugreports.qt.io/browse/QTBUG-3564 (yes that's from 2009 and it's still accurate) +Truly bizarre. I'll just refrain from styling it from now... +*/ +QSlider::handle { + background-color: #dcdcdc; +} +QSlider::handle:disabled { + background-color: #7e7e7e; +} + +QCheckBox { + padding: 2px 0px; +} +QCheckBox::indicator { + padding: 0px; + margin: 0px; + border: 0px; + width: 13px; + height: 13px; +} +QCheckBox::indicator:unchecked { + image: url(:/dolphin_dark_win/checkbox-empty.svg); +} +QCheckBox::indicator:unchecked:disabled { + image: url(:/dolphin_dark_win/checkbox-empty-disabled.svg); +} +QCheckBox::indicator:checked { + image: url(:/dolphin_dark_win/checkbox-checked.svg); +} +QCheckBox::indicator:checked:disabled { + image: url(:/dolphin_dark_win/checkbox-checked-disabled.svg); +} +QCheckBox::indicator:indeterminate { + image: url(:/dolphin_dark_win/checkbox-half.svg); +} +QCheckBox::indicator:indeterminate:disabled { + image: url(:/dolphin_dark_win/checkbox-half-disabled.svg); +} + +QRadioButton { + padding: 2px 0px; +} +QRadioButton::indicator { + padding: 0px; + margin: 0px; + border: 0px; + width: 13px; + height: 13px; +} +QRadioButton::indicator:unchecked { + image: url(:/dolphin_dark_win/radiobutton-empty.svg); +} +QRadioButton::indicator:unchecked:disabled { + image: url(:/dolphin_dark_win/radiobutton-empty-disabled.svg); +} +QRadioButton::indicator:checked { + image: url(:/dolphin_dark_win/radiobutton-checked.svg); +} +QRadioButton::indicator:checked:disabled { + image: url(:/dolphin_dark_win/radiobutton-checked-disabled.svg); +} + +QListView::indicator:unchecked { + image: url(:/dolphin_dark_win/checkbox-empty.svg); +} +QListView::indicator:checked { + image: url(:/dolphin_dark_win/checkbox-checked.svg); +} +QListView::indicator:indeterminate { + image: url(:/dolphin_dark_win/checkbox-half.svg); +} + +QTabBar QToolButton { + background-color: #202020; + min-width: 0px; +} +QTabBar QToolButton::left-arrow { + image: url(:/dolphin_dark_win/left-triangle-tabbar.svg); +} +QTabBar QToolButton::right-arrow { + image: url(:/dolphin_dark_win/right-triangle-tabbar.svg); +} diff --git a/Source/Core/DolphinQt/Styles/Dark/dockwidget-close.svg b/Source/Core/DolphinQt/Styles/Dark/dockwidget-close.svg new file mode 100644 index 0000000000..a58a58caa9 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/dockwidget-close.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/dockwidget-undock.svg b/Source/Core/DolphinQt/Styles/Dark/dockwidget-undock.svg new file mode 100644 index 0000000000..a3d7563030 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/dockwidget-undock.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/down-triangle-spinbox.svg b/Source/Core/DolphinQt/Styles/Dark/down-triangle-spinbox.svg new file mode 100644 index 0000000000..f406b170d9 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/down-triangle-spinbox.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/down-triangle.svg b/Source/Core/DolphinQt/Styles/Dark/down-triangle.svg new file mode 100644 index 0000000000..4884cff9b1 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/down-triangle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/dropdown-arrow.svg b/Source/Core/DolphinQt/Styles/Dark/dropdown-arrow.svg new file mode 100644 index 0000000000..b5e46941b8 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/dropdown-arrow.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/left-triangle-tabbar.svg b/Source/Core/DolphinQt/Styles/Dark/left-triangle-tabbar.svg new file mode 100644 index 0000000000..cebe58fd57 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/left-triangle-tabbar.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/radiobutton-checked-disabled.svg b/Source/Core/DolphinQt/Styles/Dark/radiobutton-checked-disabled.svg new file mode 100644 index 0000000000..7cef56e7c8 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/radiobutton-checked-disabled.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/radiobutton-checked.svg b/Source/Core/DolphinQt/Styles/Dark/radiobutton-checked.svg new file mode 100644 index 0000000000..3f1a655397 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/radiobutton-checked.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/radiobutton-empty-disabled.svg b/Source/Core/DolphinQt/Styles/Dark/radiobutton-empty-disabled.svg new file mode 100644 index 0000000000..693e47d72d --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/radiobutton-empty-disabled.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/radiobutton-empty.svg b/Source/Core/DolphinQt/Styles/Dark/radiobutton-empty.svg new file mode 100644 index 0000000000..11bfe01b83 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/radiobutton-empty.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/right-triangle-tabbar.svg b/Source/Core/DolphinQt/Styles/Dark/right-triangle-tabbar.svg new file mode 100644 index 0000000000..eff00545b4 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/right-triangle-tabbar.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-down.svg b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-down.svg new file mode 100644 index 0000000000..10b5aaa26f --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-down.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-left.svg b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-left.svg new file mode 100644 index 0000000000..a7754c9fd2 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-left.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-right.svg b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-right.svg new file mode 100644 index 0000000000..342d4e49f8 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-right.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-up.svg b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-up.svg new file mode 100644 index 0000000000..935c4f7db7 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/scrollbar-arrow-up.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-down.svg b/Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-down.svg new file mode 100644 index 0000000000..3fde763da9 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-down.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-up.svg b/Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-up.svg new file mode 100644 index 0000000000..ed4a4822af --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/table-header-sort-arrow-up.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/up-triangle-spinbox.svg b/Source/Core/DolphinQt/Styles/Dark/up-triangle-spinbox.svg new file mode 100644 index 0000000000..4dc1312209 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/up-triangle-spinbox.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/Core/DolphinQt/Styles/Dark/up-triangle.svg b/Source/Core/DolphinQt/Styles/Dark/up-triangle.svg new file mode 100644 index 0000000000..d8be2c7d92 --- /dev/null +++ b/Source/Core/DolphinQt/Styles/Dark/up-triangle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From adbe56ce156b5699a97bde1bda0433a3ed189ae5 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 00:35:48 +0200 Subject: [PATCH 79/99] DolphinQt: Auto-load embedded dark theme on Windows if the user uses a system-wide dark theme. --- Source/Core/DolphinQt/Settings.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index 4849ab4adb..2a7b7b41fb 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -153,6 +153,22 @@ void Settings::SetCurrentUserStyle(const QString& stylesheet_name) stylesheet_contents = QString::fromUtf8(stylesheet.readAll().data()); } +#ifdef _WIN32 + if (stylesheet_contents.isEmpty()) + { + // No theme selected or found. Usually we would just fallthrough and set an empty stylesheet + // which would select Qt's default theme, but unlike other OSes we don't automatically get a + // default dark theme on Windows when the user has selected dark mode in the Windows settings. + // So manually check if the user wants dark mode and, if yes, load our embedded dark theme. + if (IsSystemDark()) + { + QFile file(QStringLiteral(":/dolphin_dark_win/dark.qss")); + if (file.open(QFile::ReadOnly)) + stylesheet_contents = QString::fromUtf8(file.readAll().data()); + } + } +#endif + // Define tooltips style if not already defined if (!stylesheet_contents.contains(QStringLiteral("QToolTip"), Qt::CaseSensitive)) { From e8d23af0f2799337af0b0c69a34aa717bf88766e Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 00:40:15 +0200 Subject: [PATCH 80/99] DolphinQt: Add function to set a QWidget's window decorations to dark ones on Windows. --- Source/Core/DolphinQt/CMakeLists.txt | 3 +++ Source/Core/DolphinQt/DolphinQt.vcxproj | 2 ++ .../QtUtils/SetWindowDecorations.cpp | 25 +++++++++++++++++++ .../DolphinQt/QtUtils/SetWindowDecorations.h | 9 +++++++ Source/VSProps/Base.Dolphin.props | 2 ++ 5 files changed, 41 insertions(+) create mode 100644 Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp create mode 100644 Source/Core/DolphinQt/QtUtils/SetWindowDecorations.h diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 50dbbbf57a..2633b3d264 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -294,6 +294,8 @@ add_executable(dolphin-emu QtUtils/ParallelProgressDialog.h QtUtils/PartiallyClosableTabWidget.cpp QtUtils/PartiallyClosableTabWidget.h + QtUtils/SetWindowDecorations.cpp + QtUtils/SetWindowDecorations.h QtUtils/SignalBlocking.h QtUtils/UTF8CodePointCountValidator.cpp QtUtils/UTF8CodePointCountValidator.h @@ -403,6 +405,7 @@ if (WIN32) PRIVATE gdi32.lib shell32.lib + dwmapi.lib # Needed to set window decorations for dark theme ) endif() diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 5eaf14fa9f..9217cc3788 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -188,6 +188,7 @@ + @@ -379,6 +380,7 @@ + diff --git a/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp b/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp new file mode 100644 index 0000000000..704e5a8f7f --- /dev/null +++ b/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.cpp @@ -0,0 +1,25 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "DolphinQt/QtUtils/SetWindowDecorations.h" + +#include + +#include "DolphinQt/Settings.h" + +#ifdef _WIN32 +#include +#endif + +void SetQWidgetWindowDecorations(QWidget* widget) +{ +#ifdef _WIN32 + if (!Settings::Instance().IsSystemDark()) + return; + + BOOL use_dark_title_bar = TRUE; + DwmSetWindowAttribute(HWND(widget->winId()), + 20 /* DWMWINDOWATTRIBUTE::DWMWA_USE_IMMERSIVE_DARK_MODE */, + &use_dark_title_bar, DWORD(sizeof(use_dark_title_bar))); +#endif +} diff --git a/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.h b/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.h new file mode 100644 index 0000000000..aa4b3d8687 --- /dev/null +++ b/Source/Core/DolphinQt/QtUtils/SetWindowDecorations.h @@ -0,0 +1,9 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +class QWidget; + +// Changes the window decorations (title bar) to dark if the user uses dark mode on Windows. +void SetQWidgetWindowDecorations(QWidget* widget); diff --git a/Source/VSProps/Base.Dolphin.props b/Source/VSProps/Base.Dolphin.props index a575d9290b..96fe8b6d2a 100644 --- a/Source/VSProps/Base.Dolphin.props +++ b/Source/VSProps/Base.Dolphin.props @@ -79,6 +79,8 @@ avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;bcrypt.lib;%(AdditionalDependencies) Crypt32.lib;%(AdditionalDependencies) + + dwmapi.lib;%(AdditionalDependencies) enableCompatPatches From e2fb8fab2f695ee53ab0aa7a5ff2fe752c719ce8 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 00:42:15 +0200 Subject: [PATCH 81/99] DolphinQt: Set window decorations for all top-level QWidgets. --- Source/Core/DolphinQt/Config/ARCodeWidget.cpp | 4 ++++ .../Config/CommonControllersWidget.cpp | 2 ++ .../DualShockUDPClientWidget.cpp | 2 ++ .../DolphinQt/Config/FilesystemWidget.cpp | 2 ++ .../Core/DolphinQt/Config/FreeLookWidget.cpp | 2 ++ .../Config/GamecubeControllersWidget.cpp | 8 ++++++- .../Core/DolphinQt/Config/GeckoCodeWidget.cpp | 3 +++ .../Config/Graphics/EnhancementsWidget.cpp | 9 +++++-- .../Config/Graphics/GeneralWidget.cpp | 2 ++ .../Config/Mapping/FreeLookRotation.cpp | 2 ++ .../Config/Mapping/MappingButton.cpp | 2 ++ .../Config/Mapping/MappingWidget.cpp | 3 +++ .../Config/Mapping/MappingWindow.cpp | 4 ++++ .../WiimoteEmuExtensionMotionInput.cpp | 2 ++ .../Mapping/WiimoteEmuMotionControlIMU.cpp | 2 ++ .../Core/DolphinQt/Config/PatchesWidget.cpp | 17 +++++++++++-- Source/Core/DolphinQt/Config/VerifyWidget.cpp | 2 ++ .../Config/WiimoteControllersWidget.cpp | 2 ++ Source/Core/DolphinQt/ConvertDialog.cpp | 4 ++++ .../DolphinQt/Debugger/BreakpointWidget.cpp | 4 ++++ .../DolphinQt/Debugger/CodeViewWidget.cpp | 3 +++ Source/Core/DolphinQt/Debugger/CodeWidget.cpp | 2 ++ .../DolphinQt/Debugger/RegisterWidget.cpp | 2 ++ Source/Core/DolphinQt/DiscordHandler.cpp | 2 ++ Source/Core/DolphinQt/GBAWidget.cpp | 2 ++ Source/Core/DolphinQt/GCMemcardManager.cpp | 2 ++ Source/Core/DolphinQt/GameList/GameList.cpp | 8 +++++++ .../InfinityBase/InfinityBaseWindow.cpp | 2 ++ Source/Core/DolphinQt/Main.cpp | 3 +++ Source/Core/DolphinQt/MainWindow.cpp | 24 +++++++++++++++++++ Source/Core/DolphinQt/MenuBar.cpp | 10 ++++++-- Source/Core/DolphinQt/NKitWarningDialog.cpp | 7 ++++-- .../Core/DolphinQt/NetPlay/NetPlayBrowser.cpp | 2 ++ .../Core/DolphinQt/NetPlay/NetPlayDialog.cpp | 4 ++++ .../DolphinQt/QtUtils/ModalMessageBox.cpp | 3 +++ Source/Core/DolphinQt/ResourcePackManager.cpp | 2 ++ .../Core/DolphinQt/Settings/GameCubePane.cpp | 19 +++++++++++---- .../Core/DolphinQt/Settings/GeneralPane.cpp | 2 ++ Source/Core/DolphinQt/Settings/WiiPane.cpp | 4 ++++ .../SkylanderPortal/SkylanderPortalWindow.cpp | 2 ++ .../Core/DolphinQt/TAS/WiiTASInputWindow.cpp | 13 ++++++++++ Source/Core/DolphinQt/Updater.cpp | 2 ++ Source/Core/DolphinQt/WiiUpdate.cpp | 2 ++ 43 files changed, 187 insertions(+), 13 deletions(-) diff --git a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp index 667f9373c1..a25d6fe7ab 100644 --- a/Source/Core/DolphinQt/Config/ARCodeWidget.cpp +++ b/Source/Core/DolphinQt/Config/ARCodeWidget.cpp @@ -22,6 +22,7 @@ #include "DolphinQt/Config/CheatCodeEditor.h" #include "DolphinQt/Config/CheatWarningWidget.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "UICommon/GameFile.h" @@ -230,6 +231,7 @@ void ARCodeWidget::OnCodeAddClicked() CheatCodeEditor ed(this); ed.SetARCode(&ar); + SetQWidgetWindowDecorations(&ed); if (ed.exec() == QDialog::Rejected) return; @@ -253,6 +255,7 @@ void ARCodeWidget::OnCodeEditClicked() { ed.SetARCode(¤t_ar); + SetQWidgetWindowDecorations(&ed); if (ed.exec() == QDialog::Rejected) return; } @@ -261,6 +264,7 @@ void ARCodeWidget::OnCodeEditClicked() ActionReplay::ARCode ar = current_ar; ed.SetARCode(&ar); + SetQWidgetWindowDecorations(&ed); if (ed.exec() == QDialog::Rejected) return; diff --git a/Source/Core/DolphinQt/Config/CommonControllersWidget.cpp b/Source/Core/DolphinQt/Config/CommonControllersWidget.cpp index e988509f6a..9535895a73 100644 --- a/Source/Core/DolphinQt/Config/CommonControllersWidget.cpp +++ b/Source/Core/DolphinQt/Config/CommonControllersWidget.cpp @@ -13,6 +13,7 @@ #include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" @@ -59,6 +60,7 @@ void CommonControllersWidget::OnControllerInterfaceConfigure() ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this); window->setAttribute(Qt::WA_DeleteOnClose, true); window->setWindowModality(Qt::WindowModality::WindowModal); + SetQWidgetWindowDecorations(window); window->show(); } diff --git a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp index 90237057e0..04ed5437df 100644 --- a/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp +++ b/Source/Core/DolphinQt/Config/ControllerInterface/DualShockUDPClientWidget.cpp @@ -14,6 +14,7 @@ #include "Common/Config/Config.h" #include "DolphinQt/Config/ControllerInterface/DualShockUDPClientAddServerDialog.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "InputCommon/ControllerInterface/DualShockUDPClient/DualShockUDPClient.h" DualShockUDPClientWidget::DualShockUDPClientWidget() @@ -111,6 +112,7 @@ void DualShockUDPClientWidget::OnServerAdded() DualShockUDPClientAddServerDialog add_server_dialog(this); connect(&add_server_dialog, &DualShockUDPClientAddServerDialog::accepted, this, &DualShockUDPClientWidget::RefreshServerList); + SetQWidgetWindowDecorations(&add_server_dialog); add_server_dialog.exec(); } diff --git a/Source/Core/DolphinQt/Config/FilesystemWidget.cpp b/Source/Core/DolphinQt/Config/FilesystemWidget.cpp index 7dbf0014ea..56aff5b9df 100644 --- a/Source/Core/DolphinQt/Config/FilesystemWidget.cpp +++ b/Source/Core/DolphinQt/Config/FilesystemWidget.cpp @@ -25,6 +25,7 @@ #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/ParallelProgressDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "UICommon/UICommon.h" @@ -364,6 +365,7 @@ void FilesystemWidget::ExtractDirectory(const DiscIO::Partition& partition, cons dialog.Reset(); }); + SetQWidgetWindowDecorations(dialog.GetRaw()); dialog.GetRaw()->exec(); future.get(); } diff --git a/Source/Core/DolphinQt/Config/FreeLookWidget.cpp b/Source/Core/DolphinQt/Config/FreeLookWidget.cpp index e0524c06d7..5fe1ecd66d 100644 --- a/Source/Core/DolphinQt/Config/FreeLookWidget.cpp +++ b/Source/Core/DolphinQt/Config/FreeLookWidget.cpp @@ -17,6 +17,7 @@ #include "DolphinQt/Config/Mapping/MappingWindow.h" #include "DolphinQt/Config/ToolTipControls/ToolTipCheckBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" FreeLookWidget::FreeLookWidget(QWidget* parent) : QWidget(parent) @@ -97,6 +98,7 @@ void FreeLookWidget::OnFreeLookControllerConfigured() MappingWindow* window = new MappingWindow(this, MappingWindow::Type::MAPPING_FREELOOK, index); window->setAttribute(Qt::WA_DeleteOnClose, true); window->setWindowModality(Qt::WindowModality::WindowModal); + SetQWidgetWindowDecorations(window); window->show(); } diff --git a/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp index 38ea1e4e7f..7fb37866ac 100644 --- a/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp +++ b/Source/Core/DolphinQt/Config/GamecubeControllersWidget.cpp @@ -24,6 +24,7 @@ #include "DolphinQt/Config/Mapping/GCPadWiiUConfigDialog.h" #include "DolphinQt/Config/Mapping/MappingWindow.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" @@ -137,8 +138,12 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index) type = MappingWindow::Type::MAPPING_GCPAD; break; case SerialInterface::SIDEVICE_WIIU_ADAPTER: - GCPadWiiUConfigDialog(static_cast(index), this).exec(); + { + GCPadWiiUConfigDialog dialog(static_cast(index), this); + SetQWidgetWindowDecorations(&dialog); + dialog.exec(); return; + } case SerialInterface::SIDEVICE_GC_STEERING: type = MappingWindow::Type::MAPPING_GC_STEERINGWHEEL; break; @@ -161,6 +166,7 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index) MappingWindow* window = new MappingWindow(this, type, static_cast(index)); window->setAttribute(Qt::WA_DeleteOnClose, true); window->setWindowModality(Qt::WindowModality::WindowModal); + SetQWidgetWindowDecorations(window); window->show(); } diff --git a/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp b/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp index 124bb20185..988bcf329c 100644 --- a/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp +++ b/Source/Core/DolphinQt/Config/GeckoCodeWidget.cpp @@ -28,6 +28,7 @@ #include "DolphinQt/Config/CheatWarningWidget.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "UICommon/GameFile.h" @@ -201,6 +202,7 @@ void GeckoCodeWidget::AddCode() CheatCodeEditor ed(this); ed.SetGeckoCode(&code); + SetQWidgetWindowDecorations(&ed); if (ed.exec() == QDialog::Rejected) return; @@ -219,6 +221,7 @@ void GeckoCodeWidget::EditCode() CheatCodeEditor ed(this); ed.SetGeckoCode(&m_gecko_codes[index]); + SetQWidgetWindowDecorations(&ed); if (ed.exec() == QDialog::Rejected) return; diff --git a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp index c1c0495929..09e8ec11e0 100644 --- a/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/EnhancementsWidget.cpp @@ -22,6 +22,7 @@ #include "DolphinQt/Config/Graphics/GraphicsWindow.h" #include "DolphinQt/Config/Graphics/PostProcessingConfigWindow.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" #include "VideoCommon/PostProcessing.h" @@ -570,11 +571,15 @@ void EnhancementsWidget::AddDescriptions() void EnhancementsWidget::ConfigureColorCorrection() { - ColorCorrectionConfigWindow(this).exec(); + ColorCorrectionConfigWindow dialog(this); + SetQWidgetWindowDecorations(&dialog); + dialog.exec(); } void EnhancementsWidget::ConfigurePostProcessingShader() { const std::string shader = Config::Get(Config::GFX_ENHANCE_POST_SHADER); - PostProcessingConfigWindow(this, shader).exec(); + PostProcessingConfigWindow dialog(this, shader); + SetQWidgetWindowDecorations(&dialog); + dialog.exec(); } diff --git a/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp b/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp index 8733419f60..95a39f9a45 100644 --- a/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp +++ b/Source/Core/DolphinQt/Config/Graphics/GeneralWidget.cpp @@ -24,6 +24,7 @@ #include "DolphinQt/Config/Graphics/GraphicsWindow.h" #include "DolphinQt/Config/ToolTipControls/ToolTipComboBox.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" #include "VideoCommon/VideoBackendBase.h" @@ -164,6 +165,7 @@ void GeneralWidget::SaveSettings() confirm_sw.setWindowTitle(tr("Confirm backend change")); confirm_sw.setText(tr(warningMessage->c_str())); + SetQWidgetWindowDecorations(&confirm_sw); if (confirm_sw.exec() != QMessageBox::Yes) { m_backend_combo->setCurrentIndex(m_backend_combo->findData( diff --git a/Source/Core/DolphinQt/Config/Mapping/FreeLookRotation.cpp b/Source/Core/DolphinQt/Config/Mapping/FreeLookRotation.cpp index dfd8532624..d6594fb063 100644 --- a/Source/Core/DolphinQt/Config/Mapping/FreeLookRotation.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/FreeLookRotation.cpp @@ -11,6 +11,7 @@ #include "Core/FreeLookManager.h" #include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "InputCommon/InputConfig.h" FreeLookRotation::FreeLookRotation(MappingWindow* window) : MappingWidget(window) @@ -33,6 +34,7 @@ void FreeLookRotation::CreateMainLayout() ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this); window->setAttribute(Qt::WA_DeleteOnClose, true); window->setWindowModality(Qt::WindowModality::WindowModal); + SetQWidgetWindowDecorations(window); window->show(); }); m_main_layout->addLayout(alternate_input_layout, 0, 0, 1, -1); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp index 78c776007d..bfc3d751e4 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingButton.cpp @@ -12,6 +12,7 @@ #include "DolphinQt/Config/Mapping/MappingCommon.h" #include "DolphinQt/Config/Mapping/MappingWidget.h" #include "DolphinQt/Config/Mapping/MappingWindow.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControllerEmu/ControlGroup/Buttons.h" @@ -97,6 +98,7 @@ void MappingButton::AdvancedPressed() { IOWindow io(m_parent, m_parent->GetController(), m_reference, m_reference->IsInput() ? IOWindow::Type::Input : IOWindow::Type::Output); + SetQWidgetWindowDecorations(&io); io.exec(); ConfigChanged(); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp index 02d8c852b7..cfb9483ba6 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWidget.cpp @@ -16,6 +16,7 @@ #include "DolphinQt/Config/Mapping/MappingIndicator.h" #include "DolphinQt/Config/Mapping/MappingNumeric.h" #include "DolphinQt/Config/Mapping/MappingWindow.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControllerEmu/Control/Control.h" @@ -248,6 +249,7 @@ void MappingWidget::ShowAdvancedControlGroupDialog(ControllerEmu::ControlGroup* // Enable "Close" button functionality. connect(button_box, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); + SetQWidgetWindowDecorations(&dialog); dialog.exec(); } @@ -303,6 +305,7 @@ MappingWidget::CreateSettingAdvancedMappingButton(ControllerEmu::NumericSettingB setting.SetExpressionFromValue(); IOWindow io(this, GetController(), &setting.GetInputReference(), IOWindow::Type::Input); + SetQWidgetWindowDecorations(&io); io.exec(); setting.SimplifyIfPossible(); diff --git a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp index dcb1cc83a1..688870869e 100644 --- a/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/MappingWindow.cpp @@ -49,6 +49,7 @@ #include "DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/WindowActivationEventFilter.h" #include "DolphinQt/QtUtils/WrapInScrollArea.h" #include "DolphinQt/Settings.h" @@ -255,6 +256,7 @@ void MappingWindow::OnDeleteProfilePressed() error.setIcon(QMessageBox::Critical); error.setWindowTitle(tr("Error")); error.setText(tr("The profile '%1' does not exist").arg(profile_name)); + SetQWidgetWindowDecorations(&error); error.exec(); return; } @@ -267,6 +269,7 @@ void MappingWindow::OnDeleteProfilePressed() confirm.setInformativeText(tr("This cannot be undone!")); confirm.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + SetQWidgetWindowDecorations(&confirm); if (confirm.exec() != QMessageBox::Yes) { return; @@ -294,6 +297,7 @@ void MappingWindow::OnLoadProfilePressed() error.setIcon(QMessageBox::Critical); error.setWindowTitle(tr("Error")); error.setText(tr("The profile '%1' does not exist").arg(m_profiles_combo->currentText())); + SetQWidgetWindowDecorations(&error); error.exec(); return; } diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp index 9292cecc9d..4e004cd8b5 100644 --- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuExtensionMotionInput.cpp @@ -14,6 +14,7 @@ #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "InputCommon/InputConfig.h" @@ -42,6 +43,7 @@ void WiimoteEmuExtensionMotionInput::CreateNunchukLayout() ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this); window->setAttribute(Qt::WA_DeleteOnClose, true); window->setWindowModality(Qt::WindowModality::WindowModal); + SetQWidgetWindowDecorations(window); window->show(); }); layout->addLayout(warning_layout, 0, 0, 1, -1); diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp index dfa29bfb15..8d07e9201e 100644 --- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp @@ -15,6 +15,7 @@ #include "Core/HW/WiimoteEmu/WiimoteEmu.h" #include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "InputCommon/InputConfig.h" @@ -40,6 +41,7 @@ void WiimoteEmuMotionControlIMU::CreateMainLayout() ControllerInterfaceWindow* window = new ControllerInterfaceWindow(this); window->setAttribute(Qt::WA_DeleteOnClose, true); window->setWindowModality(Qt::WindowModality::WindowModal); + SetQWidgetWindowDecorations(window); window->show(); }); diff --git a/Source/Core/DolphinQt/Config/PatchesWidget.cpp b/Source/Core/DolphinQt/Config/PatchesWidget.cpp index a8abbf72ba..e1fd12f913 100644 --- a/Source/Core/DolphinQt/Config/PatchesWidget.cpp +++ b/Source/Core/DolphinQt/Config/PatchesWidget.cpp @@ -15,6 +15,7 @@ #include "Core/PatchEngine.h" #include "DolphinQt/Config/NewPatchDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "UICommon/GameFile.h" @@ -74,7 +75,13 @@ void PatchesWidget::OnAdd() PatchEngine::Patch patch; patch.user_defined = true; - if (NewPatchDialog(this, patch).exec()) + bool new_patch_confirmed = false; + { + NewPatchDialog dialog(this, patch); + SetQWidgetWindowDecorations(&dialog); + new_patch_confirmed = dialog.exec(); + } + if (new_patch_confirmed) { m_patches.push_back(patch); SavePatches(); @@ -98,7 +105,13 @@ void PatchesWidget::OnEdit() patch.name = tr("%1 (Copy)").arg(QString::fromStdString(patch.name)).toStdString(); } - if (NewPatchDialog(this, patch).exec()) + bool new_patch_confirmed = false; + { + NewPatchDialog dialog(this, patch); + SetQWidgetWindowDecorations(&dialog); + new_patch_confirmed = dialog.exec(); + } + if (new_patch_confirmed) { if (patch.user_defined) { diff --git a/Source/Core/DolphinQt/Config/VerifyWidget.cpp b/Source/Core/DolphinQt/Config/VerifyWidget.cpp index 87879c6659..6b21d77690 100644 --- a/Source/Core/DolphinQt/Config/VerifyWidget.cpp +++ b/Source/Core/DolphinQt/Config/VerifyWidget.cpp @@ -20,6 +20,7 @@ #include "DiscIO/Volume.h" #include "DiscIO/VolumeVerifier.h" #include "DolphinQt/QtUtils/ParallelProgressDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" VerifyWidget::VerifyWidget(std::shared_ptr volume) : m_volume(std::move(volume)) @@ -180,6 +181,7 @@ void VerifyWidget::Verify() return result; }); + SetQWidgetWindowDecorations(progress.GetRaw()); progress.GetRaw()->exec(); std::optional result = future.get(); diff --git a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp index 28f15a46d7..d702acf5e1 100644 --- a/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp +++ b/Source/Core/DolphinQt/Config/WiimoteControllersWidget.cpp @@ -33,6 +33,7 @@ #include "DolphinQt/Config/Mapping/MappingWindow.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" @@ -261,6 +262,7 @@ void WiimoteControllersWidget::OnWiimoteConfigure(size_t index) MappingWindow* window = new MappingWindow(this, type, static_cast(index)); window->setAttribute(Qt::WA_DeleteOnClose, true); window->setWindowModality(Qt::WindowModality::WindowModal); + SetQWidgetWindowDecorations(window); window->show(); } diff --git a/Source/Core/DolphinQt/ConvertDialog.cpp b/Source/Core/DolphinQt/ConvertDialog.cpp index 85b48edb6c..e6be43015f 100644 --- a/Source/Core/DolphinQt/ConvertDialog.cpp +++ b/Source/Core/DolphinQt/ConvertDialog.cpp @@ -31,6 +31,7 @@ #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/ParallelProgressDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "UICommon/GameFile.h" #include "UICommon/UICommon.h" @@ -285,6 +286,7 @@ bool ConvertDialog::ShowAreYouSureDialog(const QString& text) warning.setInformativeText(text); warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + SetQWidgetWindowDecorations(&warning); return warning.exec() == QMessageBox::Yes; } @@ -409,6 +411,7 @@ void ConvertDialog::Convert() .arg(dst_info.fileName())); confirm_replace.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + SetQWidgetWindowDecorations(&confirm_replace); if (confirm_replace.exec() == QMessageBox::No) continue; } @@ -519,6 +522,7 @@ void ConvertDialog::Convert() break; } + SetQWidgetWindowDecorations(progress_dialog.GetRaw()); progress_dialog.GetRaw()->exec(); if (!success.get()) { diff --git a/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp b/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp index de04411ece..bf29361973 100644 --- a/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp @@ -22,6 +22,7 @@ #include "DolphinQt/Debugger/BreakpointDialog.h" #include "DolphinQt/Debugger/MemoryWidget.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" @@ -313,6 +314,7 @@ void BreakpointWidget::OnClear() void BreakpointWidget::OnNewBreakpoint() { BreakpointDialog* dialog = new BreakpointDialog(this); + SetQWidgetWindowDecorations(dialog); dialog->exec(); } @@ -322,12 +324,14 @@ void BreakpointWidget::OnEditBreakpoint(u32 address, bool is_instruction_bp) { auto* dialog = new BreakpointDialog(this, m_system.GetPowerPC().GetBreakPoints().GetBreakpoint(address)); + SetQWidgetWindowDecorations(dialog); dialog->exec(); } else { auto* dialog = new BreakpointDialog(this, m_system.GetPowerPC().GetMemChecks().GetMemCheck(address)); + SetQWidgetWindowDecorations(dialog); dialog->exec(); } diff --git a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp index 625a5fabb8..65ddd69692 100644 --- a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp @@ -37,6 +37,7 @@ #include "Core/System.h" #include "DolphinQt/Debugger/PatchInstructionDialog.h" #include "DolphinQt/Host.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" @@ -733,6 +734,7 @@ void CodeViewWidget::AutoStep(CodeTrace::AutoStop option) .arg(QString::fromStdString(fmt::format("{:#x}", fmt::join(mem_out, ", ")))); msgbox.setInformativeText(msgtext); + SetQWidgetWindowDecorations(&msgbox); msgbox.exec(); } while (msgbox.clickedButton() == (QAbstractButton*)run_button); @@ -1010,6 +1012,7 @@ void CodeViewWidget::OnReplaceInstruction() auto& debug_interface = m_system.GetPowerPC().GetDebugInterface(); PatchInstructionDialog dialog(this, addr, debug_interface.ReadInstruction(guard, addr)); + SetQWidgetWindowDecorations(&dialog); if (dialog.exec() == QDialog::Accepted) { debug_interface.SetPatch(guard, addr, dialog.GetCode()); diff --git a/Source/Core/DolphinQt/Debugger/CodeWidget.cpp b/Source/Core/DolphinQt/Debugger/CodeWidget.cpp index 4315196996..650e17e905 100644 --- a/Source/Core/DolphinQt/Debugger/CodeWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeWidget.cpp @@ -28,6 +28,7 @@ #include "Core/PowerPC/PowerPC.h" #include "Core/System.h" #include "DolphinQt/Host.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" static const QString BOX_SPLITTER_STYLESHEET = QStringLiteral( @@ -213,6 +214,7 @@ void CodeWidget::OnDiff() if (!m_diff_dialog) m_diff_dialog = new CodeDiffDialog(this); m_diff_dialog->setWindowFlag(Qt::WindowMinimizeButtonHint); + SetQWidgetWindowDecorations(m_diff_dialog); m_diff_dialog->show(); m_diff_dialog->raise(); m_diff_dialog->activateWindow(); diff --git a/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp b/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp index 324d680dbb..fa31e620fc 100644 --- a/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/RegisterWidget.cpp @@ -18,6 +18,7 @@ #include "Core/PowerPC/PowerPC.h" #include "Core/System.h" #include "DolphinQt/Host.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" RegisterWidget::RegisterWidget(QWidget* parent) @@ -307,6 +308,7 @@ void RegisterWidget::AutoStep(const std::string& reg) const break; // Can keep running and try again after a time out. + SetQWidgetWindowDecorations(&msgbox); msgbox.exec(); if (msgbox.clickedButton() != (QAbstractButton*)run_button) break; diff --git a/Source/Core/DolphinQt/DiscordHandler.cpp b/Source/Core/DolphinQt/DiscordHandler.cpp index 49363321db..7e14dce42d 100644 --- a/Source/Core/DolphinQt/DiscordHandler.cpp +++ b/Source/Core/DolphinQt/DiscordHandler.cpp @@ -16,6 +16,7 @@ #include "DolphinQt/DiscordJoinRequestDialog.h" #include "DolphinQt/QtUtils/RunOnObject.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" DiscordHandler::DiscordHandler(QWidget* parent) : QObject{parent}, m_parent{parent} { @@ -60,6 +61,7 @@ void DiscordHandler::ShowNewJoinRequest(const std::string& id, const std::string std::lock_guard lock(m_request_dialogs_mutex); m_request_dialogs.emplace_front(m_parent, id, discord_tag, avatar); DiscordJoinRequestDialog& request_dialog = m_request_dialogs.front(); + SetQWidgetWindowDecorations(&request_dialog); request_dialog.show(); request_dialog.raise(); request_dialog.activateWindow(); diff --git a/Source/Core/DolphinQt/GBAWidget.cpp b/Source/Core/DolphinQt/GBAWidget.cpp index 6805321df5..0a7ba2b84d 100644 --- a/Source/Core/DolphinQt/GBAWidget.cpp +++ b/Source/Core/DolphinQt/GBAWidget.cpp @@ -29,6 +29,7 @@ #include "Core/System.h" #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" #include "DolphinQt/Settings/GameCubePane.h" @@ -486,6 +487,7 @@ void GBAWidget::contextMenuEvent(QContextMenuEvent* event) size_menu->addAction(x4_action); menu->move(event->globalPos()); + SetQWidgetWindowDecorations(menu); menu->show(); } diff --git a/Source/Core/DolphinQt/GCMemcardManager.cpp b/Source/Core/DolphinQt/GCMemcardManager.cpp index 8bbe9061dc..405bee200e 100644 --- a/Source/Core/DolphinQt/GCMemcardManager.cpp +++ b/Source/Core/DolphinQt/GCMemcardManager.cpp @@ -42,6 +42,7 @@ #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" using namespace ExpansionInterface; @@ -695,6 +696,7 @@ void GCMemcardManager::FixChecksums() void GCMemcardManager::CreateNewCard(Slot slot) { GCMemcardCreateNewDialog dialog(this); + SetQWidgetWindowDecorations(&dialog); if (dialog.exec() == QDialog::Accepted) m_slot_file_edit[slot]->setText(QString::fromStdString(dialog.GetMemoryCardPath())); } diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index c918c4555d..9f2731af65 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -67,6 +67,7 @@ #include "DolphinQt/QtUtils/DoubleClickEventFilter.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/ParallelProgressDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" #include "DolphinQt/WiiUpdate.h" @@ -546,6 +547,7 @@ void GameList::OpenProperties() connect(properties, &PropertiesDialog::OpenGraphicsSettings, this, &GameList::OpenGraphicsSettings); + SetQWidgetWindowDecorations(properties); properties->show(); } @@ -600,6 +602,7 @@ void GameList::ConvertFile() return; ConvertDialog dialog{std::move(games), this}; + SetQWidgetWindowDecorations(&dialog); dialog.exec(); } @@ -617,6 +620,7 @@ void GameList::InstallWAD() result_dialog.setWindowTitle(success ? tr("Success") : tr("Failure")); result_dialog.setText(success ? tr("Successfully installed this title to the NAND.") : tr("Failed to install this title to the NAND.")); + SetQWidgetWindowDecorations(&result_dialog); result_dialog.exec(); } @@ -634,6 +638,7 @@ void GameList::UninstallWAD() "this title from the NAND without deleting its save data. Continue?")); warning_dialog.setStandardButtons(QMessageBox::No | QMessageBox::Yes); + SetQWidgetWindowDecorations(&warning_dialog); if (warning_dialog.exec() == QMessageBox::No) return; @@ -645,6 +650,7 @@ void GameList::UninstallWAD() result_dialog.setWindowTitle(success ? tr("Success") : tr("Failure")); result_dialog.setText(success ? tr("Successfully removed this title from the NAND.") : tr("Failed to remove this title from the NAND.")); + SetQWidgetWindowDecorations(&result_dialog); result_dialog.exec(); } @@ -818,6 +824,7 @@ void GameList::DeleteFile() confirm_dialog.setInformativeText(tr("This cannot be undone!")); confirm_dialog.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + SetQWidgetWindowDecorations(&confirm_dialog); if (confirm_dialog.exec() == QMessageBox::Yes) { for (const auto& game : GetSelectedGames()) @@ -843,6 +850,7 @@ void GameList::DeleteFile() "delete the file or whether it's still in use.")); error_dialog.setStandardButtons(QMessageBox::Retry | QMessageBox::Abort); + SetQWidgetWindowDecorations(&error_dialog); if (error_dialog.exec() == QMessageBox::Abort) break; } diff --git a/Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp b/Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp index 685c582f33..cb66245cb4 100644 --- a/Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp +++ b/Source/Core/DolphinQt/InfinityBase/InfinityBaseWindow.cpp @@ -26,6 +26,7 @@ #include "Core/System.h" #include "DolphinQt/QtUtils/DolphinFileDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" // Qt is not guaranteed to keep track of file paths using native file pickers, so we use this @@ -149,6 +150,7 @@ void InfinityBaseWindow::LoadFigure(u8 slot) void InfinityBaseWindow::CreateFigure(u8 slot) { CreateFigureDialog create_dlg(this, slot); + SetQWidgetWindowDecorations(&create_dlg); if (create_dlg.exec() == CreateFigureDialog::Accepted) { LoadFigurePath(slot, create_dlg.GetFilePath()); diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index a530f14f8d..611efe47ed 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -35,6 +35,7 @@ #include "DolphinQt/MainWindow.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/RunOnObject.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" #include "DolphinQt/Translation.h" @@ -92,6 +93,7 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no return QMessageBox::NoIcon; }()); + SetQWidgetWindowDecorations(&message_box); const int button = message_box.exec(); if (button == QMessageBox::Yes) return true; @@ -284,6 +286,7 @@ int main(int argc, char* argv[]) "This authorization can be revoked at any time through Dolphin's " "settings.")); + SetQWidgetWindowDecorations(&analytics_prompt); const int answer = analytics_prompt.exec(); Config::SetBase(Config::MAIN_ANALYTICS_PERMISSION_ASKED, true); diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 42a6a04603..b193fe15c7 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -108,6 +108,7 @@ #include "DolphinQt/QtUtils/ParallelProgressDialog.h" #include "DolphinQt/QtUtils/QueueOnObject.h" #include "DolphinQt/QtUtils/RunOnObject.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/WindowActivationEventFilter.h" #include "DolphinQt/RenderWidget.h" #include "DolphinQt/ResourcePackManager.h" @@ -1225,6 +1226,7 @@ void MainWindow::ShowControllersWindow() InstallHotkeyFilter(m_controllers_window); } + SetQWidgetWindowDecorations(m_controllers_window); m_controllers_window->show(); m_controllers_window->raise(); m_controllers_window->activateWindow(); @@ -1238,6 +1240,7 @@ void MainWindow::ShowFreeLookWindow() InstallHotkeyFilter(m_freelook_window); } + SetQWidgetWindowDecorations(m_freelook_window); m_freelook_window->show(); m_freelook_window->raise(); m_freelook_window->activateWindow(); @@ -1251,6 +1254,7 @@ void MainWindow::ShowSettingsWindow() InstallHotkeyFilter(m_settings_window); } + SetQWidgetWindowDecorations(m_settings_window); m_settings_window->show(); m_settings_window->raise(); m_settings_window->activateWindow(); @@ -1271,6 +1275,7 @@ void MainWindow::ShowGeneralWindow() void MainWindow::ShowAboutDialog() { AboutDialog about{this}; + SetQWidgetWindowDecorations(&about); about.exec(); } @@ -1282,6 +1287,7 @@ void MainWindow::ShowHotkeyDialog() InstallHotkeyFilter(m_hotkey_window); } + SetQWidgetWindowDecorations(m_hotkey_window); m_hotkey_window->show(); m_hotkey_window->raise(); m_hotkey_window->activateWindow(); @@ -1304,6 +1310,7 @@ void MainWindow::ShowGraphicsWindow() InstallHotkeyFilter(m_graphics_window); } + SetQWidgetWindowDecorations(m_graphics_window); m_graphics_window->show(); m_graphics_window->raise(); m_graphics_window->activateWindow(); @@ -1311,6 +1318,7 @@ void MainWindow::ShowGraphicsWindow() void MainWindow::ShowNetPlaySetupDialog() { + SetQWidgetWindowDecorations(m_netplay_setup_dialog); m_netplay_setup_dialog->show(); m_netplay_setup_dialog->raise(); m_netplay_setup_dialog->activateWindow(); @@ -1321,6 +1329,7 @@ void MainWindow::ShowNetPlayBrowser() auto* browser = new NetPlayBrowser(this); browser->setAttribute(Qt::WA_DeleteOnClose, true); connect(browser, &NetPlayBrowser::Join, this, &MainWindow::NetPlayJoin); + SetQWidgetWindowDecorations(browser); browser->exec(); } @@ -1333,6 +1342,7 @@ void MainWindow::ShowFIFOPlayer() [this](const QString& path) { StartGame(path, ScanForSecondDisc::No); }); } + SetQWidgetWindowDecorations(m_fifo_window); m_fifo_window->show(); m_fifo_window->raise(); m_fifo_window->activateWindow(); @@ -1345,6 +1355,7 @@ void MainWindow::ShowSkylanderPortal() m_skylander_window = new SkylanderPortalWindow(); } + SetQWidgetWindowDecorations(m_skylander_window); m_skylander_window->show(); m_skylander_window->raise(); m_skylander_window->activateWindow(); @@ -1357,6 +1368,7 @@ void MainWindow::ShowInfinityBase() m_infinity_window = new InfinityBaseWindow(); } + SetQWidgetWindowDecorations(m_infinity_window); m_infinity_window->show(); m_infinity_window->raise(); m_infinity_window->activateWindow(); @@ -1759,6 +1771,7 @@ void MainWindow::OnImportNANDBackup() dialog.Reset(); }); + SetQWidgetWindowDecorations(dialog.GetRaw()); dialog.GetRaw()->exec(); result.wait(); @@ -1866,6 +1879,7 @@ void MainWindow::ShowTASInput() const auto si_device = Config::Get(Config::GetInfoForSIDevice(i)); if (si_device == SerialInterface::SIDEVICE_GC_GBA_EMULATED) { + SetQWidgetWindowDecorations(m_gba_tas_input_windows[i]); m_gba_tas_input_windows[i]->show(); m_gba_tas_input_windows[i]->raise(); m_gba_tas_input_windows[i]->activateWindow(); @@ -1873,6 +1887,7 @@ void MainWindow::ShowTASInput() else if (si_device != SerialInterface::SIDEVICE_NONE && si_device != SerialInterface::SIDEVICE_GC_GBA) { + SetQWidgetWindowDecorations(m_gc_tas_input_windows[i]); m_gc_tas_input_windows[i]->show(); m_gc_tas_input_windows[i]->raise(); m_gc_tas_input_windows[i]->activateWindow(); @@ -1884,6 +1899,7 @@ void MainWindow::ShowTASInput() if (Config::Get(Config::GetInfoForWiimoteSource(i)) == WiimoteSource::Emulated && (!Core::IsRunning() || SConfig::GetInstance().bWii)) { + SetQWidgetWindowDecorations(m_wii_tas_input_windows[i]); m_wii_tas_input_windows[i]->show(); m_wii_tas_input_windows[i]->raise(); m_wii_tas_input_windows[i]->activateWindow(); @@ -1910,6 +1926,7 @@ void MainWindow::ShowAchievementsWindow() m_achievements_window = new AchievementsWindow(this); } + SetQWidgetWindowDecorations(m_achievements_window); m_achievements_window->show(); m_achievements_window->raise(); m_achievements_window->activateWindow(); @@ -1920,6 +1937,7 @@ void MainWindow::ShowMemcardManager() { GCMemcardManager manager(this); + SetQWidgetWindowDecorations(&manager); manager.exec(); } @@ -1927,11 +1945,13 @@ void MainWindow::ShowResourcePackManager() { ResourcePackManager manager(this); + SetQWidgetWindowDecorations(&manager); manager.exec(); } void MainWindow::ShowCheatsManager() { + SetQWidgetWindowDecorations(m_cheats_manager); m_cheats_manager->show(); } @@ -1950,6 +1970,7 @@ void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game) auto& disc = std::get(boot_params->parameters); RiivolutionBootWidget w(disc.volume->GetGameID(), disc.volume->GetRevision(), disc.volume->GetDiscNumber(), game.GetFilePath(), this); + SetQWidgetWindowDecorations(&w); w.exec(); if (!w.ShouldBoot()) return; @@ -1961,7 +1982,10 @@ void MainWindow::ShowRiivolutionBootWidget(const UICommon::GameFile& game) void MainWindow::Show() { if (!Settings::Instance().IsBatchModeEnabled()) + { + SetQWidgetWindowDecorations(this); QWidget::show(); + } // If the booting of a game was requested on start up, do that now if (m_pending_boot != nullptr) diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index 37562a738c..664e40dd05 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -59,6 +59,7 @@ #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/ParallelProgressDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" #include "DolphinQt/Updater.h" @@ -1178,8 +1179,12 @@ void MenuBar::CheckNAND() return; } - if (NANDRepairDialog(result, this).exec() != QDialog::Accepted) - return; + { + NANDRepairDialog dialog(result, this); + SetQWidgetWindowDecorations(&dialog); + if (dialog.exec() != QDialog::Accepted) + return; + } if (WiiUtils::RepairNAND(ios)) { @@ -1336,6 +1341,7 @@ void MenuBar::GenerateSymbolsFromRSOAuto() return matches; }); + SetQWidgetWindowDecorations(progress.GetRaw()); progress.GetRaw()->exec(); const auto matches = future.get(); diff --git a/Source/Core/DolphinQt/NKitWarningDialog.cpp b/Source/Core/DolphinQt/NKitWarningDialog.cpp index d49db9da92..6c1bd5b117 100644 --- a/Source/Core/DolphinQt/NKitWarningDialog.cpp +++ b/Source/Core/DolphinQt/NKitWarningDialog.cpp @@ -14,14 +14,17 @@ #include "Common/Config/Config.h" #include "Core/Config/MainSettings.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" bool NKitWarningDialog::ShowUnlessDisabled(QWidget* parent) { if (Config::Get(Config::MAIN_SKIP_NKIT_WARNING)) return true; - else - return NKitWarningDialog(parent).exec() == QDialog::Accepted; + + NKitWarningDialog dialog(parent); + SetQWidgetWindowDecorations(&dialog); + return dialog.exec() == QDialog::Accepted; } NKitWarningDialog::NKitWarningDialog(QWidget* parent) : QDialog(parent) diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp b/Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp index 9acd14977d..53bdedaece 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlayBrowser.cpp @@ -26,6 +26,7 @@ #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" NetPlayBrowser::NetPlayBrowser(QWidget* parent) : QDialog(parent) @@ -303,6 +304,7 @@ void NetPlayBrowser::accept() dialog->setWindowModality(Qt::WindowModal); dialog->setTextEchoMode(QLineEdit::Password); + SetQWidgetWindowDecorations(dialog); if (dialog->exec() != QDialog::Accepted) return; diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp index c5edb9c0d9..509b5db28c 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp @@ -51,6 +51,7 @@ #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/QueueOnObject.h" #include "DolphinQt/QtUtils/RunOnObject.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" #include "DolphinQt/Settings/GameCubePane.h" @@ -213,6 +214,7 @@ void NetPlayDialog::CreateMainLayout() m_game_digest_menu->addAction(tr("Other game..."), this, [this] { GameListDialog gld(m_game_list_model, this); + SetQWidgetWindowDecorations(&gld); if (gld.exec() != QDialog::Accepted) return; Settings::Instance().GetNetPlayServer()->ComputeGameDigest( @@ -335,6 +337,7 @@ void NetPlayDialog::ConnectWidgets() Settings::Instance().GetNetPlayServer()->KickPlayer(id); }); connect(m_assign_ports_button, &QPushButton::clicked, [this] { + SetQWidgetWindowDecorations(m_pad_mapping); m_pad_mapping->exec(); Settings::Instance().GetNetPlayServer()->SetPadMapping(m_pad_mapping->GetGCPadArray()); @@ -380,6 +383,7 @@ void NetPlayDialog::ConnectWidgets() connect(m_game_button, &QPushButton::clicked, [this] { GameListDialog gld(m_game_list_model, this); + SetQWidgetWindowDecorations(&gld); if (gld.exec() == QDialog::Accepted) { Settings& settings = Settings::Instance(); diff --git a/Source/Core/DolphinQt/QtUtils/ModalMessageBox.cpp b/Source/Core/DolphinQt/QtUtils/ModalMessageBox.cpp index a12088326c..e80db0ad7e 100644 --- a/Source/Core/DolphinQt/QtUtils/ModalMessageBox.cpp +++ b/Source/Core/DolphinQt/QtUtils/ModalMessageBox.cpp @@ -5,6 +5,8 @@ #include +#include "DolphinQt/QtUtils/SetWindowDecorations.h" + ModalMessageBox::ModalMessageBox(QWidget* parent, Qt::WindowModality modality) : QMessageBox(parent != nullptr ? parent->window() : nullptr) { @@ -28,6 +30,7 @@ static inline int ExecMessageBox(ModalMessageBox::Icon icon, QWidget* parent, co msg.setStandardButtons(buttons); msg.setDefaultButton(default_button); + SetQWidgetWindowDecorations(&msg); return msg.exec(); } diff --git a/Source/Core/DolphinQt/ResourcePackManager.cpp b/Source/Core/DolphinQt/ResourcePackManager.cpp index ad464a76ea..eac48cd6c5 100644 --- a/Source/Core/DolphinQt/ResourcePackManager.cpp +++ b/Source/Core/DolphinQt/ResourcePackManager.cpp @@ -14,6 +14,7 @@ #include "Common/FileUtil.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "UICommon/ResourcePack/Manager.h" ResourcePackManager::ResourcePackManager(QWidget* widget) : QDialog(widget) @@ -241,6 +242,7 @@ void ResourcePackManager::Remove() box.setIcon(QMessageBox::Warning); box.setStandardButtons(QMessageBox::Yes | QMessageBox::Abort); + SetQWidgetWindowDecorations(&box); if (box.exec() != QMessageBox::Yes) return; diff --git a/Source/Core/DolphinQt/Settings/GameCubePane.cpp b/Source/Core/DolphinQt/Settings/GameCubePane.cpp index a19fce31fb..78be23d5f2 100644 --- a/Source/Core/DolphinQt/Settings/GameCubePane.cpp +++ b/Source/Core/DolphinQt/Settings/GameCubePane.cpp @@ -39,6 +39,7 @@ #include "DolphinQt/QtUtils/DolphinFileDialog.h" #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" #include "DolphinQt/Settings/BroadbandAdapterSettingsDialog.h" @@ -379,22 +380,32 @@ void GameCubePane::OnConfigPressed(ExpansionInterface::Slot slot) BrowseAGPRom(slot); return; case ExpansionInterface::EXIDeviceType::Microphone: + { // TODO: convert MappingWindow to use Slot? - MappingWindow(this, MappingWindow::Type::MAPPING_GC_MICROPHONE, static_cast(slot)).exec(); + MappingWindow dialog(this, MappingWindow::Type::MAPPING_GC_MICROPHONE, static_cast(slot)); + SetQWidgetWindowDecorations(&dialog); + dialog.exec(); return; + } case ExpansionInterface::EXIDeviceType::Ethernet: { - BroadbandAdapterSettingsDialog(this, BroadbandAdapterSettingsDialog::Type::Ethernet).exec(); + BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::Ethernet); + SetQWidgetWindowDecorations(&dialog); + dialog.exec(); return; } case ExpansionInterface::EXIDeviceType::EthernetXLink: { - BroadbandAdapterSettingsDialog(this, BroadbandAdapterSettingsDialog::Type::XLinkKai).exec(); + BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::XLinkKai); + SetQWidgetWindowDecorations(&dialog); + dialog.exec(); return; } case ExpansionInterface::EXIDeviceType::EthernetBuiltIn: { - BroadbandAdapterSettingsDialog(this, BroadbandAdapterSettingsDialog::Type::BuiltIn).exec(); + BroadbandAdapterSettingsDialog dialog(this, BroadbandAdapterSettingsDialog::Type::BuiltIn); + SetQWidgetWindowDecorations(&dialog); + dialog.exec(); return; } default: diff --git a/Source/Core/DolphinQt/Settings/GeneralPane.cpp b/Source/Core/DolphinQt/Settings/GeneralPane.cpp index f958a383ec..f5f56193e0 100644 --- a/Source/Core/DolphinQt/Settings/GeneralPane.cpp +++ b/Source/Core/DolphinQt/Settings/GeneralPane.cpp @@ -24,6 +24,7 @@ #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" @@ -370,6 +371,7 @@ void GeneralPane::GenerateNewIdentity() message_box.setIcon(QMessageBox::Information); message_box.setWindowTitle(tr("Identity Generation")); message_box.setText(tr("New identity generated.")); + SetQWidgetWindowDecorations(&message_box); message_box.exec(); } #endif diff --git a/Source/Core/DolphinQt/Settings/WiiPane.cpp b/Source/Core/DolphinQt/Settings/WiiPane.cpp index 9cb9677e20..19170b5517 100644 --- a/Source/Core/DolphinQt/Settings/WiiPane.cpp +++ b/Source/Core/DolphinQt/Settings/WiiPane.cpp @@ -35,6 +35,7 @@ #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/NonDefaultQPushButton.h" #include "DolphinQt/QtUtils/ParallelProgressDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/QtUtils/SignalBlocking.h" #include "DolphinQt/Settings.h" #include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h" @@ -288,6 +289,7 @@ void WiiPane::CreateSDCard() progress_dialog.Reset(); return good; }); + SetQWidgetWindowDecorations(progress_dialog.GetRaw()); progress_dialog.GetRaw()->exec(); if (!success.get()) ModalMessageBox::warning(this, tr("Convert Folder to File Now"), tr("Conversion failed.")); @@ -312,6 +314,7 @@ void WiiPane::CreateSDCard() progress_dialog.Reset(); return good; }); + SetQWidgetWindowDecorations(progress_dialog.GetRaw()); progress_dialog.GetRaw()->exec(); if (!success.get()) ModalMessageBox::warning(this, tr("Convert File to Folder Now"), tr("Conversion failed.")); @@ -468,6 +471,7 @@ void WiiPane::OnUSBWhitelistAddButton() USBDeviceAddToWhitelistDialog usb_whitelist_dialog(this); connect(&usb_whitelist_dialog, &USBDeviceAddToWhitelistDialog::accepted, this, &WiiPane::PopulateUSBPassthroughListWidget); + SetQWidgetWindowDecorations(&usb_whitelist_dialog); usb_whitelist_dialog.exec(); } diff --git a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp index 88dcbf84a8..af3d463b8c 100644 --- a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp +++ b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp @@ -34,6 +34,7 @@ #include "Core/System.h" #include "DolphinQt/QtUtils/DolphinFileDialog.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Resources.h" #include "DolphinQt/Settings.h" @@ -560,6 +561,7 @@ void SkylanderPortalWindow::CreateSkylanderAdvanced() connect(buttons, &QDialogButtonBox::rejected, create_window, &QDialog::reject); + SetQWidgetWindowDecorations(create_window); create_window->show(); create_window->raise(); } diff --git a/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp b/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp index dc08148b79..4762024a61 100644 --- a/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp +++ b/Source/Core/DolphinQt/TAS/WiiTASInputWindow.cpp @@ -28,6 +28,7 @@ #include "DolphinQt/QtUtils/AspectRatioWidget.h" #include "DolphinQt/QtUtils/QueueOnObject.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/TAS/IRWidget.h" #include "DolphinQt/TAS/TASCheckBox.h" #include "DolphinQt/TAS/TASSpinBox.h" @@ -395,15 +396,21 @@ void WiiTASInputWindow::UpdateExt() if (m_active_extension == WiimoteEmu::ExtensionNumber::NUNCHUK) { setWindowTitle(tr("Wii TAS Input %1 - Wii Remote + Nunchuk").arg(m_num + 1)); + SetQWidgetWindowDecorations(m_ir_box); m_ir_box->show(); + SetQWidgetWindowDecorations(m_nunchuk_stick_box); m_nunchuk_stick_box->show(); m_classic_right_stick_box->hide(); m_classic_left_stick_box->hide(); + SetQWidgetWindowDecorations(m_remote_accelerometer_box); m_remote_accelerometer_box->show(); m_remote_gyroscope_box->setVisible(m_is_motion_plus_attached); + SetQWidgetWindowDecorations(m_nunchuk_accelerometer_box); m_nunchuk_accelerometer_box->show(); m_triggers_box->hide(); + SetQWidgetWindowDecorations(m_nunchuk_buttons_box); m_nunchuk_buttons_box->show(); + SetQWidgetWindowDecorations(m_remote_buttons_box); m_remote_buttons_box->show(); m_classic_buttons_box->hide(); } @@ -412,14 +419,18 @@ void WiiTASInputWindow::UpdateExt() setWindowTitle(tr("Wii TAS Input %1 - Classic Controller").arg(m_num + 1)); m_ir_box->hide(); m_nunchuk_stick_box->hide(); + SetQWidgetWindowDecorations(m_classic_right_stick_box); m_classic_right_stick_box->show(); + SetQWidgetWindowDecorations(m_classic_left_stick_box); m_classic_left_stick_box->show(); m_remote_accelerometer_box->hide(); m_remote_gyroscope_box->hide(); m_nunchuk_accelerometer_box->hide(); + SetQWidgetWindowDecorations(m_triggers_box); m_triggers_box->show(); m_remote_buttons_box->hide(); m_nunchuk_buttons_box->hide(); + SetQWidgetWindowDecorations(m_classic_buttons_box); m_classic_buttons_box->show(); } else @@ -429,10 +440,12 @@ void WiiTASInputWindow::UpdateExt() m_nunchuk_stick_box->hide(); m_classic_right_stick_box->hide(); m_classic_left_stick_box->hide(); + SetQWidgetWindowDecorations(m_remote_accelerometer_box); m_remote_accelerometer_box->show(); m_remote_gyroscope_box->setVisible(m_is_motion_plus_attached); m_nunchuk_accelerometer_box->hide(); m_triggers_box->hide(); + SetQWidgetWindowDecorations(m_remote_buttons_box); m_remote_buttons_box->show(); m_nunchuk_buttons_box->hide(); m_classic_buttons_box->hide(); diff --git a/Source/Core/DolphinQt/Updater.cpp b/Source/Core/DolphinQt/Updater.cpp index 47eb57ef39..881c638914 100644 --- a/Source/Core/DolphinQt/Updater.cpp +++ b/Source/Core/DolphinQt/Updater.cpp @@ -17,6 +17,7 @@ #include "Common/Version.h" #include "DolphinQt/QtUtils/RunOnObject.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" #include "DolphinQt/Settings.h" // Refer to docs/autoupdate_overview.md for a detailed overview of the autoupdate process @@ -100,6 +101,7 @@ void Updater::OnUpdateAvailable(const NewVersionInformation& info) connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept); connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject); + SetQWidgetWindowDecorations(dialog); return dialog->exec(); }); diff --git a/Source/Core/DolphinQt/WiiUpdate.cpp b/Source/Core/DolphinQt/WiiUpdate.cpp index fc5d9ea8e9..633f02c2ce 100644 --- a/Source/Core/DolphinQt/WiiUpdate.cpp +++ b/Source/Core/DolphinQt/WiiUpdate.cpp @@ -21,6 +21,7 @@ #include "DolphinQt/QtUtils/ModalMessageBox.h" #include "DolphinQt/QtUtils/QueueOnObject.h" +#include "DolphinQt/QtUtils/SetWindowDecorations.h" namespace WiiUpdate { @@ -130,6 +131,7 @@ static WiiUtils::UpdateResult ShowProgress(QWidget* parent, Callable function, A return res; }); + SetQWidgetWindowDecorations(&dialog); dialog.exec(); return result.get(); } From 250d5f55deb0febb9ea94090332bbbbd91d1af5c Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Mon, 31 Jul 2023 23:22:53 +0200 Subject: [PATCH 82/99] DolphinQt: Switch dark/light theme when Windows theme changes. --- Source/Core/DolphinQt/Main.cpp | 17 +---------------- Source/Core/DolphinQt/MainWindow.cpp | 24 ++++++++++++++++++++++++ Source/Core/DolphinQt/MainWindow.h | 5 +++++ Source/Core/DolphinQt/Settings.cpp | 18 ++++++++++++++++++ Source/Core/DolphinQt/Settings.h | 1 + 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 611efe47ed..aa1697c6a7 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -7,8 +7,6 @@ #include #include - -#include #endif #ifdef __linux__ @@ -248,20 +246,7 @@ int main(int argc, char* argv[]) DolphinAnalytics::Instance().ReportDolphinStart("qt"); MainWindow win{std::move(boot), static_cast(options.get("movie"))}; - -#ifdef _WIN32 - // Check if the system is set to dark mode so we can set the default theme and window - // decorations accordingly. - { - using namespace winrt::Windows::UI::ViewManagement; - const UISettings settings; - const auto& color = settings.GetColorValue(UIColorType::Foreground); - - const bool is_system_dark = 5 * color.G + 2 * color.R + color.B > 8 * 128; - Settings::Instance().SetSystemDark(is_system_dark); - } -#endif - + Settings::Instance().UpdateSystemDark(); Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle()); win.Show(); diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index b193fe15c7..1f5223179c 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -1715,6 +1715,30 @@ QSize MainWindow::sizeHint() const return QSize(800, 600); } +#ifdef _WIN32 +bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr* result) +{ + auto* msg = reinterpret_cast(message); + if (msg && msg->message == WM_SETTINGCHANGE && msg->lParam != NULL && + std::wstring_view(L"ImmersiveColorSet") + .compare(reinterpret_cast(msg->lParam)) == 0) + { + // Windows light/dark theme has changed. Update our flag and refresh the theme. + auto& settings = Settings::Instance(); + const bool was_dark_before = settings.IsSystemDark(); + settings.UpdateSystemDark(); + if (settings.IsSystemDark() != was_dark_before) + settings.SetCurrentUserStyle(settings.GetCurrentUserStyle()); + + // TODO: When switching from light to dark, the window decorations remain light. Qt seems very + // convinced that it needs to change these in response to this message, so even if we set them + // to dark here, Qt sets them back to light afterwards. + } + + return false; +} +#endif + void MainWindow::OnBootGameCubeIPL(DiscIO::Region region) { StartGame(std::make_unique(BootParameters::IPL{region})); diff --git a/Source/Core/DolphinQt/MainWindow.h b/Source/Core/DolphinQt/MainWindow.h index 4654202ed7..5b5de92fd8 100644 --- a/Source/Core/DolphinQt/MainWindow.h +++ b/Source/Core/DolphinQt/MainWindow.h @@ -210,6 +210,11 @@ private: void dropEvent(QDropEvent* event) override; QSize sizeHint() const override; +#ifdef _WIN32 + // This gets called for each event from the Windows message queue. + bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override; +#endif + #ifdef HAVE_XRANDR std::unique_ptr m_xrr_config; #endif diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index 2a7b7b41fb..e35be9a8ba 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -19,6 +19,8 @@ #include +#include + #include #include #endif @@ -127,6 +129,22 @@ QString Settings::GetCurrentUserStyle() const return QFileInfo(GetQSettings().value(QStringLiteral("userstyle/path")).toString()).fileName(); } +void Settings::UpdateSystemDark() +{ +#ifdef _WIN32 + // Check if the system is set to dark mode so we can set the default theme and window + // decorations accordingly. + { + using namespace winrt::Windows::UI::ViewManagement; + const UISettings settings; + const auto& color = settings.GetColorValue(UIColorType::Foreground); + + const bool is_system_dark = 5 * color.G + 2 * color.R + color.B > 8 * 128; + Settings::Instance().SetSystemDark(is_system_dark); + } +#endif +} + void Settings::SetSystemDark(bool dark) { s_system_dark = dark; diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index ae58aca8a5..1e1e4b1d7e 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -52,6 +52,7 @@ public: // UI void SetThemeName(const QString& theme_name); + void UpdateSystemDark(); void SetSystemDark(bool dark); bool IsSystemDark(); void SetCurrentUserStyle(const QString& stylesheet_name); From d725aaa5bcb6760522997a3ba43676c88b341d63 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 1 Aug 2023 19:52:36 +0200 Subject: [PATCH 83/99] DolphinQt: Set the application palette to a matching one when the Windows dark theme is in use. --- Source/Core/DolphinQt/Main.cpp | 1 + Source/Core/DolphinQt/Settings.cpp | 34 ++++++++++++++++++++++++++++-- Source/Core/DolphinQt/Settings.h | 1 + 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index aa1697c6a7..3cf943b17b 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -246,6 +246,7 @@ int main(int argc, char* argv[]) DolphinAnalytics::Instance().ReportDolphinStart("qt"); MainWindow win{std::move(boot), static_cast(options.get("movie"))}; + Settings::Instance().InitDefaultPalette(); Settings::Instance().UpdateSystemDark(); Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle()); win.Show(); diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index e35be9a8ba..3c4461db1c 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -4,19 +4,21 @@ #include "DolphinQt/Settings.h" #include +#include #include +#include #include #include #include #include +#include #include #include +#include #include #ifdef _WIN32 -#include - #include #include @@ -50,6 +52,7 @@ #include "VideoCommon/NetPlayGolfUI.h" static bool s_system_dark = false; +static std::unique_ptr s_default_palette; Settings::Settings() { @@ -129,6 +132,11 @@ QString Settings::GetCurrentUserStyle() const return QFileInfo(GetQSettings().value(QStringLiteral("userstyle/path")).toString()).fileName(); } +void Settings::InitDefaultPalette() +{ + s_default_palette = std::make_unique(qApp->palette()); +} + void Settings::UpdateSystemDark() { #ifdef _WIN32 @@ -183,6 +191,28 @@ void Settings::SetCurrentUserStyle(const QString& stylesheet_name) QFile file(QStringLiteral(":/dolphin_dark_win/dark.qss")); if (file.open(QFile::ReadOnly)) stylesheet_contents = QString::fromUtf8(file.readAll().data()); + + QPalette palette = qApp->style()->standardPalette(); + palette.setColor(QPalette::Window, QColor(32, 32, 32)); + palette.setColor(QPalette::WindowText, QColor(220, 220, 220)); + palette.setColor(QPalette::Base, QColor(32, 32, 32)); + palette.setColor(QPalette::AlternateBase, QColor(48, 48, 48)); + palette.setColor(QPalette::PlaceholderText, QColor(126, 126, 126)); + palette.setColor(QPalette::Text, QColor(220, 220, 220)); + palette.setColor(QPalette::Button, QColor(48, 48, 48)); + palette.setColor(QPalette::ButtonText, QColor(220, 220, 220)); + palette.setColor(QPalette::BrightText, QColor(255, 255, 255)); + palette.setColor(QPalette::Highlight, QColor(0, 120, 215)); + palette.setColor(QPalette::HighlightedText, QColor(255, 255, 255)); + palette.setColor(QPalette::Link, QColor(100, 160, 220)); + palette.setColor(QPalette::LinkVisited, QColor(100, 160, 220)); + qApp->setPalette(palette); + } + else + { + // reset any palette changes that may exist from a previously set dark mode + if (s_default_palette) + qApp->setPalette(*s_default_palette); } } #endif diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index 1e1e4b1d7e..b95b768250 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -52,6 +52,7 @@ public: // UI void SetThemeName(const QString& theme_name); + void InitDefaultPalette(); void UpdateSystemDark(); void SetSystemDark(bool dark); bool IsSystemDark(); From c2e29153e9e1e831f4b29bbc7e19ebf39d18bc79 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 1 Aug 2023 20:14:03 +0200 Subject: [PATCH 84/99] DolphinQt: Set the theme before constructing the MainWindow, some panels that explicitly request palette colors get the wrong colors otherwise. --- Source/Core/DolphinQt/Main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index 3cf943b17b..39aa5c6f1f 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -245,10 +245,11 @@ int main(int argc, char* argv[]) { DolphinAnalytics::Instance().ReportDolphinStart("qt"); - MainWindow win{std::move(boot), static_cast(options.get("movie"))}; Settings::Instance().InitDefaultPalette(); Settings::Instance().UpdateSystemDark(); Settings::Instance().SetCurrentUserStyle(Settings::Instance().GetCurrentUserStyle()); + + MainWindow win{std::move(boot), static_cast(options.get("movie"))}; win.Show(); #if defined(USE_ANALYTICS) && USE_ANALYTICS From 24012cfc7f396177732e9a8b7d849045a65a5512 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Tue, 1 Aug 2023 20:47:17 +0200 Subject: [PATCH 85/99] DolphinQt: Adjust panel-specific colors and syntax highlighting for dark theme. --- .../Config/GameConfigHighlighter.cpp | 27 ++++++++++-- .../DolphinQt/Config/Mapping/IOWindow.cpp | 33 +++++++++++---- .../DolphinQt/Debugger/CodeViewWidget.cpp | 6 +-- Source/Core/DolphinQt/MainWindow.cpp | 6 +++ Source/Core/DolphinQt/Settings.cpp | 5 +++ Source/Core/DolphinQt/Settings.h | 1 + .../SkylanderPortal/SkylanderPortalWindow.cpp | 42 +++++++++++++------ .../SkylanderPortal/SkylanderPortalWindow.h | 5 ++- 8 files changed, 97 insertions(+), 28 deletions(-) diff --git a/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp b/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp index 0d892b18a5..4473fde5a9 100644 --- a/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp +++ b/Source/Core/DolphinQt/Config/GameConfigHighlighter.cpp @@ -3,6 +3,11 @@ #include "DolphinQt/Config/GameConfigHighlighter.h" +#include +#include + +#include "DolphinQt/Settings.h" + struct HighlightingRule { QRegularExpression pattern; @@ -13,22 +18,36 @@ GameConfigHighlighter::~GameConfigHighlighter() = default; GameConfigHighlighter::GameConfigHighlighter(QTextDocument* parent) : QSyntaxHighlighter(parent) { + const bool is_dark_theme = Settings::Instance().IsThemeDark(); + QTextCharFormat equal_format; - equal_format.setForeground(Qt::red); + if (is_dark_theme) + equal_format.setForeground(QBrush{QColor(255, 96, 96)}); + else + equal_format.setForeground(Qt::red); QTextCharFormat section_format; section_format.setFontWeight(QFont::Bold); QTextCharFormat comment_format; - comment_format.setForeground(Qt::darkGreen); + if (is_dark_theme) + comment_format.setForeground(QBrush{QColor(0, 220, 0)}); + else + comment_format.setForeground(Qt::darkGreen); comment_format.setFontItalic(true); QTextCharFormat const_format; const_format.setFontWeight(QFont::Bold); - const_format.setForeground(Qt::blue); + if (is_dark_theme) + const_format.setForeground(QBrush{QColor(132, 132, 255)}); + else + const_format.setForeground(Qt::blue); QTextCharFormat num_format; - num_format.setForeground(Qt::darkBlue); + if (is_dark_theme) + num_format.setForeground(QBrush{QColor(66, 138, 255)}); + else + num_format.setForeground(Qt::darkBlue); m_rules.emplace_back(HighlightingRule{QRegularExpression(QStringLiteral("=")), equal_format}); m_rules.emplace_back( diff --git a/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp index 8bec82f015..d70ae2d68f 100644 --- a/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -38,7 +40,6 @@ namespace { -// TODO: Make sure these functions return colors that will be visible in the current theme. QTextCharFormat GetSpecialCharFormat() { QTextCharFormat format; @@ -49,7 +50,10 @@ QTextCharFormat GetSpecialCharFormat() QTextCharFormat GetLiteralCharFormat() { QTextCharFormat format; - format.setForeground(QBrush{Qt::darkMagenta}); + if (Settings::Instance().IsThemeDark()) + format.setForeground(QBrush{QColor(171, 132, 219)}); + else + format.setForeground(QBrush{Qt::darkMagenta}); return format; } @@ -57,35 +61,50 @@ QTextCharFormat GetInvalidCharFormat() { QTextCharFormat format; format.setUnderlineStyle(QTextCharFormat::WaveUnderline); - format.setUnderlineColor(Qt::darkRed); + if (Settings::Instance().IsThemeDark()) + format.setUnderlineColor(QColor(255, 69, 0)); + else + format.setUnderlineColor(Qt::darkRed); return format; } QTextCharFormat GetControlCharFormat() { QTextCharFormat format; - format.setForeground(QBrush{Qt::darkGreen}); + if (Settings::Instance().IsThemeDark()) + format.setForeground(QBrush{QColor(0, 220, 0)}); + else + format.setForeground(QBrush{Qt::darkGreen}); return format; } QTextCharFormat GetVariableCharFormat() { QTextCharFormat format; - format.setForeground(QBrush{Qt::darkYellow}); + if (Settings::Instance().IsThemeDark()) + format.setForeground(QBrush{QColor(226, 226, 0)}); + else + format.setForeground(QBrush{Qt::darkYellow}); return format; } QTextCharFormat GetBarewordCharFormat() { QTextCharFormat format; - format.setForeground(QBrush{Qt::darkBlue}); + if (Settings::Instance().IsThemeDark()) + format.setForeground(QBrush{QColor(66, 138, 255)}); + else + format.setForeground(QBrush{Qt::darkBlue}); return format; } QTextCharFormat GetCommentCharFormat() { QTextCharFormat format; - format.setForeground(QBrush{Qt::darkGray}); + if (Settings::Instance().IsThemeDark()) + format.setForeground(QBrush{QColor(176, 176, 176)}); + else + format.setForeground(QBrush{Qt::darkGray}); return format; } } // namespace diff --git a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp index 65ddd69692..5507875997 100644 --- a/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/CodeViewWidget.cpp @@ -307,7 +307,7 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard) const std::optional pc = guard ? std::make_optional(power_pc.GetPPCState().pc) : std::nullopt; - const bool dark_theme = qApp->palette().color(QPalette::Base).valueF() < 0.5; + const bool dark_theme = Settings::Instance().IsThemeDark(); m_branches.clear(); @@ -350,7 +350,7 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard) } else if (color != 0xFFFFFF) { - item->setBackground(dark_theme ? QColor(color).darker(240) : QColor(color)); + item->setBackground(dark_theme ? QColor(color).darker(400) : QColor(color)); } } @@ -372,7 +372,7 @@ void CodeViewWidget::Update(const Core::CPUThreadGuard* guard) description_item->setText( tr("--> %1").arg(QString::fromStdString(debug_interface.GetDescription(branch_addr)))); - param_item->setForeground(Qt::magenta); + param_item->setForeground(dark_theme ? QColor(255, 135, 255) : Qt::magenta); } if (ins == "blr") diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 1f5223179c..67d4ac46bb 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -1728,8 +1728,14 @@ bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr const bool was_dark_before = settings.IsSystemDark(); settings.UpdateSystemDark(); if (settings.IsSystemDark() != was_dark_before) + { settings.SetCurrentUserStyle(settings.GetCurrentUserStyle()); + // force the colors in the Skylander window to update + if (m_skylander_window) + m_skylander_window->RefreshList(); + } + // TODO: When switching from light to dark, the window decorations remain light. Qt seems very // convinced that it needs to change these in response to this message, so even if we set them // to dark here, Qt sets them back to light afterwards. diff --git a/Source/Core/DolphinQt/Settings.cpp b/Source/Core/DolphinQt/Settings.cpp index 3c4461db1c..ebcf90ee8e 100644 --- a/Source/Core/DolphinQt/Settings.cpp +++ b/Source/Core/DolphinQt/Settings.cpp @@ -163,6 +163,11 @@ bool Settings::IsSystemDark() return s_system_dark; } +bool Settings::IsThemeDark() +{ + return qApp->palette().color(QPalette::Base).valueF() < 0.5; +} + // Calling this before the main window has been created breaks the style of some widgets. void Settings::SetCurrentUserStyle(const QString& stylesheet_name) { diff --git a/Source/Core/DolphinQt/Settings.h b/Source/Core/DolphinQt/Settings.h index b95b768250..5583ed0628 100644 --- a/Source/Core/DolphinQt/Settings.h +++ b/Source/Core/DolphinQt/Settings.h @@ -56,6 +56,7 @@ public: void UpdateSystemDark(); void SetSystemDark(bool dark); bool IsSystemDark(); + bool IsThemeDark(); void SetCurrentUserStyle(const QString& stylesheet_name); QString GetCurrentUserStyle() const; diff --git a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp index af3d463b8c..2ef2d43edb 100644 --- a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp +++ b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp @@ -612,6 +612,8 @@ void SkylanderPortalWindow::UpdateCurrentIDs() void SkylanderPortalWindow::RefreshList() { + const bool is_dark_theme = Settings::Instance().IsThemeDark(); + const int row = m_skylander_list->currentRow(); m_skylander_list->clear(); if (m_only_show_collection->isChecked()) @@ -635,8 +637,16 @@ void SkylanderPortalWindow::RefreshList() { const uint qvar = (ids.first << 16) | ids.second; QListWidgetItem* skylander = new QListWidgetItem(file.baseName()); - skylander->setBackground(GetBaseColor(ids)); - skylander->setForeground(QBrush(QColor(0, 0, 0, 255))); + if (is_dark_theme) + { + skylander->setBackground(GetBaseColor(ids, true)); + skylander->setForeground(QBrush(QColor(220, 220, 220))); + } + else + { + skylander->setBackground(GetBaseColor(ids, false)); + skylander->setForeground(QBrush(QColor(0, 0, 0))); + } skylander->setData(1, qvar); m_skylander_list->addItem(skylander); } @@ -652,8 +662,16 @@ void SkylanderPortalWindow::RefreshList() { const uint qvar = (entry.first.first << 16) | entry.first.second; QListWidgetItem* skylander = new QListWidgetItem(tr(entry.second.name)); - skylander->setBackground(GetBaseColor(entry.first)); - skylander->setForeground(QBrush(QColor(0, 0, 0, 255))); + if (is_dark_theme) + { + skylander->setBackground(GetBaseColor(entry.first, true)); + skylander->setForeground(QBrush(QColor(220, 220, 220))); + } + else + { + skylander->setBackground(GetBaseColor(entry.first, false)); + skylander->setForeground(QBrush(QColor(0, 0, 0))); + } skylander->setData(1, qvar); m_skylander_list->addItem(skylander); } @@ -897,27 +915,27 @@ int SkylanderPortalWindow::GetElementRadio() return -1; } -QBrush SkylanderPortalWindow::GetBaseColor(std::pair ids) +QBrush SkylanderPortalWindow::GetBaseColor(std::pair ids, bool dark_theme) { auto skylander = IOS::HLE::USB::list_skylanders.find(ids); if (skylander == IOS::HLE::USB::list_skylanders.end()) - return QBrush(QColor(255, 255, 255, 255)); + return QBrush(dark_theme ? QColor(32, 32, 32) : QColor(255, 255, 255)); switch ((*skylander).second.game) { case IOS::HLE::USB::Game::SpyrosAdv: - return QBrush(QColor(240, 255, 240, 255)); + return QBrush(dark_theme ? QColor(10, 42, 90) : QColor(240, 255, 240)); case IOS::HLE::USB::Game::Giants: - return QBrush(QColor(255, 240, 215, 255)); + return QBrush(dark_theme ? QColor(120, 16, 12) : QColor(255, 240, 215)); case IOS::HLE::USB::Game::SwapForce: - return QBrush(QColor(240, 245, 255, 255)); + return QBrush(dark_theme ? QColor(28, 45, 12) : QColor(240, 245, 255)); case IOS::HLE::USB::Game::TrapTeam: - return QBrush(QColor(255, 240, 240, 255)); + return QBrush(dark_theme ? QColor(0, 56, 76) : QColor(255, 240, 240)); case IOS::HLE::USB::Game::Superchargers: - return QBrush(QColor(247, 228, 215, 255)); + return QBrush(dark_theme ? QColor(90, 12, 12) : QColor(247, 228, 215)); default: - return QBrush(QColor(255, 255, 255, 255)); + return QBrush(dark_theme ? QColor(32, 32, 32) : QColor(255, 255, 255)); } } diff --git a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h index 72ce63420a..293b056199 100644 --- a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h +++ b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h @@ -37,6 +37,8 @@ public: explicit SkylanderPortalWindow(QWidget* parent = nullptr); ~SkylanderPortalWindow() override; + void RefreshList(); + protected: std::array m_edit_skylanders; std::array, MAX_SKYLANDERS> m_sky_slots; @@ -60,7 +62,6 @@ private: // Behind the scenes void OnEmulationStateChanged(Core::State state); void OnCollectionPathChanged(); - void RefreshList(); void UpdateCurrentIDs(); void CreateSkyfile(const QString& path, bool load_after); void LoadSkyfilePath(u8 slot, const QString& path); @@ -71,7 +72,7 @@ private: QString GetFilePath(u16 id, u16 var); u8 GetCurrentSlot(); int GetElementRadio(); - QBrush GetBaseColor(std::pair ids); + QBrush GetBaseColor(std::pair ids, bool dark_theme); int GetGameID(IOS::HLE::USB::Game game); int GetElementID(IOS::HLE::USB::Element elem); From 783ff26eddb9bb035526887605d6f6ce036d1fba Mon Sep 17 00:00:00 2001 From: Harkaran Mann Date: Thu, 10 Aug 2023 00:26:28 -0700 Subject: [PATCH 86/99] DolphinQt: Turn of wii save options during emulation --- Source/Core/DolphinQt/GameList/GameList.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index c918c4555d..0f2c3beb66 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -466,8 +466,14 @@ void GameList::ShowContextMenu(const QPoint&) if (!is_mod_descriptor && (platform == DiscIO::Platform::WiiWAD || platform == DiscIO::Platform::WiiDisc)) { - menu->addAction(tr("Open Wii &Save Folder"), this, &GameList::OpenWiiSaveFolder); - menu->addAction(tr("Export Wii Save"), this, &GameList::ExportWiiSave); + QAction* open_wii_save_folder = + menu->addAction(tr("Open Wii &Save Folder"), this, &GameList::OpenWiiSaveFolder); + QAction* export_wii_save = + menu->addAction(tr("Export Wii Save"), this, &GameList::ExportWiiSave); + + open_wii_save_folder->setEnabled(!Core::IsRunning()); + export_wii_save->setEnabled(!Core::IsRunning()); + menu->addSeparator(); } From e6c7f4e14b43bfc0977321c7a9e3825ae91a95e3 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Sat, 12 Aug 2023 21:33:43 +0200 Subject: [PATCH 87/99] DolphinQt: Add ToolTipPushButton. --- Source/Core/DolphinQt/CMakeLists.txt | 2 ++ .../ToolTipControls/ToolTipPushButton.cpp | 14 ++++++++++++++ .../ToolTipControls/ToolTipPushButton.h | 19 +++++++++++++++++++ Source/Core/DolphinQt/DolphinQt.vcxproj | 2 ++ 4 files changed, 37 insertions(+) create mode 100644 Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.cpp create mode 100644 Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.h diff --git a/Source/Core/DolphinQt/CMakeLists.txt b/Source/Core/DolphinQt/CMakeLists.txt index 2633b3d264..4079d3db94 100644 --- a/Source/Core/DolphinQt/CMakeLists.txt +++ b/Source/Core/DolphinQt/CMakeLists.txt @@ -181,6 +181,8 @@ add_executable(dolphin-emu Config/ToolTipControls/ToolTipCheckBox.h Config/ToolTipControls/ToolTipComboBox.cpp Config/ToolTipControls/ToolTipComboBox.h + Config/ToolTipControls/ToolTipPushButton.cpp + Config/ToolTipControls/ToolTipPushButton.h Config/ToolTipControls/ToolTipRadioButton.cpp Config/ToolTipControls/ToolTipRadioButton.h Config/ToolTipControls/ToolTipSlider.cpp diff --git a/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.cpp b/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.cpp new file mode 100644 index 0000000000..c15aefea9e --- /dev/null +++ b/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.cpp @@ -0,0 +1,14 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "DolphinQt/Config/ToolTipControls/ToolTipPushButton.h" + +ToolTipPushButton::ToolTipPushButton(const QString& text, QWidget* parent) + : ToolTipWidget(text, parent) +{ +} + +QPoint ToolTipPushButton::GetToolTipPosition() const +{ + return pos() + QPoint(width() / 2, height() / 2); +} diff --git a/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.h b/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.h new file mode 100644 index 0000000000..aba4e42785 --- /dev/null +++ b/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipPushButton.h @@ -0,0 +1,19 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "DolphinQt/Config/ToolTipControls/ToolTipWidget.h" + +#include + +#include "DolphinQt/QtUtils/NonDefaultQPushButton.h" + +class ToolTipPushButton : public ToolTipWidget +{ +public: + explicit ToolTipPushButton(const QString& text = {}, QWidget* parent = nullptr); + +private: + QPoint GetToolTipPosition() const override; +}; diff --git a/Source/Core/DolphinQt/DolphinQt.vcxproj b/Source/Core/DolphinQt/DolphinQt.vcxproj index 9217cc3788..4ac411b410 100644 --- a/Source/Core/DolphinQt/DolphinQt.vcxproj +++ b/Source/Core/DolphinQt/DolphinQt.vcxproj @@ -127,6 +127,7 @@ + @@ -327,6 +328,7 @@ + From 9955a06dbd7effb451a67e09720222fac8ba9601 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 12 Aug 2023 12:53:57 -0700 Subject: [PATCH 88/99] NandPaths: Resolve Android tautological comparison warning Android interprets char as unsigned char, so comparing with 0 triggers a tautological-unsigned-char-zero-compare warning. Casting c to an unsigned char and removing the comparison with 0 resolves the warning while needing one less comparison on all platforms. --- Source/Core/Common/NandPaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/NandPaths.cpp b/Source/Core/Common/NandPaths.cpp index c9217565bb..e6f2d2a88b 100644 --- a/Source/Core/Common/NandPaths.cpp +++ b/Source/Core/Common/NandPaths.cpp @@ -107,7 +107,7 @@ static bool IsIllegalCharacter(char c) { static const std::unordered_set illegal_chars = {'\"', '*', '/', ':', '<', '>', '?', '\\', '|', '\x7f'}; - return (c >= 0 && c <= 0x1F) || illegal_chars.find(c) != illegal_chars.end(); + return static_cast(c) <= 0x1F || illegal_chars.find(c) != illegal_chars.end(); } std::string EscapeFileName(const std::string& filename) From 9ad0d9ca6adbe94c9f60b85042789432950395ce Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 12 Aug 2023 13:55:18 -0700 Subject: [PATCH 89/99] NandPaths: Use initializer_list instead of unordered_set --- Source/Core/Common/NandPaths.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/Core/Common/NandPaths.cpp b/Source/Core/Common/NandPaths.cpp index e6f2d2a88b..5e6aa57d70 100644 --- a/Source/Core/Common/NandPaths.cpp +++ b/Source/Core/Common/NandPaths.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -105,9 +104,9 @@ bool IsTitlePath(const std::string& path, std::optional from, u64 static bool IsIllegalCharacter(char c) { - static const std::unordered_set illegal_chars = {'\"', '*', '/', ':', '<', - '>', '?', '\\', '|', '\x7f'}; - return static_cast(c) <= 0x1F || illegal_chars.find(c) != illegal_chars.end(); + static constexpr auto illegal_chars = {'\"', '*', '/', ':', '<', '>', '?', '\\', '|', '\x7f'}; + return static_cast(c) <= 0x1F || + std::find(illegal_chars.begin(), illegal_chars.end(), c) != illegal_chars.end(); } std::string EscapeFileName(const std::string& filename) From 77d33d61de5f562fec21c69f0f8c9dd192ceff4d Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 12 Aug 2023 20:16:37 -0700 Subject: [PATCH 90/99] GCAdapter: Fix spelling of constants --- Source/Core/InputCommon/GCAdapter.cpp | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index ec3c3a1fb3..2b0ce2b6c0 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -99,9 +99,9 @@ enum class ControllerType : u8 static std::array s_controller_rumble; -constexpr size_t CONTROLER_INPUT_PAYLOAD_EXPECTED_SIZE = 37; -constexpr size_t CONTROLER_OUTPUT_INIT_PAYLOAD_SIZE = 1; -constexpr size_t CONTROLER_OUTPUT_RUMBLE_PAYLOAD_SIZE = 5; +constexpr size_t CONTROLLER_INPUT_PAYLOAD_EXPECTED_SIZE = 37; +constexpr size_t CONTROLLER_OUTPUT_INIT_PAYLOAD_SIZE = 1; +constexpr size_t CONTROLLER_OUTPUT_RUMBLE_PAYLOAD_SIZE = 5; struct PortState { @@ -115,7 +115,7 @@ struct PortState // Only access with s_mutex held! static std::array s_port_states; -static std::array s_controller_write_payload; +static std::array s_controller_write_payload; static std::atomic s_controller_write_payload_size{0}; static std::thread s_read_adapter_thread; @@ -200,7 +200,7 @@ static void ReadThreadFunc() while (s_read_adapter_thread_running.IsSet()) { #if GCADAPTER_USE_LIBUSB_IMPLEMENTATION - std::array input_buffer; + std::array input_buffer; int payload_size = 0; int error = libusb_interrupt_transfer(s_handle, s_endpoint_in, input_buffer.data(), @@ -289,7 +289,7 @@ static void WriteThreadFunc() LibusbUtils::ErrorWrap(error)); } #elif GCADAPTER_USE_ANDROID_IMPLEMENTATION - const jbyteArray jrumble_array = env->NewByteArray(CONTROLER_OUTPUT_RUMBLE_PAYLOAD_SIZE); + const jbyteArray jrumble_array = env->NewByteArray(CONTROLLER_OUTPUT_RUMBLE_PAYLOAD_SIZE); jbyte* const jrumble = env->GetByteArrayElements(jrumble_array, nullptr); { @@ -650,9 +650,9 @@ static void AddGCAdapter(libusb_device* device) config.reset(); int size = 0; - std::array payload = {0x13}; + std::array payload = {0x13}; error = libusb_interrupt_transfer(s_handle, s_endpoint_out, payload.data(), - CONTROLER_OUTPUT_INIT_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); + CONTROLLER_OUTPUT_INIT_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); if (error != LIBUSB_SUCCESS) { WARN_LOG_FMT(CONTROLLERINTERFACE, "AddGCAdapter: libusb_interrupt_transfer failed: {}", @@ -776,7 +776,7 @@ static ControllerType IdentifyControllerType(u8 data) void ProcessInputPayload(const u8* data, std::size_t size) { - if (size != CONTROLER_INPUT_PAYLOAD_EXPECTED_SIZE + if (size != CONTROLLER_INPUT_PAYLOAD_EXPECTED_SIZE #if GCADAPTER_USE_LIBUSB_IMPLEMENTATION || data[0] != LIBUSB_DT_HID #endif @@ -891,11 +891,11 @@ void ResetRumble() return; ResetRumbleLockNeeded(); #elif GCADAPTER_USE_ANDROID_IMPLEMENTATION - std::array rumble = {0x11, 0, 0, 0, 0}; + std::array rumble = {0x11, 0, 0, 0, 0}; { std::lock_guard lk(s_write_mutex); s_controller_write_payload = rumble; - s_controller_write_payload_size.store(CONTROLER_OUTPUT_RUMBLE_PAYLOAD_SIZE); + s_controller_write_payload_size.store(CONTROLLER_OUTPUT_RUMBLE_PAYLOAD_SIZE); } s_write_happened.Set(); #endif @@ -913,14 +913,14 @@ static void ResetRumbleLockNeeded() std::fill(std::begin(s_controller_rumble), std::end(s_controller_rumble), 0); - std::array rumble = { + std::array rumble = { 0x11, s_controller_rumble[0], s_controller_rumble[1], s_controller_rumble[2], s_controller_rumble[3]}; int size = 0; const int error = libusb_interrupt_transfer(s_handle, s_endpoint_out, rumble.data(), - CONTROLER_OUTPUT_RUMBLE_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); + CONTROLLER_OUTPUT_RUMBLE_PAYLOAD_SIZE, &size, USB_TIMEOUT_MS); if (error != LIBUSB_SUCCESS) { WARN_LOG_FMT(CONTROLLERINTERFACE, "ResetRumbleLockNeeded: libusb_interrupt_transfer failed: {}", @@ -949,7 +949,7 @@ void Output(int chan, u8 rumble_command) s_port_states[chan].controller_type != ControllerType::Wireless) { s_controller_rumble[chan] = rumble_command; - std::array rumble = { + std::array rumble = { 0x11, s_controller_rumble[0], s_controller_rumble[1], s_controller_rumble[2], s_controller_rumble[3]}; { @@ -957,7 +957,7 @@ void Output(int chan, u8 rumble_command) std::lock_guard lk(s_write_mutex); #endif s_controller_write_payload = rumble; - s_controller_write_payload_size.store(CONTROLER_OUTPUT_RUMBLE_PAYLOAD_SIZE); + s_controller_write_payload_size.store(CONTROLLER_OUTPUT_RUMBLE_PAYLOAD_SIZE); } s_write_happened.Set(); } From 274b11e4e911768e1218d32381102432e93cccd3 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 12 Aug 2023 20:18:15 -0700 Subject: [PATCH 91/99] GCAdapter: Fix Android unused constant warning CONTROLLER_OUTPUT_INIT_PAYLOAD_SIZE is only used by the libusb implementation. --- Source/Core/InputCommon/GCAdapter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Core/InputCommon/GCAdapter.cpp b/Source/Core/InputCommon/GCAdapter.cpp index 2b0ce2b6c0..6334a23778 100644 --- a/Source/Core/InputCommon/GCAdapter.cpp +++ b/Source/Core/InputCommon/GCAdapter.cpp @@ -100,7 +100,9 @@ enum class ControllerType : u8 static std::array s_controller_rumble; constexpr size_t CONTROLLER_INPUT_PAYLOAD_EXPECTED_SIZE = 37; +#if GCADAPTER_USE_LIBUSB_IMPLEMENTATION constexpr size_t CONTROLLER_OUTPUT_INIT_PAYLOAD_SIZE = 1; +#endif constexpr size_t CONTROLLER_OUTPUT_RUMBLE_PAYLOAD_SIZE = 5; struct PortState From 720191d1f75f43bb8b649bad571114db007ae048 Mon Sep 17 00:00:00 2001 From: Dentomologist Date: Sat, 12 Aug 2023 20:37:01 -0700 Subject: [PATCH 92/99] AbstractFramebuffer: Fix Android reorder-ctor warning Move declaration of m_additional_color_attachments so its initialization order matches that of the constructor. --- Source/Core/VideoCommon/AbstractFramebuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/AbstractFramebuffer.h b/Source/Core/VideoCommon/AbstractFramebuffer.h index e4c3b0451c..194dca24bc 100644 --- a/Source/Core/VideoCommon/AbstractFramebuffer.h +++ b/Source/Core/VideoCommon/AbstractFramebuffer.h @@ -44,9 +44,9 @@ public: protected: AbstractTexture* m_color_attachment; AbstractTexture* m_depth_attachment; + std::vector m_additional_color_attachments; AbstractTextureFormat m_color_format; AbstractTextureFormat m_depth_format; - std::vector m_additional_color_attachments; u32 m_width; u32 m_height; u32 m_layers; From 31d6aa51170bf44cc39a2ec655887bcf0acf249a Mon Sep 17 00:00:00 2001 From: Mandar1jn Date: Wed, 9 Aug 2023 21:23:17 +0200 Subject: [PATCH 93/99] Skylanders: expand and improve character list The previous list had some issues. A lot of variant id's were set to 0x0000. Althought this works for some figures, on a technicallity implemented into the games, they are technically wrong and don't result in exactly the same experience as the real figures. For example, the previous small fry got a "series 1" text in the summon screen. The real small fry does not have this. I also added figure types so I can add seperate generation logic later. The Kaos element only applies to 3 items. So, I decided to throw it under others since it's not listed as an element in the manual and you can easily search for Kaos --- .../Core/Core/IOS/USB/Emulated/Skylander.cpp | 989 ++++++++++-------- Source/Core/Core/IOS/USB/Emulated/Skylander.h | 26 +- .../SkylanderPortal/SkylanderPortalWindow.cpp | 292 +++--- .../SkylanderPortal/SkylanderPortalWindow.h | 19 +- 4 files changed, 711 insertions(+), 615 deletions(-) diff --git a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp index 97c2b36c7f..d42eb70eba 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp +++ b/Source/Core/Core/IOS/USB/Emulated/Skylander.cpp @@ -19,465 +19,536 @@ namespace IOS::HLE::USB { const std::map, SkyData> list_skylanders = { - {{0, 0x0000}, {"Whirlwind", Game::SpyrosAdv, Element::Air}}, - {{0, 0x1801}, {"Series 2 Whirlwind", Game::Giants, Element::Air}}, - {{0, 0x1C02}, {"Polar Whirlwind", Game::Giants, Element::Air}}, - {{0, 0x2805}, {"Horn Blast Whirlwind", Game::SwapForce, Element::Air}}, - {{0, 0x3810}, {"Eon's Elite Whirlwind", Game::TrapTeam, Element::Air}}, - {{1, 0x0000}, {"Sonic Boom", Game::SpyrosAdv, Element::Air}}, - {{1, 0x1801}, {"Series 2 Sonic Boom", Game::Giants, Element::Air}}, - {{2, 0x0000}, {"Warnado", Game::SpyrosAdv, Element::Air}}, - {{2, 0x2206}, {"LightCore Warnado", Game::SwapForce, Element::Air}}, - {{3, 0x0000}, {"Lightning Rod", Game::SpyrosAdv, Element::Air}}, - {{3, 0x1801}, {"Series 2 Lightning Rod", Game::Giants, Element::Air}}, - {{4, 0x0000}, {"Bash", Game::SpyrosAdv, Element::Earth}}, - {{4, 0x1801}, {"Series 2 Bash", Game::Giants, Element::Earth}}, - {{5, 0x0000}, {"Terrafin", Game::SpyrosAdv, Element::Earth}}, - {{5, 0x1801}, {"Series 2 Terrafin", Game::Giants, Element::Earth}}, - {{5, 0x2805}, {"Knockout Terrafin", Game::SwapForce, Element::Earth}}, - {{5, 0x3810}, {"Eon's Elite Terrafin", Game::TrapTeam, Element::Earth}}, - {{6, 0x0000}, {"Dino Rang", Game::SpyrosAdv, Element::Earth}}, - {{6, 0x4810}, {"Eon's Elite Dino Rang", Game::Superchargers, Element::Earth}}, - {{7, 0x0000}, {"Prism Break", Game::SpyrosAdv, Element::Earth}}, - {{7, 0x1206}, {"LightCore Prism Break", Game::Giants, Element::Earth}}, - {{7, 0x1801}, {"Series 2 Prism Break", Game::Giants, Element::Earth}}, - {{7, 0x2805}, {"Hyper Beam Prism Break", Game::SwapForce, Element::Earth}}, - {{8, 0x0000}, {"Sunburn", Game::SpyrosAdv, Element::Fire}}, - {{9, 0x0000}, {"Eruptor", Game::SpyrosAdv, Element::Fire}}, - {{9, 0x1206}, {"LightCore Eruptor", Game::Giants, Element::Fire}}, - {{9, 0x1801}, {"Series 2 Eruptor", Game::Giants, Element::Fire}}, - {{9, 0x2C02}, {"Volcanic Eruptor", Game::SwapForce, Element::Fire}}, - {{9, 0x2805}, {"Lava Barf Eruptor", Game::SwapForce, Element::Fire}}, - {{9, 0x3810}, {"Eon's Elite Eruptor", Game::TrapTeam, Element::Fire}}, - {{10, 0x0000}, {"Ignitor", Game::SpyrosAdv, Element::Fire}}, - {{10, 0x1801}, {"Series 2 Ignitor", Game::Giants, Element::Fire}}, - {{10, 0x1C03}, {"Legendary Ignitor", Game::Giants, Element::Fire}}, - {{11, 0x0000}, {"Flameslinger", Game::SpyrosAdv, Element::Fire}}, - {{11, 0x1801}, {"Series 2 Flameslinger", Game::Giants, Element::Fire}}, - {{12, 0x0000}, {"Zap", Game::SpyrosAdv, Element::Water}}, - {{12, 0x1801}, {"Series 2 Zap", Game::Giants, Element::Water}}, - {{13, 0x0000}, {"Wham Shell", Game::SpyrosAdv, Element::Water}}, - {{13, 0x2206}, {"LightCore Wham Shell", Game::SwapForce, Element::Water}}, - {{14, 0x0000}, {"Gill Grunt", Game::SpyrosAdv, Element::Water}}, - {{14, 0x1801}, {"Series 2 Gill Grunt", Game::Giants, Element::Water}}, - {{14, 0x2805}, {"Anchors Away Gill Grunt", Game::SwapForce, Element::Water}}, - {{14, 0x3805}, {"Tidal Wave Gill Grunt", Game::TrapTeam, Element::Water}}, - {{14, 0x3810}, {"Eon's Elite Gill Grunt", Game::TrapTeam, Element::Water}}, - {{15, 0x0000}, {"Slam Bam", Game::SpyrosAdv, Element::Water}}, - {{15, 0x1801}, {"Series 2 Slam Bam", Game::Giants, Element::Water}}, - {{15, 0x1C03}, {"Legendary Slam Bam", Game::Giants, Element::Water}}, - {{15, 0x4810}, {"Eon's Elite Slam Bam", Game::Superchargers, Element::Water}}, - {{16, 0x0000}, {"Spyro", Game::SpyrosAdv, Element::Magic}}, - {{16, 0x1801}, {"Series 2 Spyro", Game::Giants, Element::Magic}}, - {{16, 0x2805}, {"Mega Ram Spyro", Game::SwapForce, Element::Magic}}, - {{16, 0x2C02}, {"Dark Mega Ram Spyro", Game::SwapForce, Element::Magic}}, - {{16, 0x3810}, {"Eon's Elite Spyro", Game::TrapTeam, Element::Magic}}, - {{17, 0x0000}, {"Voodood", Game::SpyrosAdv, Element::Magic}}, - {{17, 0x4810}, {"Eon's Elite Voodood", Game::Superchargers, Element::Magic}}, - {{18, 0x0000}, {"Double Trouble", Game::SpyrosAdv, Element::Magic}}, - {{18, 0x1801}, {"Series 2 Double Trouble", Game::Giants, Element::Magic}}, - {{18, 0x1C02}, {"Royal Double Trouble", Game::Giants, Element::Magic}}, - {{19, 0x0000}, {"Trigger Happy", Game::SpyrosAdv, Element::Tech}}, - {{19, 0x1801}, {"Series 2 Trigger Happy", Game::Giants, Element::Tech}}, - {{19, 0x2805}, {"Big Bang Trigger Happy", Game::SwapForce, Element::Tech}}, - {{19, 0x2C02}, {"Springtime Trigger Happy", Game::SwapForce, Element::Tech}}, - {{19, 0x3810}, {"Eon's Elite Trigger Happy", Game::TrapTeam, Element::Tech}}, - {{20, 0x0000}, {"Drobot", Game::SpyrosAdv, Element::Tech}}, - {{20, 0x1206}, {"LightCore Drobot", Game::Giants, Element::Tech}}, - {{20, 0x1801}, {"Series 2 Drobot", Game::Giants, Element::Tech}}, - {{21, 0x0000}, {"Drill Seargeant", Game::SpyrosAdv, Element::Tech}}, - {{21, 0x1801}, {"Series 2 Drill Seargeant", Game::Giants, Element::Tech}}, - {{22, 0x0000}, {"Boomer", Game::SpyrosAdv, Element::Tech}}, - {{22, 0x4810}, {"Eon's Elite Boomer", Game::Superchargers, Element::Tech}}, - {{23, 0x0000}, {"Wrecking Ball", Game::SpyrosAdv, Element::Magic}}, - {{23, 0x1801}, {"Series 2 Wrecking Ball", Game::Giants, Element::Magic}}, - {{24, 0x0000}, {"Camo", Game::SpyrosAdv, Element::Life}}, - {{24, 0x2805}, {"Thorn Horn Camo", Game::SwapForce, Element::Life}}, - {{25, 0x0000}, {"Zook", Game::SpyrosAdv, Element::Life}}, - {{25, 0x1801}, {"Series 2 Zook", Game::Giants, Element::Life}}, - {{25, 0x4810}, {"Eon's Elite Zook", Game::Superchargers, Element::Life}}, - {{26, 0x0000}, {"Stealth Elf", Game::SpyrosAdv, Element::Life}}, - {{26, 0x1801}, {"Series 2 Stealth Elf", Game::Giants, Element::Life}}, - {{26, 0x1C03}, {"Legendary Stealth Elf", Game::Giants, Element::Life}}, - {{26, 0x2C02}, {"Dark Stealth Elf", Game::SwapForce, Element::Life}}, - {{26, 0x2805}, {"Ninja Stealth Elf", Game::SwapForce, Element::Life}}, - {{26, 0x3810}, {"Eon's Elite Stealth Elf", Game::TrapTeam, Element::Life}}, - {{27, 0x0000}, {"Stump Smash", Game::SpyrosAdv, Element::Life}}, - {{27, 0x1801}, {"Series 2 Stump Smash", Game::Giants, Element::Life}}, - {{28, 0x0000}, {"Dark Spyro", Game::SpyrosAdv, Element::Magic}}, - {{29, 0x0000}, {"Hex", Game::SpyrosAdv, Element::Undead}}, - {{29, 0x1206}, {"LightCore Hex", Game::Giants, Element::Undead}}, - {{29, 0x1801}, {"Series 2 Hex", Game::Giants, Element::Undead}}, - {{30, 0x0000}, {"Chop Chop", Game::SpyrosAdv, Element::Undead}}, - {{30, 0x1801}, {"Series 2 Chop Chop", Game::Giants, Element::Undead}}, - {{30, 0x2805}, {"Twin Blade Chop Chop", Game::SwapForce, Element::Undead}}, - {{30, 0x3810}, {"Eon's Elite Chop Chop", Game::TrapTeam, Element::Undead}}, - {{31, 0x0000}, {"Ghost Roaster", Game::SpyrosAdv, Element::Undead}}, - {{31, 0x4810}, {"Eon's Elite Ghost Roaster", Game::Superchargers, Element::Undead}}, - {{32, 0x0000}, {"Cynder", Game::SpyrosAdv, Element::Undead}}, - {{32, 0x1801}, {"Series 2 Cynder", Game::Giants, Element::Undead}}, - {{32, 0x2805}, {"Phantom Cynder", Game::SwapForce, Element::Undead}}, - {{100, 0x0000}, {"Jet Vac", Game::Giants, Element::Air}}, - {{100, 0x1206}, {"LightCore Jet Vac", Game::Giants, Element::Air}}, - {{100, 0x1403}, {"Legendary Jet Vac", Game::Giants, Element::Air}}, - {{100, 0x2805}, {"Turbo Jet Vac", Game::SwapForce, Element::Air}}, - {{100, 0x3805}, {"Full Blast Jet Vac", Game::TrapTeam, Element::Air}}, - {{101, 0x0000}, {"Swarm", Game::Giants, Element::Air}}, - {{102, 0x0000}, {"Crusher", Game::Giants, Element::Earth}}, - {{102, 0x1602}, {"Granite Crusher", Game::Giants, Element::Earth}}, - {{103, 0x0000}, {"Flashwing", Game::Giants, Element::Earth}}, - {{103, 0x1402}, {"Jade Flash Wing", Game::Giants, Element::Earth}}, - {{103, 0x2206}, {"LightCore Flashwing", Game::SwapForce, Element::Earth}}, - {{104, 0x0000}, {"Hot Head", Game::Giants, Element::Fire}}, - {{105, 0x0000}, {"Hot Dog", Game::Giants, Element::Fire}}, - {{105, 0x1402}, {"Molten Hot Dog", Game::Giants, Element::Fire}}, - {{105, 0x2805}, {"Fire Bone Hot Dog", Game::SwapForce, Element::Fire}}, - {{106, 0x0000}, {"Chill", Game::Giants, Element::Water}}, - {{106, 0x1206}, {"LightCore Chill", Game::Giants, Element::Water}}, - {{106, 0x1603}, {"Legendary LightCore Chill", Game::Giants, Element::Water}}, - {{106, 0x2805}, {"Blizzard Chill", Game::SwapForce, Element::Water}}, - {{107, 0x0000}, {"Thumpback", Game::Giants, Element::Water}}, - {{108, 0x0000}, {"Pop Fizz", Game::Giants, Element::Magic}}, - {{108, 0x1206}, {"LightCore Pop Fizz", Game::Giants, Element::Magic}}, - {{108, 0x1402}, {"Punch Pop Fizz", Game::Giants, Element::Magic}}, - {{108, 0x2805}, {"Super Gulp Pop Fizz", Game::SwapForce, Element::Magic}}, - {{108, 0x3805}, {"Fizzy Frenzy Pop Fizz", Game::TrapTeam, Element::Magic}}, - {{108, 0x3C02}, {"Love Potion Pop Fizz", Game::TrapTeam, Element::Magic}}, - {{109, 0x0000}, {"Ninjini", Game::Giants, Element::Magic}}, - {{109, 0x1602}, {"Scarlet Ninjini", Game::Giants, Element::Magic}}, - {{110, 0x0000}, {"Bouncer", Game::Giants, Element::Tech}}, - {{110, 0x1603}, {"Legendary Bouncer", Game::Giants, Element::Tech}}, - {{111, 0x0000}, {"Sprocket", Game::Giants, Element::Tech}}, - {{111, 0x2805}, {"Heavy Duty Sprocket", Game::SwapForce, Element::Tech}}, - {{112, 0x0000}, {"Tree Rex", Game::Giants, Element::Life}}, - {{112, 0x1602}, {"Gnarly Tree Rex", Game::Giants, Element::Life}}, - {{113, 0x0000}, {"Shroomboom", Game::Giants, Element::Life}}, - {{113, 0x1206}, {"LightCore Shroomboom", Game::Giants, Element::Life}}, - {{113, 0x3805}, {"Sure Shot Shroomboom", Game::TrapTeam, Element::Life}}, - {{114, 0x0000}, {"Eye Brawl", Game::Giants, Element::Undead}}, - {{115, 0x0000}, {"Fright Rider", Game::Giants, Element::Undead}}, - {{200, 0x0000}, {"Anvil Rain", Game::SpyrosAdv}}, - {{201, 0x0000}, {"Hidden Treasure", Game::SpyrosAdv}}, - {{201, 0x2000}, {"Platinum Hidden Treasure", Game::Giants}}, - {{202, 0x0000}, {"Healing Elixir", Game::SpyrosAdv}}, - {{203, 0x0000}, {"Ghost Pirate Swords", Game::SpyrosAdv}}, - {{204, 0x0000}, {"Time Twist Hourglass", Game::SpyrosAdv}}, - {{205, 0x0000}, {"Sky Iron Shield", Game::SpyrosAdv}}, - {{206, 0x0000}, {"Winged Boots", Game::SpyrosAdv}}, - {{207, 0x0000}, {"Sparx the Dragonfly", Game::SpyrosAdv}}, - {{208, 0x0000}, {"Dragonfire Cannon", Game::Giants}}, - {{208, 0x1602}, {"Golden Dragonfire Cannon", Game::Giants}}, - {{209, 0x0000}, {"Scorpion Striker Catapult", Game::Giants}}, - {{210, 0x3002}, {"Biter's Bane", Game::TrapTeam, Element::Magic}}, - {{210, 0x3008}, {"Sorcerous Skull", Game::TrapTeam, Element::Magic}}, - {{210, 0x300B}, {"Axe of Illusion", Game::TrapTeam, Element::Magic}}, - {{210, 0x300E}, {"Arcane Hourglass", Game::TrapTeam, Element::Magic}}, - {{210, 0x3012}, {"Spell Slapper", Game::TrapTeam, Element::Magic}}, - {{210, 0x3014}, {"Rune Rocket", Game::TrapTeam, Element::Magic}}, - {{211, 0x3001}, {"Tidal Tiki", Game::TrapTeam, Element::Water}}, - {{211, 0x3002}, {"Wet Walter", Game::TrapTeam, Element::Water}}, - {{211, 0x3006}, {"Flood Flask", Game::TrapTeam, Element::Water}}, - {{211, 0x3406}, {"Legendary Flood Flask", Game::TrapTeam, Element::Water}}, - {{211, 0x3007}, {"Soaking Staff", Game::TrapTeam, Element::Water}}, - {{211, 0x300B}, {"Aqua Axe", Game::TrapTeam, Element::Water}}, - {{211, 0x3016}, {"Frost Helm", Game::TrapTeam, Element::Water}}, - {{212, 0x3003}, {"Breezy Bird", Game::TrapTeam, Element::Air}}, - {{212, 0x3006}, {"Drafty Decanter", Game::TrapTeam, Element::Air}}, - {{212, 0x300D}, {"Tempest Timer", Game::TrapTeam, Element::Air}}, - {{212, 0x3010}, {"Cloudy Cobra", Game::TrapTeam, Element::Air}}, - {{212, 0x3011}, {"Storm Warning", Game::TrapTeam, Element::Air}}, - {{212, 0x3018}, {"Cyclone Saber", Game::TrapTeam, Element::Air}}, - {{213, 0x3004}, {"Spirit Sphere", Game::TrapTeam, Element::Undead}}, - {{213, 0x3404}, {"Legendary Spirit Sphere", Game::TrapTeam, Element::Undead}}, - {{213, 0x3008}, {"Spectral Skull", Game::TrapTeam, Element::Undead}}, - {{213, 0x3408}, {"Legendary Spectral Skull", Game::TrapTeam, Element::Undead}}, - {{213, 0x300B}, {"Haunted Hatchet", Game::TrapTeam, Element::Undead}}, - {{213, 0x300C}, {"Grim Gripper", Game::TrapTeam, Element::Undead}}, - {{213, 0x3010}, {"Spooky Snake", Game::TrapTeam, Element::Undead}}, - {{213, 0x3017}, {"Dream Piercer", Game::TrapTeam, Element::Undead}}, - {{214, 0x3000}, {"Tech Totem", Game::TrapTeam, Element::Tech}}, - {{214, 0x3007}, {"Automatic Angel", Game::TrapTeam, Element::Tech}}, - {{214, 0x3009}, {"Factory Flower", Game::TrapTeam, Element::Tech}}, - {{214, 0x300C}, {"Grabbing Gadget", Game::TrapTeam, Element::Tech}}, - {{214, 0x3016}, {"Makers Mana", Game::TrapTeam, Element::Tech}}, - {{214, 0x301A}, {"Topsy Techy", Game::TrapTeam, Element::Tech}}, - {{215, 0x3005}, {"Eternal Flame", Game::TrapTeam, Element::Fire}}, - {{215, 0x3009}, {"Fire Flower", Game::TrapTeam, Element::Fire}}, - {{215, 0x3011}, {"Scorching Stopper", Game::TrapTeam, Element::Fire}}, - {{215, 0x3012}, {"Searing Spinner", Game::TrapTeam, Element::Fire}}, - {{215, 0x3017}, {"Spark Spear", Game::TrapTeam, Element::Fire}}, - {{215, 0x301B}, {"Blazing Belch", Game::TrapTeam, Element::Fire}}, - {{216, 0x3000}, {"Banded Boulder", Game::TrapTeam, Element::Earth}}, - {{216, 0x3003}, {"Rock Hawk", Game::TrapTeam, Element::Earth}}, - {{216, 0x300A}, {"Slag Hammer", Game::TrapTeam, Element::Earth}}, - {{216, 0x300E}, {"Dust Of Time", Game::TrapTeam, Element::Earth}}, - {{216, 0x3013}, {"Spinning Sandstorm", Game::TrapTeam, Element::Earth}}, - {{216, 0x301A}, {"Rubble Trouble", Game::TrapTeam, Element::Earth}}, - {{217, 0x3003}, {"Oak Eagle", Game::TrapTeam, Element::Life}}, - {{217, 0x3005}, {"Emerald Energy", Game::TrapTeam, Element::Life}}, - {{217, 0x300A}, {"Weed Whacker", Game::TrapTeam, Element::Life}}, - {{217, 0x3010}, {"Seed Serpent", Game::TrapTeam, Element::Life}}, - {{217, 0x3018}, {"Jade Blade", Game::TrapTeam, Element::Life}}, - {{217, 0x301B}, {"Shrub Shrieker", Game::TrapTeam, Element::Life}}, - {{218, 0x3000}, {"Dark Dagger", Game::TrapTeam}}, - {{218, 0x3014}, {"Shadow Spider", Game::TrapTeam}}, - {{218, 0x301A}, {"Ghastly Grimace", Game::TrapTeam}}, - {{219, 0x3000}, {"Shining Ship", Game::TrapTeam}}, - {{219, 0x300F}, {"Heavenly Hawk", Game::TrapTeam}}, - {{219, 0x301B}, {"Beam Scream", Game::TrapTeam}}, - {{220, 0x301E}, {"Kaos Trap", Game::TrapTeam}}, - {{220, 0x351F}, {"Ultimate Kaos Trap", Game::TrapTeam}}, - {{230, 0x0000}, {"Hand of Fate", Game::TrapTeam}}, - {{230, 0x3403}, {"Legendary Hand of Fate", Game::TrapTeam}}, - {{231, 0x0000}, {"Piggy Bank", Game::TrapTeam}}, - {{232, 0x0000}, {"Rocket Ram", Game::TrapTeam}}, - {{233, 0x0000}, {"Tiki Speaky", Game::TrapTeam}}, - {{300, 0x0000}, {"Dragon's Peak", Game::SpyrosAdv}}, - {{301, 0x0000}, {"Empire of Ice", Game::SpyrosAdv}}, - {{302, 0x0000}, {"Pirate Seas", Game::SpyrosAdv}}, - {{303, 0x0000}, {"Darklight Crypt", Game::SpyrosAdv}}, - {{304, 0x0000}, {"Volcanic Vault", Game::SpyrosAdv}}, - {{305, 0x0000}, {"Mirror of Mystery", Game::TrapTeam}}, - {{306, 0x0000}, {"Nightmare Express", Game::TrapTeam}}, - {{307, 0x0000}, {"Sunscraper Spire", Game::TrapTeam}}, - {{308, 0x0000}, {"Midnight Museum", Game::TrapTeam}}, - {{404, 0x0000}, {"Legendary Bash", Game::SpyrosAdv, Element::Earth}}, - {{416, 0x0000}, {"Legendary Spyro", Game::SpyrosAdv, Element::Magic}}, - {{419, 0x0000}, {"Legendary Trigger Happy", Game::SpyrosAdv, Element::Tech}}, - {{430, 0x0000}, {"Legendary Chop Chop", Game::SpyrosAdv, Element::Undead}}, - {{450, 0x0000}, {"Gusto", Game::TrapTeam, Element::Air}}, - {{451, 0x0000}, {"Thunderbolt", Game::TrapTeam, Element::Air}}, - {{452, 0x0000}, {"Fling Kong", Game::TrapTeam, Element::Air}}, - {{453, 0x0000}, {"Blades", Game::TrapTeam, Element::Air}}, - {{453, 0x3403}, {"Legendary Blades", Game::TrapTeam, Element::Air}}, - {{454, 0x0000}, {"Wallop", Game::TrapTeam, Element::Earth}}, - {{455, 0x0000}, {"Head Rush", Game::TrapTeam, Element::Earth}}, - {{455, 0x3402}, {"Nitro Head Rush", Game::TrapTeam, Element::Earth}}, - {{456, 0x0000}, {"Fist Bump", Game::TrapTeam, Element::Earth}}, - {{457, 0x0000}, {"Rocky Roll", Game::TrapTeam, Element::Earth}}, - {{458, 0x0000}, {"Wildfire", Game::TrapTeam, Element::Fire}}, - {{458, 0x3402}, {"Dark Wildfire", Game::TrapTeam, Element::Fire}}, - {{459, 0x0000}, {"Ka Boom", Game::TrapTeam, Element::Fire}}, - {{460, 0x0000}, {"Trail Blazer", Game::TrapTeam, Element::Fire}}, - {{461, 0x0000}, {"Torch", Game::TrapTeam, Element::Fire}}, - {{462, 0x0000}, {"Snap Shot", Game::TrapTeam, Element::Water}}, - {{462, 0x3402}, {"Dark Snap Shot", Game::TrapTeam, Element::Water}}, - {{463, 0x0000}, {"Lob Star", Game::TrapTeam, Element::Water}}, - {{463, 0x3402}, {"Winterfest Lob-Star", Game::TrapTeam, Element::Water}}, - {{464, 0x0000}, {"Flip Wreck", Game::TrapTeam, Element::Water}}, - {{465, 0x0000}, {"Echo", Game::TrapTeam, Element::Water}}, - {{466, 0x0000}, {"Blastermind", Game::TrapTeam, Element::Magic}}, - {{467, 0x0000}, {"Enigma", Game::TrapTeam, Element::Magic}}, - {{468, 0x0000}, {"Deja Vu", Game::TrapTeam, Element::Magic}}, - {{468, 0x3403}, {"Legendary Deja Vu", Game::TrapTeam, Element::Magic}}, - {{469, 0x0000}, {"Cobra Cadabra", Game::TrapTeam, Element::Magic}}, - {{469, 0x3402}, {"King Cobra Cadabra", Game::TrapTeam, Element::Magic}}, - {{470, 0x0000}, {"Jawbreaker", Game::TrapTeam, Element::Tech}}, - {{470, 0x3403}, {"Legendary Jawbreaker", Game::TrapTeam, Element::Tech}}, - {{471, 0x0000}, {"Gearshift", Game::TrapTeam, Element::Tech}}, - {{472, 0x0000}, {"Chopper", Game::TrapTeam, Element::Tech}}, - {{473, 0x0000}, {"Tread Head", Game::TrapTeam, Element::Tech}}, - {{474, 0x0000}, {"Bushwack", Game::TrapTeam, Element::Life}}, - {{474, 0x3403}, {"Legendary Bushwack", Game::TrapTeam, Element::Life}}, - {{475, 0x0000}, {"Tuff Luck", Game::TrapTeam, Element::Life}}, - {{476, 0x0000}, {"Food Fight", Game::TrapTeam, Element::Life}}, - {{476, 0x3402}, {"Dark Food Fight", Game::TrapTeam, Element::Life}}, - {{477, 0x0000}, {"High Five", Game::TrapTeam, Element::Life}}, - {{478, 0x0000}, {"Krypt King", Game::TrapTeam, Element::Undead}}, - {{478, 0x3402}, {"Nitro Krypt King", Game::TrapTeam, Element::Undead}}, - {{479, 0x0000}, {"Short Cut", Game::TrapTeam, Element::Undead}}, - {{480, 0x0000}, {"Bat Spin", Game::TrapTeam, Element::Undead}}, - {{481, 0x0000}, {"Funny Bone", Game::TrapTeam, Element::Undead}}, - {{482, 0x0000}, {"Knight Light", Game::TrapTeam}}, - {{483, 0x0000}, {"Spotlight", Game::TrapTeam}}, - {{484, 0x0000}, {"Knight Mare", Game::TrapTeam}}, - {{485, 0x0000}, {"Blackout", Game::TrapTeam}}, - {{502, 0x0000}, {"Bop (Mini)", Game::TrapTeam, Element::Earth}}, - {{503, 0x0000}, {"Spry (Mini)", Game::TrapTeam, Element::Magic}}, - {{504, 0x0000}, {"Hijinx (Mini)", Game::TrapTeam, Element::Undead}}, - {{505, 0x0000}, {"Terrabite (Sidekick)", Game::SpyrosAdv, Element::Earth}}, - {{505, 0x3000}, {"Terrabite (Mini)", Game::TrapTeam, Element::Earth}}, - {{506, 0x0000}, {"Breeze (Mini)", Game::TrapTeam, Element::Air}}, - {{507, 0x0000}, {"Weeruptor (Mini)", Game::TrapTeam, Element::Fire}}, - {{507, 0x3402}, {"Eggcellent Weeruptor (Mini)", Game::TrapTeam, Element::Fire}}, - {{508, 0x0000}, {"Pet Vac (Mini)", Game::TrapTeam, Element::Air}}, - {{508, 0x3402}, {"Power Punch Pet Vac (Mini)", Game::TrapTeam, Element::Air}}, - {{509, 0x0000}, {"Small Fry (Mini)", Game::TrapTeam, Element::Fire}}, - {{510, 0x0000}, {"Drobit (Mini)", Game::TrapTeam, Element::Tech}}, - {{514, 0x0000}, {"Gill Runt (Sidekick)", Game::SpyrosAdv, Element::Water}}, - {{514, 0x3000}, {"Gill Runt (Mini)", Game::TrapTeam, Element::Water}}, - {{519, 0x0000}, {"Trigger Snappy (Sidekick)", Game::SpyrosAdv, Element::Tech}}, - {{519, 0x3000}, {"Trigger Snappy (Mini)", Game::TrapTeam, Element::Tech}}, - {{526, 0x0000}, {"Whisper Elf (Sidekick)", Game::SpyrosAdv, Element::Life}}, - {{526, 0x3000}, {"Whisper Elf (Mini)", Game::TrapTeam, Element::Life}}, - {{540, 0x0000}, {"Barkley (Sidekick)", Game::Giants, Element::Life}}, - {{540, 0x3000}, {"Barkley (Mini)", Game::TrapTeam, Element::Life}}, - {{540, 0x3402}, {"Gnarly Barkley (Mini)", Game::TrapTeam, Element::Life}}, - {{541, 0x0000}, {"Thumpling (Sidekick)", Game::Giants, Element::Water}}, - {{541, 0x3000}, {"Thumpling (Mini)", Game::TrapTeam, Element::Water}}, - {{542, 0x0000}, {"Mini-Jini (Sidekick)", Game::Giants, Element::Magic}}, - {{542, 0x3000}, {"Mini-Jini (Mini)", Game::TrapTeam, Element::Magic}}, - {{543, 0x0000}, {"Eye Small (Sidekick)", Game::Giants, Element::Undead}}, - {{543, 0x3000}, {"Eye Small (Mini)", Game::TrapTeam, Element::Undead}}, - {{1000, 0x0000}, {"Boom Jet (Bottom)", Game::SwapForce, Element::Air}}, - {{1001, 0x0000}, {"Free Ranger (Bottom)", Game::SwapForce, Element::Air}}, - {{1001, 0x2403}, {"Legendary Free Ranger (Bottom)", Game::SwapForce, Element::Air}}, - {{1002, 0x0000}, {"Rubble Rouser (Bottom)", Game::SwapForce, Element::Earth}}, - {{1003, 0x0000}, {"Doom Stone (Bottom)", Game::SwapForce, Element::Earth}}, - {{1004, 0x0000}, {"Blast Zone (Bottom)", Game::SwapForce, Element::Fire}}, - {{1004, 0x2402}, {"Dark Blast Zone (Bottom)", Game::SwapForce, Element::Fire}}, - {{1005, 0x0000}, {"Fire Kraken (Bottom)", Game::SwapForce, Element::Fire}}, - {{1005, 0x2402}, {"Jade Fire Kraken (Bottom)", Game::SwapForce, Element::Fire}}, - {{1006, 0x0000}, {"Stink Bomb (Bottom)", Game::SwapForce, Element::Life}}, - {{1007, 0x0000}, {"Grilla Drilla (Bottom)", Game::SwapForce, Element::Life}}, - {{1008, 0x0000}, {"Hoot Loop (Bottom)", Game::SwapForce, Element::Magic}}, - {{1008, 0x2402}, {"Enchanted Hoot Loop (Bottom)", Game::SwapForce, Element::Magic}}, - {{1009, 0x0000}, {"Trap Shadow (Bottom)", Game::SwapForce, Element::Magic}}, - {{1010, 0x0000}, {"Magna Charge (Bottom)", Game::SwapForce, Element::Tech}}, - {{1010, 0x2402}, {"Nitro Magna Charge (Bottom)", Game::SwapForce, Element::Tech}}, - {{1011, 0x0000}, {"Spy Rise (Bottom)", Game::SwapForce, Element::Tech}}, - {{1012, 0x0000}, {"Night Shift (Bottom)", Game::SwapForce, Element::Undead}}, - {{1012, 0x2403}, {"Legendary Night Shift (Bottom)", Game::SwapForce, Element::Undead}}, - {{1013, 0x0000}, {"Rattle Shake (Bottom)", Game::SwapForce, Element::Undead}}, - {{1013, 0x2402}, {"Quick Draw Rattle Shake (Bottom)", Game::SwapForce, Element::Undead}}, - {{1014, 0x0000}, {"Freeze Blade (Bottom)", Game::SwapForce, Element::Water}}, - {{1014, 0x2402}, {"Nitro Freeze Blade (Bottom)", Game::SwapForce, Element::Water}}, - {{1015, 0x0000}, {"Wash Buckler (Bottom)", Game::SwapForce, Element::Water}}, - {{1015, 0x2402}, {"Dark Wash Buckler (Bottom)", Game::SwapForce, Element::Water}}, - {{2000, 0x0000}, {"Boom Jet (Top)", Game::SwapForce, Element::Air}}, - {{2001, 0x0000}, {"Free Ranger (Top)", Game::SwapForce, Element::Air}}, - {{2001, 0x2403}, {"Legendary Free Ranger (Top)", Game::SwapForce, Element::Air}}, - {{2002, 0x0000}, {"Rubble Rouser (Top)", Game::SwapForce, Element::Earth}}, - {{2003, 0x0000}, {"Doom Stone (Top)", Game::SwapForce, Element::Earth}}, - {{2004, 0x0000}, {"Blast Zone (Top)", Game::SwapForce, Element::Fire}}, - {{2004, 0x2402}, {"Dark Blast Zone (Top)", Game::SwapForce, Element::Fire}}, - {{2005, 0x0000}, {"Fire Kraken (Top)", Game::SwapForce, Element::Fire}}, - {{2005, 0x2402}, {"Jade Fire Kraken (Top)", Game::SwapForce, Element::Fire}}, - {{2006, 0x0000}, {"Stink Bomb (Top)", Game::SwapForce, Element::Life}}, - {{2007, 0x0000}, {"Grilla Drilla (Top)", Game::SwapForce, Element::Life}}, - {{2008, 0x0000}, {"Hoot Loop (Top)", Game::SwapForce, Element::Magic}}, - {{2008, 0x2402}, {"Enchanted Hoot Loop (Top)", Game::SwapForce, Element::Magic}}, - {{2009, 0x0000}, {"Trap Shadow (Top)", Game::SwapForce, Element::Magic}}, - {{2010, 0x0000}, {"Magna Charge (Top)", Game::SwapForce, Element::Tech}}, - {{2010, 0x2402}, {"Nitro Magna Charge (Top)", Game::SwapForce, Element::Tech}}, - {{2011, 0x0000}, {"Spy Rise (Top)", Game::SwapForce, Element::Tech}}, - {{2012, 0x0000}, {"Night Shift (Top)", Game::SwapForce, Element::Undead}}, - {{2012, 0x2403}, {"Legendary Night Shift (Top)", Game::SwapForce, Element::Undead}}, - {{2013, 0x0000}, {"Rattle Shake (Top)", Game::SwapForce, Element::Undead}}, - {{2013, 0x2402}, {"Quick Draw Rattle Shake (Top)", Game::SwapForce, Element::Undead}}, - {{2014, 0x0000}, {"Freeze Blade (Top)", Game::SwapForce, Element::Water}}, - {{2014, 0x2402}, {"Nitro Freeze Blade (Top)", Game::SwapForce, Element::Water}}, - {{2015, 0x0000}, {"Wash Buckler (Top)", Game::SwapForce, Element::Water}}, - {{2015, 0x2402}, {"Dark Wash Buckler (Top)", Game::SwapForce, Element::Water}}, - {{3000, 0x0000}, {"Scratch", Game::SwapForce, Element::Air}}, - {{3001, 0x0000}, {"Pop Thorn", Game::SwapForce, Element::Air}}, - {{3002, 0x0000}, {"Slobber Tooth", Game::SwapForce, Element::Earth}}, - {{3002, 0x2402}, {"Dark Slobber Tooth", Game::SwapForce, Element::Earth}}, - {{3003, 0x0000}, {"Scorp", Game::SwapForce, Element::Earth}}, - {{3004, 0x0000}, {"Fryno", Game::SwapForce, Element::Fire}}, - {{3004, 0x3805}, {"Hog Wild Fryno", Game::SwapForce, Element::Fire}}, - {{3005, 0x0000}, {"Smolderdash", Game::SwapForce, Element::Fire}}, - {{3005, 0x2206}, {"LightCore Smolderdash", Game::SwapForce, Element::Fire}}, - {{3006, 0x0000}, {"Bumble Blast", Game::SwapForce, Element::Life}}, - {{3006, 0x2206}, {"LightCore Bumble Blast", Game::SwapForce, Element::Life}}, - {{3006, 0x2402}, {"Jolly Bumble Blast", Game::SwapForce, Element::Life}}, - {{3007, 0x0000}, {"Zoo Lou", Game::SwapForce, Element::Life}}, - {{3007, 0x2403}, {"Legendary Zoo Lou", Game::SwapForce, Element::Life}}, - {{3008, 0x0000}, {"Dune Bug", Game::SwapForce, Element::Magic}}, - {{3009, 0x0000}, {"Star Strike", Game::SwapForce, Element::Magic}}, - {{3009, 0x2206}, {"LightCore Star Strike", Game::SwapForce, Element::Magic}}, - {{3009, 0x2602}, {"Enchanted Star Strike", Game::SwapForce, Element::Magic}}, - {{3010, 0x0000}, {"Countdown", Game::SwapForce, Element::Tech}}, - {{3010, 0x2206}, {"LightCore Countdown", Game::SwapForce, Element::Tech}}, - {{3010, 0x2402}, {"Kickoff Countdown", Game::SwapForce, Element::Tech}}, - {{3011, 0x0000}, {"Wind Up", Game::SwapForce, Element::Tech}}, - {{3011, 0x2404}, {"Gear Head VVind Up", Game::SwapForce, Element::Tech}}, - {{3012, 0x0000}, {"Roller Brawl", Game::SwapForce, Element::Undead}}, - {{3013, 0x0000}, {"Grim Creeper", Game::SwapForce, Element::Undead}}, - {{3013, 0x2206}, {"LightCore Grim Creeper", Game::SwapForce, Element::Undead}}, - {{3013, 0x2603}, {"Legendary Grim Creeper", Game::SwapForce, Element::Undead}}, - {{3014, 0x0000}, {"Rip Tide", Game::SwapForce, Element::Water}}, - {{3015, 0x0000}, {"Punk Shock", Game::SwapForce, Element::Water}}, - {{3200, 0x0000}, {"Battle Hammer", Game::SwapForce}}, - {{3201, 0x0000}, {"Sky Diamond", Game::SwapForce}}, - {{3202, 0x0000}, {"Platinum Sheep", Game::SwapForce}}, - {{3203, 0x0000}, {"Groove Machine", Game::SwapForce}}, - {{3204, 0x0000}, {"UFO Hat", Game::SwapForce}}, - {{3220, 0x0000}, {"Jet Stream", Game::Superchargers, Element::Air}}, - {{3221, 0x0000}, {"Tomb Buggy", Game::Superchargers, Element::Undead}}, - {{3222, 0x0000}, {"Reef Ripper", Game::Superchargers, Element::Water}}, - {{3223, 0x0000}, {"Burn Cycle", Game::Superchargers, Element::Fire}}, - {{3224, 0x0000}, {"Hot Streak", Game::Superchargers, Element::Fire}}, - {{3224, 0x4004}, {"E3 Hot Streak", Game::Superchargers, Element::Fire}}, - {{3224, 0x4402}, {"Dark Hot Streak", Game::Superchargers, Element::Fire}}, - {{3224, 0x441E}, {"Golden Hot Streak", Game::Superchargers, Element::Fire}}, - {{3225, 0x0000}, {"Shark Tank", Game::Superchargers, Element::Earth}}, - {{3226, 0x0000}, {"Thump Truck", Game::Superchargers, Element::Earth}}, - {{3227, 0x0000}, {"Crypt Crusher", Game::Superchargers, Element::Undead}}, - {{3228, 0x0000}, {"Stealth Stinger", Game::Superchargers, Element::Life}}, - {{3228, 0x4402}, {"Nitro Stealth Stinger", Game::Superchargers, Element::Life}}, - {{3231, 0x0000}, {"Dive Bomber", Game::Superchargers, Element::Water}}, - {{3231, 0x4402}, {"Spring Ahead Dive Bomber", Game::Superchargers, Element::Water}}, - {{3232, 0x0000}, {"Sky Slicer", Game::Superchargers, Element::Air}}, - {{3233, 0x0000}, {"Clown Cruiser", Game::Superchargers, Element::Air}}, - {{3233, 0x4402}, {"Dark Clown Cruiser", Game::Superchargers, Element::Air}}, - {{3234, 0x0000}, {"Gold Rusher", Game::Superchargers, Element::Tech}}, - {{3234, 0x4402}, {"Power Blue Gold Rusher", Game::Superchargers, Element::Tech}}, - {{3235, 0x0000}, {"Shield Striker", Game::Superchargers, Element::Tech}}, - {{3236, 0x0000}, {"Sun Runner", Game::Superchargers}}, - {{3236, 0x4403}, {"Legendary Sun Runner", Game::Superchargers}}, - {{3237, 0x0000}, {"Sea Shadow", Game::Superchargers}}, - {{3237, 0x4402}, {"Dark Sea Shadow", Game::Superchargers}}, - {{3238, 0x0000}, {"Splatter Splasher", Game::Superchargers, Element::Magic}}, - {{3238, 0x4402}, {"Power Blue Splatter Splasher", Game::Superchargers, Element::Magic}}, - {{3239, 0x0000}, {"Soda Skimmer", Game::Superchargers, Element::Magic}}, - {{3239, 0x4402}, {"Nitro Soda Skimmer", Game::Superchargers, Element::Magic}}, - {{3240, 0x0000}, {"Barrel Blaster", Game::Superchargers, Element::Tech}}, - {{3240, 0x4402}, {"Dark Barrel Blaster", Game::Superchargers, Element::Tech}}, - {{3241, 0x0000}, {"Buzz Wing", Game::Superchargers, Element::Life}}, - {{3300, 0x0000}, {"Sheep Wreck Island", Game::SwapForce}}, - {{3301, 0x0000}, {"Tower of Time", Game::SwapForce}}, - {{3302, 0x0000}, {"Fiery Forge", Game::SwapForce}}, - {{3303, 0x0000}, {"Arkeyan Crossbow", Game::SwapForce}}, - {{3400, 0x0000}, {"Fiesta", Game::Superchargers, Element::Undead}}, - {{3400, 0x4515}, {"Frightful Fiesta", Game::Superchargers, Element::Undead}}, - {{3401, 0x0000}, {"High Volt", Game::Superchargers, Element::Tech}}, - {{3402, 0x0000}, {"Splat", Game::Superchargers, Element::Magic}}, - {{3402, 0x4502}, {"Power Blue Splat", Game::Superchargers, Element::Magic}}, - {{3406, 0x0000}, {"Stormblade", Game::Superchargers, Element::Air}}, - {{3406, 0x4502}, {"Dark Stormblade", Game::Superchargers, Element::Air}}, - {{3411, 0x0000}, {"Smash Hit", Game::Superchargers, Element::Earth}}, - {{3411, 0x4502}, {"Steel Plated Smash Hit", Game::Superchargers, Element::Earth}}, - {{3412, 0x0000}, {"Spitfire", Game::Superchargers, Element::Fire}}, - {{3412, 0x4502}, {"Dark Spitfire", Game::Superchargers, Element::Fire}}, - {{3413, 0x0000}, {"Hurricane Jet Vac", Game::Superchargers, Element::Air}}, - {{3413, 0x4503}, {"Legendary Hurricane Jet Vac", Game::Superchargers, Element::Air}}, - {{3414, 0x0000}, {"Double Dare Trigger Happy", Game::Superchargers, Element::Tech}}, - {{3414, 0x4502}, {"Power Blue Double Dare Trigger Happy", Game::Superchargers, Element::Tech}}, - {{3415, 0x0000}, {"Super Shot Stealth Elf", Game::Superchargers, Element::Life}}, - {{3415, 0x4502}, {"Dark Super Shot Stealth Elf", Game::Superchargers, Element::Life}}, - {{3416, 0x0000}, {"Shark Shooter Terrafin", Game::Superchargers, Element::Earth}}, - {{3417, 0x0000}, {"Bone Bash Roller Brawl", Game::Superchargers, Element::Undead}}, - {{3417, 0x4503}, {"Legendary Bone Bash Roller Brawl", Game::Superchargers, Element::Undead}}, - {{3420, 0x0000}, {"Big Bubble Pop Fizz", Game::Superchargers, Element::Magic}}, - {{3420, 0x450E}, {"Birthday Bash Big Bubble Pop Fizz", Game::Superchargers, Element::Magic}}, - {{3421, 0x0000}, {"Lava Lance Eruptor", Game::Superchargers, Element::Fire}}, - {{3422, 0x0000}, {"Deep Dive Gill Grunt", Game::Superchargers, Element::Water}}, - {{3423, 0x0000}, {"Turbo Charge Donkey Kong", Game::Superchargers, Element::Life}}, - {{3423, 0x4502}, {"Dark Turbo Charge Donkey Kong", Game::Superchargers, Element::Life}}, - {{3424, 0x0000}, {"Hammer Slam Bowser", Game::Superchargers, Element::Fire}}, - {{3424, 0x4502}, {"Dark Hammer Slam Bowser", Game::Superchargers, Element::Fire}}, - {{3425, 0x0000}, {"Dive-Clops", Game::Superchargers, Element::Water}}, - {{3425, 0x450E}, {"Missile-Tow Dive-Clops", Game::Superchargers, Element::Water}}, - {{3426, 0x0000}, {"Astroblast", Game::Superchargers}}, - {{3426, 0x4503}, {"Legendary Astroblast", Game::Superchargers}}, - {{3427, 0x0000}, {"Nightfall", Game::Superchargers}}, - {{3428, 0x0000}, {"Thrillipede", Game::Superchargers, Element::Life}}, - {{3428, 0x450D}, {"Eggcited Thrillipede", Game::Superchargers, Element::Life}}, - {{3500, 0x0000}, {"Sky Trophy", Game::Superchargers}}, - {{3501, 0x0000}, {"Land Trophy", Game::Superchargers}}, - {{3502, 0x0000}, {"Sea Trophy", Game::Superchargers}}, - {{3503, 0x0000}, {"Kaos Trophy", Game::Superchargers}}}; + {{0, 0x0000}, {"Whirlwind", Game::SpyrosAdv, Element::Air, Type::Skylander}}, + {{0, 0x1801}, {"Whirlwind (S2)", Game::Giants, Element::Air, Type::Skylander}}, + {{0, 0x1C02}, {"Whirlwind (Polar)", Game::Giants, Element::Air, Type::Skylander}}, + {{0, 0x2805}, {"Whirlwind (Horn Blast)", Game::SwapForce, Element::Air, Type::Skylander}}, + {{0, 0x3810}, {"Whirlwind (Eon's Elite)", Game::TrapTeam, Element::Air, Type::Skylander}}, + {{1, 0x0000}, {"Sonic Boom", Game::SpyrosAdv, Element::Air, Type::Skylander}}, + {{1, 0x1801}, {"Sonic Boom (S2)", Game::Giants, Element::Air, Type::Skylander}}, + {{1, 0x1811}, {"Sonic Boom (Glow In The Dark)", Game::Giants, Element::Air, Type::Skylander}}, + {{1, 0x1813}, {"Sonic Boom (Sparkle)", Game::Giants, Element::Air, Type::Skylander}}, + {{2, 0x0000}, {"Warnado", Game::SpyrosAdv, Element::Air, Type::Skylander}}, + {{2, 0x2206}, {"Warnado (Lightcore)", Game::SwapForce, Element::Air, Type::Skylander}}, + {{3, 0x0000}, {"Lightning Rod", Game::SpyrosAdv, Element::Air, Type::Skylander}}, + {{3, 0x1801}, {"Lightning Rod (S2)", Game::Giants, Element::Air, Type::Skylander}}, + {{4, 0x0000}, {"Bash", Game::SpyrosAdv, Element::Earth, Type::Skylander}}, + {{4, 0x1801}, {"Bash (S2)", Game::Giants, Element::Earth, Type::Skylander}}, + {{5, 0x0000}, {"Terrafin", Game::SpyrosAdv, Element::Earth, Type::Skylander}}, + {{5, 0x1801}, {"Terrafin (S2)", Game::Giants, Element::Earth, Type::Skylander}}, + {{5, 0x2805}, {"Terrafin (Knockout)", Game::SwapForce, Element::Earth, Type::Skylander}}, + {{5, 0x3810}, {"Terrafin (Eon's Elite)", Game::TrapTeam, Element::Earth, Type::Skylander}}, + {{6, 0x0000}, {"Dino-Rang", Game::SpyrosAdv, Element::Earth, Type::Skylander}}, + {{6, 0x4810}, + {"Dino-Rang (Eon's Elite)", Game::Superchargers, Element::Earth, Type::Skylander}}, + {{7, 0x0000}, {"Prism Break", Game::SpyrosAdv, Element::Earth, Type::Skylander}}, + {{7, 0x1206}, {"Prism Break (Lightcore)", Game::Giants, Element::Earth, Type::Skylander}}, + {{7, 0x1801}, {"Prism Break (S2)", Game::Giants, Element::Earth, Type::Skylander}}, + {{7, 0x2805}, {"Prism Break (Hyper Beam)", Game::SwapForce, Element::Earth, Type::Skylander}}, + {{8, 0x0000}, {"Sunburn", Game::SpyrosAdv, Element::Fire, Type::Skylander}}, + {{9, 0x0000}, {"Eruptor", Game::SpyrosAdv, Element::Fire, Type::Skylander}}, + {{9, 0x1206}, {"Eruptor (Lightcore)", Game::Giants, Element::Fire, Type::Skylander}}, + {{9, 0x1801}, {"Eruptor (S2)", Game::Giants, Element::Fire, Type::Skylander}}, + {{9, 0x2805}, {"Eruptor (Lava Barf)", Game::SwapForce, Element::Fire, Type::Skylander}}, + {{9, 0x2C02}, {"Eruptor (Volcanic)", Game::SwapForce, Element::Fire, Type::Skylander}}, + {{9, 0x3810}, {"Eruptor (Eon's Elite)", Game::TrapTeam, Element::Fire, Type::Skylander}}, + {{10, 0x0000}, {"Ignitor", Game::SpyrosAdv, Element::Fire, Type::Skylander}}, + {{10, 0x1801}, {"Ignitor (S2)", Game::Giants, Element::Fire, Type::Skylander}}, + {{10, 0x1C03}, {"Ignitor (Legendary)", Game::Giants, Element::Fire, Type::Skylander}}, + {{11, 0x0000}, {"Flameslinger", Game::SpyrosAdv, Element::Fire, Type::Skylander}}, + {{11, 0x1801}, {"Flameslinger (S2)", Game::Giants, Element::Fire, Type::Skylander}}, + {{11, 0x1802}, {"Flameslinger (Golden)", Game::Giants, Element::Fire, Type::Skylander}}, + {{12, 0x0000}, {"Zap", Game::SpyrosAdv, Element::Water, Type::Skylander}}, + {{12, 0x1801}, {"Zap (S2)", Game::Giants, Element::Water, Type::Skylander}}, + {{13, 0x0000}, {"Wham-Shell", Game::SpyrosAdv, Element::Water, Type::Skylander}}, + {{13, 0x2206}, {"Wham-Shell (Lightcore)", Game::SwapForce, Element::Water, Type::Skylander}}, + {{14, 0x0000}, {"Gill Grunt", Game::SpyrosAdv, Element::Water, Type::Skylander}}, + {{14, 0x1801}, {"Gill Grunt (S2)", Game::Giants, Element::Water, Type::Skylander}}, + {{14, 0x1817}, {"Gill Grunt (Metallic)", Game::Giants, Element::Water, Type::Skylander}}, + {{14, 0x2805}, {"Gill Grunt (Anchors Away)", Game::SwapForce, Element::Water, Type::Skylander}}, + {{14, 0x3809}, {"Gill Grunt (Tidal Wave)", Game::TrapTeam, Element::Water, Type::Skylander}}, + {{14, 0x3810}, {"Gill Grunt (Eon's Elite)", Game::TrapTeam, Element::Water, Type::Skylander}}, + {{15, 0x0000}, {"Slam Bam", Game::SpyrosAdv, Element::Water, Type::Skylander}}, + {{15, 0x1801}, {"Slam Bam (S2)", Game::Giants, Element::Water, Type::Skylander}}, + {{15, 0x1C03}, {"Slam Bam (Legendary)", Game::Giants, Element::Water, Type::Skylander}}, + {{15, 0x3810}, + {"Slam Bam (Eon's Elite)", Game::Superchargers, Element::Water, Type::Skylander}}, + {{16, 0x0000}, {"Spyro", Game::SpyrosAdv, Element::Magic, Type::Skylander}}, + {{16, 0x1801}, {"Spyro (S2)", Game::Giants, Element::Magic, Type::Skylander}}, + {{16, 0x2805}, {"Spyro (Mega Ram)", Game::SwapForce, Element::Magic, Type::Skylander}}, + {{16, 0x2C02}, {"Spyro (Dark Mega Ram)", Game::SwapForce, Element::Magic, Type::Skylander}}, + {{16, 0x3810}, {"Spyro (Eon's Elite)", Game::TrapTeam, Element::Magic, Type::Skylander}}, + {{17, 0x0000}, {"Voodood", Game::SpyrosAdv, Element::Magic, Type::Skylander}}, + {{17, 0x3810}, {"Voodood (Eon's Elite)", Game::Superchargers, Element::Magic, Type::Skylander}}, + {{18, 0x0000}, {"Double Trouble", Game::SpyrosAdv, Element::Magic, Type::Skylander}}, + {{18, 0x1801}, {"Double Trouble (S2)", Game::Giants, Element::Magic, Type::Skylander}}, + {{18, 0x1C02}, {"Double Trouble (Royal)", Game::Giants, Element::Magic, Type::Skylander}}, + {{19, 0x0000}, {"Trigger Happy", Game::SpyrosAdv, Element::Tech, Type::Skylander}}, + {{19, 0x1801}, {"Trigger Happy (S2)", Game::Giants, Element::Tech, Type::Skylander}}, + {{19, 0x2805}, {"Trigger Happy (Big Bang)", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{19, 0x2C02}, {"Trigger Happy (Springtime)", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{19, 0x3810}, {"Trigger Happy (Eon's Elite)", Game::TrapTeam, Element::Tech, Type::Skylander}}, + {{20, 0x0000}, {"Drobot", Game::SpyrosAdv, Element::Tech, Type::Skylander}}, + {{20, 0x1206}, {"Drobot (Lightcore)", Game::Giants, Element::Tech, Type::Skylander}}, + {{20, 0x1801}, {"Drobot (S2)", Game::Giants, Element::Tech, Type::Skylander}}, + {{21, 0x0000}, {"Drill Sergeant", Game::SpyrosAdv, Element::Tech, Type::Skylander}}, + {{21, 0x1801}, {"Drill Sergeant (S2)", Game::Giants, Element::Tech, Type::Skylander}}, + {{22, 0x0000}, {"Boomer", Game::SpyrosAdv, Element::Tech, Type::Skylander}}, + {{22, 0x4810}, {"Boomer (Eon's Elite)", Game::Superchargers, Element::Tech, Type::Skylander}}, + {{23, 0x0000}, {"Wrecking Ball", Game::SpyrosAdv, Element::Magic, Type::Skylander}}, + {{23, 0x1801}, {"Wrecking Ball (S2)", Game::Giants, Element::Magic, Type::Skylander}}, + {{24, 0x0000}, {"Camo", Game::SpyrosAdv, Element::Life, Type::Skylander}}, + {{24, 0x2805}, {"Camo (Thorn Horn)", Game::SwapForce, Element::Life, Type::Skylander}}, + {{25, 0x0000}, {"Zook", Game::SpyrosAdv, Element::Life, Type::Skylander}}, + {{25, 0x1801}, {"Zook (S2)", Game::Giants, Element::Life, Type::Skylander}}, + {{25, 0x3810}, {"Zook (Eon's Elite)", Game::Superchargers, Element::Life, Type::Skylander}}, + {{26, 0x0000}, {"Stealth Elf", Game::SpyrosAdv, Element::Life, Type::Skylander}}, + {{26, 0x1801}, {"Stealth Elf (S2)", Game::Giants, Element::Life, Type::Skylander}}, + {{26, 0x1C03}, {"Stealth Elf (Legendary)", Game::Giants, Element::Life, Type::Skylander}}, + {{26, 0x2805}, {"Stealth Elf (Ninja)", Game::SwapForce, Element::Life, Type::Skylander}}, + {{26, 0x2C02}, {"Stealth Elf (Dark)", Game::SwapForce, Element::Life, Type::Skylander}}, + {{26, 0x3810}, {"Stealth Elf (Eon's Elite)", Game::TrapTeam, Element::Life, Type::Skylander}}, + {{27, 0x0000}, {"Stump Smash", Game::SpyrosAdv, Element::Life, Type::Skylander}}, + {{27, 0x1801}, {"Stump Smash (S2)", Game::Giants, Element::Life, Type::Skylander}}, + {{28, 0x0000}, {"Spyro (Dark)", Game::SpyrosAdv, Element::Magic, Type::Skylander}}, + {{29, 0x0000}, {"Hex", Game::SpyrosAdv, Element::Undead, Type::Skylander}}, + {{29, 0x1206}, {"Hex (Lightcore)", Game::Giants, Element::Undead, Type::Skylander}}, + {{29, 0x1801}, {"Hex (S2)", Game::Giants, Element::Undead, Type::Skylander}}, + {{30, 0x0000}, {"Chop Chop", Game::SpyrosAdv, Element::Undead, Type::Skylander}}, + {{30, 0x1801}, {"Chop Chop (S2)", Game::Giants, Element::Undead, Type::Skylander}}, + {{30, 0x2805}, {"Chop Chop (Twin Blade)", Game::SwapForce, Element::Undead, Type::Skylander}}, + {{30, 0x2816}, + {"Chop Chop (Green Twin Blade)", Game::SwapForce, Element::Undead, Type::Skylander}}, + {{30, 0x3810}, {"Chop Chop (Eon's Elite)", Game::TrapTeam, Element::Undead, Type::Skylander}}, + {{31, 0x0000}, {"Ghost Roaster", Game::SpyrosAdv, Element::Undead, Type::Skylander}}, + {{31, 0x4810}, + {"Ghost Roaster (Eon's Elite)", Game::Superchargers, Element::Undead, Type::Skylander}}, + {{32, 0x0000}, {"Cynder", Game::SpyrosAdv, Element::Undead, Type::Skylander}}, + {{32, 0x1801}, {"Cynder (S2)", Game::Giants, Element::Undead, Type::Skylander}}, + {{32, 0x1811}, {"Cynder (Glow In The Dark)", Game::Giants, Element::Undead, Type::Skylander}}, + {{32, 0x2805}, {"Cynder (Phantom)", Game::SwapForce, Element::Undead, Type::Skylander}}, + {{32, 0x301D}, {"Cynder (Clear)", Game::SpyrosAdv, Element::Undead, Type::Skylander}}, + {{100, 0x1000}, {"Jet-Vac", Game::Giants, Element::Air, Type::Skylander}}, + {{100, 0x1206}, {"Jet-Vac (Lightcore)", Game::Giants, Element::Air, Type::Skylander}}, + {{100, 0x1403}, {"Jet-Vac (Legendary)", Game::Giants, Element::Air, Type::Skylander}}, + {{100, 0x2805}, {"Jet Vac (Turbo)", Game::SwapForce, Element::Air, Type::Skylander}}, + {{100, 0x3805}, {"Jet-Vac (Full Blast)", Game::TrapTeam, Element::Air, Type::Skylander}}, + {{101, 0x1206}, {"Swarm", Game::Giants, Element::Air, Type::Giant}}, + {{102, 0x1206}, {"Crusher", Game::Giants, Element::Earth, Type::Giant}}, + {{102, 0x1602}, {"Crusher (Granite)", Game::Giants, Element::Earth, Type::Giant}}, + {{103, 0x1000}, {"Flashwing", Game::Giants, Element::Earth, Type::Skylander}}, + {{103, 0x1402}, {"Flashwing (Jade)", Game::Giants, Element::Earth, Type::Skylander}}, + {{103, 0x2206}, {"Flashwing (Lightcore)", Game::SwapForce, Element::Earth, Type::Skylander}}, + {{104, 0x1206}, {"Hot Head", Game::Giants, Element::Fire, Type::Giant}}, + {{104, 0x1213}, {"Hot Head (Sparkle)", Game::Giants, Element::Fire, Type::Skylander}}, + {{105, 0x1000}, {"Hot Dog", Game::Giants, Element::Fire, Type::Skylander}}, + {{105, 0x1402}, {"Hot Dog (Molten)", Game::Giants, Element::Fire, Type::Skylander}}, + {{105, 0x2805}, {"Hot Dog (Fire Bone)", Game::SwapForce, Element::Fire, Type::Skylander}}, + {{106, 0x1000}, {"Chill", Game::Giants, Element::Water, Type::Skylander}}, + {{106, 0x1206}, {"Chill (Lightcore)", Game::Giants, Element::Water, Type::Skylander}}, + {{106, 0x1603}, {"Chill (Legendary)", Game::Giants, Element::Water, Type::Skylander}}, + {{106, 0x2805}, {"Chill (Blizzard)", Game::SwapForce, Element::Water, Type::Skylander}}, + {{107, 0x1206}, {"Thumpback", Game::Giants, Element::Water, Type::Giant}}, + {{108, 0x1000}, {"Pop Fizz", Game::Giants, Element::Magic, Type::Skylander}}, + {{108, 0x1206}, {"Pop Fizz (Lightcore)", Game::Giants, Element::Magic, Type::Skylander}}, + {{108, 0x1402}, {"Pop Fizz (Punch)", Game::Giants, Element::Magic, Type::Skylander}}, + {{108, 0x2805}, {"Pop Fizz (Super Gulp)", Game::SwapForce, Element::Magic, Type::Skylander}}, + {{108, 0x3805}, {"Pop Fizz (Fizzy Frenzy)", Game::TrapTeam, Element::Magic, Type::Skylander}}, + {{108, 0x3C02}, {"Pop Fizz (Love Potion)", Game::TrapTeam, Element::Magic, Type::Skylander}}, + {{109, 0x1206}, {"Ninjini", Game::Giants, Element::Magic, Type::Giant}}, + {{109, 0x1602}, {"Ninjini (Scarlet)", Game::Giants, Element::Magic, Type::Giant}}, + {{110, 0x1206}, {"Bouncer", Game::Giants, Element::Tech, Type::Giant}}, + {{110, 0x1603}, {"Bouncer (Legendary)", Game::Giants, Element::Tech, Type::Giant}}, + {{111, 0x1000}, {"Sprocket", Game::Giants, Element::Tech, Type::Skylander}}, + {{111, 0x2805}, {"Sprocket (Heavy Duty)", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{111, 0x2819}, {"Sprocket (Heavy Metal)", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{112, 0x1206}, {"Tree Rex", Game::Giants, Element::Life, Type::Giant}}, + {{112, 0x1602}, {"Tree Rex (Gnarly)", Game::Giants, Element::Life, Type::Giant}}, + {{113, 0x1000}, {"Shroomboom", Game::Giants, Element::Life, Type::Skylander}}, + {{113, 0x1206}, {"Shroomboom (Lightcore)", Game::Giants, Element::Life, Type::Skylander}}, + {{113, 0x3801}, {"Shroomboom (Sure Shot)", Game::TrapTeam, Element::Life, Type::Skylander}}, + {{114, 0x1206}, {"Eye-Brawl", Game::Giants, Element::Undead, Type::Giant}}, + {{114, 0x1215}, {"Eye-Brawl (Pumpkin)", Game::Giants, Element::Undead, Type::Giant}}, + {{115, 0x1000}, {"Fright Rider", Game::Giants, Element::Undead, Type::Skylander}}, + {{115, 0x1011}, {"Fright Rider (Halloween)", Game::Giants, Element::Undead, Type::Skylander}}, + {{115, 0x1811}, + {"Fright Rider (Glow In The Dark)", Game::Giants, Element::Undead, Type::Skylander}}, + {{404, 0x0000}, {"Bash (Legendary)", Game::SpyrosAdv, Element::Earth, Type::Skylander}}, + {{416, 0x0000}, {"Spyro (Legendary)", Game::SpyrosAdv, Element::Magic, Type::Skylander}}, + {{419, 0x0000}, {"Trigger Happy (Legendary)", Game::SpyrosAdv, Element::Tech, Type::Skylander}}, + {{430, 0x0000}, {"Chop Chop (Legendary)", Game::SpyrosAdv, Element::Undead, Type::Skylander}}, + {{450, 0x3000}, {"Gusto", Game::TrapTeam, Element::Air, Type::TrapMaster}}, + {{451, 0x3000}, {"Thunderbolt", Game::TrapTeam, Element::Air, Type::TrapMaster}}, + {{451, 0x301D}, {"Thunderbolt (Clear)", Game::TrapTeam, Element::Air, Type::TrapMaster}}, + {{452, 0x3000}, {"Fling Kong", Game::TrapTeam, Element::Air, Type::Skylander}}, + {{453, 0x3000}, {"Blades", Game::TrapTeam, Element::Air, Type::Skylander}}, + {{453, 0x3403}, {"Blades (Legendary)", Game::TrapTeam, Element::Air, Type::Skylander}}, + {{454, 0x3000}, {"Wallop", Game::TrapTeam, Element::Earth, Type::TrapMaster}}, + {{455, 0x3000}, {"Head Rush", Game::TrapTeam, Element::Earth, Type::TrapMaster}}, + {{455, 0x3402}, {"Head Rush (Nitro)", Game::TrapTeam, Element::Earth, Type::Skylander}}, + {{456, 0x3000}, {"Fist Bump", Game::TrapTeam, Element::Earth, Type::Skylander}}, + {{457, 0x3000}, {"Rocky Roll", Game::TrapTeam, Element::Earth, Type::Skylander}}, + {{458, 0x3000}, {"Wildfire", Game::TrapTeam, Element::Fire, Type::TrapMaster}}, + {{458, 0x3402}, {"Wildfire (Dark)", Game::TrapTeam, Element::Fire, Type::TrapMaster}}, + {{459, 0x3000}, {"Kaboom", Game::TrapTeam, Element::Fire, Type::TrapMaster}}, + {{460, 0x3000}, {"Trail Blazer", Game::TrapTeam, Element::Fire, Type::Skylander}}, + {{461, 0x3000}, {"Torch", Game::TrapTeam, Element::Fire, Type::Skylander}}, + {{462, 0x3000}, {"Snap Shot", Game::TrapTeam, Element::Water, Type::TrapMaster}}, + {{462, 0x450F}, {"Snap Shot (Virtual)", Game::TrapTeam, Element::Water, Type::TrapMaster}}, + {{462, 0x3402}, {"Snap Shot (Dark)", Game::TrapTeam, Element::Water, Type::TrapMaster}}, + {{463, 0x3000}, {"Lob Star", Game::TrapTeam, Element::Water, Type::TrapMaster}}, + {{463, 0x3402}, {"Lob Star (Winterfest)", Game::TrapTeam, Element::Water, Type::TrapMaster}}, + {{464, 0x3000}, {"Flip Wreck", Game::TrapTeam, Element::Water, Type::Skylander}}, + {{465, 0x3000}, {"Echo", Game::TrapTeam, Element::Water, Type::Skylander}}, + {{466, 0x3000}, {"Blastermind", Game::TrapTeam, Element::Magic, Type::TrapMaster}}, + {{467, 0x3000}, {"Enigma", Game::TrapTeam, Element::Magic, Type::TrapMaster}}, + {{468, 0x3000}, {"Deja Vu", Game::TrapTeam, Element::Magic, Type::Skylander}}, + {{468, 0x3403}, {"Deja Vu (Legendary)", Game::TrapTeam, Element::Magic, Type::Skylander}}, + {{469, 0x3000}, {"Cobra Cadabra", Game::TrapTeam, Element::Magic, Type::Skylander}}, + {{469, 0x3402}, {"Cobra Cadabra (King)", Game::TrapTeam, Element::Magic, Type::Skylander}}, + {{470, 0x3000}, {"Jawbreaker", Game::TrapTeam, Element::Tech, Type::TrapMaster}}, + {{470, 0x3403}, {"Jawbreaker (Legendary)", Game::TrapTeam, Element::Tech, Type::TrapMaster}}, + {{471, 0x3000}, {"Gearshift", Game::TrapTeam, Element::Tech, Type::TrapMaster}}, + {{472, 0x3000}, {"Chopper", Game::TrapTeam, Element::Tech, Type::Skylander}}, + {{473, 0x3000}, {"Tread Head", Game::TrapTeam, Element::Tech, Type::Skylander}}, + {{474, 0x3000}, {"Bushwhack", Game::TrapTeam, Element::Life, Type::TrapMaster}}, + {{474, 0x3403}, {"Bushwhack (Legendary)", Game::TrapTeam, Element::Life, Type::TrapMaster}}, + {{475, 0x3000}, {"Tuff Luck", Game::TrapTeam, Element::Life, Type::TrapMaster}}, + {{475, 0x301D}, {"Tuff Luck (Clear)", Game::TrapTeam, Element::Life, Type::TrapMaster}}, + {{476, 0x3000}, {"Food Fight", Game::TrapTeam, Element::Life, Type::Skylander}}, + {{476, 0x3402}, {"Food Fight (Dark)", Game::TrapTeam, Element::Life, Type::Skylander}}, + {{476, 0x450F}, {"Food Fight (Virtual)", Game::TrapTeam, Element::Life, Type::Skylander}}, + {{477, 0x3000}, {"High Five", Game::TrapTeam, Element::Life, Type::Skylander}}, + {{478, 0x3000}, {"Krypt King", Game::TrapTeam, Element::Undead, Type::TrapMaster}}, + {{478, 0x3402}, {"Krypt King (Nitro)", Game::TrapTeam, Element::Undead, Type::TrapMaster}}, + {{479, 0x3000}, {"Short Cut", Game::TrapTeam, Element::Undead, Type::TrapMaster}}, + {{480, 0x3000}, {"Bat Spin", Game::TrapTeam, Element::Undead, Type::Skylander}}, + {{481, 0x3000}, {"Funny Bone", Game::TrapTeam, Element::Undead, Type::Skylander}}, + {{482, 0x3000}, {"Knight Light", Game::TrapTeam, Element::Light, Type::TrapMaster}}, + {{483, 0x3000}, {"Spot Light", Game::TrapTeam, Element::Light, Type::Skylander}}, + {{484, 0x3000}, {"Knight Mare", Game::TrapTeam, Element::Dark, Type::TrapMaster}}, + {{485, 0x3000}, {"Blackout", Game::TrapTeam, Element::Dark, Type::Skylander}}, + {{502, 0x3000}, {"Bop", Game::TrapTeam, Element::Earth, Type::Mini}}, + {{503, 0x3000}, {"Spry", Game::TrapTeam, Element::Magic, Type::Mini}}, + {{504, 0x3000}, {"Hijinx", Game::TrapTeam, Element::Undead, Type::Mini}}, + {{505, 0x3000}, {"Terrabite", Game::TrapTeam, Element::Earth, Type::Mini}}, + {{506, 0x3000}, {"Breeze", Game::TrapTeam, Element::Air, Type::Mini}}, + {{507, 0x3000}, {"Weeruptor", Game::TrapTeam, Element::Fire, Type::Mini}}, + {{507, 0x3402}, {"Weeruptor (Eggsellent)", Game::TrapTeam, Element::Fire, Type::Mini}}, + {{508, 0x3000}, {"Pet Vac", Game::TrapTeam, Element::Air, Type::Mini}}, + {{508, 0x3402}, {"Pet Vac (Power Punch)", Game::TrapTeam, Element::Air, Type::Mini}}, + {{509, 0x3000}, {"Small Fry", Game::TrapTeam, Element::Fire, Type::Mini}}, + {{510, 0x3000}, {"Drobit", Game::TrapTeam, Element::Tech, Type::Mini}}, + {{514, 0x3000}, {"Gill Runt", Game::TrapTeam, Element::Water, Type::Mini}}, + {{519, 0x3000}, {"Trigger Snappy", Game::TrapTeam, Element::Tech, Type::Mini}}, + {{526, 0x3000}, {"Whisper Elf", Game::TrapTeam, Element::Life, Type::Mini}}, + {{540, 0x1000}, {"Barkley (Sidekick)", Game::Giants, Element::Life, Type::Mini}}, + {{540, 0x3000}, {"Barkley", Game::TrapTeam, Element::Life, Type::Mini}}, + {{540, 0x3402}, {"Barkley (Gnarly)", Game::TrapTeam, Element::Life, Type::Mini}}, + {{541, 0x1000}, {"Thumpling (Sidekick)", Game::Giants, Element::Water, Type::Mini}}, + {{541, 0x3000}, {"Thumpling", Game::TrapTeam, Element::Water, Type::Mini}}, + {{542, 0x1000}, {"Mini Jini (Sidekick)", Game::Giants, Element::Magic, Type::Mini}}, + {{542, 0x3000}, {"Mini Jini", Game::TrapTeam, Element::Magic, Type::Mini}}, + {{543, 0x1000}, {"Eye-Small (Sidekick)", Game::Giants, Element::Undead, Type::Mini}}, + {{543, 0x3000}, {"Eye-Small", Game::TrapTeam, Element::Undead, Type::Mini}}, + {{1000, 0x2000}, {"Boom Jet (Bottom)", Game::SwapForce, Element::Air, Type::Swapper}}, + {{1001, 0x2000}, {"Free Ranger (Bottom)", Game::SwapForce, Element::Air, Type::Swapper}}, + {{1001, 0x2403}, + {"Free Ranger (Legendary) (Bottom)", Game::SwapForce, Element::Air, Type::Swapper}}, + {{1002, 0x2000}, {"Rubble Rouser (Bottom)", Game::SwapForce, Element::Earth, Type::Swapper}}, + {{1003, 0x2000}, {"Doom Stone (Bottom)", Game::SwapForce, Element::Earth, Type::Swapper}}, + {{1004, 0x2000}, {"Blast Zone (Bottom)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{1004, 0x2402}, {"Blast Zone (Dark) (Bottom)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{1005, 0x2000}, {"Fire Kraken (Bottom)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{1005, 0x2402}, + {"Fire Kraken (Jade) (Bottom)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{1006, 0x2000}, {"Stink Bomb (Bottom)", Game::SwapForce, Element::Life, Type::Swapper}}, + {{1007, 0x2000}, {"Grilla Drilla (Bottom)", Game::SwapForce, Element::Life, Type::Swapper}}, + {{1008, 0x2000}, {"Hoot Loop (Bottom)", Game::SwapForce, Element::Magic, Type::Swapper}}, + {{1008, 0x2402}, + {"Hoot Loop (Enchanted) (Bottom)", Game::SwapForce, Element::Magic, Type::Swapper}}, + {{1009, 0x2000}, {"Trap Shadow (Bottom)", Game::SwapForce, Element::Magic, Type::Swapper}}, + {{1010, 0x2000}, {"Magna Charge (Bottom)", Game::SwapForce, Element::Tech, Type::Swapper}}, + {{1010, 0x2402}, + {"Magna Charge (Nitro) (Bottom)", Game::SwapForce, Element::Tech, Type::Swapper}}, + {{1011, 0x2000}, {"Spy Rise (Bottom)", Game::SwapForce, Element::Tech, Type::Swapper}}, + {{1012, 0x2000}, {"Night Shift (Bottom)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{1012, 0x2403}, + {"Night Shift (Legendary) (Bottom)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{1013, 0x2000}, {"Rattle Shake (Bottom)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{1013, 0x2402}, + {"Rattle Shake (Quickdraw) (Bottom)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{1014, 0x2000}, {"Freeze Blade (Bottom)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{1014, 0x2402}, + {"Freeze Blade (Nitro) (Bottom)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{1015, 0x2000}, {"Wash Buckler (Bottom)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{1015, 0x2402}, + {"Wash Buckler (Dark) (Bottom)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{2000, 0x2000}, {"Boom Jet (Top)", Game::SwapForce, Element::Air, Type::Swapper}}, + {{2001, 0x2000}, {"Free Ranger (Top)", Game::SwapForce, Element::Air, Type::Swapper}}, + {{2001, 0x2403}, + {"Free Ranger (Legendary) (Top)", Game::SwapForce, Element::Air, Type::Swapper}}, + {{2002, 0x2000}, {"Rubble Rouser (Top)", Game::SwapForce, Element::Earth, Type::Swapper}}, + {{2003, 0x2000}, {"Doom Stone (Top)", Game::SwapForce, Element::Earth, Type::Swapper}}, + {{2004, 0x2000}, {"Blast Zone (Top)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{2004, 0x2402}, {"Blast Zone (Dark) (Top)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{2005, 0x2000}, {"Fire Kraken (Top)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{2005, 0x2402}, {"Fire Kraken (Jade) (Top)", Game::SwapForce, Element::Fire, Type::Swapper}}, + {{2006, 0x2000}, {"Stink Bomb (Top)", Game::SwapForce, Element::Life, Type::Swapper}}, + {{2007, 0x2000}, {"Grilla Drilla (Top)", Game::SwapForce, Element::Life, Type::Swapper}}, + {{2008, 0x2000}, {"Hoot Loop (Top)", Game::SwapForce, Element::Magic, Type::Swapper}}, + {{2008, 0x2402}, + {"Hoot Loop (Enchanted) (Top)", Game::SwapForce, Element::Magic, Type::Swapper}}, + {{2009, 0x2000}, {"Trap Shadow (Top)", Game::SwapForce, Element::Magic, Type::Swapper}}, + {{2010, 0x2000}, {"Magna Charge (Top)", Game::SwapForce, Element::Tech, Type::Swapper}}, + {{2010, 0x2402}, {"Magna Charge (Nitro) (Top)", Game::SwapForce, Element::Tech, Type::Swapper}}, + {{2011, 0x2000}, {"Spy Rise (Top)", Game::SwapForce, Element::Tech, Type::Swapper}}, + {{2012, 0x2000}, {"Night Shift (Top)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{2012, 0x2403}, + {"Night Shift (Legendary) (Top)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{2013, 0x2000}, {"Rattle Shake (Top)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{2013, 0x2402}, + {"Rattle Shake (Quickdraw) (Top)", Game::SwapForce, Element::Undead, Type::Swapper}}, + {{2014, 0x2000}, {"Freeze Blade (Top)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{2014, 0x2402}, + {"Freeze Blade (Nitro) (Top)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{2015, 0x2000}, {"Wash Buckler (Top)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{2015, 0x2402}, {"Wash Buckler (Dark) (Top)", Game::SwapForce, Element::Water, Type::Swapper}}, + {{3000, 0x2000}, {"Scratch", Game::SwapForce, Element::Air, Type::Skylander}}, + {{3001, 0x2000}, {"Pop Thorn", Game::SwapForce, Element::Air, Type::Skylander}}, + {{3002, 0x2000}, {"Slobber Tooth", Game::SwapForce, Element::Earth, Type::Skylander}}, + {{3002, 0x2402}, {"Slobber Tooth (Dark)", Game::SwapForce, Element::Earth, Type::Skylander}}, + {{3003, 0x2000}, {"Scorp", Game::SwapForce, Element::Earth, Type::Skylander}}, + {{3004, 0x2000}, {"Fryno", Game::SwapForce, Element::Fire, Type::Skylander}}, + {{3004, 0x3801}, {"Fryno (Hog Wild)", Game::TrapTeam, Element::Fire, Type::Skylander}}, + {{3005, 0x2000}, {"Smolderdash", Game::SwapForce, Element::Fire, Type::Skylander}}, + {{3005, 0x2206}, {"Smolderdash (Lightcore)", Game::SwapForce, Element::Fire, Type::Skylander}}, + {{3006, 0x2000}, {"Bumble Blast", Game::SwapForce, Element::Life, Type::Skylander}}, + {{3006, 0x2206}, {"Bumble Blast (Lightcore)", Game::SwapForce, Element::Life, Type::Skylander}}, + {{3006, 0x2402}, {"Bumble Blast (Jolly)", Game::SwapForce, Element::Life, Type::Skylander}}, + {{3007, 0x2000}, {"Zoo Lou", Game::SwapForce, Element::Life, Type::Skylander}}, + {{3007, 0x2403}, {"Zoo Lou (Legendary)", Game::SwapForce, Element::Life, Type::Skylander}}, + {{3008, 0x2000}, {"Dune Bug", Game::SwapForce, Element::Magic, Type::Skylander}}, + {{3009, 0x2000}, {"Star Strike", Game::SwapForce, Element::Magic, Type::Skylander}}, + {{3009, 0x2206}, {"Star Strike (Lightcore)", Game::SwapForce, Element::Magic, Type::Skylander}}, + {{3009, 0x2602}, + {"Star Strike (Lightcore Enchanted)", Game::SwapForce, Element::Magic, Type::Skylander}}, + {{3010, 0x2000}, {"Countdown", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{3010, 0x2206}, {"Countdown (Lightcore)", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{3010, 0x2402}, {"Countdown (Kickoff)", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{3011, 0x2000}, {"Wind Up", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{3011, 0x2404}, + {"Wind Up (Gear Head Vicarious Visions)", Game::SwapForce, Element::Tech, Type::Skylander}}, + {{3012, 0x2000}, {"Roller Brawl", Game::SwapForce, Element::Undead, Type::Skylander}}, + {{3013, 0x2000}, {"Grim Creeper", Game::SwapForce, Element::Undead, Type::Skylander}}, + {{3013, 0x2206}, + {"Grim Creeper (Lightcore)", Game::SwapForce, Element::Undead, Type::Skylander}}, + {{3013, 0x2603}, + {"Grim Creeper (Legendary) (Lightcore)", Game::SwapForce, Element::Undead, Type::Skylander}}, + {{3014, 0x2000}, {"Rip Tide", Game::SwapForce, Element::Water, Type::Skylander}}, + {{3015, 0x2000}, {"Punk Shock", Game::SwapForce, Element::Water, Type::Skylander}}, + {{3400, 0x4100}, {"Fiesta", Game::Superchargers, Element::Undead, Type::Skylander}}, + {{3400, 0x4515}, {"Fiesta (Frightful)", Game::Superchargers, Element::Undead, Type::Skylander}}, + {{3401, 0x4100}, {"High Volt", Game::Superchargers, Element::Tech, Type::Skylander}}, + {{3402, 0x4100}, {"Splat", Game::Superchargers, Element::Magic, Type::Skylander}}, + {{3402, 0x4502}, {"Splat (Power Blue)", Game::Superchargers, Element::Magic, Type::Skylander}}, + {{3406, 0x4100}, {"Stormblade", Game::Superchargers, Element::Air, Type::Skylander}}, + {{3406, 0x4502}, {"Stormblade (Dark)", Game::Superchargers, Element::Air, Type::Skylander}}, + {{3406, 0x4503}, {"Stormblade (Dark)", Game::Superchargers, Element::Air, Type::Skylander}}, + {{3411, 0x4100}, {"Smash Hit", Game::Superchargers, Element::Earth, Type::Skylander}}, + {{3411, 0x4502}, + {"Smash Hit (Steel Plated)", Game::Superchargers, Element::Earth, Type::Skylander}}, + {{3412, 0x4100}, {"Spitfire", Game::Superchargers, Element::Fire, Type::Skylander}}, + {{3412, 0x4502}, {"Spitfire (Dark)", Game::Superchargers, Element::Fire, Type::Skylander}}, + {{3412, 0x450F}, {"Spitfire (Instant)", Game::Superchargers, Element::Fire, Type::Skylander}}, + {{3413, 0x4100}, {"Jet-Vac (Hurricane)", Game::Superchargers, Element::Air, Type::Skylander}}, + {{3413, 0x4503}, + {"Jet-Vac (Legendary Hurricane)", Game::Superchargers, Element::Air, Type::Skylander}}, + {{3414, 0x4100}, + {"Trigger Happy (Double Dare)", Game::Superchargers, Element::Tech, Type::Skylander}}, + {{3414, 0x4502}, + {"Trigger Happy (Power Blue)", Game::Superchargers, Element::Tech, Type::Skylander}}, + {{3415, 0x4100}, + {"Stealth Elf (Super Shot)", Game::Superchargers, Element::Life, Type::Skylander}}, + {{3415, 0x4502}, + {"Stealth Elf (Dark Super Shot)", Game::Superchargers, Element::Life, Type::Skylander}}, + {{3415, 0x450F}, + {"Stealth Elf (Instant)", Game::Superchargers, Element::Life, Type::Skylander}}, + {{3416, 0x4100}, + {"Terrafin (Shark Shooter)", Game::Superchargers, Element::Earth, Type::Skylander}}, + {{3417, 0x4100}, + {"Roller Brawl (Bone Bash)", Game::Superchargers, Element::Undead, Type::Skylander}}, + {{3417, 0x4503}, + {"Roller Brawl (Legendary Bone Bash)", Game::Superchargers, Element::Undead, Type::Skylander}}, + {{3420, 0x4100}, + {"Pop Fizz (Big Bubble)", Game::Superchargers, Element::Magic, Type::Skylander}}, + {{3420, 0x450E}, + {"Pop Fizz (Birthday Bash Big Bubble)", Game::Superchargers, Element::Magic, Type::Skylander}}, + {{3421, 0x4100}, {"Eruptor (Lava Lance)", Game::Superchargers, Element::Fire, Type::Skylander}}, + {{3422, 0x4100}, + {"Gill Grunt (Deep Dive)", Game::Superchargers, Element::Water, Type::Skylander}}, + {{3423, 0x4100}, + {"Donkey Kong (Turbo Charge)", Game::Superchargers, Element::Life, Type::Skylander}}, + {{3423, 0x4502}, + {"Donkey Kong (Dark Turbo Charge)", Game::Superchargers, Element::Life, Type::Skylander}}, + {{3424, 0x4100}, {"Bowser (Hammer Slam)", Game::Superchargers, Element::Fire, Type::Skylander}}, + {{3424, 0x4502}, + {"Bowser (Dark Hammer Slam)", Game::Superchargers, Element::Fire, Type::Skylander}}, + {{3425, 0x4100}, {"Dive-Clops", Game::Superchargers, Element::Water, Type::Skylander}}, + {{3425, 0x450E}, + {"Dive-Clops (Missile-Tow)", Game::Superchargers, Element::Water, Type::Skylander}}, + {{3425, 0x450F}, + {"Dive-Clops (Instant)", Game::Superchargers, Element::Water, Type::Skylander}}, + {{3426, 0x4100}, {"Astroblast", Game::Superchargers, Element::Tech, Type::Skylander}}, + {{3426, 0x4503}, + {"Astroblast (Legendary)", Game::Superchargers, Element::Light, Type::Skylander}}, + {{3427, 0x4100}, {"Nightfall", Game::Superchargers, Element::Dark, Type::Skylander}}, + {{3428, 0x4100}, {"Thrillipede", Game::Superchargers, Element::Life, Type::Skylander}}, + {{3428, 0x450D}, + {"Thrillipede (Eggcited)", Game::Superchargers, Element::Life, Type::Skylander}}, + {{200, 0x2000}, {"Anvil Rain", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{201, 0x2000}, {"Hidden Treasure", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{202, 0x2000}, {"Healing Elixer", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{203, 0x2000}, {"Ghost Pirate Swords", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{204, 0x2000}, {"Time Twister Hourglass", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{205, 0x2000}, {"Sky-Iron Shield", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{206, 0x2000}, {"Winged Boots", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{207, 0x2000}, {"Sparx Dragonfly", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{208, 0x1206}, {"Dragonfire Cannon", Game::Giants, Element::Other, Type::Item}}, + {{208, 0x1602}, {"Golden Dragonfire Cannon", Game::Giants, Element::Other, Type::Item}}, + {{209, 0x1206}, {"Scorpion Striker Catapult", Game::Giants, Element::Other, Type::Item}}, + {{230, 0x0000}, {"Hand Of Fate", Game::TrapTeam, Element::Other, Type::Item}}, + {{230, 0x3403}, {"Hand Of Fate (Legendary)", Game::TrapTeam, Element::Other, Type::Item}}, + {{231, 0x0000}, {"Piggy Bank", Game::TrapTeam, Element::Other, Type::Item}}, + {{232, 0x0000}, {"Rocket Ram", Game::TrapTeam, Element::Other, Type::Item}}, + {{233, 0x0000}, {"Tiki Speaky", Game::TrapTeam, Element::Other, Type::Item}}, + {{300, 0x0000}, {"Dragon's Peak", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{301, 0x2000}, {"Empire Of Ice", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{302, 0x2000}, {"Pirate Ship", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{303, 0x2000}, {"Darklight Crypt", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{304, 0x2000}, {"Volcanic Vault", Game::SpyrosAdv, Element::Other, Type::Item}}, + {{305, 0x3000}, {"Mirror Of Mystery", Game::TrapTeam, Element::Other, Type::Item}}, + {{306, 0x3000}, {"Nightmare Express", Game::TrapTeam, Element::Other, Type::Item}}, + {{307, 0x3206}, {"Sunscraper Spire", Game::TrapTeam, Element::Other, Type::Item}}, + {{308, 0x3206}, {"Midnight Museum", Game::TrapTeam, Element::Other, Type::Item}}, + {{3200, 0x2000}, {"Battle Hammer", Game::SwapForce, Element::Other, Type::Item}}, + {{3201, 0x2000}, {"Sky Diamond", Game::SwapForce, Element::Other, Type::Item}}, + {{3202, 0x2000}, {"Platinum Sheep", Game::SwapForce, Element::Other, Type::Item}}, + {{3203, 0x2000}, {"Groove Machine", Game::SwapForce, Element::Other, Type::Item}}, + {{3204, 0x2000}, {"Ufo Hat", Game::SwapForce, Element::Other, Type::Item}}, + {{3300, 0x2000}, {"Sheep Wreck Island", Game::SwapForce, Element::Other, Type::Item}}, + {{3301, 0x2000}, {"Tower Of Time", Game::SwapForce, Element::Other, Type::Item}}, + {{3302, 0x2206}, {"Fiery Forge", Game::SwapForce, Element::Other, Type::Item}}, + {{3303, 0x2206}, {"Arkeyan Crossbow", Game::SwapForce, Element::Other, Type::Item}}, + {{210, 0x3001}, {"Magic Log Holder", Game::TrapTeam, Element::Magic, Type::Trap}}, + {{210, 0x3008}, {"Magic Skull", Game::TrapTeam, Element::Magic, Type::Trap}}, + {{210, 0x300B}, {"Magic Axe", Game::TrapTeam, Element::Magic, Type::Trap}}, + {{210, 0x300E}, {"Magic Hourglass", Game::TrapTeam, Element::Magic, Type::Trap}}, + {{210, 0x3012}, {"Magic Totem", Game::TrapTeam, Element::Magic, Type::Trap}}, + {{210, 0x3015}, {"Magic Rocket", Game::TrapTeam, Element::Magic, Type::Trap}}, + {{211, 0x3001}, {"Water Tiki", Game::TrapTeam, Element::Water, Type::Trap}}, + {{211, 0x3002}, {"Water Log Holder", Game::TrapTeam, Element::Water, Type::Trap}}, + {{211, 0x3006}, {"Water Jughead", Game::TrapTeam, Element::Water, Type::Trap}}, + {{211, 0x3007}, {"Water Angel", Game::TrapTeam, Element::Water, Type::Trap}}, + {{211, 0x300B}, {"Water Axe", Game::TrapTeam, Element::Water, Type::Trap}}, + {{211, 0x3016}, {"Water Flying Helmet", Game::TrapTeam, Element::Water, Type::Trap}}, + {{211, 0x3406}, {"Water Jughead (Legendary)", Game::TrapTeam, Element::Water, Type::Trap}}, + {{212, 0x3003}, {"Air Toucan", Game::TrapTeam, Element::Air, Type::Trap}}, + {{212, 0x3006}, {"Air Jughead", Game::TrapTeam, Element::Air, Type::Trap}}, + {{212, 0x300E}, {"Air Hourglass", Game::TrapTeam, Element::Air, Type::Trap}}, + {{212, 0x3010}, {"Air Snake", Game::TrapTeam, Element::Air, Type::Trap}}, + {{212, 0x3011}, {"Air Screamer", Game::TrapTeam, Element::Air, Type::Trap}}, + {{212, 0x3018}, {"Air Sword", Game::TrapTeam, Element::Air, Type::Trap}}, + {{213, 0x3004}, {"Undead Orb", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{213, 0x3008}, {"Undead Skull", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{213, 0x300B}, {"Undead Axe", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{213, 0x300C}, {"Undead Hand", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{213, 0x3010}, {"Undead Snake", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{213, 0x3017}, {"Undead Captain's Hat", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{213, 0x3404}, {"Undead Orb (Legendary)", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{213, 0x3408}, {"Undead Skull (Legendary)", Game::TrapTeam, Element::Undead, Type::Trap}}, + {{214, 0x3001}, {"Tech Tiki", Game::TrapTeam, Element::Tech, Type::Trap}}, + {{214, 0x3007}, {"Tech Angel", Game::TrapTeam, Element::Tech, Type::Trap}}, + {{214, 0x3009}, {"Tech Scepter", Game::TrapTeam, Element::Tech, Type::Trap}}, + {{214, 0x300C}, {"Tech Hand", Game::TrapTeam, Element::Tech, Type::Trap}}, + {{214, 0x3016}, {"Tech Flying Helmet", Game::TrapTeam, Element::Tech, Type::Trap}}, + {{214, 0x301A}, {"Tech Handstand", Game::TrapTeam, Element::Tech, Type::Trap}}, + {{215, 0x3001}, {"Fire Flower", Game::TrapTeam, Element::Fire, Type::Trap}}, + {{215, 0x3005}, {"Fire Torch", Game::TrapTeam, Element::Fire, Type::Trap}}, + {{215, 0x3009}, {"Fire Flower (NEW)", Game::TrapTeam, Element::Fire, Type::Trap}}, + {{215, 0x3011}, {"Fire Screamer", Game::TrapTeam, Element::Fire, Type::Trap}}, + {{215, 0x3012}, {"Fire Totem", Game::TrapTeam, Element::Fire, Type::Trap}}, + {{215, 0x3017}, {"Fire Captain's Hat", Game::TrapTeam, Element::Fire, Type::Trap}}, + {{215, 0x301B}, {"Fire Yawn", Game::TrapTeam, Element::Fire, Type::Trap}}, + {{216, 0x3003}, {"Earth Toucan", Game::TrapTeam, Element::Earth, Type::Trap}}, + {{216, 0x3004}, {"Earth Orb", Game::TrapTeam, Element::Earth, Type::Trap}}, + {{216, 0x300A}, {"Earth Hammer", Game::TrapTeam, Element::Earth, Type::Trap}}, + {{216, 0x300E}, {"Earth Hourglass", Game::TrapTeam, Element::Earth, Type::Trap}}, + {{216, 0x3012}, {"Earth Totem", Game::TrapTeam, Element::Earth, Type::Trap}}, + {{216, 0x301A}, {"Earth Handstand", Game::TrapTeam, Element::Earth, Type::Trap}}, + {{217, 0x3001}, {"Life Toucan", Game::TrapTeam, Element::Life, Type::Trap}}, + {{217, 0x3003}, {"Life Toucan (NEW)", Game::TrapTeam, Element::Life, Type::Trap}}, + {{217, 0x3005}, {"Life Torch", Game::TrapTeam, Element::Life, Type::Trap}}, + {{217, 0x300A}, {"Life Hammer", Game::TrapTeam, Element::Life, Type::Trap}}, + {{217, 0x3010}, {"Life Snake", Game::TrapTeam, Element::Life, Type::Trap}}, + {{217, 0x3018}, {"Life Sword", Game::TrapTeam, Element::Life, Type::Trap}}, + {{217, 0x301B}, {"Life Yawn", Game::TrapTeam, Element::Life, Type::Trap}}, + {{218, 0x3014}, {"Dark Spider", Game::TrapTeam, Element::Dark, Type::Trap}}, + {{218, 0x3018}, {"Dark Sword", Game::TrapTeam, Element::Dark, Type::Trap}}, + {{218, 0x301A}, {"Dark Handstand", Game::TrapTeam, Element::Dark, Type::Trap}}, + {{219, 0x300F}, {"Light Owl", Game::TrapTeam, Element::Light, Type::Trap}}, + {{219, 0x3015}, {"Light Rocket", Game::TrapTeam, Element::Light, Type::Trap}}, + {{219, 0x301B}, {"Light Yawn", Game::TrapTeam, Element::Light, Type::Trap}}, + {{220, 0x301E}, {"Kaos", Game::TrapTeam, Element::Other, Type::Trap}}, + {{220, 0x351F}, {"Kaos (Ultimate)", Game::TrapTeam, Element::Other, Type::Trap}}, + {{3500, 0x4000}, {"Sky Trophy", Game::Superchargers, Element::Air, Type::Trophy}}, + {{3500, 0x4403}, {"Sky Trophy (Legendary)", Game::Superchargers, Element::Air, Type::Trophy}}, + {{3501, 0x4000}, {"Land Trophy", Game::Superchargers, Element::Earth, Type::Trophy}}, + {{3502, 0x4000}, {"Sea Trophy", Game::Superchargers, Element::Water, Type::Trophy}}, + {{3503, 0x4000}, {"Kaos Trophy", Game::Superchargers, Element::Other, Type::Trophy}}, + {{3220, 0x4000}, {"Jet Stream", Game::Superchargers, Element::Air, Type::Vehicle}}, + {{3221, 0x4000}, {"Tomb Buggy", Game::Superchargers, Element::Undead, Type::Vehicle}}, + {{3222, 0x4000}, {"Reef Ripper", Game::Superchargers, Element::Water, Type::Vehicle}}, + {{3223, 0x4000}, {"Burn-Cycle", Game::Superchargers, Element::Fire, Type::Vehicle}}, + {{3224, 0x4000}, {"Hot Streak", Game::Superchargers, Element::Fire, Type::Vehicle}}, + {{3224, 0x4004}, {"Hot Streak (Mobile)", Game::Superchargers, Element::Fire, Type::Vehicle}}, + {{3224, 0x4402}, {"Hot Streak (Dark)", Game::Superchargers, Element::Fire, Type::Vehicle}}, + {{3224, 0x441E}, + {"Hot Streak (Golden) (E3)", Game::Superchargers, Element::Fire, Type::Vehicle}}, + {{3224, 0x450F}, {"Hot Streak (Instant)", Game::Superchargers, Element::Fire, Type::Vehicle}}, + {{3225, 0x4000}, {"Shark Tank", Game::Superchargers, Element::Earth, Type::Vehicle}}, + {{3226, 0x4000}, {"Thump Truck", Game::Superchargers, Element::Earth, Type::Vehicle}}, + {{3227, 0x4000}, {"Crypt Crusher", Game::Superchargers, Element::Undead, Type::Vehicle}}, + {{3228, 0x4000}, {"Stealth Stinger", Game::Superchargers, Element::Life, Type::Vehicle}}, + {{3228, 0x4402}, + {"Stealth Stinger (Nitro)", Game::Superchargers, Element::Life, Type::Vehicle}}, + {{3228, 0x450F}, + {"Stealth Stinger (Instant)", Game::Superchargers, Element::Life, Type::Vehicle}}, + {{3231, 0x4000}, {"Dive Bomber", Game::Superchargers, Element::Water, Type::Vehicle}}, + {{3231, 0x4402}, + {"Dive Bomber (Spring Ahead)", Game::Superchargers, Element::Water, Type::Vehicle}}, + {{3231, 0x450F}, {"Dive Bomber (Instant)", Game::Superchargers, Element::Water, Type::Vehicle}}, + {{3232, 0x4000}, {"Sky Slicer", Game::Superchargers, Element::Air, Type::Vehicle}}, + {{3233, 0x4000}, {"Clown Cruiser", Game::Superchargers, Element::Air, Type::Vehicle}}, + {{3233, 0x4402}, {"Clown Cruiser (Dark)", Game::Superchargers, Element::Air, Type::Vehicle}}, + {{3234, 0x4000}, {"Gold Rusher", Game::Superchargers, Element::Tech, Type::Vehicle}}, + {{3234, 0x4402}, + {"Gold Rusher (Power Blue)", Game::Superchargers, Element::Tech, Type::Vehicle}}, + {{3235, 0x4000}, {"Shield Striker", Game::Superchargers, Element::Tech, Type::Vehicle}}, + {{3236, 0x4000}, {"Sun Runner", Game::Superchargers, Element::Light, Type::Vehicle}}, + {{3236, 0x4403}, + {"Sun Runner (Legendary)", Game::Superchargers, Element::Light, Type::Vehicle}}, + {{3237, 0x4000}, {"Sea Shadow", Game::Superchargers, Element::Dark, Type::Vehicle}}, + {{3237, 0x4402}, {"Sea Shadow (Dark)", Game::Superchargers, Element::Dark, Type::Vehicle}}, + {{3238, 0x4000}, {"Splatter Splasher", Game::Superchargers, Element::Magic, Type::Vehicle}}, + {{3238, 0x4402}, + {"Splatter Splasher (Power Blue)", Game::Superchargers, Element::Magic, Type::Vehicle}}, + {{3239, 0x4000}, {"Soda Skimmer", Game::Superchargers, Element::Magic, Type::Vehicle}}, + {{3239, 0x4402}, {"Soda Skimmer (Nitro)", Game::Superchargers, Element::Magic, Type::Vehicle}}, + {{3240, 0x4000}, {"Barrel Blaster", Game::Superchargers, Element::Tech, Type::Vehicle}}, + {{3240, 0x4402}, {"Barrel Blaster (Dark)", Game::Superchargers, Element::Tech, Type::Vehicle}}, + {{3241, 0x4000}, {"Buzz Wing", Game::Superchargers, Element::Life, Type::Vehicle}}, +}; SkylanderUSB::SkylanderUSB(EmulationKernel& ios, const std::string& device_name) : m_ios(ios) { diff --git a/Source/Core/Core/IOS/USB/Emulated/Skylander.h b/Source/Core/Core/IOS/USB/Emulated/Skylander.h index a66116cc32..d21f30d478 100644 --- a/Source/Core/Core/IOS/USB/Emulated/Skylander.h +++ b/Source/Core/Core/IOS/USB/Emulated/Skylander.h @@ -16,6 +16,9 @@ // The status array is 32 bits and every character takes 2 bits. // 32/2 = 16 constexpr u8 MAX_SKYLANDERS = 16; +constexpr u8 NUM_SKYLANDER_GAMES = 5; +constexpr u8 NUM_SKYLANDER_TYPES = 10; +constexpr u8 NUM_SKYLANDER_ELEMENTS = 11; namespace IOS::HLE::USB { @@ -25,12 +28,24 @@ enum class Game Giants, SwapForce, TrapTeam, - Superchargers, - Other, + Superchargers +}; +enum class Type +{ + Skylander = 1, + Giant, + Swapper, + TrapMaster, + Mini, + Item, + Trophy, + Vehicle, + Trap, + Unknown }; enum class Element { - Magic, + Magic = 1, Fire, Air, Life, @@ -38,14 +53,17 @@ enum class Element Earth, Water, Tech, + Dark, + Light, Other }; struct SkyData { const char* name = ""; - Game game = Game::Other; + Game game = Game::SpyrosAdv; Element element = Element::Other; + Type type = Type::Unknown; }; extern const std::map, SkyData> list_skylanders; diff --git a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp index 2ef2d43edb..654be376d4 100644 --- a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp +++ b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.cpp @@ -103,6 +103,11 @@ void SkylanderPortalWindow::CreateMainWindow() auto* select_layout = new QHBoxLayout; + setMinimumWidth(770); + + // yes, that +1 on 755 is needed to avoid scroll bars on the element selection + setMinimumHeight(756); + // left and right widgets within window separated into own functions for readability select_layout->addLayout(CreateSlotLayout()); select_layout->addLayout(CreateFinderLayout()); @@ -262,25 +267,25 @@ QVBoxLayout* SkylanderPortalWindow::CreateFinderLayout() } // i18n: Figures for the game Skylanders: Spyro's Adventure. The game has the same title in all // countries it was released in, except Japan, where it's named スカイランダーズ スパイロの大冒険. - m_game_filters[GetGameID(IOS::HLE::USB::Game::SpyrosAdv)]->setText(tr("Spyro's Adventure")); + m_game_filters[GetGameID(Game::SpyrosAdv)]->setText(tr("Spyro's Adventure")); // i18n: Figures for the game Skylanders: Giants. The game has the same title in all countries // it was released in. It was not released in Japan. - m_game_filters[GetGameID(IOS::HLE::USB::Game::Giants)]->setText(tr("Giants")); + m_game_filters[GetGameID(Game::Giants)]->setText(tr("Giants")); // i18n: Figures for the game Skylanders: Swap Force. The game has the same title in all countries // it was released in. It was not released in Japan. - m_game_filters[GetGameID(IOS::HLE::USB::Game::SwapForce)]->setText(tr("Swap Force")); + m_game_filters[GetGameID(Game::SwapForce)]->setText(tr("Swap Force")); // i18n: Figures for the game Skylanders: Trap Team. The game has the same title in all countries // it was released in. It was not released in Japan. - m_game_filters[GetGameID(IOS::HLE::USB::Game::TrapTeam)]->setText(tr("Trap Team")); + m_game_filters[GetGameID(Game::TrapTeam)]->setText(tr("Trap Team")); // i18n: Figures for the games Skylanders: SuperChargers (not available for the Wii) and // Skylanders: SuperChargers Racing (available for the Wii). The games have the same titles in // all countries they were released in. They were not released in Japan. - m_game_filters[GetGameID(IOS::HLE::USB::Game::Superchargers)]->setText(tr("SuperChargers")); + m_game_filters[GetGameID(Game::Superchargers)]->setText(tr("SuperChargers")); search_checkbox_group->setLayout(search_checkbox_layout); search_checkbox_scroll_area->setWidget(search_checkbox_group); search_game_layout->addWidget(search_checkbox_scroll_area); search_game_group->setLayout(search_game_layout); - search_game_group->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + search_game_group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); search_filters_layout->addWidget(search_game_group); // WIDGET: Filter by Element @@ -297,63 +302,139 @@ QVBoxLayout* SkylanderPortalWindow::CreateFinderLayout() auto* search_radio_layout = new QHBoxLayout(); auto* radio_layout_left = new QVBoxLayout(); - for (int i = 0; i < 10; i += 2) + auto* radio_layout_right = new QVBoxLayout(); + for (int i = 0; i < NUM_SKYLANDER_ELEMENTS_RADIO; i++) { QRadioButton* radio = new QRadioButton(this); radio->setProperty("id", i); + if (i == 0) + { + radio->setChecked(true); + } connect(radio, &QRadioButton::toggled, this, &SkylanderPortalWindow::RefreshList); m_element_filter[i] = radio; - radio_layout_left->addWidget(radio); + + if (i % 2 == 0) + { + radio_layout_left->addWidget(radio); + } + else + { + radio_layout_right->addWidget(radio); + } } search_radio_layout->addLayout(radio_layout_left); - - auto* radio_layout_right = new QVBoxLayout(); - for (int i = 1; i < 10; i += 2) - { - QRadioButton* radio = new QRadioButton(this); - radio->setProperty("id", i); - connect(radio, &QRadioButton::toggled, this, &SkylanderPortalWindow::RefreshList); - m_element_filter[i] = radio; - radio_layout_right->addWidget(radio); - } + search_radio_layout->setDirection(QBoxLayout::Direction::LeftToRight); + search_radio_layout->addSpacing(35); search_radio_layout->addLayout(radio_layout_right); m_element_filter[0]->setText(tr("All")); m_element_filter[0]->setChecked(true); // i18n: One of the elements in the Skylanders games. Japanese: まほう. For official translations // in other languages, check the SuperChargers manual at https://support.activision.com/manuals - m_element_filter[1]->setText(tr("Magic")); + m_element_filter[GetElementID(Element::Magic)]->setText(tr("Magic")); // i18n: One of the elements in the Skylanders games. Japanese: 水. For official translations // in other languages, check the SuperChargers manual at https://support.activision.com/manuals - m_element_filter[2]->setText(tr("Water")); + m_element_filter[GetElementID(Element::Water)]->setText(tr("Water")); // i18n: One of the elements in the Skylanders games. Japanese: マシン. For official translations // in other languages, check the SuperChargers manual at https://support.activision.com/manuals - m_element_filter[3]->setText(tr("Tech")); + m_element_filter[GetElementID(Element::Tech)]->setText(tr("Tech")); // i18n: One of the elements in the Skylanders games. Japanese: 火. For official translations // in other languages, check the SuperChargers manual at https://support.activision.com/manuals - m_element_filter[4]->setText(tr("Fire")); + m_element_filter[GetElementID(Element::Fire)]->setText(tr("Fire")); // i18n: One of the elements in the Skylanders games. Japanese: 土. For official translations // in other languages, check the SuperChargers manual at https://support.activision.com/manuals - m_element_filter[5]->setText(tr("Earth")); + m_element_filter[GetElementID(Element::Earth)]->setText(tr("Earth")); // i18n: One of the elements in the Skylanders games. Japanese: ライフ. For official translations // in other languages, check the SuperChargers manual at https://support.activision.com/manuals - m_element_filter[6]->setText(tr("Life")); + m_element_filter[GetElementID(Element::Life)]->setText(tr("Life")); // i18n: One of the elements in the Skylanders games. Japanese: 風. For official translations // in other languages, check the SuperChargers manual at https://support.activision.com/manuals - m_element_filter[7]->setText(tr("Air")); + m_element_filter[GetElementID(Element::Air)]->setText(tr("Air")); // i18n: One of the elements in the Skylanders games. Japanese: アンデッド. For official // translations in other languages, check the SuperChargers manual at // https://support.activision.com/manuals - m_element_filter[8]->setText(tr("Undead")); - m_element_filter[9]->setText(tr("Other")); + m_element_filter[GetElementID(Element::Undead)]->setText(tr("Undead")); + // i18n: One of the elements in the Skylanders games. For official translations + // in other languages, check the SuperChargers manual at https://support.activision.com/manuals + m_element_filter[GetElementID(Element::Dark)]->setText(tr("Dark")); + // i18n: One of the elements in the Skylanders games. For official translations + // in other languages, check the SuperChargers manual at https://support.activision.com/manuals + m_element_filter[GetElementID(Element::Light)]->setText(tr("Light")); + m_element_filter[GetElementID(Element::Other)]->setText(tr("Other")); search_radio_group->setLayout(search_radio_layout); search_radio_scroll_area->setWidget(search_radio_group); search_element_layout->addWidget(search_radio_scroll_area); + search_radio_scroll_area->setAlignment(Qt::AlignHCenter); search_element_group->setLayout(search_element_layout); - search_element_group->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); + search_element_group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); search_filters_layout->addWidget(search_element_group); + // Widget: Filter by Type + auto* search_type_group = new QGroupBox(tr("Figure type")); + auto* search_type_layout = new QVBoxLayout(); + auto* search_type_radio_scroll_area = new QScrollArea(); + search_type_radio_scroll_area->setContentsMargins(0, 0, 0, 0); + search_type_radio_scroll_area->setFrameStyle(QFrame::NoFrame); + auto* search_type_radio_group = new QFrame(); + search_type_radio_group->setContentsMargins(0, 0, 0, 0); + auto* search_type_radio_layout = new QHBoxLayout(); + + auto* radio_type_layout_left = new QVBoxLayout(); + auto* radio_type_layout_right = new QVBoxLayout(); + for (int i = 0; i < NUM_SKYLANDER_TYPES; i++) + { + QRadioButton* radio = new QRadioButton(this); + radio->setProperty("id", i); + if (i == 0) + { + radio->setChecked(true); + } + connect(radio, &QRadioButton::toggled, this, &SkylanderPortalWindow::RefreshList); + m_type_filter[i] = radio; + + if (i % 2 == 0) + { + radio_type_layout_left->addWidget(radio); + } + else + { + radio_type_layout_right->addWidget(radio); + } + } + search_type_radio_layout->addLayout(radio_type_layout_left); + search_type_radio_layout->addLayout(radio_type_layout_right); + + m_type_filter[0]->setText(tr("All")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::Skylander)]->setText(tr("Skylander")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::Giant)]->setText(tr("Giant")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::Swapper)]->setText(tr("Swapper")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::TrapMaster)]->setText(tr("Trap Master")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::Mini)]->setText(tr("Mini")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::Item)]->setText(tr("Item")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::Trophy)]->setText(tr("Trophy")); + // i18n: One of the figure types in the Skylanders games. For official translations + // in other languages, check the SuperChargers manual at https://support.activision.com/manuals + m_type_filter[GetTypeID(Type::Vehicle)]->setText(tr("Vehicle")); + // i18n: One of the figure types in the Skylanders games. + m_type_filter[GetTypeID(Type::Trap)]->setText(tr("Trap")); + + search_type_radio_group->setLayout(search_type_radio_layout); + search_type_radio_scroll_area->setWidget(search_type_radio_group); + search_type_radio_scroll_area->setAlignment(Qt::AlignHCenter); + search_type_layout->addWidget(search_type_radio_scroll_area); + search_type_group->setLayout(search_type_layout); + search_type_group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + search_filters_layout->addWidget(search_type_group); + // Widget: Other Filters auto* other_box = new QGroupBox(tr("Other")); auto* other_layout = new QVBoxLayout; @@ -790,30 +871,12 @@ bool SkylanderPortalWindow::PassesFilter(QString name, u16 id, u16 var) bool pass = false; // Check against active game filters - if (m_game_filters[GetGameID(IOS::HLE::USB::Game::SpyrosAdv)]->isChecked()) + for (size_t i = 0; i < NUM_SKYLANDER_GAMES; i++) { - if (character.game == IOS::HLE::USB::Game::SpyrosAdv) - pass = true; - } - if (m_game_filters[GetGameID(IOS::HLE::USB::Game::Giants)]->isChecked()) - { - if (character.game == IOS::HLE::USB::Game::Giants) - pass = true; - } - if (m_game_filters[GetGameID(IOS::HLE::USB::Game::SwapForce)]->isChecked()) - { - if (character.game == IOS::HLE::USB::Game::SwapForce) - pass = true; - } - if (m_game_filters[GetGameID(IOS::HLE::USB::Game::TrapTeam)]->isChecked()) - { - if (character.game == IOS::HLE::USB::Game::TrapTeam) - pass = true; - } - if (m_game_filters[GetGameID(IOS::HLE::USB::Game::Superchargers)]->isChecked()) - { - if (character.game == IOS::HLE::USB::Game::Superchargers) + if (m_game_filters[i]->isChecked() && character.game == (Game)i) + { pass = true; + } } if (!pass) return false; @@ -823,45 +886,12 @@ bool SkylanderPortalWindow::PassesFilter(QString name, u16 id, u16 var) return false; // Check against active element filter - switch (GetElementRadio()) - { - case 1: - if (character.element != IOS::HLE::USB::Element::Magic) - return false; - break; - case 2: - if (character.element != IOS::HLE::USB::Element::Water) - return false; - break; - case 3: - if (character.element != IOS::HLE::USB::Element::Tech) - return false; - break; - case 4: - if (character.element != IOS::HLE::USB::Element::Fire) - return false; - break; - case 5: - if (character.element != IOS::HLE::USB::Element::Earth) - return false; - break; - case 6: - if (character.element != IOS::HLE::USB::Element::Life) - return false; - break; - case 7: - if (character.element != IOS::HLE::USB::Element::Air) - return false; - break; - case 8: - if (character.element != IOS::HLE::USB::Element::Undead) - return false; - break; - case 9: - if (character.element != IOS::HLE::USB::Element::Other) - return false; - break; - } + if ((Element)GetElementRadio() != character.element && GetElementRadio() != 0) + return false; + + // Check against active type filter + if ((Type)GetTypeRadio() != character.type && GetTypeRadio() != 0) + return false; return true; } @@ -915,6 +945,18 @@ int SkylanderPortalWindow::GetElementRadio() return -1; } +int SkylanderPortalWindow::GetTypeRadio() +{ + for (auto radio : m_type_filter) + { + if (radio->isChecked()) + { + return radio->property("id").toInt(); + } + } + return -1; +} + QBrush SkylanderPortalWindow::GetBaseColor(std::pair ids, bool dark_theme) { auto skylander = IOS::HLE::USB::list_skylanders.find(ids); @@ -924,76 +966,32 @@ QBrush SkylanderPortalWindow::GetBaseColor(std::pair ids, switch ((*skylander).second.game) { - case IOS::HLE::USB::Game::SpyrosAdv: + case Game::SpyrosAdv: return QBrush(dark_theme ? QColor(10, 42, 90) : QColor(240, 255, 240)); - case IOS::HLE::USB::Game::Giants: + case Game::Giants: return QBrush(dark_theme ? QColor(120, 16, 12) : QColor(255, 240, 215)); - case IOS::HLE::USB::Game::SwapForce: + case Game::SwapForce: return QBrush(dark_theme ? QColor(28, 45, 12) : QColor(240, 245, 255)); - case IOS::HLE::USB::Game::TrapTeam: + case Game::TrapTeam: return QBrush(dark_theme ? QColor(0, 56, 76) : QColor(255, 240, 240)); - case IOS::HLE::USB::Game::Superchargers: + case Game::Superchargers: return QBrush(dark_theme ? QColor(90, 12, 12) : QColor(247, 228, 215)); default: return QBrush(dark_theme ? QColor(32, 32, 32) : QColor(255, 255, 255)); } } -int SkylanderPortalWindow::GetGameID(IOS::HLE::USB::Game game) +int SkylanderPortalWindow::GetGameID(Game game) { - switch (game) - { - case IOS::HLE::USB::Game::SpyrosAdv: - return 0; - - case IOS::HLE::USB::Game::Giants: - return 1; - - case IOS::HLE::USB::Game::SwapForce: - return 2; - - case IOS::HLE::USB::Game::TrapTeam: - return 3; - - case IOS::HLE::USB::Game::Superchargers: - return 4; - - case IOS::HLE::USB::Game::Other: - return 5; - } - return -1; + return (int)game; } -int SkylanderPortalWindow::GetElementID(IOS::HLE::USB::Element elem) +int SkylanderPortalWindow::GetElementID(Element elem) { - switch (elem) - { - case IOS::HLE::USB::Element::Magic: - return 0; - - case IOS::HLE::USB::Element::Fire: - return 1; - - case IOS::HLE::USB::Element::Air: - return 2; - - case IOS::HLE::USB::Element::Life: - return 3; - - case IOS::HLE::USB::Element::Undead: - return 4; - - case IOS::HLE::USB::Element::Earth: - return 5; - - case IOS::HLE::USB::Element::Water: - return 6; - - case IOS::HLE::USB::Element::Tech: - return 7; - - case IOS::HLE::USB::Element::Other: - return 8; - } - return -1; + return (int)elem; +} + +int SkylanderPortalWindow::GetTypeID(Type type) +{ + return (int)type; } diff --git a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h index 293b056199..ce67dbff7e 100644 --- a/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h +++ b/Source/Core/DolphinQt/SkylanderPortal/SkylanderPortalWindow.h @@ -23,6 +23,12 @@ class QPushButton; class QRadioButton; class QListWidget; +using Element = IOS::HLE::USB::Element; +using Game = IOS::HLE::USB::Game; +using Type = IOS::HLE::USB::Type; + +constexpr u8 NUM_SKYLANDER_ELEMENTS_RADIO = NUM_SKYLANDER_ELEMENTS + 1; + struct Skylander { u8 portal_slot; @@ -72,15 +78,17 @@ private: QString GetFilePath(u16 id, u16 var); u8 GetCurrentSlot(); int GetElementRadio(); + int GetTypeRadio(); QBrush GetBaseColor(std::pair ids, bool dark_theme); - int GetGameID(IOS::HLE::USB::Game game); - int GetElementID(IOS::HLE::USB::Element elem); + int GetGameID(Game game); + int GetElementID(Element elem); + int GetTypeID(Type type); bool m_emulating; QCheckBox* m_enabled_checkbox; QFrame* m_group_skylanders; QFrame* m_command_buttons; - std::array m_slot_radios; + std::array m_slot_radios; // Qt is not guaranteed to keep track of file paths using native file pickers, so we use this // variable to ensure we open at the most recent Skylander file location @@ -90,8 +98,9 @@ private: QLineEdit* m_path_edit; QPushButton* m_path_select; - std::array m_game_filters; - std::array m_element_filter; + std::array m_game_filters; + std::array m_element_filter; + std::array m_type_filter; QCheckBox* m_only_show_collection; QLineEdit* m_sky_search; QListWidget* m_skylander_list; From 89e2fc1dd30d5a0ed61f9221cc7bb96961f85e6e Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sun, 13 Aug 2023 17:21:16 -0500 Subject: [PATCH 94/99] VideoBackends: update SRVDescriptorTable size in DX12 to use pixel sampler constant --- Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp index 3f6035feda..84bac629ac 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp +++ b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp @@ -654,7 +654,7 @@ bool Gfx::UpdateSRVDescriptorTable() static constexpr std::array src_sizes = { 1, 1, 1, 1, 1, 1, 1, 1}; DescriptorHandle dst_base_handle; - const UINT dst_handle_sizes = 8; + const UINT dst_handle_sizes = VideoCommon::MAX_PIXEL_SHADER_SAMPLERS; if (!g_dx_context->GetDescriptorAllocator()->Allocate(VideoCommon::MAX_PIXEL_SHADER_SAMPLERS, &dst_base_handle)) return false; From c43c9101c07376297abbbbc40ef9a1965a1681cd Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Mon, 14 Aug 2023 11:27:39 +0200 Subject: [PATCH 95/99] CMake: use version flags if Git isn't found --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ee44d04458..2cff081391 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -790,7 +790,7 @@ if(NOT GIT_FOUND) endif() add_custom_target( dolphin_scmrev - ${CMAKE_COMMAND} -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} -DDISTRIBUTOR=${DISTRIBUTOR} -DDOLPHIN_DEFAULT_UPDATE_TRACK=${DOLPHIN_DEFAULT_UPDATE_TRACK} -DGIT_FOUND=${GIT_FOUND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -P ${CMAKE_SOURCE_DIR}/CMake/ScmRevGen.cmake + ${CMAKE_COMMAND} -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} -DDISTRIBUTOR=${DISTRIBUTOR} -DDOLPHIN_DEFAULT_UPDATE_TRACK=${DOLPHIN_DEFAULT_UPDATE_TRACK} -DGIT_FOUND=${GIT_FOUND} -DGIT_EXECUTABLE=${GIT_EXECUTABLE} -DDOLPHIN_WC_REVISION=${DOLPHIN_WC_REVISION} -DDOLPHIN_WC_DESCRIBE=${DOLPHIN_WC_DESCRIBE} -DDOLPHIN_WC_BRANCH=${DOLPHIN_WC_BRANCH} -P ${CMAKE_SOURCE_DIR}/CMake/ScmRevGen.cmake BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/Source/Core/Common/scmrev.h VERBATIM ) From 1d77bddc3b4090ebc4541375bf4caef18e3b6868 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 15 Aug 2023 13:31:18 +0200 Subject: [PATCH 96/99] ControllerInterface/Android: Add null check to AddDevice The Google Play Console is showing some users getting a crash here, and indeed, InputDevice.getDevice can return null. --- .../InputCommon/ControllerInterface/Android/Android.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp index 1fa4f1c42b..50858cd3de 100644 --- a/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Android/Android.cpp @@ -908,6 +908,12 @@ static void AddDevice(JNIEnv* env, int device_id) jobject input_device = env->CallStaticObjectMethod(s_input_device_class, s_input_device_get_device, device_id); + if (!input_device) + { + ERROR_LOG_FMT(CONTROLLERINTERFACE, "Could not find device with ID {}", device_id); + return; + } + auto device = std::make_shared(env, input_device); env->DeleteLocalRef(input_device); From 0bb5c88a220234f9cfdd3054a7d1b7352f06d673 Mon Sep 17 00:00:00 2001 From: MikeIsAStar <99037623+MikeIsAStar@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:40:30 -0400 Subject: [PATCH 97/99] Retrieve page table information from the data cache Thanks to @mkwcat for identifying the problematic code. --- Source/Core/Core/PowerPC/MMU.cpp | 10 +++++----- Source/Core/Core/PowerPC/MMU.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/PowerPC/MMU.cpp b/Source/Core/Core/PowerPC/MMU.cpp index a1597b96a5..9ce95211ce 100644 --- a/Source/Core/Core/PowerPC/MMU.cpp +++ b/Source/Core/Core/PowerPC/MMU.cpp @@ -1387,8 +1387,8 @@ void MMU::InvalidateTLBEntry(u32 address) } // Page Address Translation -MMU::TranslateAddressResult MMU::TranslatePageAddress(const EffectiveAddress address, - const XCheckTLBFlag flag, bool* wi) +template +MMU::TranslateAddressResult MMU::TranslatePageAddress(const EffectiveAddress address, bool* wi) { // TLB cache // This catches 99%+ of lookups in practice, so the actual page table entry code below doesn't @@ -1441,11 +1441,11 @@ MMU::TranslateAddressResult MMU::TranslatePageAddress(const EffectiveAddress add for (int i = 0; i < 8; i++, pteg_addr += 8) { - const u32 pteg = m_memory.Read_U32(pteg_addr); + const u32 pteg = ReadFromHardware(pteg_addr); if (pte1.Hex == pteg) { - UPTE_Hi pte2(m_memory.Read_U32(pteg_addr + 4)); + UPTE_Hi pte2(ReadFromHardware(pteg_addr + 4)); // set the access bits switch (flag) @@ -1643,7 +1643,7 @@ MMU::TranslateAddressResult MMU::TranslateAddress(u32 address) if (TranslateBatAddress(IsOpcodeFlag(flag) ? m_ibat_table : m_dbat_table, &address, &wi)) return TranslateAddressResult{TranslateAddressResultEnum::BAT_TRANSLATED, address, wi}; - return TranslatePageAddress(EffectiveAddress{address}, flag, &wi); + return TranslatePageAddress(EffectiveAddress{address}, &wi); } std::optional MMU::GetTranslatedAddress(u32 address) diff --git a/Source/Core/Core/PowerPC/MMU.h b/Source/Core/Core/PowerPC/MMU.h index 2ee0173eb5..eb8981d0d9 100644 --- a/Source/Core/Core/PowerPC/MMU.h +++ b/Source/Core/Core/PowerPC/MMU.h @@ -292,8 +292,8 @@ private: template TranslateAddressResult TranslateAddress(u32 address); - TranslateAddressResult TranslatePageAddress(const EffectiveAddress address, - const XCheckTLBFlag flag, bool* wi); + template + TranslateAddressResult TranslatePageAddress(const EffectiveAddress address, bool* wi); void GenerateDSIException(u32 effective_address, bool write); void GenerateISIException(u32 effective_address); From b969282b72f1e5267cf4e9af4e6612cb948b2bff Mon Sep 17 00:00:00 2001 From: takayhan-AMD <123373764+takayhan-AMD@users.noreply.github.com> Date: Sat, 12 Aug 2023 11:16:25 +0200 Subject: [PATCH 98/99] Remove out-dated hack of AMD driver issue WRT dual-source blending output index. --- Source/Core/VideoCommon/DriverDetails.cpp | 2 -- Source/Core/VideoCommon/DriverDetails.h | 8 -------- Source/Core/VideoCommon/PixelShaderGen.cpp | 11 ++--------- Source/Core/VideoCommon/UberShaderPixel.cpp | 11 ++--------- 4 files changed, 4 insertions(+), 28 deletions(-) diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index ffd5fa48d7..e217c9d530 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -90,8 +90,6 @@ constexpr BugInfo m_known_bugs[] = { -1.0, true}, {API_OPENGL, OS_ALL, VENDOR_MESA, DRIVER_I965, Family::UNKNOWN, BUG_BROKEN_CLIP_DISTANCE, -1.0, -1.0, true}, - {API_VULKAN, OS_WINDOWS, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, - BUG_BROKEN_FRAGMENT_SHADER_INDEX_DECORATION, -1.0, -1.0, true}, {API_OPENGL, OS_WINDOWS, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_BROKEN_DUAL_SOURCE_BLENDING, -1.0, -1.0, true}, {API_OPENGL, OS_OSX, VENDOR_INTEL, DRIVER_INTEL, Family::UNKNOWN, diff --git a/Source/Core/VideoCommon/DriverDetails.h b/Source/Core/VideoCommon/DriverDetails.h index 3e59e576c6..bc5daa8c31 100644 --- a/Source/Core/VideoCommon/DriverDetails.h +++ b/Source/Core/VideoCommon/DriverDetails.h @@ -224,14 +224,6 @@ enum Bug // the gl_ClipDistance inputs from the vertex shader. BUG_BROKEN_CLIP_DISTANCE, - // Bug: Dual-source outputs from fragment shaders are broken on AMD Vulkan drivers - // Started Version: -1 - // Ended Version: -1 - // Fragment shaders that specify dual-source outputs, via layout(location = 0, index = ...) cause - // the driver to fail to create graphics pipelines. The workaround for this is to specify the - // index as a MRT location instead, or omit the binding completely. - BUG_BROKEN_FRAGMENT_SHADER_INDEX_DECORATION, - // Bug: Dual-source outputs from fragment shaders are broken on some drivers. // Started Version: -1 // Ended Version: -1 diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 57b2113bc3..0b96e49f4a 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -837,21 +837,14 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos else #endif { - bool has_broken_decoration = - DriverDetails::HasBug(DriverDetails::BUG_BROKEN_FRAGMENT_SHADER_INDEX_DECORATION); - - out.Write("{} {} {} {};\n", - has_broken_decoration ? "FRAGMENT_OUTPUT_LOCATION(0)" : - "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0)", + out.Write("{} {} {} {};\n", "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0)", use_framebuffer_fetch ? "FRAGMENT_INOUT" : "out", uid_data->uint_output ? "uvec4" : "vec4", use_framebuffer_fetch ? "real_ocol0" : "ocol0"); if (!uid_data->no_dual_src) { - out.Write("{} out {} ocol1;\n", - has_broken_decoration ? "FRAGMENT_OUTPUT_LOCATION(1)" : - "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1)", + out.Write("{} out {} ocol1;\n", "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1)", uid_data->uint_output ? "uvec4" : "vec4"); } } diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index 0bf4b3072c..f54e42bf60 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -106,21 +106,14 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, else #endif { - bool has_broken_decoration = - DriverDetails::HasBug(DriverDetails::BUG_BROKEN_FRAGMENT_SHADER_INDEX_DECORATION); - - out.Write("{} {} {} {};\n", - has_broken_decoration ? "FRAGMENT_OUTPUT_LOCATION(0)" : - "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0)", + out.Write("{} {} {} {};\n", "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 0)", use_framebuffer_fetch ? "FRAGMENT_INOUT" : "out", uid_data->uint_output ? "uvec4" : "vec4", use_framebuffer_fetch ? "real_ocol0" : "ocol0"); if (use_dual_source) { - out.Write("{} out {} ocol1;\n", - has_broken_decoration ? "FRAGMENT_OUTPUT_LOCATION(1)" : - "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1)", + out.Write("{} out {} ocol1;\n", "FRAGMENT_OUTPUT_LOCATION_INDEXED(0, 1)", uid_data->uint_output ? "uvec4" : "vec4"); } } From 86910f406e3680c4cb01f37e5f29f894a25342cb Mon Sep 17 00:00:00 2001 From: JosJuice Date: Wed, 16 Aug 2023 09:54:24 +0200 Subject: [PATCH 99/99] VideoCommon: Fix std::filesystem::path encoding conversion In std::string, you can store strings using any encoding, but in Dolphin we have decided to use UTF-8. The problem is that if you convert between std::string and std::filesystem::path using the built-in methods, the standard library will make up its own assumption of what encoding you're using in the std::string. On most OSes this is UTF-8, but on Windows it's whatever the user's code page is. What I believe is the C++ standard authors' intended solution to this is to use std::u8string instead of std::string, but that's a big hassle to move over to, because there's no convenient way to convert between std::string and std::u8string. Instead, in Dolphin, we have added helper functions that convert between std::string and std::filesystem::path in the manner we want. You *always* have to use these when converting between std::string and std::filesystem::path, otherwise we get these kinds of encoding problems that we've been having with custom textures. Fixes https://bugs.dolphin-emu.org/issues/13328. --- .../Assets/DirectFilesystemAssetLibrary.cpp | 30 +++++++++---------- Source/Core/VideoCommon/HiresTextures.cpp | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp index cc21549e54..3d92c7fb82 100644 --- a/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp +++ b/Source/Core/VideoCommon/Assets/DirectFilesystemAssetLibrary.cpp @@ -103,18 +103,18 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadPixelShader(const } const auto approx_mem_size = metadata_size + shader_size; - if (!File::ReadFileToString(shader->second.string(), data->m_shader_source)) + if (!File::ReadFileToString(PathToString(shader->second), data->m_shader_source)) { ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the shader file '{}',", asset_id, - shader->second.string()); + PathToString(shader->second)); return {}; } std::string json_data; - if (!File::ReadFileToString(metadata->second.string(), json_data)) + if (!File::ReadFileToString(PathToString(metadata->second), json_data)) { ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the json file '{}',", asset_id, - metadata->second.string()); + PathToString(metadata->second)); return {}; } @@ -125,7 +125,7 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadPixelShader(const { ERROR_LOG_FMT(VIDEO, "Asset '{}' error - failed to load the json file '{}', due to parse error: {}", - asset_id, metadata->second.string(), error); + asset_id, PathToString(metadata->second), error); return {}; } if (!root.is()) @@ -133,7 +133,7 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadPixelShader(const ERROR_LOG_FMT( VIDEO, "Asset '{}' error - failed to load the json file '{}', due to root not being an object!", - asset_id, metadata->second.string()); + asset_id, PathToString(metadata->second)); return {}; } @@ -159,10 +159,10 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMaterial(const As const auto& asset_path = asset_map.begin()->second; std::string json_data; - if (!File::ReadFileToString(asset_path.string(), json_data)) + if (!File::ReadFileToString(PathToString(asset_path), json_data)) { ERROR_LOG_FMT(VIDEO, "Asset '{}' error - material failed to load the json file '{}',", - asset_id, asset_path.string()); + asset_id, PathToString(asset_path)); return {}; } @@ -174,7 +174,7 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMaterial(const As ERROR_LOG_FMT( VIDEO, "Asset '{}' error - material failed to load the json file '{}', due to parse error: {}", - asset_id, asset_path.string(), error); + asset_id, PathToString(asset_path), error); return {}; } if (!root.is()) @@ -182,7 +182,7 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMaterial(const As ERROR_LOG_FMT(VIDEO, "Asset '{}' error - material failed to load the json file '{}', due to root not " "being an object!", - asset_id, asset_path.string()); + asset_id, PathToString(asset_path)); return {}; } @@ -193,7 +193,7 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadMaterial(const As ERROR_LOG_FMT(VIDEO, "Asset '{}' error - material failed to load the json file '{}', as material " "json could not be parsed!", - asset_id, asset_path.string()); + asset_id, PathToString(asset_path)); return {}; } @@ -222,11 +222,11 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const Ass asset_id, ec); return {}; } - auto ext = asset_path.extension().string(); + auto ext = PathToString(asset_path.extension()); Common::ToLower(&ext); if (ext == ".dds") { - if (!LoadDDSTexture(data, asset_path.string())) + if (!LoadDDSTexture(data, PathToString(asset_path))) { ERROR_LOG_FMT(VIDEO, "Asset '{}' error - could not load dds texture!", asset_id); return {}; @@ -243,7 +243,7 @@ CustomAssetLibrary::LoadInfo DirectFilesystemAssetLibrary::LoadTexture(const Ass if (data->m_levels.empty()) data->m_levels.push_back({}); - if (!LoadPNGTexture(&data->m_levels[0], asset_path.string())) + if (!LoadPNGTexture(&data->m_levels[0], PathToString(asset_path))) { ERROR_LOG_FMT(VIDEO, "Asset '{}' error - could not load png texture!", asset_id); return {}; @@ -275,7 +275,7 @@ bool DirectFilesystemAssetLibrary::LoadMips(const std::filesystem::path& asset_p std::string path; std::string filename; std::string extension; - SplitPath(asset_path.string(), &path, &filename, &extension); + SplitPath(PathToString(asset_path), &path, &filename, &extension); std::string extension_lower = extension; Common::ToLower(&extension_lower); diff --git a/Source/Core/VideoCommon/HiresTextures.cpp b/Source/Core/VideoCommon/HiresTextures.cpp index f9f3134e35..6a489973a5 100644 --- a/Source/Core/VideoCommon/HiresTextures.cpp +++ b/Source/Core/VideoCommon/HiresTextures.cpp @@ -131,7 +131,7 @@ void HiresTexture::Update() // Since this is just a texture (single file) the mapper doesn't really matter // just provide a string s_file_library->SetAssetIDMapData( - filename, std::map{{"", path}}); + filename, std::map{{"", StringToPath(path)}}); if (g_ActiveConfig.bCacheHiresTextures) {