Merge pull request #8041 from Morph1984/inline-swkbd

applets/swkbd: Add support for an updated inline software keyboard
This commit is contained in:
bunnei 2022-03-25 23:19:11 -07:00 committed by GitHub
commit 664d8c8732
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 397 additions and 148 deletions

View file

@ -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() { void SoftwareKeyboard::InitializeFrontendNormalKeyboard() {
if (is_background) { std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
const auto& appear_arg = swkbd_calc_arg.appear_arg; swkbd_config_common.ok_text.data(), swkbd_config_common.ok_text.size());
std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( std::u16string header_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
appear_arg.ok_text.data(), appear_arg.ok_text.size()); swkbd_config_common.header_text.data(), swkbd_config_common.header_text.size());
const u32 max_text_length = std::u16string sub_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH swkbd_config_common.sub_text.data(), swkbd_config_common.sub_text.size());
? appear_arg.max_text_length
: DEFAULT_MAX_TEXT_LENGTH;
const u32 min_text_length = std::u16string guide_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0; swkbd_config_common.guide_text.data(), swkbd_config_common.guide_text.size());
const s32 initial_cursor_position = const u32 max_text_length =
current_cursor_position > 0 ? current_cursor_position : 0; 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 auto text_draw_type = const u32 min_text_length = swkbd_config_common.min_text_length <= max_text_length
max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; ? swkbd_config_common.min_text_length
: 0;
Core::Frontend::KeyboardInitializeParameters initialize_parameters{ const s32 initial_cursor_position = [this] {
.ok_text{std::move(ok_text)}, switch (swkbd_config_common.initial_cursor_position) {
.header_text{}, case SwkbdInitialCursorPosition::Start:
.sub_text{}, default:
.guide_text{}, return 0;
.initial_text{current_text}, case SwkbdInitialCursorPosition::End:
.max_text_length{max_text_length}, return static_cast<s32>(initial_text.size());
.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( const auto text_draw_type = [this, max_text_length] {
true, std::move(initialize_parameters), {}, switch (swkbd_config_common.text_draw_type) {
[this](SwkbdReplyType reply_type, std::u16string submitted_text, s32 cursor_position) { case SwkbdTextDrawType::Line:
SubmitTextInline(reply_type, submitted_text, cursor_position); default:
}); return max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box;
} else { case SwkbdTextDrawType::Box:
std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( case SwkbdTextDrawType::DownloadCode:
swkbd_config_common.ok_text.data(), swkbd_config_common.ok_text.size()); return swkbd_config_common.text_draw_type;
}
}();
std::u16string header_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( const auto enable_return_button =
swkbd_config_common.header_text.data(), swkbd_config_common.header_text.size()); text_draw_type == SwkbdTextDrawType::Box ? swkbd_config_common.enable_return_button : false;
std::u16string sub_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( const auto disable_cancel_button = swkbd_applet_version >= SwkbdAppletVersion::Version393227
swkbd_config_common.sub_text.data(), swkbd_config_common.sub_text.size()); ? swkbd_config_new.disable_cancel_button
: false;
std::u16string guide_text = Common::UTF16StringFromFixedZeroTerminatedBuffer( Core::Frontend::KeyboardInitializeParameters initialize_parameters{
swkbd_config_common.guide_text.data(), swkbd_config_common.guide_text.size()); .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},
};
const u32 max_text_length = frontend.InitializeKeyboard(
swkbd_config_common.max_text_length > 0 && false, std::move(initialize_parameters),
swkbd_config_common.max_text_length <= DEFAULT_MAX_TEXT_LENGTH [this](SwkbdResult result, std::u16string submitted_text, bool confirmed) {
? swkbd_config_common.max_text_length SubmitTextNormal(result, submitted_text, confirmed);
: DEFAULT_MAX_TEXT_LENGTH; },
{});
}
const u32 min_text_length = swkbd_config_common.min_text_length <= max_text_length void SoftwareKeyboard::InitializeFrontendInlineKeyboard(
? swkbd_config_common.min_text_length Core::Frontend::KeyboardInitializeParameters initialize_parameters) {
: 0; 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);
});
}
const s32 initial_cursor_position = [this] { void SoftwareKeyboard::InitializeFrontendInlineKeyboardOld() {
switch (swkbd_config_common.initial_cursor_position) { const auto& appear_arg = swkbd_calc_arg_old.appear_arg;
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] { std::u16string ok_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
switch (swkbd_config_common.text_draw_type) { appear_arg.ok_text.data(), appear_arg.ok_text.size());
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 const u32 max_text_length =
? swkbd_config_common.enable_return_button appear_arg.max_text_length > 0 && appear_arg.max_text_length <= DEFAULT_MAX_TEXT_LENGTH
: false; ? appear_arg.max_text_length
: DEFAULT_MAX_TEXT_LENGTH;
const auto disable_cancel_button = swkbd_applet_version >= SwkbdAppletVersion::Version393227 const u32 min_text_length =
? swkbd_config_new.disable_cancel_button appear_arg.min_text_length <= max_text_length ? appear_arg.min_text_length : 0;
: false;
Core::Frontend::KeyboardInitializeParameters initialize_parameters{ const s32 initial_cursor_position = current_cursor_position > 0 ? current_cursor_position : 0;
.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( const auto text_draw_type =
false, std::move(initialize_parameters), max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box;
[this](SwkbdResult result, std::u16string submitted_text, bool confirmed) {
SubmitTextNormal(result, submitted_text, confirmed); 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_x{swkbd_calc_arg_old.key_top_scale_x},
.key_top_scale_y{swkbd_calc_arg.key_top_scale_y}, .key_top_scale_y{swkbd_calc_arg_old.key_top_scale_y},
.key_top_translate_x{swkbd_calc_arg.key_top_translate_x}, .key_top_translate_x{swkbd_calc_arg_old.key_top_translate_x},
.key_top_translate_y{swkbd_calc_arg.key_top_translate_y}, .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}, .key_top_as_floating{swkbd_calc_arg_old.key_top_as_floating},
.enable_backspace_button{swkbd_calc_arg.enable_backspace_button}, .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), std::memcpy(&swkbd_calc_arg_common, request_data.data() + sizeof(SwkbdRequestCommand),
sizeof(SwkbdCalcArg)); sizeof(SwkbdCalcArgCommon));
if (swkbd_calc_arg.flags.set_input_text) { 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( current_text = Common::UTF16StringFromFixedZeroTerminatedBuffer(
swkbd_calc_arg.input_text.data(), swkbd_calc_arg.input_text.size()); swkbd_calc_arg_old.input_text.data(), swkbd_calc_arg_old.input_text.size());
} }
if (swkbd_calc_arg.flags.set_cursor_position) { if (swkbd_calc_arg_common.flags.set_cursor_position) {
current_cursor_position = swkbd_calc_arg.cursor_position; current_cursor_position = swkbd_calc_arg_old.cursor_position;
} }
if (swkbd_calc_arg.flags.set_utf8_mode) { if (swkbd_calc_arg_common.flags.set_utf8_mode) {
inline_use_utf8 = swkbd_calc_arg.utf8_mode; inline_use_utf8 = swkbd_calc_arg_old.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) { if (swkbd_state == SwkbdState::NotInitialized &&
InitializeFrontendKeyboard(); swkbd_calc_arg_common.flags.set_initialize_arg) {
InitializeFrontendInlineKeyboardOld();
ChangeState(SwkbdState::InitializedIsHidden); ChangeState(SwkbdState::InitializedIsHidden);
ReplyFinishedInitialize(); ReplyFinishedInitialize();
} }
if (!swkbd_calc_arg.flags.set_initialize_arg && if (!swkbd_calc_arg_common.flags.set_initialize_arg &&
(swkbd_calc_arg.flags.set_input_text || swkbd_calc_arg.flags.set_cursor_position)) { (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) { if (swkbd_state == SwkbdState::InitializedIsHidden && swkbd_calc_arg_common.flags.appear) {
ShowInlineKeyboard(); ShowInlineKeyboardOld();
return; return;
} }
if (swkbd_state == SwkbdState::InitializedIsShown && swkbd_calc_arg.flags.disappear) { 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(); HideInlineKeyboard();
return; return;
} }

View file

@ -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. * Signals the frontend to initialize the normal software keyboard with common parameters.
* This initializes either the normal software keyboard or the inline software keyboard
* depending on the state of is_background.
* 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};

View file

@ -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,46 @@ 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{}; f32 volume{};
s32 cursor_position{}; s32 cursor_position{};
SwkbdAppearArg appear_arg{}; SwkbdAppearArgOld 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);
@ -265,7 +293,39 @@ struct SwkbdCalcArg {
u8 se_group{}; u8 se_group{};
INSERT_PADDING_BYTES(3); INSERT_PADDING_BYTES(3);
}; };
static_assert(sizeof(SwkbdCalcArg) == 0x4A0, "SwkbdCalcArg has incorrect size."); 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 { struct SwkbdChangedStringArg {
u32 text_length{}; u32 text_length{};