diff options
Diffstat (limited to 'src/core/hle')
| -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 |
3 files changed, 95 insertions, 14 deletions
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}; |