From 2bf4555591d246ba315505d5b70fcaee43c1fa11 Mon Sep 17 00:00:00 2001
From: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com>
Date: Fri, 9 Jun 2023 11:11:53 +0100
Subject: [PATCH] Swkbd Applet Fixes (#5236)

* Swkbd Applet Fixes

* Forgot a full stop

* Update src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Update src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
---
 src/Ryujinx.Ava/Assets/Locales/en_US.json      |  2 +-
 .../UI/Applet/SwkbdAppletDialog.axaml.cs       |  2 +-
 .../SoftwareKeyboard/CJKCharacterValidation.cs | 17 +++++++++++++++++
 .../Applets/SoftwareKeyboard/KeyboardMode.cs   | 18 +++++++++++++-----
 src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs     |  4 ++--
 5 files changed, 34 insertions(+), 9 deletions(-)
 create mode 100644 src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs

diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json
index 79765db16e..4065a1dfbe 100644
--- a/src/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/src/Ryujinx.Ava/Assets/Locales/en_US.json
@@ -545,7 +545,7 @@
   "SwkbdMinRangeCharacters": "Must be {0}-{1} characters long",
   "SoftwareKeyboard": "Software Keyboard",
   "SoftwareKeyboardModeNumbersOnly": "Must be numbers only",
-  "SoftwareKeyboardModeAlphabet": "Must be alphabets only",
+  "SoftwareKeyboardModeAlphabet": "Must be non CJK-characters only",
   "SoftwareKeyboardModeASCII": "Must be ASCII text only",
   "DialogControllerAppletMessagePlayerRange": "Application requests {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
   "DialogControllerAppletMessage": "Application requests exactly {0} player(s) with:\n\nTYPES: {1}\n\nPLAYERS: {2}\n\n{3}Please open Settings and reconfigure Input now or press Close.",
diff --git a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
index 04bc461930..81258b4489 100644
--- a/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Applet/SwkbdAppletDialog.axaml.cs
@@ -146,7 +146,7 @@ namespace Ryujinx.Ava.UI.Controls
                 case KeyboardMode.Alphabet:
                     localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeAlphabet);
                     validationInfoText = string.IsNullOrEmpty(validationInfoText) ? localeText : string.Join("\n", validationInfoText, localeText);
-                    _checkInput = text => text.All(char.IsAsciiLetter);
+                    _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
                     break;
                 case KeyboardMode.ASCII:
                     localeText = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.SoftwareKeyboardModeASCII);
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs
new file mode 100644
index 0000000000..36e6ff512f
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs
@@ -0,0 +1,17 @@
+using System.Text.RegularExpressions;
+
+namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
+{
+    public static partial class CJKCharacterValidation
+    {
+        public static bool IsCJK(char value)
+        {
+            Regex regex = CJKRegex();
+
+            return regex.IsMatch(value.ToString());
+        }
+
+        [GeneratedRegex("\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")]
+        private static partial Regex CJKRegex();
+    }
+}
\ No newline at end of file
diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
index 01b3c9634d..e28622111b 100644
--- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
+++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
@@ -6,22 +6,30 @@
     public enum KeyboardMode : uint
     {
         /// <summary>
-        /// A full alpha-numeric keyboard.
+        /// All UTF-16 characters allowed.
         /// </summary>
         Default = 0,
 
         /// <summary>
-        /// Number pad.
+        /// Only numbers allowed.
         /// </summary>
         NumbersOnly = 1,
 
         /// <summary>
-        /// ASCII characters keyboard.
+        /// Only ASCII characters allowed.
         /// </summary>
         ASCII = 2,
 
-        FullLatin          = 3,
-        Alphabet           = 4,
+        /// <summary>
+        /// Synonymous with default.
+        /// </summary>
+        FullLatin = 3,
+        
+        /// <summary>
+        /// All UTF-16 characters except CJK characters allowed.
+        /// </summary>
+        Alphabet = 4,
+        
         SimplifiedChinese  = 5,
         TraditionalChinese = 6,
         Korean             = 7,
diff --git a/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs b/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs
index 28067b7514..13d30f6c05 100644
--- a/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs
+++ b/src/Ryujinx/Ui/Applet/SwkbdAppletDialog.cs
@@ -93,8 +93,8 @@ namespace Ryujinx.Ui.Applet
                     _checkInput = text => text.All(char.IsDigit);
                     break;
                 case KeyboardMode.Alphabet:
-                    _validationInfoText += "<i>Must be alphabets only.</i>";
-                    _checkInput = text => text.All(char.IsAsciiLetter);
+                    _validationInfoText += "<i>Must be non CJK-characters only.</i>";
+                    _checkInput = text => text.All(value => !CJKCharacterValidation.IsCJK(value));
                     break;
                 case KeyboardMode.ASCII:
                     _validationInfoText += "<i>Must be ASCII text only.</i>";