diff options
| author | Liam <byteslice@airmail.cc> | 2023-12-31 09:40:32 -0500 |
|---|---|---|
| committer | Liam <byteslice@airmail.cc> | 2024-01-29 18:43:45 -0500 |
| commit | dfb9fa0144ca79e596f6f2b1bc960b1a44745aa6 (patch) | |
| tree | b90633109392383feaa8420e984c40c9a1799903 /src/core/hle/service/am/applets | |
| parent | a7e9d7842dc78e09bfe50ba3bc471b8a75d29b96 (diff) | |
am: re-namespace frontend applets to frontend directory
Diffstat (limited to 'src/core/hle/service/am/applets')
21 files changed, 0 insertions, 5170 deletions
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp deleted file mode 100644 index 1b756fbd7..000000000 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "common/logging/log.h" -#include "core/core.h" -#include "core/frontend/applets/cabinet.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_cabinet.h" -#include "core/hle/service/am/storage.h" -#include "core/hle/service/mii/mii_manager.h" -#include "core/hle/service/nfc/common/device.h" -#include "hid_core/hid_core.h" - -namespace Service::AM::Applets { - -Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::CabinetApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_}, - service_context{system_, "CabinetApplet"} { - - availability_change_event = - service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent"); -} - -Cabinet::~Cabinet() { - service_context.CloseEvent(availability_change_event); -}; - -void Cabinet::Initialize() { - Applet::Initialize(); - - LOG_INFO(Service_HID, "Initializing Cabinet Applet."); - - LOG_DEBUG(Service_HID, - "Initializing Applet with common_args: arg_version={}, lib_version={}, " - "play_startup_sound={}, size={}, system_tick={}, theme_color={}", - common_args.arguments_version, common_args.library_version, - common_args.play_startup_sound, common_args.size, common_args.system_tick, - common_args.theme_color); - - const auto storage = broker.PopNormalDataToApplet(); - ASSERT(storage != nullptr); - - const auto applet_input_data = storage->GetData(); - ASSERT(applet_input_data.size() >= sizeof(StartParamForAmiiboSettings)); - - std::memcpy(&applet_input_common, applet_input_data.data(), - sizeof(StartParamForAmiiboSettings)); -} - -bool Cabinet::TransactionComplete() const { - return is_complete; -} - -Result Cabinet::GetStatus() const { - return ResultSuccess; -} - -void Cabinet::ExecuteInteractive() { - ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); -} - -void Cabinet::Execute() { - if (is_complete) { - return; - } - - const auto callback = [this](bool apply_changes, const std::string& amiibo_name) { - DisplayCompleted(apply_changes, amiibo_name); - }; - - // TODO: listen on all controllers - if (nfp_device == nullptr) { - nfp_device = std::make_shared<Service::NFC::NfcDevice>( - system.HIDCore().GetFirstNpadId(), system, service_context, availability_change_event); - nfp_device->Initialize(); - nfp_device->StartDetection(Service::NFC::NfcProtocol::All); - } - - const Core::Frontend::CabinetParameters parameters{ - .tag_info = applet_input_common.tag_info, - .register_info = applet_input_common.register_info, - .mode = applet_input_common.applet_mode, - }; - - switch (applet_input_common.applet_mode) { - case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: - case Service::NFP::CabinetMode::StartGameDataEraser: - case Service::NFP::CabinetMode::StartRestorer: - case Service::NFP::CabinetMode::StartFormatter: - frontend.ShowCabinetApplet(callback, parameters, nfp_device); - break; - default: - UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); - DisplayCompleted(false, {}); - break; - } -} - -void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) { - Service::Mii::MiiManager manager; - ReturnValueForAmiiboSettings applet_output{}; - - if (!apply_changes) { - Cancel(); - } - - if (nfp_device->GetCurrentState() != Service::NFC::DeviceState::TagFound && - nfp_device->GetCurrentState() != Service::NFC::DeviceState::TagMounted) { - Cancel(); - } - - if (nfp_device->GetCurrentState() == Service::NFC::DeviceState::TagFound) { - nfp_device->Mount(Service::NFP::ModelType::Amiibo, Service::NFP::MountTarget::All); - } - - switch (applet_input_common.applet_mode) { - case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { - Service::NFP::RegisterInfoPrivate register_info{}; - std::memcpy(register_info.amiibo_name.data(), amiibo_name.data(), - std::min(amiibo_name.size(), register_info.amiibo_name.size() - 1)); - register_info.mii_store_data.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All); - register_info.mii_store_data.SetNickname({u'y', u'u', u'z', u'u'}); - nfp_device->SetRegisterInfoPrivate(register_info); - break; - } - case Service::NFP::CabinetMode::StartGameDataEraser: - nfp_device->DeleteApplicationArea(); - break; - case Service::NFP::CabinetMode::StartRestorer: - nfp_device->Restore(); - break; - case Service::NFP::CabinetMode::StartFormatter: - nfp_device->Format(); - break; - default: - UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); - break; - } - - applet_output.device_handle = applet_input_common.device_handle; - applet_output.result = CabinetResult::Cancel; - const auto reg_result = nfp_device->GetRegisterInfo(applet_output.register_info); - const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info); - nfp_device->Finalize(); - - if (reg_result.IsSuccess()) { - applet_output.result |= CabinetResult::RegisterInfo; - } - - if (tag_result.IsSuccess()) { - applet_output.result |= CabinetResult::TagInfo; - } - - std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings)); - std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); - - is_complete = true; - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); -} - -void Cabinet::Cancel() { - ReturnValueForAmiiboSettings applet_output{}; - applet_output.device_handle = applet_input_common.device_handle; - applet_output.result = CabinetResult::Cancel; - nfp_device->Finalize(); - - std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings)); - std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); - - is_complete = true; - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); -} - -Result Cabinet::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h deleted file mode 100644 index f498796f7..000000000 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ /dev/null @@ -1,114 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> - -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applets.h" -#include "core/hle/service/kernel_helpers.h" -#include "core/hle/service/nfp/nfp_types.h" - -namespace Kernel { -class KEvent; -class KReadableEvent; -} // namespace Kernel - -namespace Core { -class System; -} // namespace Core - -namespace Service::NFC { -class NfcDevice; -} - -namespace Service::AM::Applets { - -enum class CabinetAppletVersion : u32 { - Version1 = 0x1, -}; - -enum class CabinetFlags : u8 { - None = 0, - DeviceHandle = 1 << 0, - TagInfo = 1 << 1, - RegisterInfo = 1 << 2, - All = DeviceHandle | TagInfo | RegisterInfo, -}; -DECLARE_ENUM_FLAG_OPERATORS(CabinetFlags) - -enum class CabinetResult : u8 { - Cancel = 0, - TagInfo = 1 << 1, - RegisterInfo = 1 << 2, - All = TagInfo | RegisterInfo, -}; -DECLARE_ENUM_FLAG_OPERATORS(CabinetResult) - -// This is nn::nfp::AmiiboSettingsStartParam -struct AmiiboSettingsStartParam { - u64 device_handle; - std::array<u8, 0x20> param_1; - u8 param_2; -}; -static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, - "AmiiboSettingsStartParam is an invalid size"); - -#pragma pack(push, 1) -// This is nn::nfp::StartParamForAmiiboSettings -struct StartParamForAmiiboSettings { - u8 param_1; - Service::NFP::CabinetMode applet_mode; - CabinetFlags flags; - u8 amiibo_settings_1; - u64 device_handle; - Service::NFP::TagInfo tag_info; - Service::NFP::RegisterInfo register_info; - std::array<u8, 0x20> amiibo_settings_3; - INSERT_PADDING_BYTES(0x24); -}; -static_assert(sizeof(StartParamForAmiiboSettings) == 0x1A8, - "StartParamForAmiiboSettings is an invalid size"); - -// This is nn::nfp::ReturnValueForAmiiboSettings -struct ReturnValueForAmiiboSettings { - CabinetResult result; - INSERT_PADDING_BYTES(0x3); - u64 device_handle; - Service::NFP::TagInfo tag_info; - Service::NFP::RegisterInfo register_info; - INSERT_PADDING_BYTES(0x24); -}; -static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188, - "ReturnValueForAmiiboSettings is an invalid size"); -#pragma pack(pop) - -class Cabinet final : public Applet { -public: - explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::CabinetApplet& frontend_); - ~Cabinet() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - void DisplayCompleted(bool apply_changes, std::string_view amiibo_name); - void Cancel(); - Result RequestExit() override; - -private: - const Core::Frontend::CabinetApplet& frontend; - Core::System& system; - - bool is_complete{false}; - std::shared_ptr<Service::NFC::NfcDevice> nfp_device; - Kernel::KEvent* availability_change_event; - KernelHelpers::ServiceContext service_context; - StartParamForAmiiboSettings applet_input_common{}; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp deleted file mode 100644 index bc8de6b60..000000000 --- a/src/core/hle/service/am/applets/applet_controller.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <algorithm> -#include <cstring> - -#include "common/assert.h" -#include "common/logging/log.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/frontend/applets/controller.h" -#include "core/hle/result.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_controller.h" -#include "core/hle/service/am/storage.h" -#include "hid_core/frontend/emulated_controller.h" -#include "hid_core/hid_core.h" -#include "hid_core/hid_types.h" -#include "hid_core/resources/npad/npad.h" - -namespace Service::AM::Applets { - -[[maybe_unused]] constexpr Result ResultControllerSupportCanceled{ErrorModule::HID, 3101}; -[[maybe_unused]] constexpr Result ResultControllerSupportNotSupportedNpadStyle{ErrorModule::HID, - 3102}; - -static Core::Frontend::ControllerParameters ConvertToFrontendParameters( - ControllerSupportArgPrivate private_arg, ControllerSupportArgHeader header, bool enable_text, - std::vector<IdentificationColor> identification_colors, std::vector<ExplainText> text) { - Core::HID::NpadStyleTag npad_style_set; - npad_style_set.raw = private_arg.style_set; - - return { - .min_players = std::max(s8{1}, header.player_count_min), - .max_players = header.player_count_max, - .keep_controllers_connected = header.enable_take_over_connection, - .enable_single_mode = header.enable_single_mode, - .enable_border_color = header.enable_identification_color, - .border_colors = std::move(identification_colors), - .enable_explain_text = enable_text, - .explain_text = std::move(text), - .allow_pro_controller = npad_style_set.fullkey == 1, - .allow_handheld = npad_style_set.handheld == 1, - .allow_dual_joycons = npad_style_set.joycon_dual == 1, - .allow_left_joycon = npad_style_set.joycon_left == 1, - .allow_right_joycon = npad_style_set.joycon_right == 1, - }; -} - -Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::ControllerApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -Controller::~Controller() = default; - -void Controller::Initialize() { - Applet::Initialize(); - - LOG_INFO(Service_HID, "Initializing Controller Applet."); - - LOG_DEBUG(Service_HID, - "Initializing Applet with common_args: arg_version={}, lib_version={}, " - "play_startup_sound={}, size={}, system_tick={}, theme_color={}", - common_args.arguments_version, common_args.library_version, - common_args.play_startup_sound, common_args.size, common_args.system_tick, - common_args.theme_color); - - controller_applet_version = ControllerAppletVersion{common_args.library_version}; - - const auto private_arg_storage = broker.PopNormalDataToApplet(); - ASSERT(private_arg_storage != nullptr); - - const auto& private_arg = private_arg_storage->GetData(); - ASSERT(private_arg.size() == sizeof(ControllerSupportArgPrivate)); - - std::memcpy(&controller_private_arg, private_arg.data(), private_arg.size()); - ASSERT_MSG(controller_private_arg.arg_private_size == sizeof(ControllerSupportArgPrivate), - "Unknown ControllerSupportArgPrivate revision={} with size={}", - controller_applet_version, controller_private_arg.arg_private_size); - - // Some games such as Cave Story+ set invalid values for the ControllerSupportMode. - // Defer to arg_size to set the ControllerSupportMode. - if (controller_private_arg.mode >= ControllerSupportMode::MaxControllerSupportMode) { - switch (controller_private_arg.arg_size) { - case sizeof(ControllerSupportArgOld): - case sizeof(ControllerSupportArgNew): - controller_private_arg.mode = ControllerSupportMode::ShowControllerSupport; - break; - case sizeof(ControllerUpdateFirmwareArg): - controller_private_arg.mode = ControllerSupportMode::ShowControllerFirmwareUpdate; - break; - case sizeof(ControllerKeyRemappingArg): - controller_private_arg.mode = - ControllerSupportMode::ShowControllerKeyRemappingForSystem; - break; - default: - UNIMPLEMENTED_MSG("Unknown ControllerPrivateArg mode={} with arg_size={}", - controller_private_arg.mode, controller_private_arg.arg_size); - controller_private_arg.mode = ControllerSupportMode::ShowControllerSupport; - break; - } - } - - // Some games such as Cave Story+ set invalid values for the ControllerSupportCaller. - // This is always 0 (Application) except with ShowControllerFirmwareUpdateForSystem. - if (controller_private_arg.caller >= ControllerSupportCaller::MaxControllerSupportCaller) { - if (controller_private_arg.flag_1 && - (controller_private_arg.mode == ControllerSupportMode::ShowControllerFirmwareUpdate || - controller_private_arg.mode == - ControllerSupportMode::ShowControllerKeyRemappingForSystem)) { - controller_private_arg.caller = ControllerSupportCaller::System; - } else { - controller_private_arg.caller = ControllerSupportCaller::Application; - } - } - - switch (controller_private_arg.mode) { - case ControllerSupportMode::ShowControllerSupport: - case ControllerSupportMode::ShowControllerStrapGuide: { - const auto user_arg_storage = broker.PopNormalDataToApplet(); - ASSERT(user_arg_storage != nullptr); - - const auto& user_arg = user_arg_storage->GetData(); - switch (controller_applet_version) { - case ControllerAppletVersion::Version3: - case ControllerAppletVersion::Version4: - case ControllerAppletVersion::Version5: - ASSERT(user_arg.size() == sizeof(ControllerSupportArgOld)); - std::memcpy(&controller_user_arg_old, user_arg.data(), user_arg.size()); - break; - case ControllerAppletVersion::Version7: - case ControllerAppletVersion::Version8: - ASSERT(user_arg.size() == sizeof(ControllerSupportArgNew)); - std::memcpy(&controller_user_arg_new, user_arg.data(), user_arg.size()); - break; - default: - UNIMPLEMENTED_MSG("Unknown ControllerSupportArg revision={} with size={}", - controller_applet_version, controller_private_arg.arg_size); - ASSERT(user_arg.size() >= sizeof(ControllerSupportArgNew)); - std::memcpy(&controller_user_arg_new, user_arg.data(), sizeof(ControllerSupportArgNew)); - break; - } - break; - } - case ControllerSupportMode::ShowControllerFirmwareUpdate: { - const auto update_arg_storage = broker.PopNormalDataToApplet(); - ASSERT(update_arg_storage != nullptr); - - const auto& update_arg = update_arg_storage->GetData(); - ASSERT(update_arg.size() == sizeof(ControllerUpdateFirmwareArg)); - - std::memcpy(&controller_update_arg, update_arg.data(), update_arg.size()); - break; - } - case ControllerSupportMode::ShowControllerKeyRemappingForSystem: { - const auto remapping_arg_storage = broker.PopNormalDataToApplet(); - ASSERT(remapping_arg_storage != nullptr); - - const auto& remapping_arg = remapping_arg_storage->GetData(); - ASSERT(remapping_arg.size() == sizeof(ControllerKeyRemappingArg)); - - std::memcpy(&controller_key_remapping_arg, remapping_arg.data(), remapping_arg.size()); - break; - } - default: { - UNIMPLEMENTED_MSG("Unimplemented ControllerSupportMode={}", controller_private_arg.mode); - break; - } - } -} - -bool Controller::TransactionComplete() const { - return complete; -} - -Result Controller::GetStatus() const { - return status; -} - -void Controller::ExecuteInteractive() { - ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); -} - -void Controller::Execute() { - switch (controller_private_arg.mode) { - case ControllerSupportMode::ShowControllerSupport: { - const auto parameters = [this] { - switch (controller_applet_version) { - case ControllerAppletVersion::Version3: - case ControllerAppletVersion::Version4: - case ControllerAppletVersion::Version5: - return ConvertToFrontendParameters( - controller_private_arg, controller_user_arg_old.header, - controller_user_arg_old.enable_explain_text, - std::vector<IdentificationColor>( - controller_user_arg_old.identification_colors.begin(), - controller_user_arg_old.identification_colors.end()), - std::vector<ExplainText>(controller_user_arg_old.explain_text.begin(), - controller_user_arg_old.explain_text.end())); - case ControllerAppletVersion::Version7: - case ControllerAppletVersion::Version8: - default: - return ConvertToFrontendParameters( - controller_private_arg, controller_user_arg_new.header, - controller_user_arg_new.enable_explain_text, - std::vector<IdentificationColor>( - controller_user_arg_new.identification_colors.begin(), - controller_user_arg_new.identification_colors.end()), - std::vector<ExplainText>(controller_user_arg_new.explain_text.begin(), - controller_user_arg_new.explain_text.end())); - } - }(); - - is_single_mode = parameters.enable_single_mode; - - LOG_DEBUG(Service_HID, - "Controller Parameters: min_players={}, max_players={}, " - "keep_controllers_connected={}, enable_single_mode={}, enable_border_color={}, " - "enable_explain_text={}, allow_pro_controller={}, allow_handheld={}, " - "allow_dual_joycons={}, allow_left_joycon={}, allow_right_joycon={}", - parameters.min_players, parameters.max_players, - parameters.keep_controllers_connected, parameters.enable_single_mode, - parameters.enable_border_color, parameters.enable_explain_text, - parameters.allow_pro_controller, parameters.allow_handheld, - parameters.allow_dual_joycons, parameters.allow_left_joycon, - parameters.allow_right_joycon); - - frontend.ReconfigureControllers( - [this](bool is_success) { ConfigurationComplete(is_success); }, parameters); - break; - } - case ControllerSupportMode::ShowControllerStrapGuide: - case ControllerSupportMode::ShowControllerFirmwareUpdate: - case ControllerSupportMode::ShowControllerKeyRemappingForSystem: - UNIMPLEMENTED_MSG("ControllerSupportMode={} is not implemented", - controller_private_arg.mode); - ConfigurationComplete(true); - break; - default: { - ConfigurationComplete(true); - break; - } - } -} - -void Controller::ConfigurationComplete(bool is_success) { - ControllerSupportResultInfo result_info{}; - - // If enable_single_mode is enabled, player_count is 1 regardless of any other parameters. - // Otherwise, only count connected players from P1-P8. - result_info.player_count = is_single_mode ? 1 : system.HIDCore().GetPlayerCount(); - - result_info.selected_id = static_cast<u32>(system.HIDCore().GetFirstNpadId()); - - result_info.result = - is_success ? ControllerSupportResult::Success : ControllerSupportResult::Cancel; - - LOG_DEBUG(Service_HID, "Result Info: player_count={}, selected_id={}, result={}", - result_info.player_count, result_info.selected_id, result_info.result); - - complete = true; - out_data = std::vector<u8>(sizeof(ControllerSupportResultInfo)); - std::memcpy(out_data.data(), &result_info, out_data.size()); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); -} - -Result Controller::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h deleted file mode 100644 index 9f839f3d7..000000000 --- a/src/core/hle/service/am/applets/applet_controller.h +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include <vector> - -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applets.h" - -namespace Core { -class System; -} - -namespace Core::HID { -enum class NpadStyleSet : u32; -} - -namespace Service::AM::Applets { - -using IdentificationColor = std::array<u8, 4>; -using ExplainText = std::array<char, 0x81>; - -enum class ControllerAppletVersion : u32_le { - Version3 = 0x3, // 1.0.0 - 2.3.0 - Version4 = 0x4, // 3.0.0 - 5.1.0 - Version5 = 0x5, // 6.0.0 - 7.0.1 - Version7 = 0x7, // 8.0.0 - 10.2.0 - Version8 = 0x8, // 11.0.0+ -}; - -enum class ControllerSupportMode : u8 { - ShowControllerSupport, - ShowControllerStrapGuide, - ShowControllerFirmwareUpdate, - ShowControllerKeyRemappingForSystem, - - MaxControllerSupportMode, -}; - -enum class ControllerSupportCaller : u8 { - Application, - System, - - MaxControllerSupportCaller, -}; - -enum class ControllerSupportResult : u32 { - Success = 0, - Cancel = 2, -}; - -struct ControllerSupportArgPrivate { - u32 arg_private_size{}; - u32 arg_size{}; - bool is_home_menu{}; - bool flag_1{}; - ControllerSupportMode mode{}; - ControllerSupportCaller caller{}; - Core::HID::NpadStyleSet style_set{}; - u32 joy_hold_type{}; -}; -static_assert(sizeof(ControllerSupportArgPrivate) == 0x14, - "ControllerSupportArgPrivate has incorrect size."); - -struct ControllerSupportArgHeader { - s8 player_count_min{}; - s8 player_count_max{}; - bool enable_take_over_connection{}; - bool enable_left_justify{}; - bool enable_permit_joy_dual{}; - bool enable_single_mode{}; - bool enable_identification_color{}; -}; -static_assert(sizeof(ControllerSupportArgHeader) == 0x7, - "ControllerSupportArgHeader has incorrect size."); - -// LibraryAppletVersion 0x3, 0x4, 0x5 -struct ControllerSupportArgOld { - ControllerSupportArgHeader header{}; - std::array<IdentificationColor, 4> identification_colors{}; - bool enable_explain_text{}; - std::array<ExplainText, 4> explain_text{}; -}; -static_assert(sizeof(ControllerSupportArgOld) == 0x21C, - "ControllerSupportArgOld has incorrect size."); - -// LibraryAppletVersion 0x7, 0x8 -struct ControllerSupportArgNew { - ControllerSupportArgHeader header{}; - std::array<IdentificationColor, 8> identification_colors{}; - bool enable_explain_text{}; - std::array<ExplainText, 8> explain_text{}; -}; -static_assert(sizeof(ControllerSupportArgNew) == 0x430, - "ControllerSupportArgNew has incorrect size."); - -struct ControllerUpdateFirmwareArg { - bool enable_force_update{}; - INSERT_PADDING_BYTES(3); -}; -static_assert(sizeof(ControllerUpdateFirmwareArg) == 0x4, - "ControllerUpdateFirmwareArg has incorrect size."); - -struct ControllerKeyRemappingArg { - u64 unknown{}; - u32 unknown_2{}; - INSERT_PADDING_WORDS(1); -}; -static_assert(sizeof(ControllerKeyRemappingArg) == 0x10, - "ControllerKeyRemappingArg has incorrect size."); - -struct ControllerSupportResultInfo { - s8 player_count{}; - INSERT_PADDING_BYTES(3); - u32 selected_id{}; - ControllerSupportResult result{}; -}; -static_assert(sizeof(ControllerSupportResultInfo) == 0xC, - "ControllerSupportResultInfo has incorrect size."); - -class Controller final : public Applet { -public: - explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::ControllerApplet& frontend_); - ~Controller() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - void ConfigurationComplete(bool is_success); - -private: - const Core::Frontend::ControllerApplet& frontend; - Core::System& system; - - ControllerAppletVersion controller_applet_version; - ControllerSupportArgPrivate controller_private_arg; - ControllerSupportArgOld controller_user_arg_old; - ControllerSupportArgNew controller_user_arg_new; - ControllerUpdateFirmwareArg controller_update_arg; - ControllerKeyRemappingArg controller_key_remapping_arg; - bool complete{false}; - Result status{ResultSuccess}; - bool is_single_mode{false}; - std::vector<u8> out_data; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp deleted file mode 100644 index 96126832c..000000000 --- a/src/core/hle/service/am/applets/applet_error.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <array> -#include <cstring> -#include "common/assert.h" -#include "common/logging/log.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/frontend/applets/error.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_error.h" -#include "core/hle/service/am/storage.h" -#include "core/reporter.h" - -namespace Service::AM::Applets { - -struct ErrorCode { - u32 error_category{}; - u32 error_number{}; - - static constexpr ErrorCode FromU64(u64 error_code) { - return { - .error_category{static_cast<u32>(error_code >> 32)}, - .error_number{static_cast<u32>(error_code & 0xFFFFFFFF)}, - }; - } - - static constexpr ErrorCode FromResult(Result result) { - return { - .error_category{2000 + static_cast<u32>(result.GetModule())}, - .error_number{result.GetDescription()}, - }; - } - - constexpr Result ToResult() const { - return Result{static_cast<ErrorModule>(error_category - 2000), error_number}; - } -}; -static_assert(sizeof(ErrorCode) == 0x8, "ErrorCode has incorrect size."); - -#pragma pack(push, 4) -struct ShowError { - u8 mode; - bool jump; - INSERT_PADDING_BYTES_NOINIT(4); - bool use_64bit_error_code; - INSERT_PADDING_BYTES_NOINIT(1); - u64 error_code_64; - u32 error_code_32; -}; -static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size."); -#pragma pack(pop) - -struct ShowErrorRecord { - u8 mode; - bool jump; - INSERT_PADDING_BYTES_NOINIT(6); - u64 error_code_64; - u64 posix_time; -}; -static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect size."); - -struct SystemErrorArg { - u8 mode; - bool jump; - INSERT_PADDING_BYTES_NOINIT(6); - u64 error_code_64; - std::array<char, 8> language_code; - std::array<char, 0x800> main_text; - std::array<char, 0x800> detail_text; -}; -static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect size."); - -struct ApplicationErrorArg { - u8 mode; - bool jump; - INSERT_PADDING_BYTES_NOINIT(6); - u32 error_code; - std::array<char, 8> language_code; - std::array<char, 0x800> main_text; - std::array<char, 0x800> detail_text; -}; -static_assert(sizeof(ApplicationErrorArg) == 0x1014, "ApplicationErrorArg has incorrect size."); - -union Error::ErrorArguments { - ShowError error; - ShowErrorRecord error_record; - SystemErrorArg system_error; - ApplicationErrorArg application_error; - std::array<u8, 0x1018> raw{}; -}; - -namespace { -template <typename T> -void CopyArgumentData(const std::vector<u8>& data, T& variable) { - ASSERT(data.size() >= sizeof(T)); - std::memcpy(&variable, data.data(), sizeof(T)); -} - -Result Decode64BitError(u64 error) { - return ErrorCode::FromU64(error).ToResult(); -} - -} // Anonymous namespace - -Error::Error(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::ErrorApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -Error::~Error() = default; - -void Error::Initialize() { - Applet::Initialize(); - args = std::make_unique<ErrorArguments>(); - complete = false; - - const auto storage = broker.PopNormalDataToApplet(); - ASSERT(storage != nullptr); - const auto data = storage->GetData(); - - ASSERT(!data.empty()); - std::memcpy(&mode, data.data(), sizeof(ErrorAppletMode)); - - switch (mode) { - case ErrorAppletMode::ShowError: - CopyArgumentData(data, args->error); - if (args->error.use_64bit_error_code) { - error_code = Decode64BitError(args->error.error_code_64); - } else { - error_code = Result(args->error.error_code_32); - } - break; - case ErrorAppletMode::ShowSystemError: - CopyArgumentData(data, args->system_error); - error_code = Result(Decode64BitError(args->system_error.error_code_64)); - break; - case ErrorAppletMode::ShowApplicationError: - CopyArgumentData(data, args->application_error); - error_code = Result(args->application_error.error_code); - break; - case ErrorAppletMode::ShowErrorPctl: - CopyArgumentData(data, args->error_record); - error_code = Decode64BitError(args->error_record.error_code_64); - break; - case ErrorAppletMode::ShowErrorRecord: - CopyArgumentData(data, args->error_record); - error_code = Decode64BitError(args->error_record.error_code_64); - break; - default: - UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); - break; - } -} - -bool Error::TransactionComplete() const { - return complete; -} - -Result Error::GetStatus() const { - return ResultSuccess; -} - -void Error::ExecuteInteractive() { - ASSERT_MSG(false, "Unexpected interactive applet data!"); -} - -void Error::Execute() { - if (complete) { - return; - } - - const auto callback = [this] { DisplayCompleted(); }; - const auto title_id = system.GetApplicationProcessProgramID(); - const auto& reporter{system.GetReporter()}; - - switch (mode) { - case ErrorAppletMode::ShowError: - reporter.SaveErrorReport(title_id, error_code); - frontend.ShowError(error_code, callback); - break; - case ErrorAppletMode::ShowSystemError: - case ErrorAppletMode::ShowApplicationError: { - const auto is_system = mode == ErrorAppletMode::ShowSystemError; - const auto& main_text = - is_system ? args->system_error.main_text : args->application_error.main_text; - const auto& detail_text = - is_system ? args->system_error.detail_text : args->application_error.detail_text; - - const auto main_text_string = - Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()); - const auto detail_text_string = - Common::StringFromFixedZeroTerminatedBuffer(detail_text.data(), detail_text.size()); - - reporter.SaveErrorReport(title_id, error_code, main_text_string, detail_text_string); - frontend.ShowCustomErrorText(error_code, main_text_string, detail_text_string, callback); - break; - } - case ErrorAppletMode::ShowErrorPctl: - case ErrorAppletMode::ShowErrorRecord: - reporter.SaveErrorReport(title_id, error_code, - fmt::format("{:016X}", args->error_record.posix_time)); - frontend.ShowErrorWithTimestamp( - error_code, std::chrono::seconds{args->error_record.posix_time}, callback); - break; - default: - UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); - DisplayCompleted(); - } -} - -void Error::DisplayCompleted() { - complete = true; - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{})); - broker.SignalStateChanged(); -} - -Result Error::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_error.h b/src/core/hle/service/am/applets/applet_error.h deleted file mode 100644 index d822a32bb..000000000 --- a/src/core/hle/service/am/applets/applet_error.h +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applets.h" - -namespace Core { -class System; -} - -namespace Service::AM::Applets { - -enum class ErrorAppletMode : u8 { - ShowError = 0, - ShowSystemError = 1, - ShowApplicationError = 2, - ShowEula = 3, - ShowErrorPctl = 4, - ShowErrorRecord = 5, - ShowUpdateEula = 8, -}; - -class Error final : public Applet { -public: - explicit Error(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::ErrorApplet& frontend_); - ~Error() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - void DisplayCompleted(); - -private: - union ErrorArguments; - - const Core::Frontend::ErrorApplet& frontend; - Result error_code = ResultSuccess; - ErrorAppletMode mode = ErrorAppletMode::ShowError; - std::unique_ptr<ErrorArguments> args; - - bool complete = false; - Core::System& system; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp deleted file mode 100644 index c010c78e2..000000000 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ /dev/null @@ -1,269 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "common/hex_util.h" -#include "common/logging/log.h" -#include "core/core.h" -#include "core/frontend/applets/general_frontend.h" -#include "core/hle/result.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_general_backend.h" -#include "core/hle/service/am/storage.h" -#include "core/reporter.h" - -namespace Service::AM::Applets { - -constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; - -static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) { - std::shared_ptr<IStorage> storage = broker.PopNormalDataToApplet(); - for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) { - const auto data = storage->GetData(); - LOG_INFO(Service_AM, - "called (STUBBED), during {} received normal data with size={:08X}, data={}", - prefix, data.size(), Common::HexToString(data)); - } - - storage = broker.PopInteractiveDataToApplet(); - for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) { - const auto data = storage->GetData(); - LOG_INFO(Service_AM, - "called (STUBBED), during {} received interactive data with size={:08X}, data={}", - prefix, data.size(), Common::HexToString(data)); - } -} - -Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_, - Core::Frontend::ParentalControlsApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -Auth::~Auth() = default; - -void Auth::Initialize() { - Applet::Initialize(); - complete = false; - - const auto storage = broker.PopNormalDataToApplet(); - ASSERT(storage != nullptr); - const auto data = storage->GetData(); - ASSERT(data.size() >= 0xC); - - struct Arg { - INSERT_PADDING_BYTES(4); - AuthAppletType type; - u8 arg0; - u8 arg1; - u8 arg2; - INSERT_PADDING_BYTES(1); - }; - static_assert(sizeof(Arg) == 0xC, "Arg (AuthApplet) has incorrect size."); - - Arg arg{}; - std::memcpy(&arg, data.data(), sizeof(Arg)); - - type = arg.type; - arg0 = arg.arg0; - arg1 = arg.arg1; - arg2 = arg.arg2; -} - -bool Auth::TransactionComplete() const { - return complete; -} - -Result Auth::GetStatus() const { - return successful ? ResultSuccess : ERROR_INVALID_PIN; -} - -void Auth::ExecuteInteractive() { - ASSERT_MSG(false, "Unexpected interactive applet data."); -} - -void Auth::Execute() { - if (complete) { - return; - } - - const auto unimplemented_log = [this] { - UNIMPLEMENTED_MSG("Unimplemented Auth applet type for type={:08X}, arg0={:02X}, " - "arg1={:02X}, arg2={:02X}", - type, arg0, arg1, arg2); - }; - - switch (type) { - case AuthAppletType::ShowParentalAuthentication: { - const auto callback = [this](bool is_successful) { AuthFinished(is_successful); }; - - if (arg0 == 1 && arg1 == 0 && arg2 == 1) { - // ShowAuthenticatorForConfiguration - frontend.VerifyPINForSettings(callback); - } else if (arg1 == 0 && arg2 == 0) { - // ShowParentalAuthentication(bool) - frontend.VerifyPIN(callback, static_cast<bool>(arg0)); - } else { - unimplemented_log(); - } - break; - } - case AuthAppletType::RegisterParentalPasscode: { - const auto callback = [this] { AuthFinished(true); }; - - if (arg0 == 0 && arg1 == 0 && arg2 == 0) { - // RegisterParentalPasscode - frontend.RegisterPIN(callback); - } else { - unimplemented_log(); - } - break; - } - case AuthAppletType::ChangeParentalPasscode: { - const auto callback = [this] { AuthFinished(true); }; - - if (arg0 == 0 && arg1 == 0 && arg2 == 0) { - // ChangeParentalPasscode - frontend.ChangePIN(callback); - } else { - unimplemented_log(); - } - break; - } - default: - unimplemented_log(); - break; - } -} - -void Auth::AuthFinished(bool is_successful) { - successful = is_successful; - - struct Return { - Result result_code; - }; - static_assert(sizeof(Return) == 0x4, "Return (AuthApplet) has incorrect size."); - - Return return_{GetStatus()}; - - std::vector<u8> out(sizeof(Return)); - std::memcpy(out.data(), &return_, sizeof(Return)); - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out))); - broker.SignalStateChanged(); -} - -Result Auth::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::PhotoViewerApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -PhotoViewer::~PhotoViewer() = default; - -void PhotoViewer::Initialize() { - Applet::Initialize(); - complete = false; - - const auto storage = broker.PopNormalDataToApplet(); - ASSERT(storage != nullptr); - const auto data = storage->GetData(); - ASSERT(!data.empty()); - mode = static_cast<PhotoViewerAppletMode>(data[0]); -} - -bool PhotoViewer::TransactionComplete() const { - return complete; -} - -Result PhotoViewer::GetStatus() const { - return ResultSuccess; -} - -void PhotoViewer::ExecuteInteractive() { - ASSERT_MSG(false, "Unexpected interactive applet data."); -} - -void PhotoViewer::Execute() { - if (complete) - return; - - const auto callback = [this] { ViewFinished(); }; - switch (mode) { - case PhotoViewerAppletMode::CurrentApp: - frontend.ShowPhotosForApplication(system.GetApplicationProcessProgramID(), callback); - break; - case PhotoViewerAppletMode::AllApps: - frontend.ShowAllPhotos(callback); - break; - default: - UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", mode); - break; - } -} - -void PhotoViewer::ViewFinished() { - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>{})); - broker.SignalStateChanged(); -} - -Result PhotoViewer::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_) - : Applet{system_, applet_mode_}, id{id_}, system{system_} {} - -StubApplet::~StubApplet() = default; - -void StubApplet::Initialize() { - LOG_WARNING(Service_AM, "called (STUBBED)"); - Applet::Initialize(); - - const auto data = broker.PeekDataToAppletForDebug(); - system.GetReporter().SaveUnimplementedAppletReport( - static_cast<u32>(id), static_cast<u32>(common_args.arguments_version), - common_args.library_version, static_cast<u32>(common_args.theme_color), - common_args.play_startup_sound, common_args.system_tick, data.normal, data.interactive); - - LogCurrentStorage(broker, "Initialize"); -} - -bool StubApplet::TransactionComplete() const { - LOG_WARNING(Service_AM, "called (STUBBED)"); - return true; -} - -Result StubApplet::GetStatus() const { - LOG_WARNING(Service_AM, "called (STUBBED)"); - return ResultSuccess; -} - -void StubApplet::ExecuteInteractive() { - LOG_WARNING(Service_AM, "called (STUBBED)"); - LogCurrentStorage(broker, "ExecuteInteractive"); - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.PushInteractiveDataFromApplet( - std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.SignalStateChanged(); -} - -void StubApplet::Execute() { - LOG_WARNING(Service_AM, "called (STUBBED)"); - LogCurrentStorage(broker, "Execute"); - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.PushInteractiveDataFromApplet( - std::make_shared<IStorage>(system, std::vector<u8>(0x1000))); - broker.SignalStateChanged(); -} - -Result StubApplet::RequestExit() { - // Nothing to do. - R_SUCCEED(); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_general_backend.h b/src/core/hle/service/am/applets/applet_general_backend.h deleted file mode 100644 index 34ecaebb9..000000000 --- a/src/core/hle/service/am/applets/applet_general_backend.h +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/am/applets/applets.h" - -namespace Core { -class System; -} - -namespace Service::AM::Applets { - -enum class AuthAppletType : u32 { - ShowParentalAuthentication, - RegisterParentalPasscode, - ChangeParentalPasscode, -}; - -class Auth final : public Applet { -public: - explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_, - Core::Frontend::ParentalControlsApplet& frontend_); - ~Auth() override; - - void Initialize() override; - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - void AuthFinished(bool is_successful = true); - -private: - Core::Frontend::ParentalControlsApplet& frontend; - Core::System& system; - bool complete = false; - bool successful = false; - - AuthAppletType type = AuthAppletType::ShowParentalAuthentication; - u8 arg0 = 0; - u8 arg1 = 0; - u8 arg2 = 0; -}; - -enum class PhotoViewerAppletMode : u8 { - CurrentApp = 0, - AllApps = 1, -}; - -class PhotoViewer final : public Applet { -public: - explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::PhotoViewerApplet& frontend_); - ~PhotoViewer() override; - - void Initialize() override; - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - void ViewFinished(); - -private: - const Core::Frontend::PhotoViewerApplet& frontend; - bool complete = false; - PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp; - Core::System& system; -}; - -class StubApplet final : public Applet { -public: - explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_); - ~StubApplet() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - -private: - AppletId id; - Core::System& system; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp deleted file mode 100644 index 1576b45c4..000000000 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "common/logging/log.h" -#include "core/core.h" -#include "core/frontend/applets/mii_edit.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_mii_edit.h" -#include "core/hle/service/am/storage.h" -#include "core/hle/service/mii/mii.h" -#include "core/hle/service/mii/mii_manager.h" -#include "core/hle/service/sm/sm.h" - -namespace Service::AM::Applets { - -MiiEdit::MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::MiiEditApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -MiiEdit::~MiiEdit() = default; - -void MiiEdit::Initialize() { - // Note: MiiEdit is not initialized with common arguments. - // Instead, it is initialized by an AppletInput storage with size 0x100 bytes. - // Do NOT call Applet::Initialize() here. - - const auto storage = broker.PopNormalDataToApplet(); - ASSERT(storage != nullptr); - - const auto applet_input_data = storage->GetData(); - ASSERT(applet_input_data.size() >= sizeof(MiiEditAppletInputCommon)); - - std::memcpy(&applet_input_common, applet_input_data.data(), sizeof(MiiEditAppletInputCommon)); - - LOG_INFO(Service_AM, - "Initializing MiiEdit Applet with MiiEditAppletVersion={} and MiiEditAppletMode={}", - applet_input_common.version, applet_input_common.applet_mode); - - switch (applet_input_common.version) { - case MiiEditAppletVersion::Version3: - ASSERT(applet_input_data.size() == - sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV3)); - std::memcpy(&applet_input_v3, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), - sizeof(MiiEditAppletInputV3)); - break; - case MiiEditAppletVersion::Version4: - ASSERT(applet_input_data.size() == - sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV4)); - std::memcpy(&applet_input_v4, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), - sizeof(MiiEditAppletInputV4)); - break; - default: - UNIMPLEMENTED_MSG("Unknown MiiEditAppletVersion={} with size={}", - applet_input_common.version, applet_input_data.size()); - ASSERT(applet_input_data.size() >= - sizeof(MiiEditAppletInputCommon) + sizeof(MiiEditAppletInputV4)); - std::memcpy(&applet_input_v4, applet_input_data.data() + sizeof(MiiEditAppletInputCommon), - sizeof(MiiEditAppletInputV4)); - break; - } - - manager = system.ServiceManager().GetService<Mii::IStaticService>("mii:e")->GetMiiManager(); - if (manager == nullptr) { - manager = std::make_shared<Mii::MiiManager>(); - } - manager->Initialize(metadata); -} - -bool MiiEdit::TransactionComplete() const { - return is_complete; -} - -Result MiiEdit::GetStatus() const { - return ResultSuccess; -} - -void MiiEdit::ExecuteInteractive() { - ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); -} - -void MiiEdit::Execute() { - if (is_complete) { - return; - } - - // This is a default stub for each of the MiiEdit applet modes. - switch (applet_input_common.applet_mode) { - case MiiEditAppletMode::ShowMiiEdit: - case MiiEditAppletMode::AppendMiiImage: - case MiiEditAppletMode::UpdateMiiImage: - MiiEditOutput(MiiEditResult::Success, 0); - break; - case MiiEditAppletMode::AppendMii: { - Mii::StoreData store_data{}; - store_data.BuildRandom(Mii::Age::All, Mii::Gender::All, Mii::Race::All); - store_data.SetNickname({u'y', u'u', u'z', u'u'}); - store_data.SetChecksum(); - const auto result = manager->AddOrReplace(metadata, store_data); - - if (result.IsError()) { - MiiEditOutput(MiiEditResult::Cancel, 0); - break; - } - - s32 index = manager->FindIndex(store_data.GetCreateId(), false); - - if (index == -1) { - MiiEditOutput(MiiEditResult::Cancel, 0); - break; - } - - MiiEditOutput(MiiEditResult::Success, index); - break; - } - case MiiEditAppletMode::CreateMii: { - Mii::CharInfo char_info{}; - manager->BuildRandom(char_info, Mii::Age::All, Mii::Gender::All, Mii::Race::All); - - const MiiEditCharInfo edit_char_info{ - .mii_info{char_info}, - }; - - MiiEditOutputForCharInfoEditing(MiiEditResult::Success, edit_char_info); - break; - } - case MiiEditAppletMode::EditMii: { - const MiiEditCharInfo edit_char_info{ - .mii_info{applet_input_v4.char_info.mii_info}, - }; - - MiiEditOutputForCharInfoEditing(MiiEditResult::Success, edit_char_info); - break; - } - default: - UNIMPLEMENTED_MSG("Unknown MiiEditAppletMode={}", applet_input_common.applet_mode); - - MiiEditOutput(MiiEditResult::Success, 0); - break; - } -} - -void MiiEdit::MiiEditOutput(MiiEditResult result, s32 index) { - const MiiEditAppletOutput applet_output{ - .result{result}, - .index{index}, - }; - - LOG_INFO(Input, "called, result={}, index={}", result, index); - - std::vector<u8> out_data(sizeof(MiiEditAppletOutput)); - std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutput)); - - is_complete = true; - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); -} - -void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result, - const MiiEditCharInfo& char_info) { - const MiiEditAppletOutputForCharInfoEditing applet_output{ - .result{result}, - .char_info{char_info}, - }; - - std::vector<u8> out_data(sizeof(MiiEditAppletOutputForCharInfoEditing)); - std::memcpy(out_data.data(), &applet_output, sizeof(MiiEditAppletOutputForCharInfoEditing)); - - is_complete = true; - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); -} - -Result MiiEdit::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h deleted file mode 100644 index 7ff34af49..000000000 --- a/src/core/hle/service/am/applets/applet_mii_edit.h +++ /dev/null @@ -1,52 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applet_mii_edit_types.h" -#include "core/hle/service/am/applets/applets.h" - -namespace Core { -class System; -} // namespace Core - -namespace Service::Mii { -struct DatabaseSessionMetadata; -class MiiManager; -} // namespace Service::Mii - -namespace Service::AM::Applets { - -class MiiEdit final : public Applet { -public: - explicit MiiEdit(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::MiiEditApplet& frontend_); - ~MiiEdit() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - void MiiEditOutput(MiiEditResult result, s32 index); - - void MiiEditOutputForCharInfoEditing(MiiEditResult result, const MiiEditCharInfo& char_info); - -private: - const Core::Frontend::MiiEditApplet& frontend; - Core::System& system; - - MiiEditAppletInputCommon applet_input_common{}; - MiiEditAppletInputV3 applet_input_v3{}; - MiiEditAppletInputV4 applet_input_v4{}; - - bool is_complete{false}; - std::shared_ptr<Mii::MiiManager> manager = nullptr; - Mii::DatabaseSessionMetadata metadata{}; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii_edit_types.h b/src/core/hle/service/am/applets/applet_mii_edit_types.h deleted file mode 100644 index f3d764073..000000000 --- a/src/core/hle/service/am/applets/applet_mii_edit_types.h +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> - -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/uuid.h" -#include "core/hle/service/mii/types/char_info.h" - -namespace Service::AM::Applets { - -enum class MiiEditAppletVersion : s32 { - Version3 = 0x3, // 1.0.0 - 10.1.1 - Version4 = 0x4, // 10.2.0+ -}; - -// This is nn::mii::AppletMode -enum class MiiEditAppletMode : u32 { - ShowMiiEdit = 0, - AppendMii = 1, - AppendMiiImage = 2, - UpdateMiiImage = 3, - CreateMii = 4, - EditMii = 5, -}; - -enum class MiiEditResult : u32 { - Success, - Cancel, -}; - -struct MiiEditCharInfo { - Service::Mii::CharInfo mii_info{}; -}; -static_assert(sizeof(MiiEditCharInfo) == 0x58, "MiiEditCharInfo has incorrect size."); - -struct MiiEditAppletInputCommon { - MiiEditAppletVersion version{}; - MiiEditAppletMode applet_mode{}; -}; -static_assert(sizeof(MiiEditAppletInputCommon) == 0x8, - "MiiEditAppletInputCommon has incorrect size."); - -struct MiiEditAppletInputV3 { - u32 special_mii_key_code{}; - std::array<Common::UUID, 8> valid_uuids{}; - Common::UUID used_uuid{}; - INSERT_PADDING_BYTES(0x64); -}; -static_assert(sizeof(MiiEditAppletInputV3) == 0x100 - sizeof(MiiEditAppletInputCommon), - "MiiEditAppletInputV3 has incorrect size."); - -struct MiiEditAppletInputV4 { - u32 special_mii_key_code{}; - MiiEditCharInfo char_info{}; - INSERT_PADDING_BYTES(0x28); - Common::UUID used_uuid{}; - INSERT_PADDING_BYTES(0x64); -}; -static_assert(sizeof(MiiEditAppletInputV4) == 0x100 - sizeof(MiiEditAppletInputCommon), - "MiiEditAppletInputV4 has incorrect size."); - -// This is nn::mii::AppletOutput -struct MiiEditAppletOutput { - MiiEditResult result{}; - s32 index{}; - INSERT_PADDING_BYTES(0x18); -}; -static_assert(sizeof(MiiEditAppletOutput) == 0x20, "MiiEditAppletOutput has incorrect size."); - -// This is nn::mii::AppletOutputForCharInfoEditing -struct MiiEditAppletOutputForCharInfoEditing { - MiiEditResult result{}; - MiiEditCharInfo char_info{}; - INSERT_PADDING_BYTES(0x24); -}; -static_assert(sizeof(MiiEditAppletOutputForCharInfoEditing) == 0x80, - "MiiEditAppletOutputForCharInfoEditing has incorrect size."); - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp deleted file mode 100644 index f32db6842..000000000 --- a/src/core/hle/service/am/applets/applet_profile_select.cpp +++ /dev/null @@ -1,124 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <cstring> - -#include "common/assert.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/frontend/applets/profile_select.h" -#include "core/hle/service/acc/errors.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_profile_select.h" -#include "core/hle/service/am/storage.h" - -namespace Service::AM::Applets { - -ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::ProfileSelectApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -ProfileSelect::~ProfileSelect() = default; - -void ProfileSelect::Initialize() { - complete = false; - status = ResultSuccess; - final_data.clear(); - - Applet::Initialize(); - profile_select_version = ProfileSelectAppletVersion{common_args.library_version}; - - const auto user_config_storage = broker.PopNormalDataToApplet(); - ASSERT(user_config_storage != nullptr); - const auto& user_config = user_config_storage->GetData(); - - LOG_INFO(Service_AM, "Initializing Profile Select Applet with version={}", - profile_select_version); - - switch (profile_select_version) { - case ProfileSelectAppletVersion::Version1: - ASSERT(user_config.size() == sizeof(UiSettingsV1)); - std::memcpy(&config_old, user_config.data(), sizeof(UiSettingsV1)); - break; - case ProfileSelectAppletVersion::Version2: - case ProfileSelectAppletVersion::Version3: - ASSERT(user_config.size() == sizeof(UiSettings)); - std::memcpy(&config, user_config.data(), sizeof(UiSettings)); - break; - default: - UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version); - break; - } -} - -bool ProfileSelect::TransactionComplete() const { - return complete; -} - -Result ProfileSelect::GetStatus() const { - return status; -} - -void ProfileSelect::ExecuteInteractive() { - ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); -} - -void ProfileSelect::Execute() { - if (complete) { - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); - return; - } - - Core::Frontend::ProfileSelectParameters parameters{}; - - switch (profile_select_version) { - case ProfileSelectAppletVersion::Version1: - parameters = { - .mode = config_old.mode, - .invalid_uid_list = config_old.invalid_uid_list, - .display_options = config_old.display_options, - .purpose = UserSelectionPurpose::General, - }; - break; - case ProfileSelectAppletVersion::Version2: - case ProfileSelectAppletVersion::Version3: - parameters = { - .mode = config.mode, - .invalid_uid_list = config.invalid_uid_list, - .display_options = config.display_options, - .purpose = config.purpose, - }; - break; - default: - UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version); - break; - } - - frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); }, - parameters); -} - -void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) { - UiReturnArg output{}; - - if (uuid.has_value() && uuid->IsValid()) { - output.result = 0; - output.uuid_selected = *uuid; - } else { - status = Account::ResultCancelledByUser; - output.result = Account::ResultCancelledByUser.raw; - output.uuid_selected = Common::InvalidUUID; - } - - final_data = std::vector<u8>(sizeof(UiReturnArg)); - std::memcpy(final_data.data(), &output, final_data.size()); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data))); - broker.SignalStateChanged(); -} - -Result ProfileSelect::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_profile_select.h b/src/core/hle/service/am/applets/applet_profile_select.h deleted file mode 100644 index 673eed516..000000000 --- a/src/core/hle/service/am/applets/applet_profile_select.h +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <vector> - -#include "common/common_funcs.h" -#include "common/uuid.h" -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applets.h" - -namespace Core { -class System; -} - -namespace Service::AM::Applets { - -enum class ProfileSelectAppletVersion : u32 { - Version1 = 0x1, // 1.0.0+ - Version2 = 0x10000, // 2.0.0+ - Version3 = 0x20000, // 6.0.0+ -}; - -// This is nn::account::UiMode -enum class UiMode { - UserSelector, - UserCreator, - EnsureNetworkServiceAccountAvailable, - UserIconEditor, - UserNicknameEditor, - UserCreatorForStarter, - NintendoAccountAuthorizationRequestContext, - IntroduceExternalNetworkServiceAccount, - IntroduceExternalNetworkServiceAccountForRegistration, - NintendoAccountNnidLinker, - LicenseRequirementsForNetworkService, - LicenseRequirementsForNetworkServiceWithUserContextImpl, - UserCreatorForImmediateNaLoginTest, - UserQualificationPromoter, -}; - -// This is nn::account::UserSelectionPurpose -enum class UserSelectionPurpose { - General, - GameCardRegistration, - EShopLaunch, - EShopItemShow, - PicturePost, - NintendoAccountLinkage, - SettingsUpdate, - SaveDataDeletion, - UserMigration, - SaveDataTransfer, -}; - -// This is nn::account::NintendoAccountStartupDialogType -enum class NintendoAccountStartupDialogType { - LoginAndCreate, - Login, - Create, -}; - -// This is nn::account::UserSelectionSettingsForSystemService -struct UserSelectionSettingsForSystemService { - UserSelectionPurpose purpose; - bool enable_user_creation; - INSERT_PADDING_BYTES(0x3); -}; -static_assert(sizeof(UserSelectionSettingsForSystemService) == 0x8, - "UserSelectionSettingsForSystemService has incorrect size."); - -struct UiSettingsDisplayOptions { - bool is_network_service_account_required; - bool is_skip_enabled; - bool is_system_or_launcher; - bool is_registration_permitted; - bool show_skip_button; - bool additional_select; - bool show_user_selector; - bool is_unqualified_user_selectable; -}; -static_assert(sizeof(UiSettingsDisplayOptions) == 0x8, - "UiSettingsDisplayOptions has incorrect size."); - -struct UiSettingsV1 { - UiMode mode; - INSERT_PADDING_BYTES(0x4); - std::array<Common::UUID, 8> invalid_uid_list; - u64 application_id; - UiSettingsDisplayOptions display_options; -}; -static_assert(sizeof(UiSettingsV1) == 0x98, "UiSettings has incorrect size."); - -// This is nn::account::UiSettings -struct UiSettings { - UiMode mode; - INSERT_PADDING_BYTES(0x4); - std::array<Common::UUID, 8> invalid_uid_list; - u64 application_id; - UiSettingsDisplayOptions display_options; - UserSelectionPurpose purpose; - INSERT_PADDING_BYTES(0x4); -}; -static_assert(sizeof(UiSettings) == 0xA0, "UiSettings has incorrect size."); - -// This is nn::account::UiReturnArg -struct UiReturnArg { - u64 result; - Common::UUID uuid_selected; -}; -static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size."); - -class ProfileSelect final : public Applet { -public: - explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::ProfileSelectApplet& frontend_); - ~ProfileSelect() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - void SelectionComplete(std::optional<Common::UUID> uuid); - -private: - const Core::Frontend::ProfileSelectApplet& frontend; - - UiSettings config; - UiSettingsV1 config_old; - ProfileSelectAppletVersion profile_select_version; - - bool complete = false; - Result status = ResultSuccess; - std::vector<u8> final_data; - Core::System& system; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp deleted file mode 100644 index a6a07cef3..000000000 --- a/src/core/hle/service/am/applets/applet_software_keyboard.cpp +++ /dev/null @@ -1,1277 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/string_util.h" -#include "core/core.h" -#include "core/frontend/applets/software_keyboard.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_software_keyboard.h" -#include "core/hle/service/am/storage.h" - -namespace Service::AM::Applets { - -namespace { - -// The maximum number of UTF-16 characters that can be input into the swkbd text field. -constexpr u32 DEFAULT_MAX_TEXT_LENGTH = 500; - -constexpr std::size_t REPLY_BASE_SIZE = sizeof(SwkbdState) + sizeof(SwkbdReplyType); -constexpr std::size_t REPLY_UTF8_SIZE = 0x7D4; -constexpr std::size_t REPLY_UTF16_SIZE = 0x3EC; - -constexpr const char* GetTextCheckResultName(SwkbdTextCheckResult text_check_result) { - switch (text_check_result) { - case SwkbdTextCheckResult::Success: - return "Success"; - case SwkbdTextCheckResult::Failure: - return "Failure"; - case SwkbdTextCheckResult::Confirm: - return "Confirm"; - case SwkbdTextCheckResult::Silent: - return "Silent"; - default: - UNIMPLEMENTED_MSG("Unknown TextCheckResult={}", text_check_result); - return "Unknown"; - } -} - -void SetReplyBase(std::vector<u8>& reply, SwkbdState state, SwkbdReplyType reply_type) { - std::memcpy(reply.data(), &state, sizeof(SwkbdState)); - std::memcpy(reply.data() + sizeof(SwkbdState), &reply_type, sizeof(SwkbdReplyType)); -} - -} // Anonymous namespace - -SoftwareKeyboard::SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_, - Core::Frontend::SoftwareKeyboardApplet& frontend_) - : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} - -SoftwareKeyboard::~SoftwareKeyboard() = default; - -void SoftwareKeyboard::Initialize() { - Applet::Initialize(); - - LOG_INFO(Service_AM, "Initializing Software Keyboard Applet with LibraryAppletMode={}", - applet_mode); - - LOG_DEBUG(Service_AM, - "Initializing Applet with common_args: arg_version={}, lib_version={}, " - "play_startup_sound={}, size={}, system_tick={}, theme_color={}", - common_args.arguments_version, common_args.library_version, - common_args.play_startup_sound, common_args.size, common_args.system_tick, - common_args.theme_color); - - swkbd_applet_version = SwkbdAppletVersion{common_args.library_version}; - - switch (applet_mode) { - case LibraryAppletMode::AllForeground: - InitializeForeground(); - break; - case LibraryAppletMode::Background: - case LibraryAppletMode::BackgroundIndirectDisplay: - InitializeBackground(applet_mode); - break; - default: - ASSERT_MSG(false, "Invalid LibraryAppletMode={}", applet_mode); - break; - } -} - -bool SoftwareKeyboard::TransactionComplete() const { - return complete; -} - -Result SoftwareKeyboard::GetStatus() const { - return status; -} - -void SoftwareKeyboard::ExecuteInteractive() { - if (complete) { - return; - } - - if (is_background) { - ProcessInlineKeyboardRequest(); - } else { - ProcessTextCheck(); - } -} - -void SoftwareKeyboard::Execute() { - if (complete) { - return; - } - - if (is_background) { - return; - } - - ShowNormalKeyboard(); -} - -void SoftwareKeyboard::SubmitTextNormal(SwkbdResult result, std::u16string submitted_text, - bool confirmed) { - if (complete) { - return; - } - - if (swkbd_config_common.use_text_check && result == SwkbdResult::Ok) { - if (confirmed) { - SubmitNormalOutputAndExit(result, submitted_text); - } else { - SubmitForTextCheck(submitted_text); - } - } else { - SubmitNormalOutputAndExit(result, submitted_text); - } -} - -void SoftwareKeyboard::SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text, - s32 cursor_position) { - if (complete) { - return; - } - - current_text = std::move(submitted_text); - current_cursor_position = cursor_position; - - if (inline_use_utf8) { - switch (reply_type) { - case SwkbdReplyType::ChangedString: - reply_type = SwkbdReplyType::ChangedStringUtf8; - break; - case SwkbdReplyType::MovedCursor: - reply_type = SwkbdReplyType::MovedCursorUtf8; - break; - case SwkbdReplyType::DecidedEnter: - reply_type = SwkbdReplyType::DecidedEnterUtf8; - break; - default: - break; - } - } - - if (use_changed_string_v2) { - switch (reply_type) { - case SwkbdReplyType::ChangedString: - reply_type = SwkbdReplyType::ChangedStringV2; - break; - case SwkbdReplyType::ChangedStringUtf8: - reply_type = SwkbdReplyType::ChangedStringUtf8V2; - break; - default: - break; - } - } - - if (use_moved_cursor_v2) { - switch (reply_type) { - case SwkbdReplyType::MovedCursor: - reply_type = SwkbdReplyType::MovedCursorV2; - break; - case SwkbdReplyType::MovedCursorUtf8: - reply_type = SwkbdReplyType::MovedCursorUtf8V2; - break; - default: - break; - } - } - - SendReply(reply_type); -} - -void SoftwareKeyboard::InitializeForeground() { - LOG_INFO(Service_AM, "Initializing Normal Software Keyboard Applet."); - - is_background = false; - - const auto swkbd_config_storage = broker.PopNormalDataToApplet(); - ASSERT(swkbd_config_storage != nullptr); - - const auto& swkbd_config_data = swkbd_config_storage->GetData(); - ASSERT(swkbd_config_data.size() >= sizeof(SwkbdConfigCommon)); - - std::memcpy(&swkbd_config_common, swkbd_config_data.data(), sizeof(SwkbdConfigCommon)); - - switch (swkbd_applet_version) { - case SwkbdAppletVersion::Version5: - case SwkbdAppletVersion::Version65542: - ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigOld)); - std::memcpy(&swkbd_config_old, swkbd_config_data.data() + sizeof(SwkbdConfigCommon), - sizeof(SwkbdConfigOld)); - break; - case SwkbdAppletVersion::Version196615: - case SwkbdAppletVersion::Version262152: - case SwkbdAppletVersion::Version327689: - ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigOld2)); - std::memcpy(&swkbd_config_old2, swkbd_config_data.data() + sizeof(SwkbdConfigCommon), - sizeof(SwkbdConfigOld2)); - break; - case SwkbdAppletVersion::Version393227: - case SwkbdAppletVersion::Version524301: - ASSERT(swkbd_config_data.size() == sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigNew)); - std::memcpy(&swkbd_config_new, swkbd_config_data.data() + sizeof(SwkbdConfigCommon), - sizeof(SwkbdConfigNew)); - break; - default: - UNIMPLEMENTED_MSG("Unknown SwkbdConfig revision={} with size={}", swkbd_applet_version, - swkbd_config_data.size()); - ASSERT(swkbd_config_data.size() >= sizeof(SwkbdConfigCommon) + sizeof(SwkbdConfigNew)); - std::memcpy(&swkbd_config_new, swkbd_config_data.data() + sizeof(SwkbdConfigCommon), - sizeof(SwkbdConfigNew)); - break; - } - - const auto work_buffer_storage = broker.PopNormalDataToApplet(); - ASSERT(work_buffer_storage != nullptr); - - if (swkbd_config_common.initial_string_length == 0) { - InitializeFrontendNormalKeyboard(); - return; - } - - const auto& work_buffer = work_buffer_storage->GetData(); - - std::vector<char16_t> initial_string(swkbd_config_common.initial_string_length); - - std::memcpy(initial_string.data(), - work_buffer.data() + swkbd_config_common.initial_string_offset, - swkbd_config_common.initial_string_length * sizeof(char16_t)); - - initial_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(initial_string.data(), - initial_string.size()); - - LOG_DEBUG(Service_AM, "\nInitial Text: {}", Common::UTF16ToUTF8(initial_text)); - - InitializeFrontendNormalKeyboard(); -} - -void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mode) { - LOG_INFO(Service_AM, "Initializing Inline Software Keyboard Applet."); - - is_background = true; - - const auto swkbd_inline_initialize_arg_storage = broker.PopNormalDataToApplet(); - ASSERT(swkbd_inline_initialize_arg_storage != nullptr); - - const auto& swkbd_inline_initialize_arg = swkbd_inline_initialize_arg_storage->GetData(); - ASSERT(swkbd_inline_initialize_arg.size() == sizeof(SwkbdInitializeArg)); - - std::memcpy(&swkbd_initialize_arg, swkbd_inline_initialize_arg.data(), - swkbd_inline_initialize_arg.size()); - - if (swkbd_initialize_arg.library_applet_mode_flag) { - ASSERT(library_applet_mode == LibraryAppletMode::Background); - } else { - ASSERT(library_applet_mode == LibraryAppletMode::BackgroundIndirectDisplay); - } -} - -void SoftwareKeyboard::ProcessTextCheck() { - const auto text_check_storage = broker.PopInteractiveDataToApplet(); - ASSERT(text_check_storage != nullptr); - - const auto& text_check_data = text_check_storage->GetData(); - ASSERT(text_check_data.size() == sizeof(SwkbdTextCheck)); - - SwkbdTextCheck swkbd_text_check; - - std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck)); - - std::u16string text_check_message = [this, &swkbd_text_check]() -> std::u16string { - if (swkbd_text_check.text_check_result == SwkbdTextCheckResult::Failure || - swkbd_text_check.text_check_result == SwkbdTextCheckResult::Confirm) { - return swkbd_config_common.use_utf8 - ? Common::UTF8ToUTF16(Common::StringFromFixedZeroTerminatedBuffer( - reinterpret_cast<const char*>( - swkbd_text_check.text_check_message.data()), - swkbd_text_check.text_check_message.size() * sizeof(char16_t))) - : Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_text_check.text_check_message.data(), - swkbd_text_check.text_check_message.size()); - } else { - return u""; - } - }(); - - LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}", - GetTextCheckResultName(swkbd_text_check.text_check_result), - Common::UTF16ToUTF8(text_check_message)); - - switch (swkbd_text_check.text_check_result) { - case SwkbdTextCheckResult::Success: - SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text); - break; - case SwkbdTextCheckResult::Failure: - ShowTextCheckDialog(SwkbdTextCheckResult::Failure, std::move(text_check_message)); - break; - case SwkbdTextCheckResult::Confirm: - ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, std::move(text_check_message)); - break; - case SwkbdTextCheckResult::Silent: - default: - break; - } -} - -void SoftwareKeyboard::ProcessInlineKeyboardRequest() { - const auto request_data_storage = broker.PopInteractiveDataToApplet(); - ASSERT(request_data_storage != nullptr); - - const auto& request_data = request_data_storage->GetData(); - ASSERT(request_data.size() >= sizeof(SwkbdRequestCommand)); - - SwkbdRequestCommand request_command; - - std::memcpy(&request_command, request_data.data(), sizeof(SwkbdRequestCommand)); - - switch (request_command) { - case SwkbdRequestCommand::Finalize: - RequestFinalize(request_data); - break; - case SwkbdRequestCommand::SetUserWordInfo: - RequestSetUserWordInfo(request_data); - break; - case SwkbdRequestCommand::SetCustomizeDic: - RequestSetCustomizeDic(request_data); - break; - case SwkbdRequestCommand::Calc: - RequestCalc(request_data); - break; - case SwkbdRequestCommand::SetCustomizedDictionaries: - RequestSetCustomizedDictionaries(request_data); - break; - case SwkbdRequestCommand::UnsetCustomizedDictionaries: - RequestUnsetCustomizedDictionaries(request_data); - break; - case SwkbdRequestCommand::SetChangedStringV2Flag: - RequestSetChangedStringV2Flag(request_data); - break; - case SwkbdRequestCommand::SetMovedCursorV2Flag: - RequestSetMovedCursorV2Flag(request_data); - break; - default: - UNIMPLEMENTED_MSG("Unknown SwkbdRequestCommand={}", request_command); - break; - } -} - -void SoftwareKeyboard::SubmitNormalOutputAndExit(SwkbdResult result, - std::u16string submitted_text) { - std::vector<u8> out_data(sizeof(SwkbdResult) + STRING_BUFFER_SIZE); - - if (swkbd_config_common.use_utf8) { - std::string utf8_submitted_text = Common::UTF16ToUTF8(submitted_text); - - LOG_DEBUG(Service_AM, "\nSwkbdResult: {}\nUTF-8 Submitted Text: {}", result, - utf8_submitted_text); - - std::memcpy(out_data.data(), &result, sizeof(SwkbdResult)); - std::memcpy(out_data.data() + sizeof(SwkbdResult), utf8_submitted_text.data(), - utf8_submitted_text.size()); - } else { - LOG_DEBUG(Service_AM, "\nSwkbdResult: {}\nUTF-16 Submitted Text: {}", result, - Common::UTF16ToUTF8(submitted_text)); - - std::memcpy(out_data.data(), &result, sizeof(SwkbdResult)); - std::memcpy(out_data.data() + sizeof(SwkbdResult), submitted_text.data(), - submitted_text.size() * sizeof(char16_t)); - } - - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - - ExitKeyboard(); -} - -void SoftwareKeyboard::SubmitForTextCheck(std::u16string submitted_text) { - current_text = std::move(submitted_text); - - std::vector<u8> out_data(sizeof(u64) + STRING_BUFFER_SIZE); - - if (swkbd_config_common.use_utf8) { - std::string utf8_submitted_text = Common::UTF16ToUTF8(current_text); - // Include the null terminator in the buffer size. - const u64 buffer_size = utf8_submitted_text.size() + 1; - - LOG_DEBUG(Service_AM, "\nBuffer Size: {}\nUTF-8 Submitted Text: {}", buffer_size, - utf8_submitted_text); - - std::memcpy(out_data.data(), &buffer_size, sizeof(u64)); - std::memcpy(out_data.data() + sizeof(u64), utf8_submitted_text.data(), - utf8_submitted_text.size()); - } else { - // Include the null terminator in the buffer size. - const u64 buffer_size = (current_text.size() + 1) * sizeof(char16_t); - - LOG_DEBUG(Service_AM, "\nBuffer Size: {}\nUTF-16 Submitted Text: {}", buffer_size, - Common::UTF16ToUTF8(current_text)); - - std::memcpy(out_data.data(), &buffer_size, sizeof(u64)); - std::memcpy(out_data.data() + sizeof(u64), current_text.data(), - current_text.size() * sizeof(char16_t)); - } - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); -} - -void SoftwareKeyboard::SendReply(SwkbdReplyType reply_type) { - switch (reply_type) { - case SwkbdReplyType::FinishedInitialize: - ReplyFinishedInitialize(); - break; - case SwkbdReplyType::Default: - ReplyDefault(); - break; - case SwkbdReplyType::ChangedString: - ReplyChangedString(); - break; - case SwkbdReplyType::MovedCursor: - ReplyMovedCursor(); - break; - case SwkbdReplyType::MovedTab: - ReplyMovedTab(); - break; - case SwkbdReplyType::DecidedEnter: - ReplyDecidedEnter(); - break; - case SwkbdReplyType::DecidedCancel: - ReplyDecidedCancel(); - break; - case SwkbdReplyType::ChangedStringUtf8: - ReplyChangedStringUtf8(); - break; - case SwkbdReplyType::MovedCursorUtf8: - ReplyMovedCursorUtf8(); - break; - case SwkbdReplyType::DecidedEnterUtf8: - ReplyDecidedEnterUtf8(); - break; - case SwkbdReplyType::UnsetCustomizeDic: - ReplyUnsetCustomizeDic(); - break; - case SwkbdReplyType::ReleasedUserWordInfo: - ReplyReleasedUserWordInfo(); - break; - case SwkbdReplyType::UnsetCustomizedDictionaries: - ReplyUnsetCustomizedDictionaries(); - break; - case SwkbdReplyType::ChangedStringV2: - ReplyChangedStringV2(); - break; - case SwkbdReplyType::MovedCursorV2: - ReplyMovedCursorV2(); - break; - case SwkbdReplyType::ChangedStringUtf8V2: - ReplyChangedStringUtf8V2(); - break; - case SwkbdReplyType::MovedCursorUtf8V2: - ReplyMovedCursorUtf8V2(); - break; - default: - UNIMPLEMENTED_MSG("Unknown SwkbdReplyType={}", reply_type); - ReplyDefault(); - break; - } -} - -void SoftwareKeyboard::ChangeState(SwkbdState state) { - swkbd_state = state; - - ReplyDefault(); -} - -void SoftwareKeyboard::InitializeFrontendNormalKeyboard() { - std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_config_common.ok_text.data(), swkbd_config_common.ok_text.size()); - - std::u16string header_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_config_common.header_text.data(), swkbd_config_common.header_text.size()); - - std::u16string sub_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_config_common.sub_text.data(), swkbd_config_common.sub_text.size()); - - std::u16string guide_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_config_common.guide_text.data(), swkbd_config_common.guide_text.size()); - - const u32 max_text_length = - swkbd_config_common.max_text_length > 0 && - swkbd_config_common.max_text_length <= DEFAULT_MAX_TEXT_LENGTH - ? swkbd_config_common.max_text_length - : DEFAULT_MAX_TEXT_LENGTH; - - const u32 min_text_length = swkbd_config_common.min_text_length <= max_text_length - ? swkbd_config_common.min_text_length - : 0; - - const s32 initial_cursor_position = [this] { - switch (swkbd_config_common.initial_cursor_position) { - case SwkbdInitialCursorPosition::Start: - default: - return 0; - case SwkbdInitialCursorPosition::End: - return static_cast<s32>(initial_text.size()); - } - }(); - - const auto text_draw_type = [this, max_text_length] { - switch (swkbd_config_common.text_draw_type) { - case SwkbdTextDrawType::Line: - default: - return max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; - case SwkbdTextDrawType::Box: - case SwkbdTextDrawType::DownloadCode: - return swkbd_config_common.text_draw_type; - } - }(); - - const auto enable_return_button = - text_draw_type == SwkbdTextDrawType::Box ? swkbd_config_common.enable_return_button : false; - - const auto disable_cancel_button = swkbd_applet_version >= SwkbdAppletVersion::Version393227 - ? swkbd_config_new.disable_cancel_button - : false; - - Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{std::move(ok_text)}, - .header_text{std::move(header_text)}, - .sub_text{std::move(sub_text)}, - .guide_text{std::move(guide_text)}, - .initial_text{initial_text}, - .left_optional_symbol_key{swkbd_config_common.left_optional_symbol_key}, - .right_optional_symbol_key{swkbd_config_common.right_optional_symbol_key}, - .max_text_length{max_text_length}, - .min_text_length{min_text_length}, - .initial_cursor_position{initial_cursor_position}, - .type{swkbd_config_common.type}, - .password_mode{swkbd_config_common.password_mode}, - .text_draw_type{text_draw_type}, - .key_disable_flags{swkbd_config_common.key_disable_flags}, - .use_blur_background{swkbd_config_common.use_blur_background}, - .enable_backspace_button{true}, - .enable_return_button{enable_return_button}, - .disable_cancel_button{disable_cancel_button}, - }; - - frontend.InitializeKeyboard( - false, std::move(initialize_parameters), - [this](SwkbdResult result, std::u16string submitted_text, bool confirmed) { - SubmitTextNormal(result, submitted_text, confirmed); - }, - {}); -} - -void SoftwareKeyboard::InitializeFrontendInlineKeyboard( - Core::Frontend::KeyboardInitializeParameters initialize_parameters) { - frontend.InitializeKeyboard( - true, std::move(initialize_parameters), {}, - [this](SwkbdReplyType reply_type, std::u16string submitted_text, s32 cursor_position) { - SubmitTextInline(reply_type, submitted_text, cursor_position); - }); -} - -void SoftwareKeyboard::InitializeFrontendInlineKeyboardOld() { - const auto& appear_arg = swkbd_calc_arg_old.appear_arg; - - std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - appear_arg.ok_text.data(), appear_arg.ok_text.size()); - - const u32 max_text_length = - appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH - ? appear_arg.max_text_length - : DEFAULT_MAX_TEXT_LENGTH; - - const u32 min_text_length = - appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0; - - const s32 initial_cursor_position = current_cursor_position > 0 ? current_cursor_position : 0; - - const auto text_draw_type = - max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; - - Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{std::move(ok_text)}, - .header_text{}, - .sub_text{}, - .guide_text{}, - .initial_text{current_text}, - .left_optional_symbol_key{appear_arg.left_optional_symbol_key}, - .right_optional_symbol_key{appear_arg.right_optional_symbol_key}, - .max_text_length{max_text_length}, - .min_text_length{min_text_length}, - .initial_cursor_position{initial_cursor_position}, - .type{appear_arg.type}, - .password_mode{SwkbdPasswordMode::Disabled}, - .text_draw_type{text_draw_type}, - .key_disable_flags{appear_arg.key_disable_flags}, - .use_blur_background{false}, - .enable_backspace_button{swkbd_calc_arg_old.enable_backspace_button}, - .enable_return_button{appear_arg.enable_return_button}, - .disable_cancel_button{appear_arg.disable_cancel_button}, - }; - - InitializeFrontendInlineKeyboard(std::move(initialize_parameters)); -} - -void SoftwareKeyboard::InitializeFrontendInlineKeyboardNew() { - const auto& appear_arg = swkbd_calc_arg_new.appear_arg; - - std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - appear_arg.ok_text.data(), appear_arg.ok_text.size()); - - const u32 max_text_length = - appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH - ? appear_arg.max_text_length - : DEFAULT_MAX_TEXT_LENGTH; - - const u32 min_text_length = - appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0; - - const s32 initial_cursor_position = current_cursor_position > 0 ? current_cursor_position : 0; - - const auto text_draw_type = - max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; - - Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{std::move(ok_text)}, - .header_text{}, - .sub_text{}, - .guide_text{}, - .initial_text{current_text}, - .left_optional_symbol_key{appear_arg.left_optional_symbol_key}, - .right_optional_symbol_key{appear_arg.right_optional_symbol_key}, - .max_text_length{max_text_length}, - .min_text_length{min_text_length}, - .initial_cursor_position{initial_cursor_position}, - .type{appear_arg.type}, - .password_mode{SwkbdPasswordMode::Disabled}, - .text_draw_type{text_draw_type}, - .key_disable_flags{appear_arg.key_disable_flags}, - .use_blur_background{false}, - .enable_backspace_button{swkbd_calc_arg_new.enable_backspace_button}, - .enable_return_button{appear_arg.enable_return_button}, - .disable_cancel_button{appear_arg.disable_cancel_button}, - }; - - InitializeFrontendInlineKeyboard(std::move(initialize_parameters)); -} - -void SoftwareKeyboard::ShowNormalKeyboard() { - frontend.ShowNormalKeyboard(); -} - -void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result, - std::u16string text_check_message) { - frontend.ShowTextCheckDialog(text_check_result, std::move(text_check_message)); -} - -void SoftwareKeyboard::ShowInlineKeyboard( - Core::Frontend::InlineAppearParameters appear_parameters) { - frontend.ShowInlineKeyboard(std::move(appear_parameters)); - - ChangeState(SwkbdState::InitializedIsShown); -} - -void SoftwareKeyboard::ShowInlineKeyboardOld() { - if (swkbd_state != SwkbdState::InitializedIsHidden) { - return; - } - - ChangeState(SwkbdState::InitializedIsAppearing); - - const auto& appear_arg = swkbd_calc_arg_old.appear_arg; - - const u32 max_text_length = - appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH - ? appear_arg.max_text_length - : DEFAULT_MAX_TEXT_LENGTH; - - const u32 min_text_length = - appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0; - - Core::Frontend::InlineAppearParameters appear_parameters{ - .max_text_length{max_text_length}, - .min_text_length{min_text_length}, - .key_top_scale_x{swkbd_calc_arg_old.key_top_scale_x}, - .key_top_scale_y{swkbd_calc_arg_old.key_top_scale_y}, - .key_top_translate_x{swkbd_calc_arg_old.key_top_translate_x}, - .key_top_translate_y{swkbd_calc_arg_old.key_top_translate_y}, - .type{appear_arg.type}, - .key_disable_flags{appear_arg.key_disable_flags}, - .key_top_as_floating{swkbd_calc_arg_old.key_top_as_floating}, - .enable_backspace_button{swkbd_calc_arg_old.enable_backspace_button}, - .enable_return_button{appear_arg.enable_return_button}, - .disable_cancel_button{appear_arg.disable_cancel_button}, - }; - - ShowInlineKeyboard(std::move(appear_parameters)); -} - -void SoftwareKeyboard::ShowInlineKeyboardNew() { - if (swkbd_state != SwkbdState::InitializedIsHidden) { - return; - } - - ChangeState(SwkbdState::InitializedIsAppearing); - - const auto& appear_arg = swkbd_calc_arg_new.appear_arg; - - const u32 max_text_length = - appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH - ? appear_arg.max_text_length - : DEFAULT_MAX_TEXT_LENGTH; - - const u32 min_text_length = - appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0; - - Core::Frontend::InlineAppearParameters appear_parameters{ - .max_text_length{max_text_length}, - .min_text_length{min_text_length}, - .key_top_scale_x{swkbd_calc_arg_new.key_top_scale_x}, - .key_top_scale_y{swkbd_calc_arg_new.key_top_scale_y}, - .key_top_translate_x{swkbd_calc_arg_new.key_top_translate_x}, - .key_top_translate_y{swkbd_calc_arg_new.key_top_translate_y}, - .type{appear_arg.type}, - .key_disable_flags{appear_arg.key_disable_flags}, - .key_top_as_floating{swkbd_calc_arg_new.key_top_as_floating}, - .enable_backspace_button{swkbd_calc_arg_new.enable_backspace_button}, - .enable_return_button{appear_arg.enable_return_button}, - .disable_cancel_button{appear_arg.disable_cancel_button}, - }; - - ShowInlineKeyboard(std::move(appear_parameters)); -} - -void SoftwareKeyboard::HideInlineKeyboard() { - if (swkbd_state != SwkbdState::InitializedIsShown) { - return; - } - - ChangeState(SwkbdState::InitializedIsDisappearing); - - frontend.HideInlineKeyboard(); - - ChangeState(SwkbdState::InitializedIsHidden); -} - -void SoftwareKeyboard::InlineTextChanged() { - Core::Frontend::InlineTextParameters text_parameters{ - .input_text{current_text}, - .cursor_position{current_cursor_position}, - }; - - frontend.InlineTextChanged(std::move(text_parameters)); -} - -void SoftwareKeyboard::ExitKeyboard() { - complete = true; - status = ResultSuccess; - - frontend.ExitKeyboard(); - - broker.SignalStateChanged(); -} - -Result SoftwareKeyboard::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -// Inline Software Keyboard Requests - -void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) { - LOG_DEBUG(Service_AM, "Processing Request: Finalize"); - - ChangeState(SwkbdState::NotInitialized); - - ExitKeyboard(); -} - -void SoftwareKeyboard::RequestSetUserWordInfo(const std::vector<u8>& request_data) { - LOG_WARNING(Service_AM, "SetUserWordInfo is not implemented."); - - ReplyReleasedUserWordInfo(); -} - -void SoftwareKeyboard::RequestSetCustomizeDic(const std::vector<u8>& request_data) { - LOG_WARNING(Service_AM, "SetCustomizeDic is not implemented."); -} - -void SoftwareKeyboard::RequestCalc(const std::vector<u8>& request_data) { - LOG_DEBUG(Service_AM, "Processing Request: Calc"); - - ASSERT(request_data.size() >= sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon)); - - std::memcpy(&swkbd_calc_arg_common, request_data.data() + sizeof(SwkbdRequestCommand), - sizeof(SwkbdCalcArgCommon)); - - switch (swkbd_calc_arg_common.calc_arg_size) { - case sizeof(SwkbdCalcArgCommon) + sizeof(SwkbdCalcArgOld): - ASSERT(request_data.size() == - sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon) + sizeof(SwkbdCalcArgOld)); - std::memcpy(&swkbd_calc_arg_old, - request_data.data() + sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon), - sizeof(SwkbdCalcArgOld)); - RequestCalcOld(); - break; - case sizeof(SwkbdCalcArgCommon) + sizeof(SwkbdCalcArgNew): - ASSERT(request_data.size() == - sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon) + sizeof(SwkbdCalcArgNew)); - std::memcpy(&swkbd_calc_arg_new, - request_data.data() + sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon), - sizeof(SwkbdCalcArgNew)); - RequestCalcNew(); - break; - default: - UNIMPLEMENTED_MSG("Unknown SwkbdCalcArg size={}", swkbd_calc_arg_common.calc_arg_size); - ASSERT(request_data.size() >= - sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon) + sizeof(SwkbdCalcArgNew)); - std::memcpy(&swkbd_calc_arg_new, - request_data.data() + sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon), - sizeof(SwkbdCalcArgNew)); - RequestCalcNew(); - break; - } -} - -void SoftwareKeyboard::RequestCalcOld() { - if (swkbd_calc_arg_common.flags.set_input_text) { - current_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_calc_arg_old.input_text.data(), swkbd_calc_arg_old.input_text.size()); - } - - if (swkbd_calc_arg_common.flags.set_cursor_position) { - current_cursor_position = swkbd_calc_arg_old.cursor_position; - } - - if (swkbd_calc_arg_common.flags.set_utf8_mode) { - inline_use_utf8 = swkbd_calc_arg_old.utf8_mode; - } - - if (swkbd_state <= SwkbdState::InitializedIsHidden && - swkbd_calc_arg_common.flags.unset_customize_dic) { - ReplyUnsetCustomizeDic(); - } - - if (swkbd_state <= SwkbdState::InitializedIsHidden && - swkbd_calc_arg_common.flags.unset_user_word_info) { - ReplyReleasedUserWordInfo(); - } - - if (swkbd_state == SwkbdState::NotInitialized && - swkbd_calc_arg_common.flags.set_initialize_arg) { - InitializeFrontendInlineKeyboardOld(); - - ChangeState(SwkbdState::InitializedIsHidden); - - ReplyFinishedInitialize(); - } - - if (!swkbd_calc_arg_common.flags.set_initialize_arg && - (swkbd_calc_arg_common.flags.set_input_text || - swkbd_calc_arg_common.flags.set_cursor_position)) { - InlineTextChanged(); - } - - if (swkbd_state == SwkbdState::InitializedIsHidden && swkbd_calc_arg_common.flags.appear) { - ShowInlineKeyboardOld(); - return; - } - - if (swkbd_state == SwkbdState::InitializedIsShown && swkbd_calc_arg_common.flags.disappear) { - HideInlineKeyboard(); - return; - } -} - -void SoftwareKeyboard::RequestCalcNew() { - if (swkbd_calc_arg_common.flags.set_input_text) { - current_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_calc_arg_new.input_text.data(), swkbd_calc_arg_new.input_text.size()); - } - - if (swkbd_calc_arg_common.flags.set_cursor_position) { - current_cursor_position = swkbd_calc_arg_new.cursor_position; - } - - if (swkbd_calc_arg_common.flags.set_utf8_mode) { - inline_use_utf8 = swkbd_calc_arg_new.utf8_mode; - } - - if (swkbd_state <= SwkbdState::InitializedIsHidden && - swkbd_calc_arg_common.flags.unset_customize_dic) { - ReplyUnsetCustomizeDic(); - } - - if (swkbd_state <= SwkbdState::InitializedIsHidden && - swkbd_calc_arg_common.flags.unset_user_word_info) { - ReplyReleasedUserWordInfo(); - } - - if (swkbd_state == SwkbdState::NotInitialized && - swkbd_calc_arg_common.flags.set_initialize_arg) { - InitializeFrontendInlineKeyboardNew(); - - ChangeState(SwkbdState::InitializedIsHidden); - - ReplyFinishedInitialize(); - } - - if (!swkbd_calc_arg_common.flags.set_initialize_arg && - (swkbd_calc_arg_common.flags.set_input_text || - swkbd_calc_arg_common.flags.set_cursor_position)) { - InlineTextChanged(); - } - - if (swkbd_state == SwkbdState::InitializedIsHidden && swkbd_calc_arg_common.flags.appear) { - ShowInlineKeyboardNew(); - return; - } - - if (swkbd_state == SwkbdState::InitializedIsShown && swkbd_calc_arg_common.flags.disappear) { - HideInlineKeyboard(); - return; - } -} - -void SoftwareKeyboard::RequestSetCustomizedDictionaries(const std::vector<u8>& request_data) { - LOG_WARNING(Service_AM, "SetCustomizedDictionaries is not implemented."); -} - -void SoftwareKeyboard::RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data) { - LOG_WARNING(Service_AM, "(STUBBED) Processing Request: UnsetCustomizedDictionaries"); - - ReplyUnsetCustomizedDictionaries(); -} - -void SoftwareKeyboard::RequestSetChangedStringV2Flag(const std::vector<u8>& request_data) { - LOG_DEBUG(Service_AM, "Processing Request: SetChangedStringV2Flag"); - - ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1); - - std::memcpy(&use_changed_string_v2, request_data.data() + sizeof(SwkbdRequestCommand), 1); -} - -void SoftwareKeyboard::RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data) { - LOG_DEBUG(Service_AM, "Processing Request: SetMovedCursorV2Flag"); - - ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + 1); - - std::memcpy(&use_moved_cursor_v2, request_data.data() + sizeof(SwkbdRequestCommand), 1); -} - -// Inline Software Keyboard Replies - -void SoftwareKeyboard::ReplyFinishedInitialize() { - LOG_DEBUG(Service_AM, "Sending Reply: FinishedInitialize"); - - std::vector<u8> reply(REPLY_BASE_SIZE + 1); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::FinishedInitialize); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyDefault() { - LOG_DEBUG(Service_AM, "Sending Reply: Default"); - - std::vector<u8> reply(REPLY_BASE_SIZE); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::Default); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyChangedString() { - LOG_DEBUG(Service_AM, "Sending Reply: ChangedString"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg)); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedString); - - const SwkbdChangedStringArg changed_string_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .dictionary_start_cursor_position{-1}, - .dictionary_end_cursor_position{-1}, - .cursor_position{current_cursor_position}, - }; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(), - current_text.size() * sizeof(char16_t)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg, - sizeof(SwkbdChangedStringArg)); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyMovedCursor() { - LOG_DEBUG(Service_AM, "Sending Reply: MovedCursor"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg)); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursor); - - const SwkbdMovedCursorArg moved_cursor_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .cursor_position{current_cursor_position}, - }; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(), - current_text.size() * sizeof(char16_t)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg, - sizeof(SwkbdMovedCursorArg)); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyMovedTab() { - LOG_DEBUG(Service_AM, "Sending Reply: MovedTab"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedTabArg)); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedTab); - - const SwkbdMovedTabArg moved_tab_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .cursor_position{current_cursor_position}, - }; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(), - current_text.size() * sizeof(char16_t)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_tab_arg, - sizeof(SwkbdMovedTabArg)); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyDecidedEnter() { - LOG_DEBUG(Service_AM, "Sending Reply: DecidedEnter"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdDecidedEnterArg)); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedEnter); - - const SwkbdDecidedEnterArg decided_enter_arg{ - .text_length{static_cast<u32>(current_text.size())}, - }; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(), - current_text.size() * sizeof(char16_t)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &decided_enter_arg, - sizeof(SwkbdDecidedEnterArg)); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); - - HideInlineKeyboard(); -} - -void SoftwareKeyboard::ReplyDecidedCancel() { - LOG_DEBUG(Service_AM, "Sending Reply: DecidedCancel"); - - std::vector<u8> reply(REPLY_BASE_SIZE); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedCancel); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); - - HideInlineKeyboard(); -} - -void SoftwareKeyboard::ReplyChangedStringUtf8() { - LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringUtf8"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg)); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringUtf8); - - std::string utf8_current_text = Common::UTF16ToUTF8(current_text); - - const SwkbdChangedStringArg changed_string_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .dictionary_start_cursor_position{-1}, - .dictionary_end_cursor_position{-1}, - .cursor_position{current_cursor_position}, - }; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size()); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg, - sizeof(SwkbdChangedStringArg)); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyMovedCursorUtf8() { - LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorUtf8"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg)); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorUtf8); - - std::string utf8_current_text = Common::UTF16ToUTF8(current_text); - - const SwkbdMovedCursorArg moved_cursor_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .cursor_position{current_cursor_position}, - }; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size()); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg, - sizeof(SwkbdMovedCursorArg)); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyDecidedEnterUtf8() { - LOG_DEBUG(Service_AM, "Sending Reply: DecidedEnterUtf8"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdDecidedEnterArg)); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::DecidedEnterUtf8); - - std::string utf8_current_text = Common::UTF16ToUTF8(current_text); - - const SwkbdDecidedEnterArg decided_enter_arg{ - .text_length{static_cast<u32>(current_text.size())}, - }; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size()); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &decided_enter_arg, - sizeof(SwkbdDecidedEnterArg)); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); - - HideInlineKeyboard(); -} - -void SoftwareKeyboard::ReplyUnsetCustomizeDic() { - LOG_DEBUG(Service_AM, "Sending Reply: UnsetCustomizeDic"); - - std::vector<u8> reply(REPLY_BASE_SIZE); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizeDic); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyReleasedUserWordInfo() { - LOG_DEBUG(Service_AM, "Sending Reply: ReleasedUserWordInfo"); - - std::vector<u8> reply(REPLY_BASE_SIZE); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::ReleasedUserWordInfo); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyUnsetCustomizedDictionaries() { - LOG_DEBUG(Service_AM, "Sending Reply: UnsetCustomizedDictionaries"); - - std::vector<u8> reply(REPLY_BASE_SIZE); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::UnsetCustomizedDictionaries); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyChangedStringV2() { - LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringV2"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg) + 1); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringV2); - - const SwkbdChangedStringArg changed_string_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .dictionary_start_cursor_position{-1}, - .dictionary_end_cursor_position{-1}, - .cursor_position{current_cursor_position}, - }; - - constexpr u8 flag = 0; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(), - current_text.size() * sizeof(char16_t)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &changed_string_arg, - sizeof(SwkbdChangedStringArg)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdChangedStringArg), - &flag, 1); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyMovedCursorV2() { - LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorV2"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg) + 1); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorV2); - - const SwkbdMovedCursorArg moved_cursor_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .cursor_position{current_cursor_position}, - }; - - constexpr u8 flag = 0; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, current_text.data(), - current_text.size() * sizeof(char16_t)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE, &moved_cursor_arg, - sizeof(SwkbdMovedCursorArg)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF16_SIZE + sizeof(SwkbdMovedCursorArg), - &flag, 1); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyChangedStringUtf8V2() { - LOG_DEBUG(Service_AM, "Sending Reply: ChangedStringUtf8V2"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg) + 1); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::ChangedStringUtf8V2); - - std::string utf8_current_text = Common::UTF16ToUTF8(current_text); - - const SwkbdChangedStringArg changed_string_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .dictionary_start_cursor_position{-1}, - .dictionary_end_cursor_position{-1}, - .cursor_position{current_cursor_position}, - }; - - constexpr u8 flag = 0; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size()); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &changed_string_arg, - sizeof(SwkbdChangedStringArg)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdChangedStringArg), - &flag, 1); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -void SoftwareKeyboard::ReplyMovedCursorUtf8V2() { - LOG_DEBUG(Service_AM, "Sending Reply: MovedCursorUtf8V2"); - - std::vector<u8> reply(REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg) + 1); - - SetReplyBase(reply, swkbd_state, SwkbdReplyType::MovedCursorUtf8V2); - - std::string utf8_current_text = Common::UTF16ToUTF8(current_text); - - const SwkbdMovedCursorArg moved_cursor_arg{ - .text_length{static_cast<u32>(current_text.size())}, - .cursor_position{current_cursor_position}, - }; - - constexpr u8 flag = 0; - - std::memcpy(reply.data() + REPLY_BASE_SIZE, utf8_current_text.data(), utf8_current_text.size()); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE, &moved_cursor_arg, - sizeof(SwkbdMovedCursorArg)); - std::memcpy(reply.data() + REPLY_BASE_SIZE + REPLY_UTF8_SIZE + sizeof(SwkbdMovedCursorArg), - &flag, 1); - - broker.PushInteractiveDataFromApplet(std::make_shared<IStorage>(system, std::move(reply))); -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.h b/src/core/hle/service/am/applets/applet_software_keyboard.h deleted file mode 100644 index 2e919811b..000000000 --- a/src/core/hle/service/am/applets/applet_software_keyboard.h +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applet_software_keyboard_types.h" -#include "core/hle/service/am/applets/applets.h" - -namespace Core { -class System; -} - -namespace Core::Frontend { -struct KeyboardInitializeParameters; -struct InlineAppearParameters; -} // namespace Core::Frontend - -namespace Service::AM::Applets { - -class SoftwareKeyboard final : public Applet { -public: - explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_, - Core::Frontend::SoftwareKeyboardApplet& frontend_); - ~SoftwareKeyboard() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - /** - * Submits the input text to the application. - * If text checking is enabled, the application will verify the input text. - * If use_utf8 is enabled, the input text will be converted to UTF-8 prior to being submitted. - * This should only be used by the normal software keyboard. - * - * @param result SwkbdResult enum - * @param submitted_text UTF-16 encoded string - * @param confirmed Whether the text has been confirmed after TextCheckResult::Confirm - */ - void SubmitTextNormal(SwkbdResult result, std::u16string submitted_text, bool confirmed); - - /** - * Submits the input text to the application. - * If utf8_mode is enabled, the input text will be converted to UTF-8 prior to being submitted. - * This should only be used by the inline software keyboard. - * - * @param reply_type SwkbdReplyType enum - * @param submitted_text UTF-16 encoded string - * @param cursor_position The current position of the text cursor - */ - void SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text, - s32 cursor_position); - -private: - /// Initializes the normal software keyboard. - void InitializeForeground(); - - /// Initializes the inline software keyboard. - void InitializeBackground(LibraryAppletMode library_applet_mode); - - /// Processes the text check sent by the application. - void ProcessTextCheck(); - - /// Processes the inline software keyboard request command sent by the application. - void ProcessInlineKeyboardRequest(); - - /// Submits the input text and exits the applet. - void SubmitNormalOutputAndExit(SwkbdResult result, std::u16string submitted_text); - - /// Submits the input text for text checking. - void SubmitForTextCheck(std::u16string submitted_text); - - /// Sends a reply to the application after processing a request command. - void SendReply(SwkbdReplyType reply_type); - - /// Changes the inline keyboard state. - void ChangeState(SwkbdState state); - - /** - * Signals the frontend to initialize the normal software keyboard with common parameters. - * Note that this does not cause the keyboard to appear. - * Use the ShowNormalKeyboard() functions to cause the keyboard to appear. - */ - void InitializeFrontendNormalKeyboard(); - - /** - * Signals the frontend to initialize the inline software keyboard with common parameters. - * Note that this does not cause the keyboard to appear. - * Use the ShowInlineKeyboard() to cause the keyboard to appear. - */ - void InitializeFrontendInlineKeyboard( - Core::Frontend::KeyboardInitializeParameters initialize_parameters); - - void InitializeFrontendInlineKeyboardOld(); - void InitializeFrontendInlineKeyboardNew(); - - /// Signals the frontend to show the normal software keyboard. - void ShowNormalKeyboard(); - - /// Signals the frontend to show the text check dialog. - void ShowTextCheckDialog(SwkbdTextCheckResult text_check_result, - std::u16string text_check_message); - - /// Signals the frontend to show the inline software keyboard. - void ShowInlineKeyboard(Core::Frontend::InlineAppearParameters appear_parameters); - - void ShowInlineKeyboardOld(); - void ShowInlineKeyboardNew(); - - /// Signals the frontend to hide the inline software keyboard. - void HideInlineKeyboard(); - - /// Signals the frontend that the current inline keyboard text has changed. - void InlineTextChanged(); - - /// Signals both the frontend and application that the software keyboard is exiting. - void ExitKeyboard(); - - // Inline Software Keyboard Requests - - void RequestFinalize(const std::vector<u8>& request_data); - void RequestSetUserWordInfo(const std::vector<u8>& request_data); - void RequestSetCustomizeDic(const std::vector<u8>& request_data); - void RequestCalc(const std::vector<u8>& request_data); - void RequestCalcOld(); - void RequestCalcNew(); - void RequestSetCustomizedDictionaries(const std::vector<u8>& request_data); - void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data); - void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data); - void RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data); - - // Inline Software Keyboard Replies - - void ReplyFinishedInitialize(); - void ReplyDefault(); - void ReplyChangedString(); - void ReplyMovedCursor(); - void ReplyMovedTab(); - void ReplyDecidedEnter(); - void ReplyDecidedCancel(); - void ReplyChangedStringUtf8(); - void ReplyMovedCursorUtf8(); - void ReplyDecidedEnterUtf8(); - void ReplyUnsetCustomizeDic(); - void ReplyReleasedUserWordInfo(); - void ReplyUnsetCustomizedDictionaries(); - void ReplyChangedStringV2(); - void ReplyMovedCursorV2(); - void ReplyChangedStringUtf8V2(); - void ReplyMovedCursorUtf8V2(); - - Core::Frontend::SoftwareKeyboardApplet& frontend; - Core::System& system; - - SwkbdAppletVersion swkbd_applet_version; - - SwkbdConfigCommon swkbd_config_common; - SwkbdConfigOld swkbd_config_old; - SwkbdConfigOld2 swkbd_config_old2; - SwkbdConfigNew swkbd_config_new; - std::u16string initial_text; - - SwkbdState swkbd_state{SwkbdState::NotInitialized}; - SwkbdInitializeArg swkbd_initialize_arg; - SwkbdCalcArgCommon swkbd_calc_arg_common; - SwkbdCalcArgOld swkbd_calc_arg_old; - SwkbdCalcArgNew swkbd_calc_arg_new; - bool use_changed_string_v2{false}; - bool use_moved_cursor_v2{false}; - bool inline_use_utf8{false}; - s32 current_cursor_position{}; - - std::u16string current_text; - - bool is_background{false}; - - bool complete{false}; - Result status{ResultSuccess}; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_software_keyboard_types.h b/src/core/hle/service/am/applets/applet_software_keyboard_types.h deleted file mode 100644 index 1f696900e..000000000 --- a/src/core/hle/service/am/applets/applet_software_keyboard_types.h +++ /dev/null @@ -1,354 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> - -#include "common/bit_field.h" -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/swap.h" -#include "common/uuid.h" - -namespace Service::AM::Applets { - -constexpr std::size_t MAX_OK_TEXT_LENGTH = 8; -constexpr std::size_t MAX_HEADER_TEXT_LENGTH = 64; -constexpr std::size_t MAX_SUB_TEXT_LENGTH = 128; -constexpr std::size_t MAX_GUIDE_TEXT_LENGTH = 256; -constexpr std::size_t STRING_BUFFER_SIZE = 0x7D4; - -enum class SwkbdAppletVersion : u32_le { - Version5 = 0x5, // 1.0.0 - Version65542 = 0x10006, // 2.0.0 - 2.3.0 - Version196615 = 0x30007, // 3.0.0 - 3.0.2 - Version262152 = 0x40008, // 4.0.0 - 4.1.0 - Version327689 = 0x50009, // 5.0.0 - 5.1.0 - Version393227 = 0x6000B, // 6.0.0 - 7.0.1 - Version524301 = 0x8000D, // 8.0.0+ -}; - -enum class SwkbdType : u32 { - Normal, - NumberPad, - Qwerty, - Unknown3, - Latin, - SimplifiedChinese, - TraditionalChinese, - Korean, -}; - -enum class SwkbdInitialCursorPosition : u32 { - Start, - End, -}; - -enum class SwkbdPasswordMode : u32 { - Disabled, - Enabled, -}; - -enum class SwkbdTextDrawType : u32 { - Line, - Box, - DownloadCode, -}; - -enum class SwkbdResult : u32 { - Ok, - Cancel, -}; - -enum class SwkbdTextCheckResult : u32 { - Success, - Failure, - Confirm, - Silent, -}; - -enum class SwkbdState : u32 { - NotInitialized = 0x0, - InitializedIsHidden = 0x1, - InitializedIsAppearing = 0x2, - InitializedIsShown = 0x3, - InitializedIsDisappearing = 0x4, -}; - -enum class SwkbdRequestCommand : u32 { - Finalize = 0x4, - SetUserWordInfo = 0x6, - SetCustomizeDic = 0x7, - Calc = 0xA, - SetCustomizedDictionaries = 0xB, - UnsetCustomizedDictionaries = 0xC, - SetChangedStringV2Flag = 0xD, - SetMovedCursorV2Flag = 0xE, -}; - -enum class SwkbdReplyType : u32 { - FinishedInitialize = 0x0, - Default = 0x1, - ChangedString = 0x2, - MovedCursor = 0x3, - MovedTab = 0x4, - DecidedEnter = 0x5, - DecidedCancel = 0x6, - ChangedStringUtf8 = 0x7, - MovedCursorUtf8 = 0x8, - DecidedEnterUtf8 = 0x9, - UnsetCustomizeDic = 0xA, - ReleasedUserWordInfo = 0xB, - UnsetCustomizedDictionaries = 0xC, - ChangedStringV2 = 0xD, - MovedCursorV2 = 0xE, - ChangedStringUtf8V2 = 0xF, - MovedCursorUtf8V2 = 0x10, -}; - -struct SwkbdKeyDisableFlags { - union { - u32 raw{}; - - BitField<1, 1, u32> space; - BitField<2, 1, u32> at; - BitField<3, 1, u32> percent; - BitField<4, 1, u32> slash; - BitField<5, 1, u32> backslash; - BitField<6, 1, u32> numbers; - BitField<7, 1, u32> download_code; - BitField<8, 1, u32> username; - }; -}; -static_assert(sizeof(SwkbdKeyDisableFlags) == 0x4, "SwkbdKeyDisableFlags has incorrect size."); - -struct SwkbdConfigCommon { - SwkbdType type{}; - std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{}; - char16_t left_optional_symbol_key{}; - char16_t right_optional_symbol_key{}; - bool use_prediction{}; - INSERT_PADDING_BYTES(1); - SwkbdKeyDisableFlags key_disable_flags{}; - SwkbdInitialCursorPosition initial_cursor_position{}; - std::array<char16_t, MAX_HEADER_TEXT_LENGTH + 1> header_text{}; - std::array<char16_t, MAX_SUB_TEXT_LENGTH + 1> sub_text{}; - std::array<char16_t, MAX_GUIDE_TEXT_LENGTH + 1> guide_text{}; - u32 max_text_length{}; - u32 min_text_length{}; - SwkbdPasswordMode password_mode{}; - SwkbdTextDrawType text_draw_type{}; - bool enable_return_button{}; - bool use_utf8{}; - bool use_blur_background{}; - INSERT_PADDING_BYTES(1); - u32 initial_string_offset{}; - u32 initial_string_length{}; - u32 user_dictionary_offset{}; - u32 user_dictionary_entries{}; - bool use_text_check{}; - INSERT_PADDING_BYTES(3); -}; -static_assert(sizeof(SwkbdConfigCommon) == 0x3D4, "SwkbdConfigCommon has incorrect size."); - -#pragma pack(push, 4) -// SwkbdAppletVersion 0x5, 0x10006 -struct SwkbdConfigOld { - INSERT_PADDING_WORDS(1); - VAddr text_check_callback{}; -}; -static_assert(sizeof(SwkbdConfigOld) == 0x3E0 - sizeof(SwkbdConfigCommon), - "SwkbdConfigOld has incorrect size."); - -// SwkbdAppletVersion 0x30007, 0x40008, 0x50009 -struct SwkbdConfigOld2 { - INSERT_PADDING_WORDS(1); - VAddr text_check_callback{}; - std::array<u32, 8> text_grouping{}; -}; -static_assert(sizeof(SwkbdConfigOld2) == 0x400 - sizeof(SwkbdConfigCommon), - "SwkbdConfigOld2 has incorrect size."); - -// SwkbdAppletVersion 0x6000B, 0x8000D -struct SwkbdConfigNew { - std::array<u32, 8> text_grouping{}; - std::array<u64, 24> customized_dictionary_set_entries{}; - u8 total_customized_dictionary_set_entries{}; - bool disable_cancel_button{}; - INSERT_PADDING_BYTES(18); -}; -static_assert(sizeof(SwkbdConfigNew) == 0x4C8 - sizeof(SwkbdConfigCommon), - "SwkbdConfigNew has incorrect size."); -#pragma pack(pop) - -struct SwkbdTextCheck { - SwkbdTextCheckResult text_check_result{}; - std::array<char16_t, STRING_BUFFER_SIZE / 2> text_check_message{}; -}; -static_assert(sizeof(SwkbdTextCheck) == 0x7D8, "SwkbdTextCheck has incorrect size."); - -struct SwkbdCalcArgFlags { - union { - u64 raw{}; - - BitField<0, 1, u64> set_initialize_arg; - BitField<1, 1, u64> set_volume; - BitField<2, 1, u64> appear; - BitField<3, 1, u64> set_input_text; - BitField<4, 1, u64> set_cursor_position; - BitField<5, 1, u64> set_utf8_mode; - BitField<6, 1, u64> unset_customize_dic; - BitField<7, 1, u64> disappear; - BitField<8, 1, u64> unknown; - BitField<9, 1, u64> set_key_top_translate_scale; - BitField<10, 1, u64> unset_user_word_info; - BitField<11, 1, u64> set_disable_hardware_keyboard; - }; -}; -static_assert(sizeof(SwkbdCalcArgFlags) == 0x8, "SwkbdCalcArgFlags has incorrect size."); - -struct SwkbdInitializeArg { - u32 unknown{}; - bool library_applet_mode_flag{}; - bool is_above_hos_500{}; - INSERT_PADDING_BYTES(2); -}; -static_assert(sizeof(SwkbdInitializeArg) == 0x8, "SwkbdInitializeArg has incorrect size."); - -struct SwkbdAppearArgOld { - SwkbdType type{}; - std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{}; - char16_t left_optional_symbol_key{}; - char16_t right_optional_symbol_key{}; - bool use_prediction{}; - bool disable_cancel_button{}; - SwkbdKeyDisableFlags key_disable_flags{}; - u32 max_text_length{}; - u32 min_text_length{}; - bool enable_return_button{}; - INSERT_PADDING_BYTES(3); - u32 flags{}; - bool is_use_save_data{}; - INSERT_PADDING_BYTES(7); - Common::UUID user_id{}; -}; -static_assert(sizeof(SwkbdAppearArgOld) == 0x48, "SwkbdAppearArg has incorrect size."); - -struct SwkbdAppearArgNew { - SwkbdType type{}; - std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{}; - char16_t left_optional_symbol_key{}; - char16_t right_optional_symbol_key{}; - bool use_prediction{}; - bool disable_cancel_button{}; - SwkbdKeyDisableFlags key_disable_flags{}; - u32 max_text_length{}; - u32 min_text_length{}; - bool enable_return_button{}; - INSERT_PADDING_BYTES(3); - u32 flags{}; - bool is_use_save_data{}; - INSERT_PADDING_BYTES(7); - Common::UUID user_id{}; - u64 start_sampling_number{}; - INSERT_PADDING_WORDS(8); -}; -static_assert(sizeof(SwkbdAppearArgNew) == 0x70, "SwkbdAppearArg has incorrect size."); - -struct SwkbdCalcArgCommon { - u32 unknown{}; - u16 calc_arg_size{}; - INSERT_PADDING_BYTES(2); - SwkbdCalcArgFlags flags{}; - SwkbdInitializeArg initialize_arg{}; -}; -static_assert(sizeof(SwkbdCalcArgCommon) == 0x18, "SwkbdCalcArgCommon has incorrect size."); - -struct SwkbdCalcArgOld { - f32 volume{}; - s32 cursor_position{}; - SwkbdAppearArgOld appear_arg{}; - std::array<char16_t, 0x1FA> input_text{}; - bool utf8_mode{}; - INSERT_PADDING_BYTES(1); - bool enable_backspace_button{}; - INSERT_PADDING_BYTES(3); - bool key_top_as_floating{}; - bool footer_scalable{}; - bool alpha_enabled_in_input_mode{}; - u8 input_mode_fade_type{}; - bool disable_touch{}; - bool disable_hardware_keyboard{}; - INSERT_PADDING_BYTES(8); - f32 key_top_scale_x{}; - f32 key_top_scale_y{}; - f32 key_top_translate_x{}; - f32 key_top_translate_y{}; - f32 key_top_bg_alpha{}; - f32 footer_bg_alpha{}; - f32 balloon_scale{}; - INSERT_PADDING_WORDS(4); - u8 se_group{}; - INSERT_PADDING_BYTES(3); -}; -static_assert(sizeof(SwkbdCalcArgOld) == 0x4A0 - sizeof(SwkbdCalcArgCommon), - "SwkbdCalcArgOld has incorrect size."); - -struct SwkbdCalcArgNew { - SwkbdAppearArgNew appear_arg{}; - f32 volume{}; - s32 cursor_position{}; - std::array<char16_t, 0x1FA> input_text{}; - bool utf8_mode{}; - INSERT_PADDING_BYTES(1); - bool enable_backspace_button{}; - INSERT_PADDING_BYTES(3); - bool key_top_as_floating{}; - bool footer_scalable{}; - bool alpha_enabled_in_input_mode{}; - u8 input_mode_fade_type{}; - bool disable_touch{}; - bool disable_hardware_keyboard{}; - INSERT_PADDING_BYTES(8); - f32 key_top_scale_x{}; - f32 key_top_scale_y{}; - f32 key_top_translate_x{}; - f32 key_top_translate_y{}; - f32 key_top_bg_alpha{}; - f32 footer_bg_alpha{}; - f32 balloon_scale{}; - INSERT_PADDING_WORDS(4); - u8 se_group{}; - INSERT_PADDING_BYTES(3); - INSERT_PADDING_WORDS(8); -}; -static_assert(sizeof(SwkbdCalcArgNew) == 0x4E8 - sizeof(SwkbdCalcArgCommon), - "SwkbdCalcArgNew has incorrect size."); - -struct SwkbdChangedStringArg { - u32 text_length{}; - s32 dictionary_start_cursor_position{}; - s32 dictionary_end_cursor_position{}; - s32 cursor_position{}; -}; -static_assert(sizeof(SwkbdChangedStringArg) == 0x10, "SwkbdChangedStringArg has incorrect size."); - -struct SwkbdMovedCursorArg { - u32 text_length{}; - s32 cursor_position{}; -}; -static_assert(sizeof(SwkbdMovedCursorArg) == 0x8, "SwkbdMovedCursorArg has incorrect size."); - -struct SwkbdMovedTabArg { - u32 text_length{}; - s32 cursor_position{}; -}; -static_assert(sizeof(SwkbdMovedTabArg) == 0x8, "SwkbdMovedTabArg has incorrect size."); - -struct SwkbdDecidedEnterArg { - u32 text_length{}; -}; -static_assert(sizeof(SwkbdDecidedEnterArg) == 0x4, "SwkbdDecidedEnterArg has incorrect size."); - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp deleted file mode 100644 index 871737b3e..000000000 --- a/src/core/hle/service/am/applets/applet_web_browser.cpp +++ /dev/null @@ -1,508 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "common/fs/file.h" -#include "common/fs/fs.h" -#include "common/fs/path_util.h" -#include "common/logging/log.h" -#include "common/string_util.h" -#include "core/core.h" -#include "core/file_sys/content_archive.h" -#include "core/file_sys/fs_filesystem.h" -#include "core/file_sys/nca_metadata.h" -#include "core/file_sys/patch_manager.h" -#include "core/file_sys/registered_cache.h" -#include "core/file_sys/romfs.h" -#include "core/file_sys/system_archive/system_archive.h" -#include "core/file_sys/vfs/vfs_vector.h" -#include "core/frontend/applets/web_browser.h" -#include "core/hle/result.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applets/applet_web_browser.h" -#include "core/hle/service/am/storage.h" -#include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/ns/iplatform_service_manager.h" -#include "core/loader/loader.h" - -namespace Service::AM::Applets { - -namespace { - -template <typename T> -void ParseRawValue(T& value, const std::vector<u8>& data) { - static_assert(std::is_trivially_copyable_v<T>, - "It's undefined behavior to use memcpy with non-trivially copyable objects"); - std::memcpy(&value, data.data(), data.size()); -} - -template <typename T> -T ParseRawValue(const std::vector<u8>& data) { - T value; - ParseRawValue(value, data); - return value; -} - -std::string ParseStringValue(const std::vector<u8>& data) { - return Common::StringFromFixedZeroTerminatedBuffer(reinterpret_cast<const char*>(data.data()), - data.size()); -} - -std::string GetMainURL(const std::string& url) { - const auto index = url.find('?'); - - if (index == std::string::npos) { - return url; - } - - return url.substr(0, index); -} - -std::string ResolveURL(const std::string& url) { - const auto index = url.find_first_of('%'); - - if (index == std::string::npos) { - return url; - } - - return url.substr(0, index) + "lp1" + url.substr(index + 1); -} - -WebArgInputTLVMap ReadWebArgs(const std::vector<u8>& web_arg, WebArgHeader& web_arg_header) { - std::memcpy(&web_arg_header, web_arg.data(), sizeof(WebArgHeader)); - - if (web_arg.size() == sizeof(WebArgHeader)) { - return {}; - } - - WebArgInputTLVMap input_tlv_map; - - u64 current_offset = sizeof(WebArgHeader); - - for (std::size_t i = 0; i < web_arg_header.total_tlv_entries; ++i) { - if (web_arg.size() < current_offset + sizeof(WebArgInputTLV)) { - return input_tlv_map; - } - - WebArgInputTLV input_tlv; - std::memcpy(&input_tlv, web_arg.data() + current_offset, sizeof(WebArgInputTLV)); - - current_offset += sizeof(WebArgInputTLV); - - if (web_arg.size() < current_offset + input_tlv.arg_data_size) { - return input_tlv_map; - } - - std::vector<u8> data(input_tlv.arg_data_size); - std::memcpy(data.data(), web_arg.data() + current_offset, input_tlv.arg_data_size); - - current_offset += input_tlv.arg_data_size; - - input_tlv_map.insert_or_assign(input_tlv.input_tlv_type, std::move(data)); - } - - return input_tlv_map; -} - -FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id, - FileSys::ContentRecordType nca_type) { - if (nca_type == FileSys::ContentRecordType::Data) { - const auto nca = - system.GetFileSystemController().GetSystemNANDContents()->GetEntry(title_id, nca_type); - - if (nca == nullptr) { - LOG_ERROR(Service_AM, - "NCA of type={} with title_id={:016X} is not found in the System NAND!", - nca_type, title_id); - return FileSys::SystemArchive::SynthesizeSystemArchive(title_id); - } - - return nca->GetRomFS(); - } else { - const auto nca = system.GetContentProvider().GetEntry(title_id, nca_type); - - if (nca == nullptr) { - if (nca_type == FileSys::ContentRecordType::HtmlDocument) { - LOG_WARNING(Service_AM, "Falling back to AppLoader to get the RomFS."); - FileSys::VirtualFile romfs; - system.GetAppLoader().ReadManualRomFS(romfs); - if (romfs != nullptr) { - return romfs; - } - } - - LOG_ERROR(Service_AM, - "NCA of type={} with title_id={:016X} is not found in the ContentProvider!", - nca_type, title_id); - return nullptr; - } - - const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), - system.GetContentProvider()}; - - return pm.PatchRomFS(nca.get(), nca->GetRomFS(), nca_type); - } -} - -void ExtractSharedFonts(Core::System& system) { - static constexpr std::array<const char*, 7> DECRYPTED_SHARED_FONTS{ - "FontStandard.ttf", - "FontChineseSimplified.ttf", - "FontExtendedChineseSimplified.ttf", - "FontChineseTraditional.ttf", - "FontKorean.ttf", - "FontNintendoExtended.ttf", - "FontNintendoExtended2.ttf", - }; - - const auto fonts_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "fonts"; - - for (std::size_t i = 0; i < NS::SHARED_FONTS.size(); ++i) { - const auto font_file_path = fonts_dir / DECRYPTED_SHARED_FONTS[i]; - - if (Common::FS::Exists(font_file_path)) { - continue; - } - - const auto font = NS::SHARED_FONTS[i]; - const auto font_title_id = static_cast<u64>(font.first); - - const auto nca = system.GetFileSystemController().GetSystemNANDContents()->GetEntry( - font_title_id, FileSys::ContentRecordType::Data); - - FileSys::VirtualFile romfs; - - if (!nca) { - romfs = FileSys::SystemArchive::SynthesizeSystemArchive(font_title_id); - } else { - romfs = nca->GetRomFS(); - } - - if (!romfs) { - LOG_ERROR(Service_AM, "SharedFont RomFS with title_id={:016X} cannot be extracted!", - font_title_id); - continue; - } - - const auto extracted_romfs = FileSys::ExtractRomFS(romfs); - - if (!extracted_romfs) { - LOG_ERROR(Service_AM, "SharedFont RomFS with title_id={:016X} failed to extract!", - font_title_id); - continue; - } - - const auto font_file = extracted_romfs->GetFile(font.second); - - if (!font_file) { - LOG_ERROR(Service_AM, "SharedFont RomFS with title_id={:016X} has no font file \"{}\"!", - font_title_id, font.second); - continue; - } - - std::vector<u32> font_data_u32(font_file->GetSize() / sizeof(u32)); - font_file->ReadBytes<u32>(font_data_u32.data(), font_file->GetSize()); - - std::transform(font_data_u32.begin(), font_data_u32.end(), font_data_u32.begin(), - Common::swap32); - - std::vector<u8> decrypted_data(font_file->GetSize() - 8); - - NS::DecryptSharedFontToTTF(font_data_u32, decrypted_data); - - FileSys::VirtualFile decrypted_font = std::make_shared<FileSys::VectorVfsFile>( - std::move(decrypted_data), DECRYPTED_SHARED_FONTS[i]); - - const auto temp_dir = system.GetFilesystem()->CreateDirectory( - Common::FS::PathToUTF8String(fonts_dir), FileSys::OpenMode::ReadWrite); - - const auto out_file = temp_dir->CreateFile(DECRYPTED_SHARED_FONTS[i]); - - FileSys::VfsRawCopy(decrypted_font, out_file); - } -} - -} // namespace - -WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::WebBrowserApplet& frontend_) - : Applet{system_, applet_mode_}, frontend(frontend_), system{system_} {} - -WebBrowser::~WebBrowser() = default; - -void WebBrowser::Initialize() { - Applet::Initialize(); - - LOG_INFO(Service_AM, "Initializing Web Browser Applet."); - - LOG_DEBUG(Service_AM, - "Initializing Applet with common_args: arg_version={}, lib_version={}, " - "play_startup_sound={}, size={}, system_tick={}, theme_color={}", - common_args.arguments_version, common_args.library_version, - common_args.play_startup_sound, common_args.size, common_args.system_tick, - common_args.theme_color); - - web_applet_version = WebAppletVersion{common_args.library_version}; - - const auto web_arg_storage = broker.PopNormalDataToApplet(); - ASSERT(web_arg_storage != nullptr); - - const auto& web_arg = web_arg_storage->GetData(); - ASSERT_OR_EXECUTE(web_arg.size() >= sizeof(WebArgHeader), { return; }); - - web_arg_input_tlv_map = ReadWebArgs(web_arg, web_arg_header); - - LOG_DEBUG(Service_AM, "WebArgHeader: total_tlv_entries={}, shim_kind={}", - web_arg_header.total_tlv_entries, web_arg_header.shim_kind); - - ExtractSharedFonts(system); - - switch (web_arg_header.shim_kind) { - case ShimKind::Shop: - InitializeShop(); - break; - case ShimKind::Login: - InitializeLogin(); - break; - case ShimKind::Offline: - InitializeOffline(); - break; - case ShimKind::Share: - InitializeShare(); - break; - case ShimKind::Web: - InitializeWeb(); - break; - case ShimKind::Wifi: - InitializeWifi(); - break; - case ShimKind::Lobby: - InitializeLobby(); - break; - default: - ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind); - break; - } -} - -bool WebBrowser::TransactionComplete() const { - return complete; -} - -Result WebBrowser::GetStatus() const { - return status; -} - -void WebBrowser::ExecuteInteractive() { - UNIMPLEMENTED_MSG("WebSession is not implemented"); -} - -void WebBrowser::Execute() { - switch (web_arg_header.shim_kind) { - case ShimKind::Shop: - ExecuteShop(); - break; - case ShimKind::Login: - ExecuteLogin(); - break; - case ShimKind::Offline: - ExecuteOffline(); - break; - case ShimKind::Share: - ExecuteShare(); - break; - case ShimKind::Web: - ExecuteWeb(); - break; - case ShimKind::Wifi: - ExecuteWifi(); - break; - case ShimKind::Lobby: - ExecuteLobby(); - break; - default: - ASSERT_MSG(false, "Invalid ShimKind={}", web_arg_header.shim_kind); - WebBrowserExit(WebExitReason::EndButtonPressed); - break; - } -} - -void WebBrowser::ExtractOfflineRomFS() { - LOG_DEBUG(Service_AM, "Extracting RomFS to {}", - Common::FS::PathToUTF8String(offline_cache_dir)); - - const auto extracted_romfs_dir = FileSys::ExtractRomFS(offline_romfs); - - const auto temp_dir = system.GetFilesystem()->CreateDirectory( - Common::FS::PathToUTF8String(offline_cache_dir), FileSys::OpenMode::ReadWrite); - - FileSys::VfsRawCopyD(extracted_romfs_dir, temp_dir); -} - -void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url) { - if ((web_arg_header.shim_kind == ShimKind::Share && - web_applet_version >= WebAppletVersion::Version196608) || - (web_arg_header.shim_kind == ShimKind::Web && - web_applet_version >= WebAppletVersion::Version524288)) { - // TODO: Push Output TLVs instead of a WebCommonReturnValue - } - - WebCommonReturnValue web_common_return_value; - - web_common_return_value.exit_reason = exit_reason; - std::memcpy(&web_common_return_value.last_url, last_url.data(), last_url.size()); - web_common_return_value.last_url_size = last_url.size(); - - LOG_DEBUG(Service_AM, "WebCommonReturnValue: exit_reason={}, last_url={}, last_url_size={}", - exit_reason, last_url, last_url.size()); - - complete = true; - std::vector<u8> out_data(sizeof(WebCommonReturnValue)); - std::memcpy(out_data.data(), &web_common_return_value, out_data.size()); - broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); - broker.SignalStateChanged(); -} - -Result WebBrowser::RequestExit() { - frontend.Close(); - R_SUCCEED(); -} - -bool WebBrowser::InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const { - return web_arg_input_tlv_map.find(input_tlv_type) != web_arg_input_tlv_map.end(); -} - -std::optional<std::vector<u8>> WebBrowser::GetInputTLVData(WebArgInputTLVType input_tlv_type) { - const auto map_it = web_arg_input_tlv_map.find(input_tlv_type); - - if (map_it == web_arg_input_tlv_map.end()) { - return std::nullopt; - } - - return map_it->second; -} - -void WebBrowser::InitializeShop() {} - -void WebBrowser::InitializeLogin() {} - -void WebBrowser::InitializeOffline() { - const auto document_path = - ParseStringValue(GetInputTLVData(WebArgInputTLVType::DocumentPath).value()); - - const auto document_kind = - ParseRawValue<DocumentKind>(GetInputTLVData(WebArgInputTLVType::DocumentKind).value()); - - std::string additional_paths; - - switch (document_kind) { - case DocumentKind::OfflineHtmlPage: - default: - title_id = system.GetApplicationProcessProgramID(); - nca_type = FileSys::ContentRecordType::HtmlDocument; - additional_paths = "html-document"; - break; - case DocumentKind::ApplicationLegalInformation: - title_id = ParseRawValue<u64>(GetInputTLVData(WebArgInputTLVType::ApplicationID).value()); - nca_type = FileSys::ContentRecordType::LegalInformation; - break; - case DocumentKind::SystemDataPage: - title_id = ParseRawValue<u64>(GetInputTLVData(WebArgInputTLVType::SystemDataID).value()); - nca_type = FileSys::ContentRecordType::Data; - break; - } - - static constexpr std::array<const char*, 3> RESOURCE_TYPES{ - "manual", - "legal_information", - "system_data", - }; - - offline_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / - fmt::format("offline_web_applet_{}/{:016X}", - RESOURCE_TYPES[static_cast<u32>(document_kind) - 1], title_id); - - offline_document = Common::FS::ConcatPathSafe( - offline_cache_dir, fmt::format("{}/{}", additional_paths, document_path)); -} - -void WebBrowser::InitializeShare() {} - -void WebBrowser::InitializeWeb() { - external_url = ParseStringValue(GetInputTLVData(WebArgInputTLVType::InitialURL).value()); - - // Resolve Nintendo CDN URLs. - external_url = ResolveURL(external_url); -} - -void WebBrowser::InitializeWifi() {} - -void WebBrowser::InitializeLobby() {} - -void WebBrowser::ExecuteShop() { - LOG_WARNING(Service_AM, "(STUBBED) called, Shop Applet is not implemented"); - WebBrowserExit(WebExitReason::EndButtonPressed); -} - -void WebBrowser::ExecuteLogin() { - LOG_WARNING(Service_AM, "(STUBBED) called, Login Applet is not implemented"); - WebBrowserExit(WebExitReason::EndButtonPressed); -} - -void WebBrowser::ExecuteOffline() { - // TODO (Morph): This is a hack for WebSession foreground web applets such as those used by - // Super Mario 3D All-Stars. - // TODO (Morph): Implement WebSession. - if (applet_mode == LibraryAppletMode::AllForegroundInitiallyHidden) { - LOG_WARNING(Service_AM, "WebSession is not implemented"); - return; - } - - const auto main_url = GetMainURL(Common::FS::PathToUTF8String(offline_document)); - - if (!Common::FS::Exists(main_url)) { - offline_romfs = GetOfflineRomFS(system, title_id, nca_type); - - if (offline_romfs == nullptr) { - LOG_ERROR(Service_AM, - "RomFS with title_id={:016X} and nca_type={} cannot be extracted!", title_id, - nca_type); - WebBrowserExit(WebExitReason::WindowClosed); - return; - } - } - - LOG_INFO(Service_AM, "Opening offline document at {}", - Common::FS::PathToUTF8String(offline_document)); - - frontend.OpenLocalWebPage( - Common::FS::PathToUTF8String(offline_document), [this] { ExtractOfflineRomFS(); }, - [this](WebExitReason exit_reason, std::string last_url) { - WebBrowserExit(exit_reason, last_url); - }); -} - -void WebBrowser::ExecuteShare() { - LOG_WARNING(Service_AM, "(STUBBED) called, Share Applet is not implemented"); - WebBrowserExit(WebExitReason::EndButtonPressed); -} - -void WebBrowser::ExecuteWeb() { - LOG_INFO(Service_AM, "Opening external URL at {}", external_url); - - frontend.OpenExternalWebPage(external_url, - [this](WebExitReason exit_reason, std::string last_url) { - WebBrowserExit(exit_reason, last_url); - }); -} - -void WebBrowser::ExecuteWifi() { - LOG_WARNING(Service_AM, "(STUBBED) called, Wifi Applet is not implemented"); - WebBrowserExit(WebExitReason::EndButtonPressed); -} - -void WebBrowser::ExecuteLobby() { - LOG_WARNING(Service_AM, "(STUBBED) called, Lobby Applet is not implemented"); - WebBrowserExit(WebExitReason::EndButtonPressed); -} -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_web_browser.h b/src/core/hle/service/am/applets/applet_web_browser.h deleted file mode 100644 index 36adb2510..000000000 --- a/src/core/hle/service/am/applets/applet_web_browser.h +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <filesystem> -#include <optional> - -#include "common/common_types.h" -#include "core/file_sys/vfs/vfs_types.h" -#include "core/hle/result.h" -#include "core/hle/service/am/applets/applet_web_browser_types.h" -#include "core/hle/service/am/applets/applets.h" - -namespace Core { -class System; -} - -namespace FileSys { -enum class ContentRecordType : u8; -} - -namespace Service::AM::Applets { - -class WebBrowser final : public Applet { -public: - WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_, - const Core::Frontend::WebBrowserApplet& frontend_); - - ~WebBrowser() override; - - void Initialize() override; - - bool TransactionComplete() const override; - Result GetStatus() const override; - void ExecuteInteractive() override; - void Execute() override; - Result RequestExit() override; - - void ExtractOfflineRomFS(); - - void WebBrowserExit(WebExitReason exit_reason, std::string last_url = ""); - -private: - bool InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const; - - std::optional<std::vector<u8>> GetInputTLVData(WebArgInputTLVType input_tlv_type); - - // Initializers for the various types of browser applets - void InitializeShop(); - void InitializeLogin(); - void InitializeOffline(); - void InitializeShare(); - void InitializeWeb(); - void InitializeWifi(); - void InitializeLobby(); - - // Executors for the various types of browser applets - void ExecuteShop(); - void ExecuteLogin(); - void ExecuteOffline(); - void ExecuteShare(); - void ExecuteWeb(); - void ExecuteWifi(); - void ExecuteLobby(); - - const Core::Frontend::WebBrowserApplet& frontend; - - bool complete{false}; - Result status{ResultSuccess}; - - WebAppletVersion web_applet_version{}; - WebArgHeader web_arg_header{}; - WebArgInputTLVMap web_arg_input_tlv_map; - - u64 title_id{}; - FileSys::ContentRecordType nca_type{}; - std::filesystem::path offline_cache_dir; - std::filesystem::path offline_document; - FileSys::VirtualFile offline_romfs; - - std::string external_url; - - Core::System& system; -}; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_web_browser_types.h b/src/core/hle/service/am/applets/applet_web_browser_types.h deleted file mode 100644 index c522c5c1a..000000000 --- a/src/core/hle/service/am/applets/applet_web_browser_types.h +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include <unordered_map> -#include <vector> - -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/swap.h" - -namespace Service::AM::Applets { - -enum class WebAppletVersion : u32_le { - Version0 = 0x0, // Only used by WifiWebAuthApplet - Version131072 = 0x20000, // 1.0.0 - 2.3.0 - Version196608 = 0x30000, // 3.0.0 - 4.1.0 - Version327680 = 0x50000, // 5.0.0 - 5.1.0 - Version393216 = 0x60000, // 6.0.0 - 7.0.1 - Version524288 = 0x80000, // 8.0.0+ -}; - -enum class ShimKind : u32 { - Shop = 1, - Login = 2, - Offline = 3, - Share = 4, - Web = 5, - Wifi = 6, - Lobby = 7, -}; - -enum class WebExitReason : u32 { - EndButtonPressed = 0, - BackButtonPressed = 1, - ExitRequested = 2, - CallbackURL = 3, - WindowClosed = 4, - ErrorDialog = 7, -}; - -enum class WebArgInputTLVType : u16 { - InitialURL = 0x1, - CallbackURL = 0x3, - CallbackableURL = 0x4, - ApplicationID = 0x5, - DocumentPath = 0x6, - DocumentKind = 0x7, - SystemDataID = 0x8, - ShareStartPage = 0x9, - Whitelist = 0xA, - News = 0xB, - UserID = 0xE, - AlbumEntry0 = 0xF, - ScreenShotEnabled = 0x10, - EcClientCertEnabled = 0x11, - PlayReportEnabled = 0x13, - BootDisplayKind = 0x17, - BackgroundKind = 0x18, - FooterEnabled = 0x19, - PointerEnabled = 0x1A, - LeftStickMode = 0x1B, - KeyRepeatFrame1 = 0x1C, - KeyRepeatFrame2 = 0x1D, - BootAsMediaPlayerInverted = 0x1E, - DisplayURLKind = 0x1F, - BootAsMediaPlayer = 0x21, - ShopJumpEnabled = 0x22, - MediaAutoPlayEnabled = 0x23, - LobbyParameter = 0x24, - ApplicationAlbumEntry = 0x26, - JsExtensionEnabled = 0x27, - AdditionalCommentText = 0x28, - TouchEnabledOnContents = 0x29, - UserAgentAdditionalString = 0x2A, - AdditionalMediaData0 = 0x2B, - MediaPlayerAutoCloseEnabled = 0x2C, - PageCacheEnabled = 0x2D, - WebAudioEnabled = 0x2E, - YouTubeVideoWhitelist = 0x31, - FooterFixedKind = 0x32, - PageFadeEnabled = 0x33, - MediaCreatorApplicationRatingAge = 0x34, - BootLoadingIconEnabled = 0x35, - PageScrollIndicatorEnabled = 0x36, - MediaPlayerSpeedControlEnabled = 0x37, - AlbumEntry1 = 0x38, - AlbumEntry2 = 0x39, - AlbumEntry3 = 0x3A, - AdditionalMediaData1 = 0x3B, - AdditionalMediaData2 = 0x3C, - AdditionalMediaData3 = 0x3D, - BootFooterButton = 0x3E, - OverrideWebAudioVolume = 0x3F, - OverrideMediaAudioVolume = 0x40, - BootMode = 0x41, - WebSessionEnabled = 0x42, - MediaPlayerOfflineEnabled = 0x43, -}; - -enum class WebArgOutputTLVType : u16 { - ShareExitReason = 0x1, - LastURL = 0x2, - LastURLSize = 0x3, - SharePostResult = 0x4, - PostServiceName = 0x5, - PostServiceNameSize = 0x6, - PostID = 0x7, - PostIDSize = 0x8, - MediaPlayerAutoClosedByCompletion = 0x9, -}; - -enum class DocumentKind : u32 { - OfflineHtmlPage = 1, - ApplicationLegalInformation = 2, - SystemDataPage = 3, -}; - -enum class ShareStartPage : u32 { - Default, - Settings, -}; - -enum class BootDisplayKind : u32 { - Default, - White, - Black, -}; - -enum class BackgroundKind : u32 { - Default, -}; - -enum class LeftStickMode : u32 { - Pointer, - Cursor, -}; - -enum class WebSessionBootMode : u32 { - AllForeground, - AllForegroundInitiallyHidden, -}; - -struct WebArgHeader { - u16 total_tlv_entries{}; - INSERT_PADDING_BYTES(2); - ShimKind shim_kind{}; -}; -static_assert(sizeof(WebArgHeader) == 0x8, "WebArgHeader has incorrect size."); - -struct WebArgInputTLV { - WebArgInputTLVType input_tlv_type{}; - u16 arg_data_size{}; - INSERT_PADDING_WORDS(1); -}; -static_assert(sizeof(WebArgInputTLV) == 0x8, "WebArgInputTLV has incorrect size."); - -struct WebArgOutputTLV { - WebArgOutputTLVType output_tlv_type{}; - u16 arg_data_size{}; - INSERT_PADDING_WORDS(1); -}; -static_assert(sizeof(WebArgOutputTLV) == 0x8, "WebArgOutputTLV has incorrect size."); - -struct WebCommonReturnValue { - WebExitReason exit_reason{}; - INSERT_PADDING_WORDS(1); - std::array<char, 0x1000> last_url{}; - u64 last_url_size{}; -}; -static_assert(sizeof(WebCommonReturnValue) == 0x1010, "WebCommonReturnValue has incorrect size."); - -using WebArgInputTLVMap = std::unordered_map<WebArgInputTLVType, std::vector<u8>>; - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp deleted file mode 100644 index 6a47f4b7a..000000000 --- a/src/core/hle/service/am/applets/applets.cpp +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <cstring> - -#include "common/assert.h" -#include "core/core.h" -#include "core/frontend/applets/cabinet.h" -#include "core/frontend/applets/controller.h" -#include "core/frontend/applets/error.h" -#include "core/frontend/applets/general_frontend.h" -#include "core/frontend/applets/mii_edit.h" -#include "core/frontend/applets/profile_select.h" -#include "core/frontend/applets/software_keyboard.h" -#include "core/frontend/applets/web_browser.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/service/am/am.h" -#include "core/hle/service/am/applet_ae.h" -#include "core/hle/service/am/applet_message_queue.h" -#include "core/hle/service/am/applet_oe.h" -#include "core/hle/service/am/applets/applet_cabinet.h" -#include "core/hle/service/am/applets/applet_controller.h" -#include "core/hle/service/am/applets/applet_error.h" -#include "core/hle/service/am/applets/applet_general_backend.h" -#include "core/hle/service/am/applets/applet_mii_edit.h" -#include "core/hle/service/am/applets/applet_profile_select.h" -#include "core/hle/service/am/applets/applet_software_keyboard.h" -#include "core/hle/service/am/applets/applet_web_browser.h" -#include "core/hle/service/am/applets/applets.h" -#include "core/hle/service/am/storage.h" -#include "core/hle/service/sm/sm.h" - -namespace Service::AM::Applets { - -AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) - : system{system_}, applet_mode{applet_mode_}, - service_context{system, "ILibraryAppletAccessor"} { - state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent"); - pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent"); - pop_interactive_out_data_event = - service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent"); -} - -AppletDataBroker::~AppletDataBroker() { - service_context.CloseEvent(state_changed_event); - service_context.CloseEvent(pop_out_data_event); - service_context.CloseEvent(pop_interactive_out_data_event); -} - -AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const { - std::vector<std::vector<u8>> out_normal; - - for (const auto& storage : in_channel) { - out_normal.push_back(storage->GetData()); - } - - std::vector<std::vector<u8>> out_interactive; - - for (const auto& storage : in_interactive_channel) { - out_interactive.push_back(storage->GetData()); - } - - return {std::move(out_normal), std::move(out_interactive)}; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { - if (out_channel.empty()) - return nullptr; - - auto out = std::move(out_channel.front()); - out_channel.pop_front(); - pop_out_data_event->Clear(); - return out; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() { - if (in_channel.empty()) - return nullptr; - - auto out = std::move(in_channel.front()); - in_channel.pop_front(); - return out; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() { - if (out_interactive_channel.empty()) - return nullptr; - - auto out = std::move(out_interactive_channel.front()); - out_interactive_channel.pop_front(); - pop_interactive_out_data_event->Clear(); - return out; -} - -std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() { - if (in_interactive_channel.empty()) - return nullptr; - - auto out = std::move(in_interactive_channel.front()); - in_interactive_channel.pop_front(); - return out; -} - -void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage) { - in_channel.emplace_back(std::move(storage)); -} - -void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { - out_channel.emplace_back(std::move(storage)); - pop_out_data_event->Signal(); -} - -void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { - in_interactive_channel.emplace_back(std::move(storage)); -} - -void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { - out_interactive_channel.emplace_back(std::move(storage)); - pop_interactive_out_data_event->Signal(); -} - -void AppletDataBroker::SignalStateChanged() { - state_changed_event->Signal(); - - switch (applet_mode) { - case LibraryAppletMode::AllForeground: - case LibraryAppletMode::AllForegroundInitiallyHidden: { - auto applet_oe = system.ServiceManager().GetService<AppletOE>("appletOE"); - auto applet_ae = system.ServiceManager().GetService<AppletAE>("appletAE"); - - if (applet_oe) { - applet_oe->GetMessageQueue()->FocusStateChanged(); - break; - } - - if (applet_ae) { - applet_ae->GetMessageQueue()->FocusStateChanged(); - break; - } - break; - } - default: - break; - } -} - -Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { - return pop_out_data_event->GetReadableEvent(); -} - -Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() { - return pop_interactive_out_data_event->GetReadableEvent(); -} - -Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { - return state_changed_event->GetReadableEvent(); -} - -Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_) - : broker{system_, applet_mode_}, applet_mode{applet_mode_} {} - -Applet::~Applet() = default; - -void Applet::Initialize() { - const auto common = broker.PopNormalDataToApplet(); - ASSERT(common != nullptr); - - const auto common_data = common->GetData(); - - ASSERT(common_data.size() >= sizeof(CommonArguments)); - std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments)); - - initialized = true; -} - -AppletFrontendSet::AppletFrontendSet() = default; - -AppletFrontendSet::AppletFrontendSet(CabinetApplet cabinet_applet, - ControllerApplet controller_applet, ErrorApplet error_applet, - MiiEdit mii_edit_, - ParentalControlsApplet parental_controls_applet, - PhotoViewer photo_viewer_, ProfileSelect profile_select_, - SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) - : cabinet{std::move(cabinet_applet)}, controller{std::move(controller_applet)}, - error{std::move(error_applet)}, mii_edit{std::move(mii_edit_)}, - parental_controls{std::move(parental_controls_applet)}, - photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)}, - software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {} - -AppletFrontendSet::~AppletFrontendSet() = default; - -AppletFrontendSet::AppletFrontendSet(AppletFrontendSet&&) noexcept = default; - -AppletFrontendSet& AppletFrontendSet::operator=(AppletFrontendSet&&) noexcept = default; - -AppletManager::AppletManager(Core::System& system_) : system{system_} {} - -AppletManager::~AppletManager() = default; - -const AppletFrontendSet& AppletManager::GetAppletFrontendSet() const { - return frontend; -} - -NFP::CabinetMode AppletManager::GetCabinetMode() const { - return cabinet_mode; -} - -AppletId AppletManager::GetCurrentAppletId() const { - return current_applet_id; -} - -void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { - if (set.cabinet != nullptr) { - frontend.cabinet = std::move(set.cabinet); - } - - if (set.controller != nullptr) { - frontend.controller = std::move(set.controller); - } - - if (set.error != nullptr) { - frontend.error = std::move(set.error); - } - - if (set.mii_edit != nullptr) { - frontend.mii_edit = std::move(set.mii_edit); - } - - if (set.parental_controls != nullptr) { - frontend.parental_controls = std::move(set.parental_controls); - } - - if (set.photo_viewer != nullptr) { - frontend.photo_viewer = std::move(set.photo_viewer); - } - - if (set.profile_select != nullptr) { - frontend.profile_select = std::move(set.profile_select); - } - - if (set.software_keyboard != nullptr) { - frontend.software_keyboard = std::move(set.software_keyboard); - } - - if (set.web_browser != nullptr) { - frontend.web_browser = std::move(set.web_browser); - } -} - -void AppletManager::SetCabinetMode(NFP::CabinetMode mode) { - cabinet_mode = mode; -} - -void AppletManager::SetCurrentAppletId(AppletId applet_id) { - current_applet_id = applet_id; -} - -void AppletManager::SetDefaultAppletFrontendSet() { - ClearAll(); - SetDefaultAppletsIfMissing(); -} - -void AppletManager::SetDefaultAppletsIfMissing() { - if (frontend.cabinet == nullptr) { - frontend.cabinet = std::make_unique<Core::Frontend::DefaultCabinetApplet>(); - } - - if (frontend.controller == nullptr) { - frontend.controller = - std::make_unique<Core::Frontend::DefaultControllerApplet>(system.HIDCore()); - } - - if (frontend.error == nullptr) { - frontend.error = std::make_unique<Core::Frontend::DefaultErrorApplet>(); - } - - if (frontend.mii_edit == nullptr) { - frontend.mii_edit = std::make_unique<Core::Frontend::DefaultMiiEditApplet>(); - } - - if (frontend.parental_controls == nullptr) { - frontend.parental_controls = - std::make_unique<Core::Frontend::DefaultParentalControlsApplet>(); - } - - if (frontend.photo_viewer == nullptr) { - frontend.photo_viewer = std::make_unique<Core::Frontend::DefaultPhotoViewerApplet>(); - } - - if (frontend.profile_select == nullptr) { - frontend.profile_select = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); - } - - if (frontend.software_keyboard == nullptr) { - frontend.software_keyboard = - std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); - } - - if (frontend.web_browser == nullptr) { - frontend.web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>(); - } -} - -void AppletManager::ClearAll() { - frontend = {}; -} - -std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode mode) const { - switch (id) { - case AppletId::Auth: - return std::make_shared<Auth>(system, mode, *frontend.parental_controls); - case AppletId::Cabinet: - return std::make_shared<Cabinet>(system, mode, *frontend.cabinet); - case AppletId::Controller: - return std::make_shared<Controller>(system, mode, *frontend.controller); - case AppletId::Error: - return std::make_shared<Error>(system, mode, *frontend.error); - case AppletId::ProfileSelect: - return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select); - case AppletId::SoftwareKeyboard: - return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard); - case AppletId::MiiEdit: - return std::make_shared<MiiEdit>(system, mode, *frontend.mii_edit); - case AppletId::Web: - case AppletId::Shop: - case AppletId::OfflineWeb: - case AppletId::LoginShare: - case AppletId::WebAuth: - return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser); - case AppletId::PhotoViewer: - return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer); - default: - UNIMPLEMENTED_MSG( - "No backend implementation exists for applet_id={:02X}! Falling back to stub applet.", - static_cast<u8>(id)); - return std::make_shared<StubApplet>(system, id, mode); - } -} - -} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h deleted file mode 100644 index 0bf2598b7..000000000 --- a/src/core/hle/service/am/applets/applets.h +++ /dev/null @@ -1,289 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <memory> -#include <queue> - -#include "common/swap.h" -#include "core/hle/service/kernel_helpers.h" - -union Result; - -namespace Core { -class System; -} - -namespace Core::Frontend { -class CabinetApplet; -class ControllerApplet; -class ECommerceApplet; -class ErrorApplet; -class MiiEditApplet; -class ParentalControlsApplet; -class PhotoViewerApplet; -class ProfileSelectApplet; -class SoftwareKeyboardApplet; -class WebBrowserApplet; -} // namespace Core::Frontend - -namespace Kernel { -class KernelCore; -class KEvent; -class KReadableEvent; -} // namespace Kernel - -namespace Service::NFP { -enum class CabinetMode : u8; -} // namespace Service::NFP - -namespace Service::AM { - -class IStorage; - -namespace Applets { - -enum class AppletId : u32 { - None = 0x00, - Application = 0x01, - OverlayDisplay = 0x02, - QLaunch = 0x03, - Starter = 0x04, - Auth = 0x0A, - Cabinet = 0x0B, - Controller = 0x0C, - DataErase = 0x0D, - Error = 0x0E, - NetConnect = 0x0F, - ProfileSelect = 0x10, - SoftwareKeyboard = 0x11, - MiiEdit = 0x12, - Web = 0x13, - Shop = 0x14, - PhotoViewer = 0x15, - Settings = 0x16, - OfflineWeb = 0x17, - LoginShare = 0x18, - WebAuth = 0x19, - MyPage = 0x1A, -}; - -enum class AppletProgramId : u64 { - QLaunch = 0x0100000000001000ull, - Auth = 0x0100000000001001ull, - Cabinet = 0x0100000000001002ull, - Controller = 0x0100000000001003ull, - DataErase = 0x0100000000001004ull, - Error = 0x0100000000001005ull, - NetConnect = 0x0100000000001006ull, - ProfileSelect = 0x0100000000001007ull, - SoftwareKeyboard = 0x0100000000001008ull, - MiiEdit = 0x0100000000001009ull, - Web = 0x010000000000100Aull, - Shop = 0x010000000000100Bull, - OverlayDisplay = 0x010000000000100Cull, - PhotoViewer = 0x010000000000100Dull, - Settings = 0x010000000000100Eull, - OfflineWeb = 0x010000000000100Full, - LoginShare = 0x0100000000001010ull, - WebAuth = 0x0100000000001011ull, - Starter = 0x0100000000001012ull, - MyPage = 0x0100000000001013ull, - MaxProgramId = 0x0100000000001FFFull, -}; - -enum class LibraryAppletMode : u32 { - AllForeground = 0, - Background = 1, - NoUI = 2, - BackgroundIndirectDisplay = 3, - AllForegroundInitiallyHidden = 4, -}; - -enum class CommonArgumentVersion : u32 { - Version0, - Version1, - Version2, - Version3, -}; - -enum class CommonArgumentSize : u32 { - Version3 = 0x20, -}; - -enum class ThemeColor : u32 { - BasicWhite = 0, - BasicBlack = 3, -}; - -struct CommonArguments { - CommonArgumentVersion arguments_version; - CommonArgumentSize size; - u32 library_version; - ThemeColor theme_color; - bool play_startup_sound; - u64_le system_tick; -}; -static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size."); - -class AppletDataBroker final { -public: - explicit AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_); - ~AppletDataBroker(); - - struct RawChannelData { - std::vector<std::vector<u8>> normal; - std::vector<std::vector<u8>> interactive; - }; - - // Retrieves but does not pop the data sent to applet. - RawChannelData PeekDataToAppletForDebug() const; - - std::shared_ptr<IStorage> PopNormalDataToGame(); - std::shared_ptr<IStorage> PopNormalDataToApplet(); - - std::shared_ptr<IStorage> PopInteractiveDataToGame(); - std::shared_ptr<IStorage> PopInteractiveDataToApplet(); - - void PushNormalDataFromGame(std::shared_ptr<IStorage>&& storage); - void PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage); - - void PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage); - void PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage); - - void SignalStateChanged(); - - Kernel::KReadableEvent& GetNormalDataEvent(); - Kernel::KReadableEvent& GetInteractiveDataEvent(); - Kernel::KReadableEvent& GetStateChangedEvent(); - -private: - Core::System& system; - LibraryAppletMode applet_mode; - - KernelHelpers::ServiceContext service_context; - - // Queues are named from applet's perspective - - // PopNormalDataToApplet and PushNormalDataFromGame - std::deque<std::shared_ptr<IStorage>> in_channel; - - // PopNormalDataToGame and PushNormalDataFromApplet - std::deque<std::shared_ptr<IStorage>> out_channel; - - // PopInteractiveDataToApplet and PushInteractiveDataFromGame - std::deque<std::shared_ptr<IStorage>> in_interactive_channel; - - // PopInteractiveDataToGame and PushInteractiveDataFromApplet - std::deque<std::shared_ptr<IStorage>> out_interactive_channel; - - Kernel::KEvent* state_changed_event; - - // Signaled on PushNormalDataFromApplet - Kernel::KEvent* pop_out_data_event; - - // Signaled on PushInteractiveDataFromApplet - Kernel::KEvent* pop_interactive_out_data_event; -}; - -class Applet { -public: - explicit Applet(Core::System& system_, LibraryAppletMode applet_mode_); - virtual ~Applet(); - - virtual void Initialize(); - - virtual bool TransactionComplete() const = 0; - virtual Result GetStatus() const = 0; - virtual void ExecuteInteractive() = 0; - virtual void Execute() = 0; - virtual Result RequestExit() = 0; - - AppletDataBroker& GetBroker() { - return broker; - } - - const AppletDataBroker& GetBroker() const { - return broker; - } - - LibraryAppletMode GetLibraryAppletMode() const { - return applet_mode; - } - - bool IsInitialized() const { - return initialized; - } - -protected: - CommonArguments common_args{}; - AppletDataBroker broker; - LibraryAppletMode applet_mode; - bool initialized = false; -}; - -struct AppletFrontendSet { - using CabinetApplet = std::unique_ptr<Core::Frontend::CabinetApplet>; - using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>; - using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>; - using MiiEdit = std::unique_ptr<Core::Frontend::MiiEditApplet>; - using ParentalControlsApplet = std::unique_ptr<Core::Frontend::ParentalControlsApplet>; - using PhotoViewer = std::unique_ptr<Core::Frontend::PhotoViewerApplet>; - using ProfileSelect = std::unique_ptr<Core::Frontend::ProfileSelectApplet>; - using SoftwareKeyboard = std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet>; - using WebBrowser = std::unique_ptr<Core::Frontend::WebBrowserApplet>; - - AppletFrontendSet(); - AppletFrontendSet(CabinetApplet cabinet_applet, ControllerApplet controller_applet, - ErrorApplet error_applet, MiiEdit mii_edit_, - ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_, - ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, - WebBrowser web_browser_); - ~AppletFrontendSet(); - - AppletFrontendSet(const AppletFrontendSet&) = delete; - AppletFrontendSet& operator=(const AppletFrontendSet&) = delete; - - AppletFrontendSet(AppletFrontendSet&&) noexcept; - AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept; - - CabinetApplet cabinet; - ControllerApplet controller; - ErrorApplet error; - MiiEdit mii_edit; - ParentalControlsApplet parental_controls; - PhotoViewer photo_viewer; - ProfileSelect profile_select; - SoftwareKeyboard software_keyboard; - WebBrowser web_browser; -}; - -class AppletManager { -public: - explicit AppletManager(Core::System& system_); - ~AppletManager(); - - const AppletFrontendSet& GetAppletFrontendSet() const; - NFP::CabinetMode GetCabinetMode() const; - AppletId GetCurrentAppletId() const; - - void SetAppletFrontendSet(AppletFrontendSet set); - void SetCabinetMode(NFP::CabinetMode mode); - void SetCurrentAppletId(AppletId applet_id); - void SetDefaultAppletFrontendSet(); - void SetDefaultAppletsIfMissing(); - void ClearAll(); - - std::shared_ptr<Applet> GetApplet(AppletId id, LibraryAppletMode mode) const; - -private: - AppletId current_applet_id{}; - NFP::CabinetMode cabinet_mode{}; - - AppletFrontendSet frontend; - Core::System& system; -}; - -} // namespace Applets -} // namespace Service::AM |
