From 190691f249c7ab6a4e1ae529fc76e08417397e2b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 14 Oct 2017 22:53:17 -0700 Subject: [PATCH] OSK: Limit allowed keyboards based on input mask. --- .editorconfig | 2 +- Core/Dialog/PSPOskDialog.cpp | 118 ++++++++++++++++++++++++++--------- 2 files changed, 88 insertions(+), 32 deletions(-) diff --git a/.editorconfig b/.editorconfig index 607bc73842..21b678c82b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,7 +23,7 @@ indent_style = space indent_size = 4 [Core/Dialog/PSPOskDialog.cpp] -charset = utf-16le +charset = utf-8-bom [ext/native/tools/kanjifilter.h] # This file may need to force a BOM so compilers treat as utf-8. diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 518ca2797a..cf09c4db42 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -143,6 +143,18 @@ static const wchar_t oskKeys[OSK_KEYBOARD_COUNT][5][14] = }, }; +// This isn't a complete representation of these flags, it just helps ensure we show the right keyboards. +int allowedInputFlagsMap[OSK_KEYBOARD_COUNT] = { + PSP_UTILITY_OSK_INPUTTYPE_LATIN_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL | PSP_UTILITY_OSK_INPUTTYPE_LATIN_DIGIT, + PSP_UTILITY_OSK_INPUTTYPE_LATIN_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_LATIN_SYMBOL, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HIRAGANA, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_KATAKANA | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_HALF_KATAKANA, + PSP_UTILITY_OSK_INPUTTYPE_KOREAN, + PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_LOWERCASE, + PSP_UTILITY_OSK_INPUTTYPE_RUSSIAN_UPPERCASE, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_LOWERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_SYMBOL | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_DIGIT, + PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_UPPERCASE | PSP_UTILITY_OSK_INPUTTYPE_JAPANESE_SYMBOL, +}; PSPOskDialog::PSPOskDialog() : PSPDialog() { // This can break all kinds of stuff, changing the decimal point in sprintf for example. @@ -227,6 +239,42 @@ void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input) _string = stringBuffer; } +static void FindValidKeyboard(s32 inputType, int direction, OskKeyboardLanguage &lang, OskKeyboardDisplay &disp) { + OskKeyboardLanguage origLang = lang; + OskKeyboardDisplay origDisp = disp; + + if (inputType == 0) { + return; + } + + // TODO: Limit by allowed keyboards properly... this is just an approximation. + int tries = OSK_LANGUAGE_COUNT * 2; + while (!(inputType & allowedInputFlagsMap[disp]) && tries > 0) { + if ((--tries % 1) == 0) { + lang = (OskKeyboardLanguage)((OSK_LANGUAGE_COUNT + lang + direction) % OSK_LANGUAGE_COUNT); + disp = OskKeyboardCases[lang][LOWERCASE]; + } else { + disp = OskKeyboardCases[lang][UPPERCASE]; + } + } + + if (tries == 0) { + // In case of error, let's just fall back to allowing all. + lang = origLang; + disp = origDisp; + } +} + +static bool IsKeyboardShiftValid(s32 inputType, OskKeyboardLanguage lang, OskKeyboardDisplay disp) { + // Swap disp and check if it's valid. + if (disp == OskKeyboardCases[lang][UPPERCASE]) + disp = OskKeyboardCases[lang][LOWERCASE]; + else + disp = OskKeyboardCases[lang][UPPERCASE]; + + return inputType == 0 || (inputType & allowedInputFlagsMap[disp]) != 0; +} + int PSPOskDialog::Init(u32 oskPtr) { // Ignore if already running if (GetStatus() != SCE_UTILITY_STATUS_NONE) { @@ -259,8 +307,9 @@ int PSPOskDialog::Init(u32 oskPtr) { ChangeStatusInit(OSK_INIT_DELAY_US); selectedChar = 0; - currentKeyboard = OSK_KEYBOARD_LATIN_LOWERCASE; currentKeyboardLanguage = OSK_LANGUAGE_ENGLISH; + currentKeyboard = OSK_KEYBOARD_LATIN_LOWERCASE; + FindValidKeyboard(oskParams->fields[0].inputtype, 1, currentKeyboardLanguage, currentKeyboard); ConvertUCS2ToUTF8(oskDesc, oskParams->fields[0].desc); ConvertUCS2ToUTF8(oskIntext, oskParams->fields[0].intext); @@ -887,37 +936,43 @@ int PSPOskDialog::Update(int animSpeed) { PPGeDrawText("Start", 135, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawText(di->T("Finish"), 185, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); - int index = (currentKeyboardLanguage - 1) % OSK_LANGUAGE_COUNT; - const char *countryCode; + auto lookupLangName = [&](int direction) { + // First, find the valid one... + OskKeyboardLanguage lang = (OskKeyboardLanguage)((OSK_LANGUAGE_COUNT + currentKeyboardLanguage + direction) % OSK_LANGUAGE_COUNT); + OskKeyboardDisplay disp = OskKeyboardCases[lang][LOWERCASE]; + FindValidKeyboard(oskParams->fields[0].inputtype, direction, lang, disp); - if (index >= 0) - countryCode = OskKeyboardNames[(currentKeyboardLanguage - 1) % OSK_LANGUAGE_COUNT].c_str(); - else - countryCode = OskKeyboardNames[OSK_LANGUAGE_COUNT - 1].c_str(); + if (lang == currentKeyboardLanguage) { + return (const char *)nullptr; + } - const char *language = languageMapping[countryCode].first.c_str(); + // Now, let's grab the name. + const char *countryCode = OskKeyboardNames[lang].c_str(); + const char *language = languageMapping[countryCode].first.c_str(); - if (!strcmp(countryCode, "English Full-width")) - language = "English Full-width"; - - countryCode = OskKeyboardNames[currentKeyboardLanguage].c_str(); - - if (strcmp(countryCode, "ko_KR")) { + // It seems like this is a "fake" country code for extra keyboard purposes. + if (!strcmp(countryCode, "English Full-width")) + language = "English Full-width"; + + return language; + }; + + if (OskKeyboardNames[currentKeyboardLanguage] != "ko_KR" && IsKeyboardShiftValid(oskParams->fields[0].inputtype, currentKeyboardLanguage, currentKeyboard)) { PPGeDrawText("Select", 135, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); PPGeDrawText(di->T("Shift"), 185, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); } - - PPGeDrawText("L", 235, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(language, 255, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); - countryCode = OskKeyboardNames[(currentKeyboardLanguage + 1) % OSK_LANGUAGE_COUNT].c_str(); - language = languageMapping[countryCode].first.c_str(); + const char *prevLang = lookupLangName(-1); + if (prevLang) { + PPGeDrawText("L", 235, 220, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(prevLang, 255, 222, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + } - if (!strcmp(countryCode, "English Full-width")) - language = "English Full-width"; - - PPGeDrawText("R", 235, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); - PPGeDrawText(language, 255, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + const char *nextLang = lookupLangName(1); + if (nextLang) { + PPGeDrawText("R", 235, 245, PPGE_ALIGN_LEFT, 0.6f, CalcFadedColor(0xFFFFFFFF)); + PPGeDrawText(nextLang, 255, 247, PPGE_ALIGN_LEFT, 0.5f, CalcFadedColor(0xFFFFFFFF)); + } if (IsButtonPressed(CTRL_UP) || IsButtonHeld(CTRL_UP, upBtnFramesHeld, framesHeldThreshold, framesHeldRepeatRate)) { selectedChar -= numKeyCols[currentKeyboard]; @@ -939,10 +994,12 @@ int PSPOskDialog::Update(int animSpeed) { inputChars = CombinationString(true); } else if (IsButtonPressed(CTRL_SELECT)) { // Select now swaps case. - if (currentKeyboard == OskKeyboardCases[currentKeyboardLanguage][UPPERCASE]) - currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE]; - else - currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][UPPERCASE]; + if (IsKeyboardShiftValid(oskParams->fields[0].inputtype, currentKeyboardLanguage, currentKeyboard)) { + if (currentKeyboard == OskKeyboardCases[currentKeyboardLanguage][UPPERCASE]) + currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE]; + else + currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][UPPERCASE]; + } if (selectedRow >= numKeyRows[currentKeyboard]) { selectedRow = numKeyRows[currentKeyboard] - 1; @@ -954,10 +1011,10 @@ int PSPOskDialog::Update(int animSpeed) { selectedChar = selectedRow * numKeyCols[currentKeyboard] + selectedExtra; } else if (IsButtonPressed(CTRL_RTRIGGER)) { - // TODO: Limit by allowed keyboards... // RTRIGGER now cycles languages forward. currentKeyboardLanguage = (OskKeyboardLanguage)((currentKeyboardLanguage + 1) % OSK_LANGUAGE_COUNT); currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE]; + FindValidKeyboard(oskParams->fields[0].inputtype, 1, currentKeyboardLanguage, currentKeyboard); if (selectedRow >= numKeyRows[currentKeyboard]) { selectedRow = numKeyRows[currentKeyboard] - 1; @@ -969,14 +1026,13 @@ int PSPOskDialog::Update(int animSpeed) { selectedChar = selectedRow * numKeyCols[currentKeyboard] + selectedExtra; } else if (IsButtonPressed(CTRL_LTRIGGER)) { - // TODO: Limit by allowed keyboards... // LTRIGGER now cycles languages backward. if (currentKeyboardLanguage - 1 >= 0) currentKeyboardLanguage = (OskKeyboardLanguage)((currentKeyboardLanguage - 1) % OSK_LANGUAGE_COUNT); else currentKeyboardLanguage = (OskKeyboardLanguage)(OSK_LANGUAGE_COUNT - 1); - currentKeyboard = OskKeyboardCases[currentKeyboardLanguage][LOWERCASE]; + FindValidKeyboard(oskParams->fields[0].inputtype, -1, currentKeyboardLanguage, currentKeyboard); if (selectedRow >= numKeyRows[currentKeyboard]) { selectedRow = numKeyRows[currentKeyboard] - 1;