diff options
Diffstat (limited to 'src/core/hle/service/set/settings_server.cpp')
-rw-r--r-- | src/core/hle/service/set/settings_server.cpp | 258 |
1 files changed, 167 insertions, 91 deletions
diff --git a/src/core/hle/service/set/settings_server.cpp b/src/core/hle/service/set/settings_server.cpp index b2caa00ff..a9321b98d 100644 --- a/src/core/hle/service/set/settings_server.cpp +++ b/src/core/hle/service/set/settings_server.cpp @@ -6,7 +6,9 @@ #include <chrono> #include "common/logging/log.h" #include "common/settings.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/set/key_code_map.h" #include "core/hle/service/set/settings_server.h" namespace Service::Set { @@ -15,43 +17,69 @@ constexpr std::size_t PRE_4_0_0_MAX_ENTRIES = 0xF; constexpr std::size_t POST_4_0_0_MAX_ENTRIES = 0x40; constexpr Result ResultInvalidLanguage{ErrorModule::Settings, 625}; - -void PushResponseLanguageCode(HLERequestContext& ctx, std::size_t num_language_codes) { - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast<u32>(num_language_codes)); -} - -void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entries) { - const std::size_t requested_amount = ctx.GetWriteBufferNumElements<LanguageCode>(); - const std::size_t max_amount = std::min(requested_amount, max_entries); - const std::size_t copy_amount = std::min(available_language_codes.size(), max_amount); - const std::size_t copy_size = copy_amount * sizeof(LanguageCode); - - ctx.WriteBuffer(available_language_codes.data(), copy_size); - PushResponseLanguageCode(ctx, copy_amount); -} - -void GetKeyCodeMapImpl(HLERequestContext& ctx) { - const auto language_code = - available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]; - const auto key_code = - std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), - [=](const auto& element) { return element.first == language_code; }); - KeyboardLayout layout = KeyboardLayout::EnglishUs; - if (key_code == language_to_layout.cend()) { - LOG_ERROR(Service_SET, - "Could not find keyboard layout for language index {}, defaulting to English us", - Settings::values.language_index.GetValue()); - } else { - layout = key_code->second; +constexpr Result ResultNullPointer{ErrorModule::Settings, 1261}; + +Result GetKeyCodeMapImpl(KeyCodeMap& out_key_code_map, KeyboardLayout keyboard_layout, + LanguageCode language_code) { + switch (keyboard_layout) { + case KeyboardLayout::Japanese: + out_key_code_map = KeyCodeMapJapanese; + R_SUCCEED(); + case KeyboardLayout::EnglishUs: + out_key_code_map = KeyCodeMapEnglishUsInternational; + if (language_code == LanguageCode::KO) { + out_key_code_map = KeyCodeMapKorean; + } + if (language_code == LanguageCode::ZH_HANS) { + out_key_code_map = KeyCodeMapChineseSimplified; + } + if (language_code == LanguageCode::ZH_HANT) { + out_key_code_map = KeyCodeMapChineseTraditional; + } + R_SUCCEED(); + case KeyboardLayout::EnglishUk: + out_key_code_map = KeyCodeMapEnglishUk; + R_SUCCEED(); + case KeyboardLayout::French: + out_key_code_map = KeyCodeMapFrench; + R_SUCCEED(); + case KeyboardLayout::FrenchCa: + out_key_code_map = KeyCodeMapFrenchCa; + R_SUCCEED(); + case KeyboardLayout::Spanish: + out_key_code_map = KeyCodeMapSpanish; + R_SUCCEED(); + case KeyboardLayout::SpanishLatin: + out_key_code_map = KeyCodeMapSpanishLatin; + R_SUCCEED(); + case KeyboardLayout::German: + out_key_code_map = KeyCodeMapGerman; + R_SUCCEED(); + case KeyboardLayout::Italian: + out_key_code_map = KeyCodeMapItalian; + R_SUCCEED(); + case KeyboardLayout::Portuguese: + out_key_code_map = KeyCodeMapPortuguese; + R_SUCCEED(); + case KeyboardLayout::Russian: + out_key_code_map = KeyCodeMapRussian; + R_SUCCEED(); + case KeyboardLayout::Korean: + out_key_code_map = KeyCodeMapKorean; + R_SUCCEED(); + case KeyboardLayout::ChineseSimplified: + out_key_code_map = KeyCodeMapChineseSimplified; + R_SUCCEED(); + case KeyboardLayout::ChineseTraditional: + out_key_code_map = KeyCodeMapChineseTraditional; + R_SUCCEED(); + default: + case KeyboardLayout::EnglishUsInternational: + out_key_code_map = KeyCodeMapEnglishUsInternational; + R_SUCCEED(); } - - ctx.WriteBuffer(layout); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); } + } // Anonymous namespace LanguageCode GetLanguageCodeFromIndex(std::size_t index) { @@ -61,18 +89,18 @@ LanguageCode GetLanguageCodeFromIndex(std::size_t index) { ISettingsServer::ISettingsServer(Core::System& system_) : ServiceFramework{system_, "set"} { // clang-format off static const FunctionInfo functions[] = { - {0, &ISettingsServer::GetLanguageCode, "GetLanguageCode"}, - {1, &ISettingsServer::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"}, - {2, &ISettingsServer::MakeLanguageCode, "MakeLanguageCode"}, - {3, &ISettingsServer::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"}, - {4, &ISettingsServer::GetRegionCode, "GetRegionCode"}, - {5, &ISettingsServer::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"}, - {6, &ISettingsServer::GetAvailableLanguageCodeCount2, "GetAvailableLanguageCodeCount2"}, - {7, &ISettingsServer::GetKeyCodeMap, "GetKeyCodeMap"}, - {8, &ISettingsServer::GetQuestFlag, "GetQuestFlag"}, - {9, &ISettingsServer::GetKeyCodeMap2, "GetKeyCodeMap2"}, + {0, C<&ISettingsServer::GetLanguageCode>, "GetLanguageCode"}, + {1, C<&ISettingsServer::GetAvailableLanguageCodes>, "GetAvailableLanguageCodes"}, + {2, C<&ISettingsServer::MakeLanguageCode>, "MakeLanguageCode"}, + {3, C<&ISettingsServer::GetAvailableLanguageCodeCount>, "GetAvailableLanguageCodeCount"}, + {4, C<&ISettingsServer::GetRegionCode>, "GetRegionCode"}, + {5, C<&ISettingsServer::GetAvailableLanguageCodes2>, "GetAvailableLanguageCodes2"}, + {6, C<&ISettingsServer::GetAvailableLanguageCodeCount2>, "GetAvailableLanguageCodeCount2"}, + {7, C<&ISettingsServer::GetKeyCodeMap>, "GetKeyCodeMap"}, + {8, C<&ISettingsServer::GetQuestFlag>, "GetQuestFlag"}, + {9, C<&ISettingsServer::GetKeyCodeMap2>, "GetKeyCodeMap2"}, {10, nullptr, "GetFirmwareVersionForDebug"}, - {11, &ISettingsServer::GetDeviceNickName, "GetDeviceNickName"}, + {11, C<&ISettingsServer::GetDeviceNickName>, "GetDeviceNickName"}, }; // clang-format on @@ -81,86 +109,134 @@ ISettingsServer::ISettingsServer(Core::System& system_) : ServiceFramework{syste ISettingsServer::~ISettingsServer() = default; -void ISettingsServer::GetAvailableLanguageCodes(HLERequestContext& ctx) { +Result ISettingsServer::GetLanguageCode(Out<LanguageCode> out_language_code) { + LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue()); + + *out_language_code = available_language_codes[static_cast<std::size_t>( + Settings::values.language_index.GetValue())]; + R_SUCCEED(); +} + +Result ISettingsServer::GetAvailableLanguageCodes( + Out<s32> out_count, OutArray<LanguageCode, BufferAttr_HipcPointer> out_language_codes) { LOG_DEBUG(Service_SET, "called"); - GetAvailableLanguageCodesImpl(ctx, PRE_4_0_0_MAX_ENTRIES); + const std::size_t max_amount = std::min(PRE_4_0_0_MAX_ENTRIES, out_language_codes.size()); + *out_count = static_cast<s32>(std::min(available_language_codes.size(), max_amount)); + + memcpy(out_language_codes.data(), available_language_codes.data(), + static_cast<std::size_t>(*out_count) * sizeof(LanguageCode)); + + R_SUCCEED(); } -void ISettingsServer::MakeLanguageCode(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto index = rp.Pop<u32>(); +Result ISettingsServer::MakeLanguageCode(Out<LanguageCode> out_language_code, Language language) { + LOG_DEBUG(Service_SET, "called, language={}", language); - if (index >= available_language_codes.size()) { - LOG_ERROR(Service_SET, "Invalid language code index! index={}", index); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Set::ResultInvalidLanguage); - return; - } + const auto index = static_cast<std::size_t>(language); + R_UNLESS(index < available_language_codes.size(), Set::ResultInvalidLanguage); - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.PushEnum(available_language_codes[index]); + *out_language_code = available_language_codes[index]; + R_SUCCEED(); } -void ISettingsServer::GetAvailableLanguageCodes2(HLERequestContext& ctx) { +Result ISettingsServer::GetAvailableLanguageCodeCount(Out<s32> out_count) { LOG_DEBUG(Service_SET, "called"); - GetAvailableLanguageCodesImpl(ctx, POST_4_0_0_MAX_ENTRIES); + *out_count = PRE_4_0_0_MAX_ENTRIES; + R_SUCCEED(); } -void ISettingsServer::GetAvailableLanguageCodeCount(HLERequestContext& ctx) { +Result ISettingsServer::GetRegionCode(Out<SystemRegionCode> out_region_code) { LOG_DEBUG(Service_SET, "called"); - PushResponseLanguageCode(ctx, PRE_4_0_0_MAX_ENTRIES); + *out_region_code = static_cast<SystemRegionCode>(Settings::values.region_index.GetValue()); + R_SUCCEED(); } -void ISettingsServer::GetAvailableLanguageCodeCount2(HLERequestContext& ctx) { +Result ISettingsServer::GetAvailableLanguageCodes2( + Out<s32> out_count, OutArray<LanguageCode, BufferAttr_HipcMapAlias> language_codes) { LOG_DEBUG(Service_SET, "called"); - PushResponseLanguageCode(ctx, POST_4_0_0_MAX_ENTRIES); + const std::size_t max_amount = std::min(POST_4_0_0_MAX_ENTRIES, language_codes.size()); + *out_count = static_cast<s32>(std::min(available_language_codes.size(), max_amount)); + + memcpy(language_codes.data(), available_language_codes.data(), + static_cast<std::size_t>(*out_count) * sizeof(LanguageCode)); + + R_SUCCEED(); } -void ISettingsServer::GetQuestFlag(HLERequestContext& ctx) { +Result ISettingsServer::GetAvailableLanguageCodeCount2(Out<s32> out_count) { LOG_DEBUG(Service_SET, "called"); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast<s32>(Settings::values.quest_flag.GetValue())); + *out_count = POST_4_0_0_MAX_ENTRIES; + R_SUCCEED(); } -void ISettingsServer::GetLanguageCode(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue()); +Result ISettingsServer::GetKeyCodeMap( + OutLargeData<KeyCodeMap, BufferAttr_HipcMapAlias> out_key_code_map) { + LOG_DEBUG(Service_SET, "called"); + + R_UNLESS(out_key_code_map != nullptr, ResultNullPointer); - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - rb.PushEnum( - available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]); + const auto language_code = + available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]; + const auto key_code = + std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), + [=](const auto& element) { return element.first == language_code; }); + + if (key_code == language_to_layout.cend()) { + LOG_ERROR(Service_SET, + "Could not find keyboard layout for language index {}, defaulting to English us", + Settings::values.language_index.GetValue()); + *out_key_code_map = KeyCodeMapEnglishUsInternational; + R_SUCCEED(); + } + + R_RETURN(GetKeyCodeMapImpl(*out_key_code_map, key_code->second, key_code->first)); } -void ISettingsServer::GetRegionCode(HLERequestContext& ctx) { +Result ISettingsServer::GetQuestFlag(Out<bool> out_quest_flag) { LOG_DEBUG(Service_SET, "called"); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast<u32>(Settings::values.region_index.GetValue())); + *out_quest_flag = Settings::values.quest_flag.GetValue(); + R_SUCCEED(); } -void ISettingsServer::GetKeyCodeMap(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); - GetKeyCodeMapImpl(ctx); -} +Result ISettingsServer::GetKeyCodeMap2( + OutLargeData<KeyCodeMap, BufferAttr_HipcMapAlias> out_key_code_map) { + LOG_DEBUG(Service_SET, "called"); + + R_UNLESS(out_key_code_map != nullptr, ResultNullPointer); -void ISettingsServer::GetKeyCodeMap2(HLERequestContext& ctx) { - LOG_DEBUG(Service_SET, "Called {}", ctx.Description()); - GetKeyCodeMapImpl(ctx); + const auto language_code = + available_language_codes[static_cast<s32>(Settings::values.language_index.GetValue())]; + const auto key_code = + std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), + [=](const auto& element) { return element.first == language_code; }); + + if (key_code == language_to_layout.cend()) { + LOG_ERROR(Service_SET, + "Could not find keyboard layout for language index {}, defaulting to English us", + Settings::values.language_index.GetValue()); + *out_key_code_map = KeyCodeMapEnglishUsInternational; + R_SUCCEED(); + } + + R_RETURN(GetKeyCodeMapImpl(*out_key_code_map, key_code->second, key_code->first)); } -void ISettingsServer::GetDeviceNickName(HLERequestContext& ctx) { +Result ISettingsServer::GetDeviceNickName( + OutLargeData<std::array<u8, 0x80>, BufferAttr_HipcMapAlias> out_device_name) { LOG_DEBUG(Service_SET, "called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - ctx.WriteBuffer(Settings::values.device_name.GetValue()); + + const std::size_t string_size = + std::min(Settings::values.device_name.GetValue().size(), out_device_name->size()); + + *out_device_name = {}; + memcpy(out_device_name->data(), Settings::values.device_name.GetValue().data(), string_size); + R_SUCCEED(); } } // namespace Service::Set |