From d7d2c27b48943addf3d1da1ed5d5c0e75d8f0108 Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Sun, 19 Jul 2020 18:56:16 +1000
Subject: [PATCH 1/2] swkbd: Return result for Calc request for inlined swkbd

Fixes random swkbd popups in monster hunter
---
 .../service/am/applets/software_keyboard.cpp  | 61 +++++++++++++++----
 .../service/am/applets/software_keyboard.h    |  1 +
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index fbe3686ae1..4dd947dd16 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -13,11 +13,23 @@
 
 namespace Service::AM::Applets {
 
+namespace {
+enum class Request : u32_le {
+    Finalize = 0x4,
+    SetUserWordInfo = 0x6,
+    SetCustomizeDic = 0x7,
+    Calc = 0xa,
+    SetCustomizedDictionaries = 0xb,
+    UnsetCustomizedDictionaries = 0xc,
+    UnknownD = 0xd,
+    UnknownE = 0xe,
+};
+constexpr std::size_t SWKBD_INLINE_INIT_SIZE = 0x8;
 constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8;
 constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4;
 constexpr std::size_t DEFAULT_MAX_LENGTH = 500;
 constexpr bool INTERACTIVE_STATUS_OK = false;
-
+} // namespace
 static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
     KeyboardConfig config, std::u16string initial_text) {
     Core::Frontend::SoftwareKeyboardParameters params{};
@@ -47,6 +59,7 @@ SoftwareKeyboard::~SoftwareKeyboard() = default;
 
 void SoftwareKeyboard::Initialize() {
     complete = false;
+    is_inline = false;
     initial_text.clear();
     final_data.clear();
 
@@ -56,6 +69,11 @@ void SoftwareKeyboard::Initialize() {
     ASSERT(keyboard_config_storage != nullptr);
     const auto& keyboard_config = keyboard_config_storage->GetData();
 
+    if (keyboard_config.size() == SWKBD_INLINE_INIT_SIZE) {
+        is_inline = true;
+        return;
+    }
+
     ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig));
     std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig));
 
@@ -87,16 +105,32 @@ void SoftwareKeyboard::ExecuteInteractive() {
     const auto storage = broker.PopInteractiveDataToApplet();
     ASSERT(storage != nullptr);
     const auto data = storage->GetData();
-    const auto status = static_cast<bool>(data[0]);
-
-    if (status == INTERACTIVE_STATUS_OK) {
-        complete = true;
+    if (!is_inline) {
+        const auto status = static_cast<bool>(data[0]);
+        if (status == INTERACTIVE_STATUS_OK) {
+            complete = true;
+        } else {
+            std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
+            std::memcpy(string.data(), data.data() + 4, string.size() * 2);
+            frontend.SendTextCheckDialog(
+                Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
+                [this] { broker.SignalStateChanged(); });
+        }
     } else {
-        std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string;
-        std::memcpy(string.data(), data.data() + 4, string.size() * 2);
-        frontend.SendTextCheckDialog(
-            Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()),
-            [this] { broker.SignalStateChanged(); });
+        Request request{};
+        std::memcpy(&request, data.data(), sizeof(Request));
+
+        switch (request) {
+        case Request::Calc: {
+            broker.PushNormalDataFromApplet(
+                std::make_shared<IStorage>(std::move(std::vector<u8>{1})));
+            broker.SignalStateChanged();
+            break;
+        }
+        default:
+            UNIMPLEMENTED_MSG("Request {:X} is not implemented", request);
+            break;
+        }
     }
 }
 
@@ -108,9 +142,10 @@ void SoftwareKeyboard::Execute() {
     }
 
     const auto parameters = ConvertToFrontendParameters(config, initial_text);
-
-    frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(std::move(text)); },
-                         parameters);
+    if (!is_inline) {
+        frontend.RequestText(
+            [this](std::optional<std::u16string> text) { WriteText(std::move(text)); }, parameters);
+    }
 }
 
 void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) {
diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h
index ef4801fc62..5a3824b5a7 100644
--- a/src/core/hle/service/am/applets/software_keyboard.h
+++ b/src/core/hle/service/am/applets/software_keyboard.h
@@ -78,6 +78,7 @@ private:
     KeyboardConfig config;
     std::u16string initial_text;
     bool complete = false;
+    bool is_inline = false;
     std::vector<u8> final_data;
 };
 

From 8248d76964677a5d300e552aaf17f5e0fdafec71 Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Mon, 20 Jul 2020 11:52:07 +1000
Subject: [PATCH 2/2] Address issues

---
 src/core/hle/service/am/applets/software_keyboard.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp
index 4dd947dd16..289da26199 100644
--- a/src/core/hle/service/am/applets/software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/software_keyboard.cpp
@@ -14,7 +14,7 @@
 namespace Service::AM::Applets {
 
 namespace {
-enum class Request : u32_le {
+enum class Request : u32 {
     Finalize = 0x4,
     SetUserWordInfo = 0x6,
     SetCustomizeDic = 0x7,
@@ -29,7 +29,7 @@ constexpr std::size_t SWKBD_OUTPUT_BUFFER_SIZE = 0x7D8;
 constexpr std::size_t SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE = 0x7D4;
 constexpr std::size_t DEFAULT_MAX_LENGTH = 500;
 constexpr bool INTERACTIVE_STATUS_OK = false;
-} // namespace
+} // Anonymous namespace
 static Core::Frontend::SoftwareKeyboardParameters ConvertToFrontendParameters(
     KeyboardConfig config, std::u16string initial_text) {
     Core::Frontend::SoftwareKeyboardParameters params{};