Просмотр исходного кода

Merge pull request #8041 from Morph1984/inline-swkbd

applets/swkbd: Add support for an updated inline software keyboard
bunnei 4 лет назад
Родитель
Сommit
664d8c8732

+ 321 - 153
src/core/hle/service/am/applets/applet_software_keyboard.cpp

@@ -226,7 +226,7 @@ void SoftwareKeyboard::InitializeForeground() {
     ASSERT(work_buffer_storage != nullptr);
     ASSERT(work_buffer_storage != nullptr);
 
 
     if (swkbd_config_common.initial_string_length == 0) {
     if (swkbd_config_common.initial_string_length == 0) {
-        InitializeFrontendKeyboard();
+        InitializeFrontendNormalKeyboard();
         return;
         return;
     }
     }
 
 
@@ -243,7 +243,7 @@ void SoftwareKeyboard::InitializeForeground() {
 
 
     LOG_DEBUG(Service_AM, "\nInitial Text: {}", Common::UTF16ToUTF8(initial_text));
     LOG_DEBUG(Service_AM, "\nInitial Text: {}", Common::UTF16ToUTF8(initial_text));
 
 
-    InitializeFrontendKeyboard();
+    InitializeFrontendNormalKeyboard();
 }
 }
 
 
 void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mode) {
 void SoftwareKeyboard::InitializeBackground(LibraryAppletMode library_applet_mode) {
@@ -480,129 +480,173 @@ void SoftwareKeyboard::ChangeState(SwkbdState state) {
     ReplyDefault();
     ReplyDefault();
 }
 }
 
 
-void SoftwareKeyboard::InitializeFrontendKeyboard() {
-    if (is_background) {
-        const auto& appear_arg = swkbd_calc_arg.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},
-            .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.enable_backspace_button},
-            .enable_return_button{appear_arg.enable_return_button},
-            .disable_cancel_button{appear_arg.disable_cancel_button},
-        };
-
-        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);
-            });
-    } else {
-        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},
-            .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::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},
+        .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},
+        .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},
+        .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() {
 void SoftwareKeyboard::ShowNormalKeyboard() {
@@ -614,14 +658,21 @@ void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_resul
     frontend.ShowTextCheckDialog(text_check_result, std::move(text_check_message));
     frontend.ShowTextCheckDialog(text_check_result, std::move(text_check_message));
 }
 }
 
 
-void SoftwareKeyboard::ShowInlineKeyboard() {
+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) {
     if (swkbd_state != SwkbdState::InitializedIsHidden) {
         return;
         return;
     }
     }
 
 
     ChangeState(SwkbdState::InitializedIsAppearing);
     ChangeState(SwkbdState::InitializedIsAppearing);
 
 
-    const auto& appear_arg = swkbd_calc_arg.appear_arg;
+    const auto& appear_arg = swkbd_calc_arg_old.appear_arg;
 
 
     const u32 max_text_length =
     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 > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
@@ -634,21 +685,54 @@ void SoftwareKeyboard::ShowInlineKeyboard() {
     Core::Frontend::InlineAppearParameters appear_parameters{
     Core::Frontend::InlineAppearParameters appear_parameters{
         .max_text_length{max_text_length},
         .max_text_length{max_text_length},
         .min_text_length{min_text_length},
         .min_text_length{min_text_length},
-        .key_top_scale_x{swkbd_calc_arg.key_top_scale_x},
-        .key_top_scale_y{swkbd_calc_arg.key_top_scale_y},
-        .key_top_translate_x{swkbd_calc_arg.key_top_translate_x},
-        .key_top_translate_y{swkbd_calc_arg.key_top_translate_y},
+        .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},
         .type{appear_arg.type},
         .key_disable_flags{appear_arg.key_disable_flags},
         .key_disable_flags{appear_arg.key_disable_flags},
-        .key_top_as_floating{swkbd_calc_arg.key_top_as_floating},
-        .enable_backspace_button{swkbd_calc_arg.enable_backspace_button},
+        .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},
         .enable_return_button{appear_arg.enable_return_button},
         .disable_cancel_button{appear_arg.disable_cancel_button},
         .disable_cancel_button{appear_arg.disable_cancel_button},
     };
     };
 
 
-    frontend.ShowInlineKeyboard(std::move(appear_parameters));
+    ShowInlineKeyboard(std::move(appear_parameters));
+}
 
 
-    ChangeState(SwkbdState::InitializedIsShown);
+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() {
 void SoftwareKeyboard::HideInlineKeyboard() {
@@ -693,6 +777,8 @@ void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) {
 
 
 void SoftwareKeyboard::RequestSetUserWordInfo(const std::vector<u8>& request_data) {
 void SoftwareKeyboard::RequestSetUserWordInfo(const std::vector<u8>& request_data) {
     LOG_WARNING(Service_AM, "SetUserWordInfo is not implemented.");
     LOG_WARNING(Service_AM, "SetUserWordInfo is not implemented.");
+
+    ReplyReleasedUserWordInfo();
 }
 }
 
 
 void SoftwareKeyboard::RequestSetCustomizeDic(const std::vector<u8>& request_data) {
 void SoftwareKeyboard::RequestSetCustomizeDic(const std::vector<u8>& request_data) {
@@ -702,53 +788,135 @@ void SoftwareKeyboard::RequestSetCustomizeDic(const std::vector<u8>& request_dat
 void SoftwareKeyboard::RequestCalc(const std::vector<u8>& request_data) {
 void SoftwareKeyboard::RequestCalc(const std::vector<u8>& request_data) {
     LOG_DEBUG(Service_AM, "Processing Request: Calc");
     LOG_DEBUG(Service_AM, "Processing Request: Calc");
 
 
-    ASSERT(request_data.size() == sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArg));
+    ASSERT(request_data.size() >= sizeof(SwkbdRequestCommand) + sizeof(SwkbdCalcArgCommon));
 
 
-    std::memcpy(&swkbd_calc_arg, request_data.data() + sizeof(SwkbdRequestCommand),
-                sizeof(SwkbdCalcArg));
+    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;
+    }
+}
 
 
-    if (swkbd_calc_arg.flags.set_input_text) {
+void SoftwareKeyboard::RequestCalcNew() {
+    if (swkbd_calc_arg_common.flags.set_input_text) {
         current_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
         current_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
-            swkbd_calc_arg.input_text.data(), swkbd_calc_arg.input_text.size());
+            swkbd_calc_arg_new.input_text.data(), swkbd_calc_arg_new.input_text.size());
     }
     }
 
 
-    if (swkbd_calc_arg.flags.set_cursor_position) {
-        current_cursor_position = swkbd_calc_arg.cursor_position;
+    if (swkbd_calc_arg_common.flags.set_cursor_position) {
+        current_cursor_position = swkbd_calc_arg_new.cursor_position;
     }
     }
 
 
-    if (swkbd_calc_arg.flags.set_utf8_mode) {
-        inline_use_utf8 = swkbd_calc_arg.utf8_mode;
+    if (swkbd_calc_arg_common.flags.set_utf8_mode) {
+        inline_use_utf8 = swkbd_calc_arg_new.utf8_mode;
     }
     }
 
 
     if (swkbd_state <= SwkbdState::InitializedIsHidden &&
     if (swkbd_state <= SwkbdState::InitializedIsHidden &&
-        swkbd_calc_arg.flags.unset_customize_dic) {
+        swkbd_calc_arg_common.flags.unset_customize_dic) {
         ReplyUnsetCustomizeDic();
         ReplyUnsetCustomizeDic();
     }
     }
 
 
     if (swkbd_state <= SwkbdState::InitializedIsHidden &&
     if (swkbd_state <= SwkbdState::InitializedIsHidden &&
-        swkbd_calc_arg.flags.unset_user_word_info) {
+        swkbd_calc_arg_common.flags.unset_user_word_info) {
         ReplyReleasedUserWordInfo();
         ReplyReleasedUserWordInfo();
     }
     }
 
 
-    if (swkbd_state == SwkbdState::NotInitialized && swkbd_calc_arg.flags.set_initialize_arg) {
-        InitializeFrontendKeyboard();
+    if (swkbd_state == SwkbdState::NotInitialized &&
+        swkbd_calc_arg_common.flags.set_initialize_arg) {
+        InitializeFrontendInlineKeyboardNew();
 
 
         ChangeState(SwkbdState::InitializedIsHidden);
         ChangeState(SwkbdState::InitializedIsHidden);
 
 
         ReplyFinishedInitialize();
         ReplyFinishedInitialize();
     }
     }
 
 
-    if (!swkbd_calc_arg.flags.set_initialize_arg &&
-        (swkbd_calc_arg.flags.set_input_text || swkbd_calc_arg.flags.set_cursor_position)) {
+    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();
         InlineTextChanged();
     }
     }
 
 
-    if (swkbd_state == SwkbdState::InitializedIsHidden && swkbd_calc_arg.flags.appear) {
-        ShowInlineKeyboard();
+    if (swkbd_state == SwkbdState::InitializedIsHidden && swkbd_calc_arg_common.flags.appear) {
+        ShowInlineKeyboardNew();
         return;
         return;
     }
     }
 
 
-    if (swkbd_state == SwkbdState::InitializedIsShown && swkbd_calc_arg.flags.disappear) {
+    if (swkbd_state == SwkbdState::InitializedIsShown && swkbd_calc_arg_common.flags.disappear) {
         HideInlineKeyboard();
         HideInlineKeyboard();
         return;
         return;
     }
     }

+ 28 - 7
src/core/hle/service/am/applets/applet_software_keyboard.h

@@ -13,6 +13,11 @@ namespace Core {
 class System;
 class System;
 }
 }
 
 
+namespace Core::Frontend {
+struct KeyboardInitializeParameters;
+struct InlineAppearParameters;
+} // namespace Core::Frontend
+
 namespace Service::AM::Applets {
 namespace Service::AM::Applets {
 
 
 class SoftwareKeyboard final : public Applet {
 class SoftwareKeyboard final : public Applet {
@@ -78,13 +83,22 @@ private:
     void ChangeState(SwkbdState state);
     void ChangeState(SwkbdState state);
 
 
     /**
     /**
-     * Signals the frontend to initialize the software keyboard with common parameters.
-     * This initializes either the normal software keyboard or the inline software keyboard
-     * depending on the state of is_background.
+     * Signals the frontend to initialize the normal software keyboard with common parameters.
      * Note that this does not cause the keyboard to appear.
      * Note that this does not cause the keyboard to appear.
-     * Use the respective Show*Keyboard() functions to cause the respective keyboards to appear.
+     * Use the ShowNormalKeyboard() functions to cause the keyboard to appear.
      */
      */
-    void InitializeFrontendKeyboard();
+    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.
     /// Signals the frontend to show the normal software keyboard.
     void ShowNormalKeyboard();
     void ShowNormalKeyboard();
@@ -94,7 +108,10 @@ private:
                              std::u16string text_check_message);
                              std::u16string text_check_message);
 
 
     /// Signals the frontend to show the inline software keyboard.
     /// Signals the frontend to show the inline software keyboard.
-    void ShowInlineKeyboard();
+    void ShowInlineKeyboard(Core::Frontend::InlineAppearParameters appear_parameters);
+
+    void ShowInlineKeyboardOld();
+    void ShowInlineKeyboardNew();
 
 
     /// Signals the frontend to hide the inline software keyboard.
     /// Signals the frontend to hide the inline software keyboard.
     void HideInlineKeyboard();
     void HideInlineKeyboard();
@@ -111,6 +128,8 @@ private:
     void RequestSetUserWordInfo(const std::vector<u8>& request_data);
     void RequestSetUserWordInfo(const std::vector<u8>& request_data);
     void RequestSetCustomizeDic(const std::vector<u8>& request_data);
     void RequestSetCustomizeDic(const std::vector<u8>& request_data);
     void RequestCalc(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 RequestSetCustomizedDictionaries(const std::vector<u8>& request_data);
     void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data);
     void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data);
     void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data);
     void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data);
@@ -149,7 +168,9 @@ private:
 
 
     SwkbdState swkbd_state{SwkbdState::NotInitialized};
     SwkbdState swkbd_state{SwkbdState::NotInitialized};
     SwkbdInitializeArg swkbd_initialize_arg;
     SwkbdInitializeArg swkbd_initialize_arg;
-    SwkbdCalcArg swkbd_calc_arg;
+    SwkbdCalcArgCommon swkbd_calc_arg_common;
+    SwkbdCalcArgOld swkbd_calc_arg_old;
+    SwkbdCalcArgNew swkbd_calc_arg_new;
     bool use_changed_string_v2{false};
     bool use_changed_string_v2{false};
     bool use_moved_cursor_v2{false};
     bool use_moved_cursor_v2{false};
     bool inline_use_utf8{false};
     bool inline_use_utf8{false};

+ 66 - 6
src/core/hle/service/am/applets/applet_software_keyboard_types.h

@@ -10,6 +10,7 @@
 #include "common/common_funcs.h"
 #include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "common/common_types.h"
 #include "common/swap.h"
 #include "common/swap.h"
+#include "common/uuid.h"
 
 
 namespace Service::AM::Applets {
 namespace Service::AM::Applets {
 
 
@@ -216,7 +217,7 @@ struct SwkbdInitializeArg {
 };
 };
 static_assert(sizeof(SwkbdInitializeArg) == 0x8, "SwkbdInitializeArg has incorrect size.");
 static_assert(sizeof(SwkbdInitializeArg) == 0x8, "SwkbdInitializeArg has incorrect size.");
 
 
-struct SwkbdAppearArg {
+struct SwkbdAppearArgOld {
     SwkbdType type{};
     SwkbdType type{};
     std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
     std::array<char16_t, MAX_OK_TEXT_LENGTH + 1> ok_text{};
     char16_t left_optional_symbol_key{};
     char16_t left_optional_symbol_key{};
@@ -229,19 +230,76 @@ struct SwkbdAppearArg {
     bool enable_return_button{};
     bool enable_return_button{};
     INSERT_PADDING_BYTES(3);
     INSERT_PADDING_BYTES(3);
     u32 flags{};
     u32 flags{};
-    INSERT_PADDING_WORDS(6);
+    bool is_use_save_data{};
+    INSERT_PADDING_BYTES(7);
+    Common::UUID user_id{};
 };
 };
-static_assert(sizeof(SwkbdAppearArg) == 0x48, "SwkbdAppearArg has incorrect size.");
+static_assert(sizeof(SwkbdAppearArgOld) == 0x48, "SwkbdAppearArg has incorrect size.");
 
 
-struct SwkbdCalcArg {
+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{};
     u32 unknown{};
     u16 calc_arg_size{};
     u16 calc_arg_size{};
     INSERT_PADDING_BYTES(2);
     INSERT_PADDING_BYTES(2);
     SwkbdCalcArgFlags flags{};
     SwkbdCalcArgFlags flags{};
     SwkbdInitializeArg initialize_arg{};
     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{};
     f32 volume{};
     s32 cursor_position{};
     s32 cursor_position{};
-    SwkbdAppearArg appear_arg{};
     std::array<char16_t, 0x1FA> input_text{};
     std::array<char16_t, 0x1FA> input_text{};
     bool utf8_mode{};
     bool utf8_mode{};
     INSERT_PADDING_BYTES(1);
     INSERT_PADDING_BYTES(1);
@@ -264,8 +322,10 @@ struct SwkbdCalcArg {
     INSERT_PADDING_WORDS(4);
     INSERT_PADDING_WORDS(4);
     u8 se_group{};
     u8 se_group{};
     INSERT_PADDING_BYTES(3);
     INSERT_PADDING_BYTES(3);
+    INSERT_PADDING_WORDS(8);
 };
 };
-static_assert(sizeof(SwkbdCalcArg) == 0x4A0, "SwkbdCalcArg has incorrect size.");
+static_assert(sizeof(SwkbdCalcArgNew) == 0x4E8 - sizeof(SwkbdCalcArgCommon),
+              "SwkbdCalcArgNew has incorrect size.");
 
 
 struct SwkbdChangedStringArg {
 struct SwkbdChangedStringArg {
     u32 text_length{};
     u32 text_length{};