summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/set/settings_server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/set/settings_server.cpp')
-rw-r--r--src/core/hle/service/set/settings_server.cpp258
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