diff options
| author | 2018-11-11 16:41:31 -0500 | |
|---|---|---|
| committer | 2018-11-18 10:53:47 -0500 | |
| commit | fed6ab14c37f196f2a2fd378b46d7e5bd0118224 (patch) | |
| tree | 9e199e88df8e5a35e1f18d7a2f2ca29373d90367 /src | |
| parent | am: Deglobalize software keyboard applet (diff) | |
| download | yuzu-fed6ab14c37f196f2a2fd378b46d7e5bd0118224.tar.gz yuzu-fed6ab14c37f196f2a2fd378b46d7e5bd0118224.tar.xz yuzu-fed6ab14c37f196f2a2fd378b46d7e5bd0118224.zip | |
am: Implement text check software keyboard mode
Allows the game to verify and send a message to the frontend.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/frontend/applets/software_keyboard.cpp | 6 | ||||
| -rw-r--r-- | src/core/frontend/applets/software_keyboard.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/am/am.cpp | 37 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/applets.h | 5 | ||||
| -rw-r--r-- | src/core/hle/service/am/applets/software_keyboard.cpp | 67 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 17 |
6 files changed, 120 insertions, 14 deletions
diff --git a/src/core/frontend/applets/software_keyboard.cpp b/src/core/frontend/applets/software_keyboard.cpp index 41d81c293..05e2dc6b7 100644 --- a/src/core/frontend/applets/software_keyboard.cpp +++ b/src/core/frontend/applets/software_keyboard.cpp | |||
| @@ -18,4 +18,10 @@ bool DefaultSoftwareKeyboardApplet::GetText(SoftwareKeyboardParameters parameter | |||
| 18 | return true; | 18 | return true; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(std::u16string error_message) const { | ||
| 22 | LOG_WARNING(Service_AM, | ||
| 23 | "(STUBBED) called - Default fallback software keyboard does not support text " | ||
| 24 | "check! (error_message={})", | ||
| 25 | Common::UTF16ToUTF8(error_message)); | ||
| 26 | } | ||
| 21 | } // namespace Core::Frontend | 27 | } // namespace Core::Frontend |
diff --git a/src/core/frontend/applets/software_keyboard.h b/src/core/frontend/applets/software_keyboard.h index 2ea9db889..0a82aac0d 100644 --- a/src/core/frontend/applets/software_keyboard.h +++ b/src/core/frontend/applets/software_keyboard.h | |||
| @@ -36,11 +36,13 @@ public: | |||
| 36 | virtual ~SoftwareKeyboardApplet(); | 36 | virtual ~SoftwareKeyboardApplet(); |
| 37 | 37 | ||
| 38 | virtual bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const = 0; | 38 | virtual bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const = 0; |
| 39 | virtual void SendTextCheckDialog(std::u16string error_message) const = 0; | ||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet { | 42 | class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet { |
| 42 | public: | 43 | public: |
| 43 | bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const override; | 44 | bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const override; |
| 45 | void SendTextCheckDialog(std::u16string error_message) const override; | ||
| 44 | }; | 46 | }; |
| 45 | 47 | ||
| 46 | } // namespace Core::Frontend | 48 | } // namespace Core::Frontend |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index fc464270e..ea00c5c72 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -544,7 +544,7 @@ public: | |||
| 544 | {102, nullptr, "PushExtraStorage"}, | 544 | {102, nullptr, "PushExtraStorage"}, |
| 545 | {103, &ILibraryAppletAccessor::PushInteractiveInData, "PushInteractiveInData"}, | 545 | {103, &ILibraryAppletAccessor::PushInteractiveInData, "PushInteractiveInData"}, |
| 546 | {104, &ILibraryAppletAccessor::PopInteractiveOutData, "PopInteractiveOutData"}, | 546 | {104, &ILibraryAppletAccessor::PopInteractiveOutData, "PopInteractiveOutData"}, |
| 547 | {105, nullptr, "GetPopOutDataEvent"}, | 547 | {105, &ILibraryAppletAccessor::GetPopOutDataEvent, "GetPopOutDataEvent"}, |
| 548 | {106, &ILibraryAppletAccessor::GetPopInteractiveOutDataEvent, "GetPopInteractiveOutDataEvent"}, | 548 | {106, &ILibraryAppletAccessor::GetPopInteractiveOutDataEvent, "GetPopInteractiveOutDataEvent"}, |
| 549 | {110, nullptr, "NeedsToExitProcess"}, | 549 | {110, nullptr, "NeedsToExitProcess"}, |
| 550 | {120, nullptr, "GetLibraryAppletInfo"}, | 550 | {120, nullptr, "GetLibraryAppletInfo"}, |
| @@ -558,6 +558,8 @@ public: | |||
| 558 | auto& kernel = Core::System::GetInstance().Kernel(); | 558 | auto& kernel = Core::System::GetInstance().Kernel(); |
| 559 | state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 559 | state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, |
| 560 | "ILibraryAppletAccessor:StateChangedEvent"); | 560 | "ILibraryAppletAccessor:StateChangedEvent"); |
| 561 | pop_out_data_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | ||
| 562 | "ILibraryAppletAccessor:PopDataOutEvent"); | ||
| 561 | pop_interactive_out_data_event = | 563 | pop_interactive_out_data_event = |
| 562 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, | 564 | Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, |
| 563 | "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); | 565 | "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); |
| @@ -585,9 +587,16 @@ private: | |||
| 585 | ASSERT(applet != nullptr); | 587 | ASSERT(applet != nullptr); |
| 586 | 588 | ||
| 587 | applet->Initialize(storage_stack); | 589 | applet->Initialize(storage_stack); |
| 588 | interactive_storage_stack.push_back(std::make_shared<IStorage>(applet->Execute())); | 590 | const auto data = std::make_shared<IStorage>(applet->Execute()); |
| 589 | state_changed_event->Signal(); | 591 | state_changed_event->Signal(); |
| 590 | pop_interactive_out_data_event->Signal(); | 592 | |
| 593 | if (applet->TransactionComplete()) { | ||
| 594 | storage_stack.push_back(data); | ||
| 595 | pop_out_data_event->Signal(); | ||
| 596 | } else { | ||
| 597 | interactive_storage_stack.push_back(data); | ||
| 598 | pop_interactive_out_data_event->Signal(); | ||
| 599 | } | ||
| 591 | 600 | ||
| 592 | IPC::ResponseBuilder rb{ctx, 2}; | 601 | IPC::ResponseBuilder rb{ctx, 2}; |
| 593 | rb.Push(RESULT_SUCCESS); | 602 | rb.Push(RESULT_SUCCESS); |
| @@ -617,6 +626,19 @@ private: | |||
| 617 | IPC::RequestParser rp{ctx}; | 626 | IPC::RequestParser rp{ctx}; |
| 618 | interactive_storage_stack.push_back(rp.PopIpcInterface<IStorage>()); | 627 | interactive_storage_stack.push_back(rp.PopIpcInterface<IStorage>()); |
| 619 | 628 | ||
| 629 | ASSERT(applet->IsInitialized()); | ||
| 630 | applet->ReceiveInteractiveData(interactive_storage_stack.back()); | ||
| 631 | const auto data = std::make_shared<IStorage>(applet->Execute()); | ||
| 632 | state_changed_event->Signal(); | ||
| 633 | |||
| 634 | if (applet->TransactionComplete()) { | ||
| 635 | storage_stack.push_back(data); | ||
| 636 | pop_out_data_event->Signal(); | ||
| 637 | } else { | ||
| 638 | interactive_storage_stack.push_back(data); | ||
| 639 | pop_interactive_out_data_event->Signal(); | ||
| 640 | } | ||
| 641 | |||
| 620 | IPC::ResponseBuilder rb{ctx, 2}; | 642 | IPC::ResponseBuilder rb{ctx, 2}; |
| 621 | rb.Push(RESULT_SUCCESS); | 643 | rb.Push(RESULT_SUCCESS); |
| 622 | 644 | ||
| @@ -633,9 +655,13 @@ private: | |||
| 633 | LOG_DEBUG(Service_AM, "called"); | 655 | LOG_DEBUG(Service_AM, "called"); |
| 634 | } | 656 | } |
| 635 | 657 | ||
| 636 | void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) { | 658 | void GetPopOutDataEvent(Kernel::HLERequestContext& ctx) { |
| 637 | pop_interactive_out_data_event->Signal(); | 659 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 660 | rb.Push(RESULT_SUCCESS); | ||
| 661 | rb.PushCopyObjects(pop_out_data_event); | ||
| 662 | } | ||
| 638 | 663 | ||
| 664 | void GetPopInteractiveOutDataEvent(Kernel::HLERequestContext& ctx) { | ||
| 639 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 665 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 640 | rb.Push(RESULT_SUCCESS); | 666 | rb.Push(RESULT_SUCCESS); |
| 641 | rb.PushCopyObjects(pop_interactive_out_data_event); | 667 | rb.PushCopyObjects(pop_interactive_out_data_event); |
| @@ -647,6 +673,7 @@ private: | |||
| 647 | std::vector<std::shared_ptr<IStorage>> storage_stack; | 673 | std::vector<std::shared_ptr<IStorage>> storage_stack; |
| 648 | std::vector<std::shared_ptr<IStorage>> interactive_storage_stack; | 674 | std::vector<std::shared_ptr<IStorage>> interactive_storage_stack; |
| 649 | Kernel::SharedPtr<Kernel::Event> state_changed_event; | 675 | Kernel::SharedPtr<Kernel::Event> state_changed_event; |
| 676 | Kernel::SharedPtr<Kernel::Event> pop_out_data_event; | ||
| 650 | Kernel::SharedPtr<Kernel::Event> pop_interactive_out_data_event; | 677 | Kernel::SharedPtr<Kernel::Event> pop_interactive_out_data_event; |
| 651 | }; | 678 | }; |
| 652 | 679 | ||
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 47db22fb4..6d90eb608 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include "common/swap.h" | 9 | #include "common/swap.h" |
| 10 | 10 | ||
| 11 | union ResultCode; | ||
| 12 | |||
| 11 | namespace Frontend { | 13 | namespace Frontend { |
| 12 | class SoftwareKeyboardApplet; | 14 | class SoftwareKeyboardApplet; |
| 13 | } | 15 | } |
| @@ -25,6 +27,9 @@ public: | |||
| 25 | 27 | ||
| 26 | virtual void Initialize(std::vector<std::shared_ptr<IStorage>> storage); | 28 | virtual void Initialize(std::vector<std::shared_ptr<IStorage>> storage); |
| 27 | 29 | ||
| 30 | virtual bool TransactionComplete() const = 0; | ||
| 31 | virtual ResultCode GetStatus() const = 0; | ||
| 32 | virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) = 0; | ||
| 28 | virtual IStorage Execute() = 0; | 33 | virtual IStorage Execute() = 0; |
| 29 | 34 | ||
| 30 | bool IsInitialized() const { | 35 | bool IsInitialized() const { |
diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index 556dea3e4..044a16264 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp | |||
| @@ -50,28 +50,77 @@ void SoftwareKeyboard::Initialize(std::vector<std::shared_ptr<IStorage>> storage | |||
| 50 | ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig)); | 50 | ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig)); |
| 51 | std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig)); | 51 | std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig)); |
| 52 | 52 | ||
| 53 | ASSERT_MSG(config.text_check == 0, "Text check software keyboard mode is not implemented!"); | ||
| 54 | |||
| 55 | const auto& work_buffer = storage_stack[2]->GetData(); | 53 | const auto& work_buffer = storage_stack[2]->GetData(); |
| 56 | std::memcpy(initial_text.data(), work_buffer.data() + config.initial_string_offset, | 54 | |
| 57 | config.initial_string_size); | 55 | if (config.initial_string_size == 0) |
| 56 | return; | ||
| 57 | |||
| 58 | std::vector<char16_t> string(config.initial_string_size); | ||
| 59 | std::memcpy(string.data(), work_buffer.data() + 4, string.size() * 2); | ||
| 60 | initial_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()); | ||
| 61 | } | ||
| 62 | |||
| 63 | bool SoftwareKeyboard::TransactionComplete() const { | ||
| 64 | return complete; | ||
| 65 | } | ||
| 66 | |||
| 67 | ResultCode SoftwareKeyboard::GetStatus() const { | ||
| 68 | return RESULT_SUCCESS; | ||
| 69 | } | ||
| 70 | |||
| 71 | void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> storage) { | ||
| 72 | if (complete) | ||
| 73 | return; | ||
| 74 | |||
| 75 | const auto data = storage->GetData(); | ||
| 76 | const auto status = static_cast<bool>(data[0]); | ||
| 77 | |||
| 78 | if (status == INTERACTIVE_STATUS_OK) { | ||
| 79 | complete = true; | ||
| 80 | } else { | ||
| 81 | const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()}; | ||
| 82 | |||
| 83 | std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; | ||
| 84 | std::memcpy(string.data(), data.data() + 4, string.size() * 2); | ||
| 85 | frontend.SendTextCheckDialog( | ||
| 86 | Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size())); | ||
| 87 | } | ||
| 58 | } | 88 | } |
| 59 | 89 | ||
| 60 | IStorage SoftwareKeyboard::Execute() { | 90 | IStorage SoftwareKeyboard::Execute() { |
| 61 | const auto frontend{GetSoftwareKeyboard()}; | 91 | if (complete) |
| 62 | ASSERT(frontend != nullptr); | 92 | return IStorage{final_data}; |
| 93 | |||
| 94 | const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()}; | ||
| 63 | 95 | ||
| 64 | const auto parameters = ConvertToFrontendParameters(config, initial_text); | 96 | const auto parameters = ConvertToFrontendParameters(config, initial_text); |
| 65 | 97 | ||
| 66 | std::u16string text; | 98 | std::u16string text; |
| 67 | const auto success = frontend->GetText(parameters, text); | 99 | const auto success = frontend.GetText(parameters, text); |
| 68 | 100 | ||
| 69 | std::vector<u8> output(SWKBD_OUTPUT_BUFFER_SIZE); | 101 | std::vector<u8> output(SWKBD_OUTPUT_BUFFER_SIZE); |
| 70 | 102 | ||
| 71 | if (success) { | 103 | if (success) { |
| 72 | output[0] = 1; | 104 | if (config.text_check) { |
| 105 | const auto size = static_cast<u32>(text.size() * 2 + 4); | ||
| 106 | std::memcpy(output.data(), &size, sizeof(u32)); | ||
| 107 | } else { | ||
| 108 | output[0] = 1; | ||
| 109 | } | ||
| 110 | |||
| 73 | std::memcpy(output.data() + 4, text.data(), | 111 | std::memcpy(output.data() + 4, text.data(), |
| 74 | std::min<std::size_t>(text.size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4)); | 112 | std::min(text.size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4)); |
| 113 | } else { | ||
| 114 | complete = true; | ||
| 115 | final_data = std::move(output); | ||
| 116 | return IStorage{final_data}; | ||
| 117 | } | ||
| 118 | |||
| 119 | complete = !config.text_check; | ||
| 120 | |||
| 121 | if (complete) { | ||
| 122 | final_data = std::move(output); | ||
| 123 | return IStorage{final_data}; | ||
| 75 | } | 124 | } |
| 76 | 125 | ||
| 77 | return IStorage{output}; | 126 | return IStorage{output}; |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9b2c09f32..447d9dece 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -61,6 +61,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 61 | #include "core/file_sys/romfs.h" | 61 | #include "core/file_sys/romfs.h" |
| 62 | #include "core/file_sys/savedata_factory.h" | 62 | #include "core/file_sys/savedata_factory.h" |
| 63 | #include "core/file_sys/submission_package.h" | 63 | #include "core/file_sys/submission_package.h" |
| 64 | #include "core/frontend/applets/software_keyboard.h" | ||
| 64 | #include "core/hle/kernel/process.h" | 65 | #include "core/hle/kernel/process.h" |
| 65 | #include "core/hle/service/filesystem/filesystem.h" | 66 | #include "core/hle/service/filesystem/filesystem.h" |
| 66 | #include "core/hle/service/filesystem/fsp_ldr.h" | 67 | #include "core/hle/service/filesystem/fsp_ldr.h" |
| @@ -206,6 +207,22 @@ GMainWindow::~GMainWindow() { | |||
| 206 | delete render_window; | 207 | delete render_window; |
| 207 | } | 208 | } |
| 208 | 209 | ||
| 210 | bool GMainWindow::SoftwareKeyboardGetText( | ||
| 211 | const Core::Frontend::SoftwareKeyboardParameters& parameters, std::u16string& text) { | ||
| 212 | QtSoftwareKeyboardDialog dialog(this, parameters); | ||
| 213 | dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | | ||
| 214 | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); | ||
| 215 | dialog.setWindowModality(Qt::WindowModal); | ||
| 216 | dialog.exec(); | ||
| 217 | |||
| 218 | text = dialog.GetText(); | ||
| 219 | return dialog.GetStatus(); | ||
| 220 | } | ||
| 221 | |||
| 222 | void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message) { | ||
| 223 | QMessageBox::warning(this, tr("Text Check Failed"), QString::fromStdU16String(error_message)); | ||
| 224 | } | ||
| 225 | |||
| 209 | void GMainWindow::InitializeWidgets() { | 226 | void GMainWindow::InitializeWidgets() { |
| 210 | #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING | 227 | #ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING |
| 211 | ui.action_Report_Compatibility->setVisible(true); | 228 | ui.action_Report_Compatibility->setVisible(true); |