aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.HLE/HOS/Applets/SoftwareKeyboard
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.HLE/HOS/Applets/SoftwareKeyboard')
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs18
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs48
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs93
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs33
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs298
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs18
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs17
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs56
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs26
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs14
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs12
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs31
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs12
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs18
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.pngbin1074 -> 0 bytes
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.svg80
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.pngbin992 -> 0 bytes
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.svg93
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.pngbin842 -> 0 bytes
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.svg108
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Logo_Ryujinx.pngbin52972 -> 0 bytes
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs119
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs100
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs816
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs220
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs182
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs138
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs13
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs34
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs26
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs164
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs606
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs28
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiArgs.cs13
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs22
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs13
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs19
-rw-r--r--Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs186
38 files changed, 0 insertions, 3674 deletions
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs
deleted file mode 100644
index 727b6d27..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InitialCursorPosition.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Identifies the initial position of the cursor displayed in the area.
- /// </summary>
- enum InitialCursorPosition : uint
- {
- /// <summary>
- /// Position the cursor at the beginning of the text
- /// </summary>
- Start,
-
- /// <summary>
- /// Position the cursor at the end of the text
- /// </summary>
- End
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs
deleted file mode 100644
index b17debfc..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardRequest.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Possible requests to the software keyboard when running in inline mode.
- /// </summary>
- enum InlineKeyboardRequest : uint
- {
- /// <summary>
- /// Finalize the keyboard applet.
- /// </summary>
- Finalize = 0x4,
-
- /// <summary>
- /// Set user words for text prediction.
- /// </summary>
- SetUserWordInfo = 0x6,
-
- /// <summary>
- /// Sets the CustomizeDic data. Can't be used if CustomizedDictionaries is already set.
- /// </summary>
- SetCustomizeDic = 0x7,
-
- /// <summary>
- /// Configure the keyboard applet and put it in a state where it is processing input.
- /// </summary>
- Calc = 0xA,
-
- /// <summary>
- /// Set custom dictionaries for text prediction. Can't be used if SetCustomizeDic is already set.
- /// </summary>
- SetCustomizedDictionaries = 0xB,
-
- /// <summary>
- /// Release custom dictionaries data.
- /// </summary>
- UnsetCustomizedDictionaries = 0xC,
-
- /// <summary>
- /// [8.0.0+] Request the keyboard applet to use the ChangedStringV2 response when notifying changes in text data.
- /// </summary>
- UseChangedStringV2 = 0xD,
-
- /// <summary>
- /// [8.0.0+] Request the keyboard applet to use the MovedCursorV2 response when notifying changes in cursor position.
- /// </summary>
- UseMovedCursorV2 = 0xE
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs
deleted file mode 100644
index b21db507..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardResponse.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Possible responses from the software keyboard when running in inline mode.
- /// </summary>
- enum InlineKeyboardResponse : uint
- {
- /// <summary>
- /// The software keyboard received a Calc and it is fully initialized. Reply data is ignored by the user-process.
- /// </summary>
- FinishedInitialize = 0x0,
-
- /// <summary>
- /// Default response. Official sw has no handling for this besides just closing the storage.
- /// </summary>
- Default = 0x1,
-
- /// <summary>
- /// The text data in the software keyboard changed (UTF-16 encoding).
- /// </summary>
- ChangedString = 0x2,
-
- /// <summary>
- /// The cursor position in the software keyboard changed (UTF-16 encoding).
- /// </summary>
- MovedCursor = 0x3,
-
- /// <summary>
- /// A tab in the software keyboard changed.
- /// </summary>
- MovedTab = 0x4,
-
- /// <summary>
- /// The OK key was pressed in the software keyboard, confirming the input text (UTF-16 encoding).
- /// </summary>
- DecidedEnter = 0x5,
-
- /// <summary>
- /// The Cancel key was pressed in the software keyboard, cancelling the input.
- /// </summary>
- DecidedCancel = 0x6,
-
- /// <summary>
- /// Same as ChangedString, but with UTF-8 encoding.
- /// </summary>
- ChangedStringUtf8 = 0x7,
-
- /// <summary>
- /// Same as MovedCursor, but with UTF-8 encoding.
- /// </summary>
- MovedCursorUtf8 = 0x8,
-
- /// <summary>
- /// Same as DecidedEnter, but with UTF-8 encoding.
- /// </summary>
- DecidedEnterUtf8 = 0x9,
-
- /// <summary>
- /// They software keyboard is releasing the data previously set by a SetCustomizeDic request.
- /// </summary>
- UnsetCustomizeDic = 0xA,
-
- /// <summary>
- /// They software keyboard is releasing the data previously set by a SetUserWordInfo request.
- /// </summary>
- ReleasedUserWordInfo = 0xB,
-
- /// <summary>
- /// They software keyboard is releasing the data previously set by a SetCustomizedDictionaries request.
- /// </summary>
- UnsetCustomizedDictionaries = 0xC,
-
- /// <summary>
- /// Same as ChangedString, but with additional fields.
- /// </summary>
- ChangedStringV2 = 0xD,
-
- /// <summary>
- /// Same as MovedCursor, but with additional fields.
- /// </summary>
- MovedCursorV2 = 0xE,
-
- /// <summary>
- /// Same as ChangedStringUtf8, but with additional fields.
- /// </summary>
- ChangedStringUtf8V2 = 0xF,
-
- /// <summary>
- /// Same as MovedCursorUtf8, but with additional fields.
- /// </summary>
- MovedCursorUtf8V2 = 0x10
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs
deleted file mode 100644
index 47e1a774..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineKeyboardState.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Possible states for the software keyboard when running in inline mode.
- /// </summary>
- enum InlineKeyboardState : uint
- {
- /// <summary>
- /// The software keyboard has just been created or finalized and is uninitialized.
- /// </summary>
- Uninitialized = 0x0,
-
- /// <summary>
- /// The software keyboard is initialized, but it is not visible and not processing input.
- /// </summary>
- Initialized = 0x1,
-
- /// <summary>
- /// The software keyboard is transitioning to a visible state.
- /// </summary>
- Appearing = 0x2,
-
- /// <summary>
- /// The software keyboard is visible and receiving processing input.
- /// </summary>
- Shown = 0x3,
-
- /// <summary>
- /// software keyboard is transitioning to a hidden state because the user pressed either OK or Cancel.
- /// </summary>
- Disappearing = 0x4
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs
deleted file mode 100644
index c3e45d46..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InlineResponses.cs
+++ /dev/null
@@ -1,298 +0,0 @@
-using System.IO;
-using System.Text;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- internal class InlineResponses
- {
- private const uint MaxStrLenUTF8 = 0x7D4;
- private const uint MaxStrLenUTF16 = 0x3EC;
-
- private static void BeginResponse(InlineKeyboardState state, InlineKeyboardResponse resCode, BinaryWriter writer)
- {
- writer.Write((uint)state);
- writer.Write((uint)resCode);
- }
-
- private static uint WriteString(string text, BinaryWriter writer, uint maxSize, Encoding encoding)
- {
- // Ensure the text fits in the buffer, but do not straight cut the bytes because
- // this may corrupt the encoding. Search for a cut in the source string that fits.
-
- byte[] bytes = null;
-
- for (int maxStr = text.Length; maxStr >= 0; maxStr--)
- {
- // This loop will probably will run only once.
- bytes = encoding.GetBytes(text, 0, maxStr);
- if (bytes.Length <= maxSize)
- {
- break;
- }
- }
-
- writer.Write(bytes);
- writer.Seek((int)maxSize - bytes.Length, SeekOrigin.Current);
- writer.Write((uint)text.Length); // String size
-
- return (uint)text.Length; // Return the cursor position at the end of the text
- }
-
- private static void WriteStringWithCursor(string text, uint cursor, BinaryWriter writer, uint maxSize, Encoding encoding, bool padMiddle)
- {
- uint length = WriteString(text, writer, maxSize, encoding);
-
- if (cursor > length)
- {
- cursor = length;
- }
-
- if (padMiddle)
- {
- writer.Write((int)-1); // ?
- writer.Write((int)-1); // ?
- }
-
- writer.Write(cursor); // Cursor position
- }
-
- public static byte[] FinishedInitialize(InlineKeyboardState state)
- {
- uint resSize = 2 * sizeof(uint) + 0x1;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.FinishedInitialize, writer);
- writer.Write((byte)1); // Data (ignored by the program)
-
- return stream.ToArray();
- }
- }
-
- public static byte[] Default(InlineKeyboardState state)
- {
- uint resSize = 2 * sizeof(uint);
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.Default, writer);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] ChangedString(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.ChangedString, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] MovedCursor(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.MovedCursor, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] MovedTab(string text, uint cursor, InlineKeyboardState state)
- {
- // Should be the same as MovedCursor.
-
- uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.MovedTab, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] DecidedEnter(string text, InlineKeyboardState state)
- {
- uint resSize = 3 * sizeof(uint) + MaxStrLenUTF16;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.DecidedEnter, writer);
- WriteString(text, writer, MaxStrLenUTF16, Encoding.Unicode);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] DecidedCancel(InlineKeyboardState state)
- {
- uint resSize = 2 * sizeof(uint);
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.DecidedCancel, writer);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] ChangedStringUtf8(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] MovedCursorUtf8(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] DecidedEnterUtf8(string text, InlineKeyboardState state)
- {
- uint resSize = 3 * sizeof(uint) + MaxStrLenUTF8;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.DecidedEnterUtf8, writer);
- WriteString(text, writer, MaxStrLenUTF8, Encoding.UTF8);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] UnsetCustomizeDic(InlineKeyboardState state)
- {
- uint resSize = 2 * sizeof(uint);
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.UnsetCustomizeDic, writer);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] ReleasedUserWordInfo(InlineKeyboardState state)
- {
- uint resSize = 2 * sizeof(uint);
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.ReleasedUserWordInfo, writer);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] UnsetCustomizedDictionaries(InlineKeyboardState state)
- {
- uint resSize = 2 * sizeof(uint);
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.UnsetCustomizedDictionaries, writer);
-
- return stream.ToArray();
- }
- }
-
- public static byte[] ChangedStringV2(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16 + 0x1;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.ChangedStringV2, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true);
- writer.Write((byte)0); // Flag == 0
-
- return stream.ToArray();
- }
- }
-
- public static byte[] MovedCursorV2(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16 + 0x1;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.MovedCursorV2, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
- writer.Write((byte)0); // Flag == 0
-
- return stream.ToArray();
- }
- }
-
- public static byte[] ChangedStringUtf8V2(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8 + 0x1;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8V2, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true);
- writer.Write((byte)0); // Flag == 0
-
- return stream.ToArray();
- }
- }
-
- public static byte[] MovedCursorUtf8V2(string text, uint cursor, InlineKeyboardState state)
- {
- uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8 + 0x1;
-
- using (MemoryStream stream = new MemoryStream(new byte[resSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8V2, writer);
- WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false);
- writer.Write((byte)0); // Flag == 0
-
- return stream.ToArray();
- }
- }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs
deleted file mode 100644
index c3ce2c12..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InputFormMode.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Identifies the text entry mode.
- /// </summary>
- enum InputFormMode : uint
- {
- /// <summary>
- /// Displays the text entry area as a single-line field.
- /// </summary>
- SingleLine,
-
- /// <summary>
- /// Displays the text entry area as a multi-line field.
- /// </summary>
- MultiLine
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs
deleted file mode 100644
index 1166e81d..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidButtonFlags.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Identifies prohibited buttons.
- /// </summary>
- [Flags]
- enum InvalidButtonFlags : uint
- {
- None = 0,
- AnalogStickL = 1 << 1,
- AnalogStickR = 1 << 2,
- ZL = 1 << 3,
- ZR = 1 << 4,
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs
deleted file mode 100644
index f3fd8ac8..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/InvalidCharFlags.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Identifies prohibited character sets.
- /// </summary>
- [Flags]
- enum InvalidCharFlags : uint
- {
- /// <summary>
- /// No characters are prohibited.
- /// </summary>
- None = 0 << 1,
-
- /// <summary>
- /// Prohibits spaces.
- /// </summary>
- Space = 1 << 1,
-
- /// <summary>
- /// Prohibits the at (@) symbol.
- /// </summary>
- AtSymbol = 1 << 2,
-
- /// <summary>
- /// Prohibits the percent (%) symbol.
- /// </summary>
- Percent = 1 << 3,
-
- /// <summary>
- /// Prohibits the forward slash (/) symbol.
- /// </summary>
- ForwardSlash = 1 << 4,
-
- /// <summary>
- /// Prohibits the backward slash (\) symbol.
- /// </summary>
- BackSlash = 1 << 5,
-
- /// <summary>
- /// Prohibits numbers.
- /// </summary>
- Numbers = 1 << 6,
-
- /// <summary>
- /// Prohibits characters outside of those allowed in download codes.
- /// </summary>
- DownloadCode = 1 << 7,
-
- /// <summary>
- /// Prohibits characters outside of those allowed in Mii Nicknames.
- /// </summary>
- Username = 1 << 8
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs
deleted file mode 100644
index 0b0f138b..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardCalcFlags.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Bitmask of commands encoded in the Flags field of the Calc structs.
- /// </summary>
- [Flags]
- enum KeyboardCalcFlags : ulong
- {
- Initialize = 0x1,
- SetVolume = 0x2,
- Appear = 0x4,
- SetInputText = 0x8,
- SetCursorPos = 0x10,
- SetUtf8Mode = 0x20,
- SetKeyboardBackground = 0x100,
- SetKeyboardOptions1 = 0x200,
- SetKeyboardOptions2 = 0x800,
- EnableSeGroup = 0x2000,
- DisableSeGroup = 0x4000,
- SetBackspaceEnabled = 0x8000,
- AppearTrigger = 0x10000,
- MustShow = Appear | SetInputText | AppearTrigger
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs
deleted file mode 100644
index 925d52f6..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardInputMode.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Active input options set by the keyboard applet. These options allow keyboard
- /// players to input text without conflicting with the controller mappings.
- /// </summary>
- enum KeyboardInputMode : uint
- {
- ControllerAndKeyboard,
- KeyboardOnly,
- ControllerOnly,
- Count,
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs
deleted file mode 100644
index 5184118c..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMiniaturizationMode.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// The miniaturization mode used by the keyboard in inline mode.
- /// </summary>
- enum KeyboardMiniaturizationMode : byte
- {
- None = 0,
- Auto = 1,
- Forced = 2
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
deleted file mode 100644
index f512050e..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardMode.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Identifies the variant of keyboard displayed on screen.
- /// </summary>
- enum KeyboardMode : uint
- {
- /// <summary>
- /// A full alpha-numeric keyboard.
- /// </summary>
- Default = 0,
-
- /// <summary>
- /// Number pad.
- /// </summary>
- NumbersOnly = 1,
-
- /// <summary>
- /// ASCII characters keyboard.
- /// </summary>
- ASCII = 2,
-
- FullLatin = 3,
- Alphabet = 4,
- SimplifiedChinese = 5,
- TraditionalChinese = 6,
- Korean = 7,
- LanguageSet2 = 8,
- LanguageSet2Latin = 9,
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs
deleted file mode 100644
index 4f570d3f..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/KeyboardResult.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// The intention of the user when they finish the interaction with the keyboard.
- /// </summary>
- enum KeyboardResult
- {
- NotSet = 0,
- Accept = 1,
- Cancel = 2,
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs
deleted file mode 100644
index fc9e1ff8..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/PasswordMode.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Identifies the display mode of text in a password field.
- /// </summary>
- enum PasswordMode : uint
- {
- /// <summary>
- /// Display input characters.
- /// </summary>
- Disabled,
-
- /// <summary>
- /// Hide input characters.
- /// </summary>
- Enabled
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.png b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.png
deleted file mode 100644
index a8ee784d..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.png
+++ /dev/null
Binary files differ
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.svg b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.svg
deleted file mode 100644
index 6257fd12..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnA.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="32"
- height="32"
- viewBox="0 0 8.4666665 8.4666669"
- version="1.1"
- id="svg8"
- inkscape:export-filename="C:\Users\caian\source\repos\Ryujinx\Ryujinx.HLE\HOS\Applets\SoftwareKeyboard\Resources\Icon_Accept.png"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96"
- sodipodi:docname="buttons_ab.svg"
- inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
- <defs
- id="defs2" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="15.839192"
- inkscape:cx="16.591066"
- inkscape:cy="14.090021"
- inkscape:document-units="mm"
- inkscape:current-layer="layer1"
- inkscape:document-rotation="0"
- showgrid="false"
- units="px"
- showguides="false"
- inkscape:window-width="1267"
- inkscape:window-height="976"
- inkscape:window-x="242"
- inkscape:window-y="34"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata5">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <circle
- style="fill:#ffffff;stroke-width:1.57002;fill-opacity:1"
- id="path839"
- cx="4.2333331"
- cy="4.2333331"
- r="4.2333331" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:7.02011px;line-height:1.25;font-family:sans-serif;fill:#4b4b4b;fill-opacity:1;stroke:none;stroke-width:0.376071"
- x="1.9222834"
- y="6.5921373"
- id="text835-2"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96"
- inkscape:export-filename="C:\Users\caian\source\repos\Ryujinx\Ryujinx.HLE\HOS\Applets\SoftwareKeyboard\Resources\text835-2.png"><tspan
- sodipodi:role="line"
- id="tspan833-9"
- x="1.9222834"
- y="6.5921373"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.02011px;font-family:Arial;-inkscape-font-specification:Arial;fill:#4b4b4b;fill-opacity:1;stroke-width:0.376071">A</tspan></text>
- </g>
-</svg>
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.png b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.png
deleted file mode 100644
index e1fa3454..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.png
+++ /dev/null
Binary files differ
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.svg b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.svg
deleted file mode 100644
index ea6bb9bd..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_BtnB.svg
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="32"
- height="32"
- viewBox="0 0 8.4666665 8.4666669"
- version="1.1"
- id="svg8"
- inkscape:export-filename="C:\Users\caian\source\repos\Ryujinx\Ryujinx.HLE\HOS\Applets\SoftwareKeyboard\Resources\Icon_Accept.png"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96"
- sodipodi:docname="buttons_ab.svg"
- inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
- <defs
- id="defs2" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="15.839192"
- inkscape:cx="16.591066"
- inkscape:cy="14.090021"
- inkscape:document-units="mm"
- inkscape:current-layer="layer1"
- inkscape:document-rotation="0"
- showgrid="false"
- units="px"
- showguides="false"
- inkscape:window-width="1267"
- inkscape:window-height="976"
- inkscape:window-x="242"
- inkscape:window-y="34"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata5">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <circle
- style="fill:#ffffff;stroke-width:1.57002;fill-opacity:1"
- id="path839"
- cx="4.2333331"
- cy="4.2333331"
- r="4.2333331" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:7.02012px;line-height:1.25;font-family:sans-serif;fill:#4b4b4b;fill-opacity:1;stroke:none;stroke-width:0.37607"
- x="2.0223334"
- y="6.6920195"
- id="text835"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96"><tspan
- sodipodi:role="line"
- id="tspan833"
- x="2.0223334"
- y="6.6920195"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.02012px;font-family:Arial;-inkscape-font-specification:Arial;fill:#4b4b4b;fill-opacity:1;stroke-width:0.37607">B</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:7.02011px;line-height:1.25;font-family:sans-serif;fill:#4b4b4b;fill-opacity:1;stroke:none;stroke-width:0.376071"
- x="2.0223367"
- y="6.6920156"
- id="text835-2"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96"
- inkscape:export-filename="C:\Users\caian\source\repos\Ryujinx\Ryujinx.HLE\HOS\Applets\SoftwareKeyboard\Resources\text835-2.png"><tspan
- sodipodi:role="line"
- id="tspan833-9"
- x="2.0223367"
- y="6.6920156"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.02011px;font-family:Arial;-inkscape-font-specification:Arial;fill:#4b4b4b;fill-opacity:1;stroke-width:0.376071">B</tspan></text>
- </g>
-</svg>
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.png b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.png
deleted file mode 100644
index d6dbdc1a..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.png
+++ /dev/null
Binary files differ
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.svg b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.svg
deleted file mode 100644
index 2256ebeb..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Icon_KeyF6.svg
+++ /dev/null
@@ -1,108 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="32"
- height="32"
- viewBox="0 0 8.4666665 8.4666669"
- version="1.1"
- id="svg8"
- inkscape:export-filename="C:\Users\caian\source\repos\Ryujinx\Ryujinx.HLE\HOS\Applets\SoftwareKeyboard\Resources\Icon_KeyF5.png"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96"
- sodipodi:docname="Icon_KeyF5.svg"
- inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)">
- <defs
- id="defs2" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="15.839192"
- inkscape:cx="16.591066"
- inkscape:cy="14.090021"
- inkscape:document-units="mm"
- inkscape:current-layer="layer1"
- inkscape:document-rotation="0"
- showgrid="false"
- units="px"
- showguides="false"
- inkscape:window-width="1267"
- inkscape:window-height="976"
- inkscape:window-x="242"
- inkscape:window-y="25"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata5">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1">
- <rect
- style="fill:#ffffff;stroke-width:2.21199"
- id="rect837"
- width="8.4666662"
- height="8.4666662"
- x="1.3877788e-17"
- y="0" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-weight:normal;font-size:4.23333px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264578"
- x="1.0762799"
- y="4.2016153"
- id="text835"
- inkscape:export-xdpi="96"
- inkscape:export-ydpi="96"
- transform="scale(0.9999825,1.0000175)"><tspan
- sodipodi:role="line"
- id="tspan833"
- x="1.0762799"
- y="4.2016153"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.23333px;font-family:Consolas;-inkscape-font-specification:Consolas;stroke-width:0.264578">F6</tspan></text>
- <rect
- style="fill:none;fill-opacity:1;stroke:#757575;stroke-width:0.26458333;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
- id="rect891"
- width="6.9844265"
- height="6.984426"
- x="0.74112016"
- y="0.47653681" />
- <path
- style="fill:none;stroke:#757575;stroke-width:0.264583px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- d="M 0,0 0.74112016,0.47653681"
- id="path895"
- sodipodi:nodetypes="cc" />
- <path
- style="fill:none;stroke:#757575;stroke-width:0.264583px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- d="M 8.4666662,0 7.7255461,0.47653681"
- id="path897"
- sodipodi:nodetypes="cc" />
- <path
- style="fill:none;stroke:#757575;stroke-width:0.264583px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- d="M 7.3685303e-7,8.4666667 0.7411209,7.4609628"
- id="path901"
- sodipodi:nodetypes="cc" />
- <path
- style="fill:none;stroke:#757575;stroke-width:0.264583px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
- d="M 8.4666669,8.4666667 7.7255468,7.4609628"
- id="path903"
- sodipodi:nodetypes="cc" />
- </g>
-</svg>
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Logo_Ryujinx.png b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Logo_Ryujinx.png
deleted file mode 100644
index 0e8da15e..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/Resources/Logo_Ryujinx.png
+++ /dev/null
Binary files differ
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs
deleted file mode 100644
index e1ee0507..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppear.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure with appearance configurations for the software keyboard when running in inline mode.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
- struct SoftwareKeyboardAppear
- {
- public const int OkTextLength = SoftwareKeyboardAppearEx.OkTextLength;
-
- public KeyboardMode KeyboardMode;
-
- /// <summary>
- /// The string displayed in the Submit button.
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = OkTextLength + 1)]
- public string OkText;
-
- /// <summary>
- /// The character displayed in the left button of the numeric keyboard.
- /// </summary>
- public char LeftOptionalSymbolKey;
-
- /// <summary>
- /// The character displayed in the right button of the numeric keyboard.
- /// </summary>
- public char RightOptionalSymbolKey;
-
- /// <summary>
- /// When set, predictive typing is enabled making use of the system dictionary, and any custom user dictionary.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool PredictionEnabled;
-
- /// <summary>
- /// When set, there is only the option to accept the input.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool CancelButtonDisabled;
-
- /// <summary>
- /// Specifies prohibited characters that cannot be input into the text entry area.
- /// </summary>
- public InvalidCharFlags InvalidChars;
-
- /// <summary>
- /// Maximum text length allowed.
- /// </summary>
- public int TextMaxLength;
-
- /// <summary>
- /// Minimum text length allowed.
- /// </summary>
- public int TextMinLength;
-
- /// <summary>
- /// Indicates the return button is enabled in the keyboard. This allows for input with multiple lines.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool UseNewLine;
-
- /// <summary>
- /// [10.0.0+] If value is 1 or 2, then keytopAsFloating=0 and footerScalable=1 in Calc.
- /// </summary>
- public KeyboardMiniaturizationMode MiniaturizationMode;
-
- public byte Reserved1;
- public byte Reserved2;
-
- /// <summary>
- /// Bit field with invalid buttons for the keyboard.
- /// </summary>
- public InvalidButtonFlags InvalidButtons;
-
- [MarshalAs(UnmanagedType.I1)]
- public bool UseSaveData;
-
- public uint Reserved3;
- public ushort Reserved4;
- public byte Reserved5;
- public ulong Reserved6;
- public ulong Reserved7;
-
- public SoftwareKeyboardAppearEx ToExtended()
- {
- SoftwareKeyboardAppearEx appear = new SoftwareKeyboardAppearEx();
-
- appear.KeyboardMode = KeyboardMode;
- appear.OkText = OkText;
- appear.LeftOptionalSymbolKey = LeftOptionalSymbolKey;
- appear.RightOptionalSymbolKey = RightOptionalSymbolKey;
- appear.PredictionEnabled = PredictionEnabled;
- appear.CancelButtonDisabled = CancelButtonDisabled;
- appear.InvalidChars = InvalidChars;
- appear.TextMaxLength = TextMaxLength;
- appear.TextMinLength = TextMinLength;
- appear.UseNewLine = UseNewLine;
- appear.MiniaturizationMode = MiniaturizationMode;
- appear.Reserved1 = Reserved1;
- appear.Reserved2 = Reserved2;
- appear.InvalidButtons = InvalidButtons;
- appear.UseSaveData = UseSaveData;
- appear.Reserved3 = Reserved3;
- appear.Reserved4 = Reserved4;
- appear.Reserved5 = Reserved5;
- appear.Uid0 = Reserved6;
- appear.Uid1 = Reserved7;
- appear.SamplingNumber = 0;
- appear.Reserved6 = 0;
- appear.Reserved7 = 0;
- appear.Reserved8 = 0;
- appear.Reserved9 = 0;
-
- return appear;
- }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs
deleted file mode 100644
index d1756b07..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardAppearEx.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure with appearance configurations for the software keyboard when running in inline mode.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
- struct SoftwareKeyboardAppearEx
- {
- public const int OkTextLength = 8;
-
- public KeyboardMode KeyboardMode;
-
- /// <summary>
- /// The string displayed in the Submit button.
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = OkTextLength + 1)]
- public string OkText;
-
- /// <summary>
- /// The character displayed in the left button of the numeric keyboard.
- /// </summary>
- public char LeftOptionalSymbolKey;
-
- /// <summary>
- /// The character displayed in the right button of the numeric keyboard.
- /// </summary>
- public char RightOptionalSymbolKey;
-
- /// <summary>
- /// When set, predictive typing is enabled making use of the system dictionary, and any custom user dictionary.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool PredictionEnabled;
-
- /// <summary>
- /// When set, there is only the option to accept the input.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool CancelButtonDisabled;
-
- /// <summary>
- /// Specifies prohibited characters that cannot be input into the text entry area.
- /// </summary>
- public InvalidCharFlags InvalidChars;
-
- /// <summary>
- /// Maximum text length allowed.
- /// </summary>
- public int TextMaxLength;
-
- /// <summary>
- /// Minimum text length allowed.
- /// </summary>
- public int TextMinLength;
-
- /// <summary>
- /// Indicates the return button is enabled in the keyboard. This allows for input with multiple lines.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool UseNewLine;
-
- /// <summary>
- /// [10.0.0+] If value is 1 or 2, then keytopAsFloating=0 and footerScalable=1 in Calc.
- /// </summary>
- public KeyboardMiniaturizationMode MiniaturizationMode;
-
- public byte Reserved1;
- public byte Reserved2;
-
- /// <summary>
- /// Bit field with invalid buttons for the keyboard.
- /// </summary>
- public InvalidButtonFlags InvalidButtons;
-
- [MarshalAs(UnmanagedType.I1)]
- public bool UseSaveData;
-
- public uint Reserved3;
- public ushort Reserved4;
- public byte Reserved5;
-
- /// <summary>
- /// The id of the user associated with the appear request.
- /// </summary>
- public ulong Uid0;
- public ulong Uid1;
-
- /// <summary>
- /// The sampling number for the keyboard appearance.
- /// </summary>
- public ulong SamplingNumber;
-
- public ulong Reserved6;
- public ulong Reserved7;
- public ulong Reserved8;
- public ulong Reserved9;
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
deleted file mode 100644
index 278ea56c..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardApplet.cs
+++ /dev/null
@@ -1,816 +0,0 @@
-using Ryujinx.Common;
-using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.Common.Logging;
-using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
-using Ryujinx.HLE.HOS.Services.Am.AppletAE;
-using Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad;
-using Ryujinx.HLE.Ui;
-using Ryujinx.HLE.Ui.Input;
-using Ryujinx.Memory;
-using System;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace Ryujinx.HLE.HOS.Applets
-{
- internal class SoftwareKeyboardApplet : IApplet
- {
- private const string DefaultInputText = "Ryujinx";
-
- private const int StandardBufferSize = 0x7D8;
- private const int InteractiveBufferSize = 0x7D4;
- private const int MaxUserWords = 0x1388;
- private const int MaxUiTextSize = 100;
-
- private const Key CycleInputModesKey = Key.F6;
-
- private readonly Switch _device;
-
- private SoftwareKeyboardState _foregroundState = SoftwareKeyboardState.Uninitialized;
- private volatile InlineKeyboardState _backgroundState = InlineKeyboardState.Uninitialized;
-
- private bool _isBackground = false;
-
- private AppletSession _normalSession;
- private AppletSession _interactiveSession;
-
- // Configuration for foreground mode.
- private SoftwareKeyboardConfig _keyboardForegroundConfig;
-
- // Configuration for background (inline) mode.
- private SoftwareKeyboardInitialize _keyboardBackgroundInitialize;
- private SoftwareKeyboardCustomizeDic _keyboardBackgroundDic;
- private SoftwareKeyboardDictSet _keyboardBackgroundDictSet;
- private SoftwareKeyboardUserWord[] _keyboardBackgroundUserWords;
-
- private byte[] _transferMemory;
-
- private string _textValue = "";
- private int _cursorBegin = 0;
- private Encoding _encoding = Encoding.Unicode;
- private KeyboardResult _lastResult = KeyboardResult.NotSet;
-
- private IDynamicTextInputHandler _dynamicTextInputHandler = null;
- private SoftwareKeyboardRenderer _keyboardRenderer = null;
- private NpadReader _npads = null;
- private bool _canAcceptController = false;
- private KeyboardInputMode _inputMode = KeyboardInputMode.ControllerAndKeyboard;
-
- private object _lock = new object();
-
- public event EventHandler AppletStateChanged;
-
- public SoftwareKeyboardApplet(Horizon system)
- {
- _device = system.Device;
- }
-
- public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
- {
- lock (_lock)
- {
- _normalSession = normalSession;
- _interactiveSession = interactiveSession;
-
- _interactiveSession.DataAvailable += OnInteractiveData;
-
- var launchParams = _normalSession.Pop();
- var keyboardConfig = _normalSession.Pop();
-
- _isBackground = keyboardConfig.Length == Unsafe.SizeOf<SoftwareKeyboardInitialize>();
-
- if (_isBackground)
- {
- // Initialize the keyboard applet in background mode.
-
- _keyboardBackgroundInitialize = MemoryMarshal.Read<SoftwareKeyboardInitialize>(keyboardConfig);
- _backgroundState = InlineKeyboardState.Uninitialized;
-
- if (_device.UiHandler == null)
- {
- Logger.Error?.Print(LogClass.ServiceAm, "GUI Handler is not set, software keyboard applet will not work properly");
- }
- else
- {
- // Create a text handler that converts keyboard strokes to strings.
- _dynamicTextInputHandler = _device.UiHandler.CreateDynamicTextInputHandler();
- _dynamicTextInputHandler.TextChangedEvent += HandleTextChangedEvent;
- _dynamicTextInputHandler.KeyPressedEvent += HandleKeyPressedEvent;
-
- _npads = new NpadReader(_device);
- _npads.NpadButtonDownEvent += HandleNpadButtonDownEvent;
- _npads.NpadButtonUpEvent += HandleNpadButtonUpEvent;
-
- _keyboardRenderer = new SoftwareKeyboardRenderer(_device.UiHandler.HostUiTheme);
- }
-
- return ResultCode.Success;
- }
- else
- {
- // Initialize the keyboard applet in foreground mode.
-
- if (keyboardConfig.Length < Marshal.SizeOf<SoftwareKeyboardConfig>())
- {
- Logger.Error?.Print(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
- }
- else
- {
- _keyboardForegroundConfig = ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
- }
-
- if (!_normalSession.TryPop(out _transferMemory))
- {
- Logger.Error?.Print(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
- }
-
- if (_keyboardForegroundConfig.UseUtf8)
- {
- _encoding = Encoding.UTF8;
- }
-
- _foregroundState = SoftwareKeyboardState.Ready;
-
- ExecuteForegroundKeyboard();
-
- return ResultCode.Success;
- }
- }
- }
-
- public ResultCode GetResult()
- {
- return ResultCode.Success;
- }
-
- private bool IsKeyboardActive()
- {
- return _backgroundState >= InlineKeyboardState.Appearing && _backgroundState < InlineKeyboardState.Disappearing;
- }
-
- private bool InputModeControllerEnabled()
- {
- return _inputMode == KeyboardInputMode.ControllerAndKeyboard ||
- _inputMode == KeyboardInputMode.ControllerOnly;
- }
-
- private bool InputModeTypingEnabled()
- {
- return _inputMode == KeyboardInputMode.ControllerAndKeyboard ||
- _inputMode == KeyboardInputMode.KeyboardOnly;
- }
-
- private void AdvanceInputMode()
- {
- _inputMode = (KeyboardInputMode)((int)(_inputMode + 1) % (int)KeyboardInputMode.Count);
- }
-
- public bool DrawTo(RenderingSurfaceInfo surfaceInfo, IVirtualMemoryManager destination, ulong position)
- {
- _npads?.Update();
-
- _keyboardRenderer?.SetSurfaceInfo(surfaceInfo);
-
- return _keyboardRenderer?.DrawTo(destination, position) ?? false;
- }
-
- private void ExecuteForegroundKeyboard()
- {
- string initialText = null;
-
- // Initial Text is always encoded as a UTF-16 string in the work buffer (passed as transfer memory)
- // InitialStringOffset points to the memory offset and InitialStringLength is the number of UTF-16 characters
- if (_transferMemory != null && _keyboardForegroundConfig.InitialStringLength > 0)
- {
- initialText = Encoding.Unicode.GetString(_transferMemory, _keyboardForegroundConfig.InitialStringOffset,
- 2 * _keyboardForegroundConfig.InitialStringLength);
- }
-
- // If the max string length is 0, we set it to a large default
- // length.
- if (_keyboardForegroundConfig.StringLengthMax == 0)
- {
- _keyboardForegroundConfig.StringLengthMax = 100;
- }
-
- if (_device.UiHandler == null)
- {
- Logger.Warning?.Print(LogClass.Application, "GUI Handler is not set. Falling back to default");
-
- _textValue = DefaultInputText;
- _lastResult = KeyboardResult.Accept;
- }
- else
- {
- // Call the configured GUI handler to get user's input.
- var args = new SoftwareKeyboardUiArgs
- {
- HeaderText = StripUnicodeControlCodes(_keyboardForegroundConfig.HeaderText),
- SubtitleText = StripUnicodeControlCodes(_keyboardForegroundConfig.SubtitleText),
- GuideText = StripUnicodeControlCodes(_keyboardForegroundConfig.GuideText),
- SubmitText = (!string.IsNullOrWhiteSpace(_keyboardForegroundConfig.SubmitText) ?
- _keyboardForegroundConfig.SubmitText : "OK"),
- StringLengthMin = _keyboardForegroundConfig.StringLengthMin,
- StringLengthMax = _keyboardForegroundConfig.StringLengthMax,
- InitialText = initialText
- };
-
- _lastResult = _device.UiHandler.DisplayInputDialog(args, out _textValue) ? KeyboardResult.Accept : KeyboardResult.Cancel;
- _textValue ??= initialText ?? DefaultInputText;
- }
-
- // If the game requests a string with a minimum length less
- // than our default text, repeat our default text until we meet
- // the minimum length requirement.
- // This should always be done before the text truncation step.
- while (_textValue.Length < _keyboardForegroundConfig.StringLengthMin)
- {
- _textValue = String.Join(" ", _textValue, _textValue);
- }
-
- // If our default text is longer than the allowed length,
- // we truncate it.
- if (_textValue.Length > _keyboardForegroundConfig.StringLengthMax)
- {
- _textValue = _textValue.Substring(0, _keyboardForegroundConfig.StringLengthMax);
- }
-
- // Does the application want to validate the text itself?
- if (_keyboardForegroundConfig.CheckText)
- {
- // The application needs to validate the response, so we
- // submit it to the interactive output buffer, and poll it
- // for validation. Once validated, the application will submit
- // back a validation status, which is handled in OnInteractiveDataPushIn.
- _foregroundState = SoftwareKeyboardState.ValidationPending;
-
- PushForegroundResponse(true);
- }
- else
- {
- // If the application doesn't need to validate the response,
- // we push the data to the non-interactive output buffer
- // and poll it for completion.
- _foregroundState = SoftwareKeyboardState.Complete;
-
- PushForegroundResponse(false);
-
- AppletStateChanged?.Invoke(this, null);
- }
- }
-
- private void OnInteractiveData(object sender, EventArgs e)
- {
- // Obtain the validation status response.
- var data = _interactiveSession.Pop();
-
- if (_isBackground)
- {
- lock (_lock)
- {
- OnBackgroundInteractiveData(data);
- }
- }
- else
- {
- OnForegroundInteractiveData(data);
- }
- }
-
- private void OnForegroundInteractiveData(byte[] data)
- {
- if (_foregroundState == SoftwareKeyboardState.ValidationPending)
- {
- // TODO(jduncantor):
- // If application rejects our "attempt", submit another attempt,
- // and put the applet back in PendingValidation state.
-
- // For now we assume success, so we push the final result
- // to the standard output buffer and carry on our merry way.
- PushForegroundResponse(false);
-
- AppletStateChanged?.Invoke(this, null);
-
- _foregroundState = SoftwareKeyboardState.Complete;
- }
- else if (_foregroundState == SoftwareKeyboardState.Complete)
- {
- // If we have already completed, we push the result text
- // back on the output buffer and poll the application.
- PushForegroundResponse(false);
-
- AppletStateChanged?.Invoke(this, null);
- }
- else
- {
- // We shouldn't be able to get here through standard swkbd execution.
- throw new InvalidOperationException("Software Keyboard is in an invalid state.");
- }
- }
-
- private void OnBackgroundInteractiveData(byte[] data)
- {
- // WARNING: Only invoke applet state changes after an explicit finalization
- // request from the game, this is because the inline keyboard is expected to
- // keep running in the background sending data by itself.
-
- using (MemoryStream stream = new MemoryStream(data))
- using (BinaryReader reader = new BinaryReader(stream))
- {
- var request = (InlineKeyboardRequest)reader.ReadUInt32();
-
- long remaining;
-
- Logger.Debug?.Print(LogClass.ServiceAm, $"Keyboard received command {request} in state {_backgroundState}");
-
- switch (request)
- {
- case InlineKeyboardRequest.UseChangedStringV2:
- Logger.Stub?.Print(LogClass.ServiceAm, "Inline keyboard request UseChangedStringV2");
- break;
- case InlineKeyboardRequest.UseMovedCursorV2:
- Logger.Stub?.Print(LogClass.ServiceAm, "Inline keyboard request UseMovedCursorV2");
- break;
- case InlineKeyboardRequest.SetUserWordInfo:
- // Read the user word info data.
- remaining = stream.Length - stream.Position;
- if (remaining < sizeof(int))
- {
- Logger.Warning?.Print(LogClass.ServiceAm, $"Received invalid Software Keyboard User Word Info of {remaining} bytes");
- }
- else
- {
- int wordsCount = reader.ReadInt32();
- int wordSize = Unsafe.SizeOf<SoftwareKeyboardUserWord>();
- remaining = stream.Length - stream.Position;
-
- if (wordsCount > MaxUserWords)
- {
- Logger.Warning?.Print(LogClass.ServiceAm, $"Received {wordsCount} User Words but the maximum is {MaxUserWords}");
- }
- else if (wordsCount * wordSize != remaining)
- {
- Logger.Warning?.Print(LogClass.ServiceAm, $"Received invalid Software Keyboard User Word Info data of {remaining} bytes for {wordsCount} words");
- }
- else
- {
- _keyboardBackgroundUserWords = new SoftwareKeyboardUserWord[wordsCount];
-
- for (int word = 0; word < wordsCount; word++)
- {
- _keyboardBackgroundUserWords[word] = reader.ReadStruct<SoftwareKeyboardUserWord>();
- }
- }
- }
- _interactiveSession.Push(InlineResponses.ReleasedUserWordInfo(_backgroundState));
- break;
- case InlineKeyboardRequest.SetCustomizeDic:
- // Read the custom dic data.
- remaining = stream.Length - stream.Position;
- if (remaining != Unsafe.SizeOf<SoftwareKeyboardCustomizeDic>())
- {
- Logger.Warning?.Print(LogClass.ServiceAm, $"Received invalid Software Keyboard Customize Dic of {remaining} bytes");
- }
- else
- {
- _keyboardBackgroundDic = reader.ReadStruct<SoftwareKeyboardCustomizeDic>();
- }
- break;
- case InlineKeyboardRequest.SetCustomizedDictionaries:
- // Read the custom dictionaries data.
- remaining = stream.Length - stream.Position;
- if (remaining != Unsafe.SizeOf<SoftwareKeyboardDictSet>())
- {
- Logger.Warning?.Print(LogClass.ServiceAm, $"Received invalid Software Keyboard DictSet of {remaining} bytes");
- }
- else
- {
- _keyboardBackgroundDictSet = reader.ReadStruct<SoftwareKeyboardDictSet>();
- }
- break;
- case InlineKeyboardRequest.Calc:
- // The Calc request is used to communicate configuration changes and commands to the keyboard.
- // Fields in the Calc struct and operations are masked by the Flags field.
-
- // Read the Calc data.
- SoftwareKeyboardCalcEx newCalc;
- remaining = stream.Length - stream.Position;
- if (remaining == Marshal.SizeOf<SoftwareKeyboardCalc>())
- {
- var keyboardCalcData = reader.ReadBytes((int)remaining);
- var keyboardCalc = ReadStruct<SoftwareKeyboardCalc>(keyboardCalcData);
-
- newCalc = keyboardCalc.ToExtended();
- }
- else if (remaining == Marshal.SizeOf<SoftwareKeyboardCalcEx>() || remaining == SoftwareKeyboardCalcEx.AlternativeSize)
- {
- var keyboardCalcData = reader.ReadBytes((int)remaining);
-
- newCalc = ReadStruct<SoftwareKeyboardCalcEx>(keyboardCalcData);
- }
- else
- {
- Logger.Error?.Print(LogClass.ServiceAm, $"Received invalid Software Keyboard Calc of {remaining} bytes");
-
- newCalc = new SoftwareKeyboardCalcEx();
- }
-
- // Process each individual operation specified in the flags.
-
- bool updateText = false;
-
- if ((newCalc.Flags & KeyboardCalcFlags.Initialize) != 0)
- {
- _interactiveSession.Push(InlineResponses.FinishedInitialize(_backgroundState));
-
- _backgroundState = InlineKeyboardState.Initialized;
- }
-
- if ((newCalc.Flags & KeyboardCalcFlags.SetCursorPos) != 0)
- {
- _cursorBegin = newCalc.CursorPos;
- updateText = true;
-
- Logger.Debug?.Print(LogClass.ServiceAm, $"Cursor position set to {_cursorBegin}");
- }
-
- if ((newCalc.Flags & KeyboardCalcFlags.SetInputText) != 0)
- {
- _textValue = newCalc.InputText;
- updateText = true;
-
- Logger.Debug?.Print(LogClass.ServiceAm, $"Input text set to {_textValue}");
- }
-
- if ((newCalc.Flags & KeyboardCalcFlags.SetUtf8Mode) != 0)
- {
- _encoding = newCalc.UseUtf8 ? Encoding.UTF8 : Encoding.Default;
-
- Logger.Debug?.Print(LogClass.ServiceAm, $"Encoding set to {_encoding}");
- }
-
- if (updateText)
- {
- _dynamicTextInputHandler.SetText(_textValue, _cursorBegin);
- _keyboardRenderer.UpdateTextState(_textValue, _cursorBegin, _cursorBegin, null, null);
- }
-
- if ((newCalc.Flags & KeyboardCalcFlags.MustShow) != 0)
- {
- ActivateFrontend();
-
- _backgroundState = InlineKeyboardState.Shown;
-
- PushChangedString(_textValue, (uint)_cursorBegin, _backgroundState);
- }
-
- // Send the response to the Calc
- _interactiveSession.Push(InlineResponses.Default(_backgroundState));
- break;
- case InlineKeyboardRequest.Finalize:
- // Destroy the frontend.
- DestroyFrontend();
- // The calling application wants to close the keyboard applet and will wait for a state change.
- _backgroundState = InlineKeyboardState.Uninitialized;
- AppletStateChanged?.Invoke(this, null);
- break;
- default:
- // We shouldn't be able to get here through standard swkbd execution.
- Logger.Warning?.Print(LogClass.ServiceAm, $"Invalid Software Keyboard request {request} during state {_backgroundState}");
- _interactiveSession.Push(InlineResponses.Default(_backgroundState));
- break;
- }
- }
- }
-
- private void ActivateFrontend()
- {
- Logger.Debug?.Print(LogClass.ServiceAm, $"Activating software keyboard frontend");
-
- _inputMode = KeyboardInputMode.ControllerAndKeyboard;
-
- _npads.Update(true);
-
- NpadButton buttons = _npads.GetCurrentButtonsOfAllNpads();
-
- // Block the input if the current accept key is pressed so the applet won't be instantly closed.
- _canAcceptController = (buttons & NpadButton.A) == 0;
-
- _dynamicTextInputHandler.TextProcessingEnabled = true;
-
- _keyboardRenderer.UpdateCommandState(null, null, true);
- _keyboardRenderer.UpdateTextState(null, null, null, null, true);
- }
-
- private void DeactivateFrontend()
- {
- Logger.Debug?.Print(LogClass.ServiceAm, $"Deactivating software keyboard frontend");
-
- _inputMode = KeyboardInputMode.ControllerAndKeyboard;
- _canAcceptController = false;
-
- _dynamicTextInputHandler.TextProcessingEnabled = false;
- _dynamicTextInputHandler.SetText(_textValue, _cursorBegin);
- }
-
- private void DestroyFrontend()
- {
- Logger.Debug?.Print(LogClass.ServiceAm, $"Destroying software keyboard frontend");
-
- _keyboardRenderer?.Dispose();
- _keyboardRenderer = null;
-
- if (_dynamicTextInputHandler != null)
- {
- _dynamicTextInputHandler.TextChangedEvent -= HandleTextChangedEvent;
- _dynamicTextInputHandler.KeyPressedEvent -= HandleKeyPressedEvent;
- _dynamicTextInputHandler.Dispose();
- _dynamicTextInputHandler = null;
- }
-
- if (_npads != null)
- {
- _npads.NpadButtonDownEvent -= HandleNpadButtonDownEvent;
- _npads.NpadButtonUpEvent -= HandleNpadButtonUpEvent;
- _npads = null;
- }
- }
-
- private bool HandleKeyPressedEvent(Key key)
- {
- if (key == CycleInputModesKey)
- {
- lock (_lock)
- {
- if (IsKeyboardActive())
- {
- AdvanceInputMode();
-
- bool typingEnabled = InputModeTypingEnabled();
- bool controllerEnabled = InputModeControllerEnabled();
-
- _dynamicTextInputHandler.TextProcessingEnabled = typingEnabled;
-
- _keyboardRenderer.UpdateTextState(null, null, null, null, typingEnabled);
- _keyboardRenderer.UpdateCommandState(null, null, controllerEnabled);
- }
- }
- }
-
- return true;
- }
-
- private void HandleTextChangedEvent(string text, int cursorBegin, int cursorEnd, bool overwriteMode)
- {
- lock (_lock)
- {
- // Text processing should not run with typing disabled.
- Debug.Assert(InputModeTypingEnabled());
-
- if (text.Length > MaxUiTextSize)
- {
- // Limit the text size and change it back.
- text = text.Substring(0, MaxUiTextSize);
- cursorBegin = Math.Min(cursorBegin, MaxUiTextSize);
- cursorEnd = Math.Min(cursorEnd, MaxUiTextSize);
-
- _dynamicTextInputHandler.SetText(text, cursorBegin, cursorEnd);
- }
-
- _textValue = text;
- _cursorBegin = cursorBegin;
- _keyboardRenderer.UpdateTextState(text, cursorBegin, cursorEnd, overwriteMode, null);
-
- PushUpdatedState(text, cursorBegin, KeyboardResult.NotSet);
- }
- }
-
- private void HandleNpadButtonDownEvent(int npadIndex, NpadButton button)
- {
- lock (_lock)
- {
- if (!IsKeyboardActive())
- {
- return;
- }
-
- switch (button)
- {
- case NpadButton.A:
- _keyboardRenderer.UpdateCommandState(_canAcceptController, null, null);
- break;
- case NpadButton.B:
- _keyboardRenderer.UpdateCommandState(null, _canAcceptController, null);
- break;
- }
- }
- }
-
- private void HandleNpadButtonUpEvent(int npadIndex, NpadButton button)
- {
- lock (_lock)
- {
- KeyboardResult result = KeyboardResult.NotSet;
-
- switch (button)
- {
- case NpadButton.A:
- result = KeyboardResult.Accept;
- _keyboardRenderer.UpdateCommandState(false, null, null);
- break;
- case NpadButton.B:
- result = KeyboardResult.Cancel;
- _keyboardRenderer.UpdateCommandState(null, false, null);
- break;
- }
-
- if (IsKeyboardActive())
- {
- if (!_canAcceptController)
- {
- _canAcceptController = true;
- }
- else if (InputModeControllerEnabled())
- {
- PushUpdatedState(_textValue, _cursorBegin, result);
- }
- }
- }
- }
-
- private void PushUpdatedState(string text, int cursorBegin, KeyboardResult result)
- {
- _lastResult = result;
- _textValue = text;
-
- bool cancel = result == KeyboardResult.Cancel;
- bool accept = result == KeyboardResult.Accept;
-
- if (!IsKeyboardActive())
- {
- // Keyboard is not active.
-
- return;
- }
-
- if (accept == false && cancel == false)
- {
- Logger.Debug?.Print(LogClass.ServiceAm, $"Updating keyboard text to {text} and cursor position to {cursorBegin}");
-
- PushChangedString(text, (uint)cursorBegin, _backgroundState);
- }
- else
- {
- // Disable the frontend.
- DeactivateFrontend();
-
- // The 'Complete' state indicates the Calc request has been fulfilled by the applet.
- _backgroundState = InlineKeyboardState.Disappearing;
-
- if (accept)
- {
- Logger.Debug?.Print(LogClass.ServiceAm, $"Sending keyboard OK with text {text}");
-
- DecidedEnter(text, _backgroundState);
- }
- else if (cancel)
- {
- Logger.Debug?.Print(LogClass.ServiceAm, "Sending keyboard Cancel");
-
- DecidedCancel(_backgroundState);
- }
-
- _interactiveSession.Push(InlineResponses.Default(_backgroundState));
-
- Logger.Debug?.Print(LogClass.ServiceAm, $"Resetting state of the keyboard to {_backgroundState}");
-
- // Set the state of the applet to 'Initialized' as it is the only known state so far
- // that does not soft-lock the keyboard after use.
-
- _backgroundState = InlineKeyboardState.Initialized;
-
- _interactiveSession.Push(InlineResponses.Default(_backgroundState));
- }
- }
-
- private void PushChangedString(string text, uint cursor, InlineKeyboardState state)
- {
- // TODO (Caian): The *V2 methods are not supported because the applications that request
- // them do not seem to accept them. The regular methods seem to work just fine in all cases.
-
- if (_encoding == Encoding.UTF8)
- {
- _interactiveSession.Push(InlineResponses.ChangedStringUtf8(text, cursor, state));
- }
- else
- {
- _interactiveSession.Push(InlineResponses.ChangedString(text, cursor, state));
- }
- }
-
- private void DecidedEnter(string text, InlineKeyboardState state)
- {
- if (_encoding == Encoding.UTF8)
- {
- _interactiveSession.Push(InlineResponses.DecidedEnterUtf8(text, state));
- }
- else
- {
- _interactiveSession.Push(InlineResponses.DecidedEnter(text, state));
- }
- }
-
- private void DecidedCancel(InlineKeyboardState state)
- {
- _interactiveSession.Push(InlineResponses.DecidedCancel(state));
- }
-
- private void PushForegroundResponse(bool interactive)
- {
- int bufferSize = interactive ? InteractiveBufferSize : StandardBufferSize;
-
- using (MemoryStream stream = new MemoryStream(new byte[bufferSize]))
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- byte[] output = _encoding.GetBytes(_textValue);
-
- if (!interactive)
- {
- // Result Code.
- writer.Write(_lastResult == KeyboardResult.Accept ? 0U : 1U);
- }
- else
- {
- // In interactive mode, we write the length of the text as a long, rather than
- // a result code. This field is inclusive of the 64-bit size.
- writer.Write((long)output.Length + 8);
- }
-
- writer.Write(output);
-
- if (!interactive)
- {
- _normalSession.Push(stream.ToArray());
- }
- else
- {
- _interactiveSession.Push(stream.ToArray());
- }
- }
- }
-
- /// <summary>
- /// Removes all Unicode control code characters from the input string.
- /// This includes CR/LF, tabs, null characters, escape characters,
- /// and special control codes which are used for formatting by the real keyboard applet.
- /// </summary>
- /// <remarks>
- /// Some games send special control codes (such as 0x13 "Device Control 3") as part of the string.
- /// Future implementations of the emulated keyboard applet will need to handle these as well.
- /// </remarks>
- /// <param name="input">The input string to sanitize (may be null).</param>
- /// <returns>The sanitized string.</returns>
- internal static string StripUnicodeControlCodes(string input)
- {
- if (input is null)
- {
- return null;
- }
-
- if (input.Length == 0)
- {
- return string.Empty;
- }
-
- StringBuilder sb = new StringBuilder(capacity: input.Length);
- foreach (char c in input)
- {
- if (!char.IsControl(c))
- {
- sb.Append(c);
- }
- }
-
- return sb.ToString();
- }
-
- private static T ReadStruct<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(byte[] data)
- where T : struct
- {
- GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
-
- try
- {
- return Marshal.PtrToStructure<T>(handle.AddrOfPinnedObject());
- }
- finally
- {
- handle.Free();
- }
- }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs
deleted file mode 100644
index 90df6fa3..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalc.cs
+++ /dev/null
@@ -1,220 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure with configuration options of the software keyboard when starting a new input request in inline mode.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
- struct SoftwareKeyboardCalc
- {
- public const int InputTextLength = SoftwareKeyboardCalcEx.InputTextLength;
-
- public uint Unknown;
-
- /// <summary>
- /// The size of the Calc struct, as reported by the process communicating with the applet.
- /// </summary>
- public ushort Size;
-
- public byte Unknown1;
- public byte Unknown2;
-
- /// <summary>
- /// Configuration flags. Each bit in the bitfield enabled a different operation of the keyboard
- /// using the data provided with the Calc structure.
- /// </summary>
- public KeyboardCalcFlags Flags;
-
- /// <summary>
- /// The original parameters used when initializing the keyboard applet.
- /// Flag: 0x1
- /// </summary>
- public SoftwareKeyboardInitialize Initialize;
-
- /// <summary>
- /// The audio volume used by the sound effects of the keyboard.
- /// Flag: 0x2
- /// </summary>
- public float Volume;
-
- /// <summary>
- /// The initial position of the text cursor (caret) in the provided input text.
- /// Flag: 0x10
- /// </summary>
- public int CursorPos;
-
- /// <summary>
- /// Appearance configurations for the on-screen keyboard.
- /// </summary>
- public SoftwareKeyboardAppear Appear;
-
- /// <summary>
- /// The initial input text to be used by the software keyboard.
- /// Flag: 0x8
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = InputTextLength + 1)]
- public string InputText;
-
- /// <summary>
- /// When set, the strings communicated by software keyboard will be encoded as UTF-8 instead of UTF-16.
- /// Flag: 0x20
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool UseUtf8;
-
- public byte Unknown3;
-
- /// <summary>
- /// [5.0.0+] Enable the backspace key in the software keyboard.
- /// Flag: 0x8000
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool BackspaceEnabled;
-
- public short Unknown4;
- public byte Unknown5;
-
- /// <summary>
- /// Flag: 0x200
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool KeytopAsFloating;
-
- /// <summary>
- /// Flag: 0x100
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool FooterScalable;
-
- /// <summary>
- /// Flag: 0x100
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool AlphaEnabledInInputMode;
-
- /// <summary>
- /// Flag: 0x100
- /// </summary>
- public byte InputModeFadeType;
-
- /// <summary>
- /// When set, the software keyboard ignores touch input.
- /// Flag: 0x200
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool TouchDisabled;
-
- /// <summary>
- /// When set, the software keyboard ignores hardware keyboard commands.
- /// Flag: 0x800
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool HardwareKeyboardDisabled;
-
- public uint Unknown6;
- public uint Unknown7;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x200
- /// </summary>
- public float KeytopScale0;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x200
- /// </summary>
- public float KeytopScale1;
-
- public float KeytopTranslate0;
- public float KeytopTranslate1;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x100
- /// </summary>
- public float KeytopBgAlpha;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x100
- /// </summary>
- public float FooterBgAlpha;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x200
- /// </summary>
- public float BalloonScale;
-
- public float Unknown8;
- public uint Unknown9;
- public uint Unknown10;
- public uint Unknown11;
-
- /// <summary>
- /// [5.0.0+] Enable sound effect.
- /// Flag: Enable: 0x2000
- /// Disable: 0x4000
- /// </summary>
- public byte SeGroup;
-
- /// <summary>
- /// [6.0.0+] Enables the Trigger field when Trigger is non-zero.
- /// </summary>
- public byte TriggerFlag;
-
- /// <summary>
- /// [6.0.0+] Always set to zero.
- /// </summary>
- public byte Trigger;
-
- public byte Padding;
-
- public SoftwareKeyboardCalcEx ToExtended()
- {
- SoftwareKeyboardCalcEx calc = new SoftwareKeyboardCalcEx();
-
- calc.Unknown = Unknown;
- calc.Size = Size;
- calc.Unknown1 = Unknown1;
- calc.Unknown2 = Unknown2;
- calc.Flags = Flags;
- calc.Initialize = Initialize;
- calc.Volume = Volume;
- calc.CursorPos = CursorPos;
- calc.Appear = Appear.ToExtended();
- calc.InputText = InputText;
- calc.UseUtf8 = UseUtf8;
- calc.Unknown3 = Unknown3;
- calc.BackspaceEnabled = BackspaceEnabled;
- calc.Unknown4 = Unknown4;
- calc.Unknown5 = Unknown5;
- calc.KeytopAsFloating = KeytopAsFloating;
- calc.FooterScalable = FooterScalable;
- calc.AlphaEnabledInInputMode = AlphaEnabledInInputMode;
- calc.InputModeFadeType = InputModeFadeType;
- calc.TouchDisabled = TouchDisabled;
- calc.HardwareKeyboardDisabled = HardwareKeyboardDisabled;
- calc.Unknown6 = Unknown6;
- calc.Unknown7 = Unknown7;
- calc.KeytopScale0 = KeytopScale0;
- calc.KeytopScale1 = KeytopScale1;
- calc.KeytopTranslate0 = KeytopTranslate0;
- calc.KeytopTranslate1 = KeytopTranslate1;
- calc.KeytopBgAlpha = KeytopBgAlpha;
- calc.FooterBgAlpha = FooterBgAlpha;
- calc.BalloonScale = BalloonScale;
- calc.Unknown8 = Unknown8;
- calc.Unknown9 = Unknown9;
- calc.Unknown10 = Unknown10;
- calc.Unknown11 = Unknown11;
- calc.SeGroup = SeGroup;
- calc.TriggerFlag = TriggerFlag;
- calc.Trigger = Trigger;
-
- return calc;
- }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs
deleted file mode 100644
index 2d3d5dbe..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCalcEx.cs
+++ /dev/null
@@ -1,182 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure with configuration options of the software keyboard when starting a new input request in inline mode.
- /// This is the extended version of the structure with extended appear options.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Unicode)]
- struct SoftwareKeyboardCalcEx
- {
- /// <summary>
- /// This struct was built following Switchbrew's specs, but this size (larger) is also found in real games.
- /// It's assumed that this is padding at the end of this struct, because all members seem OK.
- /// </summary>
- public const int AlternativeSize = 1256;
-
- public const int InputTextLength = 505;
-
- public uint Unknown;
-
- /// <summary>
- /// The size of the Calc struct, as reported by the process communicating with the applet.
- /// </summary>
- public ushort Size;
-
- public byte Unknown1;
- public byte Unknown2;
-
- /// <summary>
- /// Configuration flags. Each bit in the bitfield enabled a different operation of the keyboard
- /// using the data provided with the Calc structure.
- /// </summary>
- public KeyboardCalcFlags Flags;
-
- /// <summary>
- /// The original parameters used when initializing the keyboard applet.
- /// Flag: 0x1
- /// </summary>
- public SoftwareKeyboardInitialize Initialize;
-
- /// <summary>
- /// The audio volume used by the sound effects of the keyboard.
- /// Flag: 0x2
- /// </summary>
- public float Volume;
-
- /// <summary>
- /// The initial position of the text cursor (caret) in the provided input text.
- /// Flag: 0x10
- /// </summary>
- public int CursorPos;
-
- /// <summary>
- /// Appearance configurations for the on-screen keyboard.
- /// </summary>
- public SoftwareKeyboardAppearEx Appear;
-
- /// <summary>
- /// The initial input text to be used by the software keyboard.
- /// Flag: 0x8
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = InputTextLength + 1)]
- public string InputText;
-
- /// <summary>
- /// When set, the strings communicated by software keyboard will be encoded as UTF-8 instead of UTF-16.
- /// Flag: 0x20
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool UseUtf8;
-
- public byte Unknown3;
-
- /// <summary>
- /// [5.0.0+] Enable the backspace key in the software keyboard.
- /// Flag: 0x8000
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool BackspaceEnabled;
-
- public short Unknown4;
- public byte Unknown5;
-
- /// <summary>
- /// Flag: 0x200
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool KeytopAsFloating;
-
- /// <summary>
- /// Flag: 0x100
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool FooterScalable;
-
- /// <summary>
- /// Flag: 0x100
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool AlphaEnabledInInputMode;
-
- /// <summary>
- /// Flag: 0x100
- /// </summary>
- public byte InputModeFadeType;
-
- /// <summary>
- /// When set, the software keyboard ignores touch input.
- /// Flag: 0x200
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool TouchDisabled;
-
- /// <summary>
- /// When set, the software keyboard ignores hardware keyboard commands.
- /// Flag: 0x800
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool HardwareKeyboardDisabled;
-
- public uint Unknown6;
- public uint Unknown7;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x200
- /// </summary>
- public float KeytopScale0;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x200
- /// </summary>
- public float KeytopScale1;
-
- public float KeytopTranslate0;
- public float KeytopTranslate1;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x100
- /// </summary>
- public float KeytopBgAlpha;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x100
- /// </summary>
- public float FooterBgAlpha;
-
- /// <summary>
- /// Default value is 1.0.
- /// Flag: 0x200
- /// </summary>
- public float BalloonScale;
-
- public float Unknown8;
- public uint Unknown9;
- public uint Unknown10;
- public uint Unknown11;
-
- /// <summary>
- /// [5.0.0+] Enable sound effect.
- /// Flag: Enable: 0x2000
- /// Disable: 0x4000
- /// </summary>
- public byte SeGroup;
-
- /// <summary>
- /// [6.0.0+] Enables the Trigger field when Trigger is non-zero.
- /// </summary>
- public byte TriggerFlag;
-
- /// <summary>
- /// [6.0.0+] Always set to zero.
- /// </summary>
- public byte Trigger;
-
- public byte Padding;
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs
deleted file mode 100644
index fd462382..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardConfig.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure that defines the configuration options of the software keyboard.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- struct SoftwareKeyboardConfig
- {
- private const int SubmitTextLength = 8;
- private const int HeaderTextLength = 64;
- private const int SubtitleTextLength = 128;
- private const int GuideTextLength = 256;
-
- /// <summary>
- /// Type of keyboard.
- /// </summary>
- public KeyboardMode Mode;
-
- /// <summary>
- /// The string displayed in the Submit button.
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SubmitTextLength + 1)]
- public string SubmitText;
-
- /// <summary>
- /// The character displayed in the left button of the numeric keyboard.
- /// This is ignored when Mode is not set to NumbersOnly.
- /// </summary>
- public char LeftOptionalSymbolKey;
-
- /// <summary>
- /// The character displayed in the right button of the numeric keyboard.
- /// This is ignored when Mode is not set to NumbersOnly.
- /// </summary>
- public char RightOptionalSymbolKey;
-
- /// <summary>
- /// When set, predictive typing is enabled making use of the system dictionary,
- /// and any custom user dictionary.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool PredictionEnabled;
-
- /// <summary>
- /// Specifies prohibited characters that cannot be input into the text entry area.
- /// </summary>
- public InvalidCharFlags InvalidCharFlag;
-
- /// <summary>
- /// The initial position of the text cursor displayed in the text entry area.
- /// </summary>
- public InitialCursorPosition InitialCursorPosition;
-
- /// <summary>
- /// The string displayed in the header area of the keyboard.
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = HeaderTextLength + 1)]
- public string HeaderText;
-
- /// <summary>
- /// The string displayed in the subtitle area of the keyboard.
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = SubtitleTextLength + 1)]
- public string SubtitleText;
-
- /// <summary>
- /// The placeholder string displayed in the text entry area when no text is entered.
- /// </summary>
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = GuideTextLength + 1)]
- public string GuideText;
-
- /// <summary>
- /// When non-zero, specifies the maximum allowed length of the string entered into the text entry area.
- /// </summary>
- public int StringLengthMax;
-
- /// <summary>
- /// When non-zero, specifies the minimum allowed length of the string entered into the text entry area.
- /// </summary>
- public int StringLengthMin;
-
- /// <summary>
- /// When enabled, hides input characters as dots in the text entry area.
- /// </summary>
- public PasswordMode PasswordMode;
-
- /// <summary>
- /// Specifies whether the text entry area is displayed as a single-line entry, or a multi-line entry field.
- /// </summary>
- public InputFormMode InputFormMode;
-
- /// <summary>
- /// When set, enables or disables the return key. This value is ignored when single-line entry is specified as the InputFormMode.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool UseNewLine;
-
- /// <summary>
- /// When set, the software keyboard will return a UTF-8 encoded string, rather than UTF-16.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool UseUtf8;
-
- /// <summary>
- /// When set, the software keyboard will blur the game application rendered behind the keyboard.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool UseBlurBackground;
-
- /// <summary>
- /// Offset into the work buffer of the initial text when the keyboard is first displayed.
- /// </summary>
- public int InitialStringOffset;
-
- /// <summary>
- /// Length of the initial text.
- /// </summary>
- public int InitialStringLength;
-
- /// <summary>
- /// Offset into the work buffer of the custom user dictionary.
- /// </summary>
- public int CustomDictionaryOffset;
-
- /// <summary>
- /// Number of entries in the custom user dictionary.
- /// </summary>
- public int CustomDictionaryCount;
-
- /// <summary>
- /// When set, the text entered will be validated on the application side after the keyboard has been submitted.
- /// </summary>
- [MarshalAs(UnmanagedType.I1)]
- public bool CheckText;
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs
deleted file mode 100644
index 53c8c895..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardCustomizeDic.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure used by SetCustomizeDic request to software keyboard.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Size = 0x70)]
- struct SoftwareKeyboardCustomizeDic
- {
- // Unknown
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs
deleted file mode 100644
index 38554881..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardDictSet.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using Ryujinx.Common.Memory;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure with custom dictionary words for the software keyboard.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Pack = 2)]
- struct SoftwareKeyboardDictSet
- {
- /// <summary>
- /// A 0x1000-byte aligned buffer position.
- /// </summary>
- public ulong BufferPosition;
-
- /// <summary>
- /// A 0x1000-byte aligned buffer size.
- /// </summary>
- public uint BufferSize;
-
- /// <summary>
- /// Array of word entries in the buffer.
- /// </summary>
- public Array24<ulong> Entries;
-
- /// <summary>
- /// Number of used entries in the Entries field.
- /// </summary>
- public ushort TotalEntries;
-
- public ushort Padding1;
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs
deleted file mode 100644
index 764d0e38..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardInitialize.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure that mirrors the parameters used to initialize the keyboard applet.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- struct SoftwareKeyboardInitialize
- {
- public uint Unknown;
-
- /// <summary>
- /// The applet mode used when launching the swkb. The bits regarding the background vs foreground mode can be wrong.
- /// </summary>
- public byte LibMode;
-
- /// <summary>
- /// [5.0.0+] Set to 0x1 to indicate a firmware version >= 5.0.0.
- /// </summary>
- public byte FivePlus;
-
- public byte Padding1;
- public byte Padding2;
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs
deleted file mode 100644
index c30ad11b..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRenderer.cs
+++ /dev/null
@@ -1,164 +0,0 @@
-using Ryujinx.HLE.Ui;
-using Ryujinx.Memory;
-using System;
-using System.Threading;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Class that manages the renderer base class and its state in a multithreaded context.
- /// </summary>
- internal class SoftwareKeyboardRenderer : IDisposable
- {
- private const int TextBoxBlinkSleepMilliseconds = 100;
- private const int RendererWaitTimeoutMilliseconds = 100;
-
- private readonly object _stateLock = new object();
-
- private SoftwareKeyboardUiState _state = new SoftwareKeyboardUiState();
- private SoftwareKeyboardRendererBase _renderer;
-
- private TimedAction _textBoxBlinkTimedAction = new TimedAction();
- private TimedAction _renderAction = new TimedAction();
-
- public SoftwareKeyboardRenderer(IHostUiTheme uiTheme)
- {
- _renderer = new SoftwareKeyboardRendererBase(uiTheme);
-
- StartTextBoxBlinker(_textBoxBlinkTimedAction, _state, _stateLock);
- StartRenderer(_renderAction, _renderer, _state, _stateLock);
- }
-
- private static void StartTextBoxBlinker(TimedAction timedAction, SoftwareKeyboardUiState state, object stateLock)
- {
- timedAction.Reset(() =>
- {
- lock (stateLock)
- {
- // The blinker is on half of the time and events such as input
- // changes can reset the blinker.
- state.TextBoxBlinkCounter = (state.TextBoxBlinkCounter + 1) % (2 * SoftwareKeyboardRendererBase.TextBoxBlinkThreshold);
-
- // Tell the render thread there is something new to render.
- Monitor.PulseAll(stateLock);
- }
- }, TextBoxBlinkSleepMilliseconds);
- }
-
- private static void StartRenderer(TimedAction timedAction, SoftwareKeyboardRendererBase renderer, SoftwareKeyboardUiState state, object stateLock)
- {
- SoftwareKeyboardUiState internalState = new SoftwareKeyboardUiState();
-
- bool canCreateSurface = false;
- bool needsUpdate = true;
-
- timedAction.Reset(() =>
- {
- lock (stateLock)
- {
- if (!Monitor.Wait(stateLock, RendererWaitTimeoutMilliseconds))
- {
- return;
- }
-
- needsUpdate = UpdateStateField(ref state.InputText, ref internalState.InputText);
- needsUpdate |= UpdateStateField(ref state.CursorBegin, ref internalState.CursorBegin);
- needsUpdate |= UpdateStateField(ref state.CursorEnd, ref internalState.CursorEnd);
- needsUpdate |= UpdateStateField(ref state.AcceptPressed, ref internalState.AcceptPressed);
- needsUpdate |= UpdateStateField(ref state.CancelPressed, ref internalState.CancelPressed);
- needsUpdate |= UpdateStateField(ref state.OverwriteMode, ref internalState.OverwriteMode);
- needsUpdate |= UpdateStateField(ref state.TypingEnabled, ref internalState.TypingEnabled);
- needsUpdate |= UpdateStateField(ref state.ControllerEnabled, ref internalState.ControllerEnabled);
- needsUpdate |= UpdateStateField(ref state.TextBoxBlinkCounter, ref internalState.TextBoxBlinkCounter);
-
- canCreateSurface = state.SurfaceInfo != null && internalState.SurfaceInfo == null;
-
- if (canCreateSurface)
- {
- internalState.SurfaceInfo = state.SurfaceInfo;
- }
- }
-
- if (canCreateSurface)
- {
- renderer.CreateSurface(internalState.SurfaceInfo);
- }
-
- if (needsUpdate)
- {
- renderer.DrawMutableElements(internalState);
- renderer.CopyImageToBuffer();
- needsUpdate = false;
- }
- });
- }
-
- private static bool UpdateStateField<T>(ref T source, ref T destination) where T : IEquatable<T>
- {
- if (!source.Equals(destination))
- {
- destination = source;
- return true;
- }
-
- return false;
- }
-
-#pragma warning disable CS8632
- public void UpdateTextState(string? inputText, int? cursorBegin, int? cursorEnd, bool? overwriteMode, bool? typingEnabled)
-#pragma warning restore CS8632
- {
- lock (_stateLock)
- {
- // Update the parameters that were provided.
- _state.InputText = inputText != null ? inputText : _state.InputText;
- _state.CursorBegin = cursorBegin.GetValueOrDefault(_state.CursorBegin);
- _state.CursorEnd = cursorEnd.GetValueOrDefault(_state.CursorEnd);
- _state.OverwriteMode = overwriteMode.GetValueOrDefault(_state.OverwriteMode);
- _state.TypingEnabled = typingEnabled.GetValueOrDefault(_state.TypingEnabled);
-
- // Reset the cursor blink.
- _state.TextBoxBlinkCounter = 0;
-
- // Tell the render thread there is something new to render.
- Monitor.PulseAll(_stateLock);
- }
- }
-
- public void UpdateCommandState(bool? acceptPressed, bool? cancelPressed, bool? controllerEnabled)
- {
- lock (_stateLock)
- {
- // Update the parameters that were provided.
- _state.AcceptPressed = acceptPressed.GetValueOrDefault(_state.AcceptPressed);
- _state.CancelPressed = cancelPressed.GetValueOrDefault(_state.CancelPressed);
- _state.ControllerEnabled = controllerEnabled.GetValueOrDefault(_state.ControllerEnabled);
-
- // Tell the render thread there is something new to render.
- Monitor.PulseAll(_stateLock);
- }
- }
-
- public void SetSurfaceInfo(RenderingSurfaceInfo surfaceInfo)
- {
- lock (_stateLock)
- {
- _state.SurfaceInfo = surfaceInfo;
-
- // Tell the render thread there is something new to render.
- Monitor.PulseAll(_stateLock);
- }
- }
-
- internal bool DrawTo(IVirtualMemoryManager destination, ulong position)
- {
- return _renderer.WriteBufferToMemory(destination, position);
- }
-
- public void Dispose()
- {
- _textBoxBlinkTimedAction.RequestCancel();
- _renderAction.RequestCancel();
- }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
deleted file mode 100644
index 9a91fa32..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs
+++ /dev/null
@@ -1,606 +0,0 @@
-using Ryujinx.HLE.Ui;
-using Ryujinx.Memory;
-using SixLabors.Fonts;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Drawing.Processing;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Numerics;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Base class that generates the graphics for the software keyboard applet during inline mode.
- /// </summary>
- internal class SoftwareKeyboardRendererBase
- {
- public const int TextBoxBlinkThreshold = 8;
-
- const string MessageText = "Please use the keyboard to input text";
- const string AcceptText = "Accept";
- const string CancelText = "Cancel";
- const string ControllerToggleText = "Toggle input";
-
- private readonly object _bufferLock = new object();
-
- private RenderingSurfaceInfo _surfaceInfo = null;
- private Image<Argb32> _surface = null;
- private byte[] _bufferData = null;
-
- private Image _ryujinxLogo = null;
- private Image _padAcceptIcon = null;
- private Image _padCancelIcon = null;
- private Image _keyModeIcon = null;
-
- private float _textBoxOutlineWidth;
- private float _padPressedPenWidth;
-
- private Color _textNormalColor;
- private Color _textSelectedColor;
- private Color _textOverCursorColor;
-
- private IBrush _panelBrush;
- private IBrush _disabledBrush;
- private IBrush _cursorBrush;
- private IBrush _selectionBoxBrush;
-
- private Pen _textBoxOutlinePen;
- private Pen _cursorPen;
- private Pen _selectionBoxPen;
- private Pen _padPressedPen;
-
- private int _inputTextFontSize;
- private Font _messageFont;
- private Font _inputTextFont;
- private Font _labelsTextFont;
-
- private RectangleF _panelRectangle;
- private Point _logoPosition;
- private float _messagePositionY;
-
- public SoftwareKeyboardRendererBase(IHostUiTheme uiTheme)
- {
- int ryujinxLogoSize = 32;
-
- string ryujinxIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Logo_Ryujinx.png";
- _ryujinxLogo = LoadResource(Assembly.GetExecutingAssembly(), ryujinxIconPath, ryujinxLogoSize, ryujinxLogoSize);
-
- string padAcceptIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnA.png";
- string padCancelIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_BtnB.png";
- string keyModeIconPath = "Ryujinx.HLE.HOS.Applets.SoftwareKeyboard.Resources.Icon_KeyF6.png";
-
- _padAcceptIcon = LoadResource(Assembly.GetExecutingAssembly(), padAcceptIconPath , 0, 0);
- _padCancelIcon = LoadResource(Assembly.GetExecutingAssembly(), padCancelIconPath , 0, 0);
- _keyModeIcon = LoadResource(Assembly.GetExecutingAssembly(), keyModeIconPath , 0, 0);
-
- Color panelColor = ToColor(uiTheme.DefaultBackgroundColor, 255);
- Color panelTransparentColor = ToColor(uiTheme.DefaultBackgroundColor, 150);
- Color borderColor = ToColor(uiTheme.DefaultBorderColor);
- Color selectionBackgroundColor = ToColor(uiTheme.SelectionBackgroundColor);
-
- _textNormalColor = ToColor(uiTheme.DefaultForegroundColor);
- _textSelectedColor = ToColor(uiTheme.SelectionForegroundColor);
- _textOverCursorColor = ToColor(uiTheme.DefaultForegroundColor, null, true);
-
- float cursorWidth = 2;
-
- _textBoxOutlineWidth = 2;
- _padPressedPenWidth = 2;
-
- _panelBrush = new SolidBrush(panelColor);
- _disabledBrush = new SolidBrush(panelTransparentColor);
- _cursorBrush = new SolidBrush(_textNormalColor);
- _selectionBoxBrush = new SolidBrush(selectionBackgroundColor);
-
- _textBoxOutlinePen = new Pen(borderColor, _textBoxOutlineWidth);
- _cursorPen = new Pen(_textNormalColor, cursorWidth);
- _selectionBoxPen = new Pen(selectionBackgroundColor, cursorWidth);
- _padPressedPen = new Pen(borderColor, _padPressedPenWidth);
-
- _inputTextFontSize = 20;
-
- CreateFonts(uiTheme.FontFamily);
- }
-
- private void CreateFonts(string uiThemeFontFamily)
- {
- // Try a list of fonts in case any of them is not available in the system.
-
- string[] availableFonts = new string[]
- {
- uiThemeFontFamily,
- "Liberation Sans",
- "FreeSans",
- "DejaVu Sans",
- "Lucida Grande"
- };
-
- foreach (string fontFamily in availableFonts)
- {
- try
- {
- _messageFont = SystemFonts.CreateFont(fontFamily, 26, FontStyle.Regular);
- _inputTextFont = SystemFonts.CreateFont(fontFamily, _inputTextFontSize, FontStyle.Regular);
- _labelsTextFont = SystemFonts.CreateFont(fontFamily, 24, FontStyle.Regular);
-
- return;
- }
- catch
- {
- }
- }
-
- throw new Exception($"None of these fonts were found in the system: {String.Join(", ", availableFonts)}!");
- }
-
- private Color ToColor(ThemeColor color, byte? overrideAlpha = null, bool flipRgb = false)
- {
- var a = (byte)(color.A * 255);
- var r = (byte)(color.R * 255);
- var g = (byte)(color.G * 255);
- var b = (byte)(color.B * 255);
-
- if (flipRgb)
- {
- r = (byte)(255 - r);
- g = (byte)(255 - g);
- b = (byte)(255 - b);
- }
-
- return Color.FromRgba(r, g, b, overrideAlpha.GetValueOrDefault(a));
- }
-
- private Image LoadResource(Assembly assembly, string resourcePath, int newWidth, int newHeight)
- {
- Stream resourceStream = assembly.GetManifestResourceStream(resourcePath);
-
- return LoadResource(resourceStream, newWidth, newHeight);
- }
-
- private Image LoadResource(Stream resourceStream, int newWidth, int newHeight)
- {
- Debug.Assert(resourceStream != null);
-
- var image = Image.Load(resourceStream);
-
- if (newHeight != 0 && newWidth != 0)
- {
- image.Mutate(x => x.Resize(newWidth, newHeight, KnownResamplers.Lanczos3));
- }
-
- return image;
- }
-
- private void SetGraphicsOptions(IImageProcessingContext context)
- {
- context.GetGraphicsOptions().Antialias = true;
- context.GetShapeGraphicsOptions().GraphicsOptions.Antialias = true;
- }
-
- private void DrawImmutableElements()
- {
- if (_surface == null)
- {
- return;
- }
-
- _surface.Mutate(context =>
- {
- SetGraphicsOptions(context);
-
- context.Clear(Color.Transparent);
- context.Fill(_panelBrush, _panelRectangle);
- context.DrawImage(_ryujinxLogo, _logoPosition, 1);
-
- float halfWidth = _panelRectangle.Width / 2;
- float buttonsY = _panelRectangle.Y + 185;
-
- PointF disableButtonPosition = new PointF(halfWidth + 180, buttonsY);
-
- DrawControllerToggle(context, disableButtonPosition);
- });
- }
-
- public void DrawMutableElements(SoftwareKeyboardUiState state)
- {
- if (_surface == null)
- {
- return;
- }
-
- _surface.Mutate(context =>
- {
- var messageRectangle = MeasureString(MessageText, _messageFont);
- float messagePositionX = (_panelRectangle.Width - messageRectangle.Width) / 2 - messageRectangle.X;
- float messagePositionY = _messagePositionY - messageRectangle.Y;
- var messagePosition = new PointF(messagePositionX, messagePositionY);
- var messageBoundRectangle = new RectangleF(messagePositionX, messagePositionY, messageRectangle.Width, messageRectangle.Height);
-
- SetGraphicsOptions(context);
-
- context.Fill(_panelBrush, messageBoundRectangle);
-
- context.DrawText(MessageText, _messageFont, _textNormalColor, messagePosition);
-
- if (!state.TypingEnabled)
- {
- // Just draw a semi-transparent rectangle on top to fade the component with the background.
- // TODO (caian): This will not work if one decides to add make background semi-transparent as well.
-
- context.Fill(_disabledBrush, messageBoundRectangle);
- }
-
- DrawTextBox(context, state);
-
- float halfWidth = _panelRectangle.Width / 2;
- float buttonsY = _panelRectangle.Y + 185;
-
- PointF acceptButtonPosition = new PointF(halfWidth - 180, buttonsY);
- PointF cancelButtonPosition = new PointF(halfWidth , buttonsY);
- PointF disableButtonPosition = new PointF(halfWidth + 180, buttonsY);
-
- DrawPadButton(context, acceptButtonPosition, _padAcceptIcon, AcceptText, state.AcceptPressed, state.ControllerEnabled);
- DrawPadButton(context, cancelButtonPosition, _padCancelIcon, CancelText, state.CancelPressed, state.ControllerEnabled);
- });
- }
-
- public void CreateSurface(RenderingSurfaceInfo surfaceInfo)
- {
- if (_surfaceInfo != null)
- {
- return;
- }
-
- _surfaceInfo = surfaceInfo;
-
- Debug.Assert(_surfaceInfo.ColorFormat == Services.SurfaceFlinger.ColorFormat.A8B8G8R8);
-
- // Use the whole area of the image to draw, even the alignment, otherwise it may shear the final
- // image if the pitch is different.
- uint totalWidth = _surfaceInfo.Pitch / 4;
- uint totalHeight = _surfaceInfo.Size / _surfaceInfo.Pitch;
-
- Debug.Assert(_surfaceInfo.Width <= totalWidth);
- Debug.Assert(_surfaceInfo.Height <= totalHeight);
- Debug.Assert(_surfaceInfo.Pitch * _surfaceInfo.Height <= _surfaceInfo.Size);
-
- _surface = new Image<Argb32>((int)totalWidth, (int)totalHeight);
-
- ComputeConstants();
- DrawImmutableElements();
- }
-
- private void ComputeConstants()
- {
- int totalWidth = (int)_surfaceInfo.Width;
- int totalHeight = (int)_surfaceInfo.Height;
-
- int panelHeight = 240;
- int panelPositionY = totalHeight - panelHeight;
-
- _panelRectangle = new RectangleF(0, panelPositionY, totalWidth, panelHeight);
-
- _messagePositionY = panelPositionY + 60;
-
- int logoPositionX = (totalWidth - _ryujinxLogo.Width) / 2;
- int logoPositionY = panelPositionY + 18;
-
- _logoPosition = new Point(logoPositionX, logoPositionY);
- }
- private static RectangleF MeasureString(string text, Font font)
- {
- RendererOptions options = new RendererOptions(font);
-
- if (text == "")
- {
- FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
-
- return new RectangleF(0, emptyRectangle.Y, 0, emptyRectangle.Height);
- }
-
- FontRectangle rectangle = TextMeasurer.Measure(text, options);
-
- return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
- }
-
- private static RectangleF MeasureString(ReadOnlySpan<char> text, Font font)
- {
- RendererOptions options = new RendererOptions(font);
-
- if (text == "")
- {
- FontRectangle emptyRectangle = TextMeasurer.Measure(" ", options);
- return new RectangleF(0, emptyRectangle.Y, 0, emptyRectangle.Height);
- }
-
- FontRectangle rectangle = TextMeasurer.Measure(text, options);
-
- return new RectangleF(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
- }
-
- private void DrawTextBox(IImageProcessingContext context, SoftwareKeyboardUiState state)
- {
- var inputTextRectangle = MeasureString(state.InputText, _inputTextFont);
-
- float boxWidth = (int)(Math.Max(300, inputTextRectangle.Width + inputTextRectangle.X + 8));
- float boxHeight = 32;
- float boxY = _panelRectangle.Y + 110;
- float boxX = (int)((_panelRectangle.Width - boxWidth) / 2);
-
- RectangleF boxRectangle = new RectangleF(boxX, boxY, boxWidth, boxHeight);
-
- RectangleF boundRectangle = new RectangleF(_panelRectangle.X, boxY - _textBoxOutlineWidth,
- _panelRectangle.Width, boxHeight + 2 * _textBoxOutlineWidth);
-
- context.Fill(_panelBrush, boundRectangle);
-
- context.Draw(_textBoxOutlinePen, boxRectangle);
-
- float inputTextX = (_panelRectangle.Width - inputTextRectangle.Width) / 2 - inputTextRectangle.X;
- float inputTextY = boxY + 5;
-
- var inputTextPosition = new PointF(inputTextX, inputTextY);
-
- context.DrawText(state.InputText, _inputTextFont, _textNormalColor, inputTextPosition);
-
- // Draw the cursor on top of the text and redraw the text with a different color if necessary.
-
- Color cursorTextColor;
- IBrush cursorBrush;
- Pen cursorPen;
-
- float cursorPositionYTop = inputTextY + 1;
- float cursorPositionYBottom = cursorPositionYTop + _inputTextFontSize + 1;
- float cursorPositionXLeft;
- float cursorPositionXRight;
-
- bool cursorVisible = false;
-
- if (state.CursorBegin != state.CursorEnd)
- {
- Debug.Assert(state.InputText.Length > 0);
-
- cursorTextColor = _textSelectedColor;
- cursorBrush = _selectionBoxBrush;
- cursorPen = _selectionBoxPen;
-
- ReadOnlySpan<char> textUntilBegin = state.InputText.AsSpan(0, state.CursorBegin);
- ReadOnlySpan<char> textUntilEnd = state.InputText.AsSpan(0, state.CursorEnd);
-
- var selectionBeginRectangle = MeasureString(textUntilBegin, _inputTextFont);
- var selectionEndRectangle = MeasureString(textUntilEnd , _inputTextFont);
-
- cursorVisible = true;
- cursorPositionXLeft = inputTextX + selectionBeginRectangle.Width + selectionBeginRectangle.X;
- cursorPositionXRight = inputTextX + selectionEndRectangle.Width + selectionEndRectangle.X;
- }
- else
- {
- cursorTextColor = _textOverCursorColor;
- cursorBrush = _cursorBrush;
- cursorPen = _cursorPen;
-
- if (state.TextBoxBlinkCounter < TextBoxBlinkThreshold)
- {
- // Show the blinking cursor.
-
- int cursorBegin = Math.Min(state.InputText.Length, state.CursorBegin);
- ReadOnlySpan<char> textUntilCursor = state.InputText.AsSpan(0, cursorBegin);
- var cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
-
- cursorVisible = true;
- cursorPositionXLeft = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;
-
- if (state.OverwriteMode)
- {
- // The blinking cursor is in overwrite mode so it takes the size of a character.
-
- if (state.CursorBegin < state.InputText.Length)
- {
- textUntilCursor = state.InputText.AsSpan(0, cursorBegin + 1);
- cursorTextRectangle = MeasureString(textUntilCursor, _inputTextFont);
- cursorPositionXRight = inputTextX + cursorTextRectangle.Width + cursorTextRectangle.X;
- }
- else
- {
- cursorPositionXRight = cursorPositionXLeft + _inputTextFontSize / 2;
- }
- }
- else
- {
- // The blinking cursor is in insert mode so it is only a line.
- cursorPositionXRight = cursorPositionXLeft;
- }
- }
- else
- {
- cursorPositionXLeft = inputTextX;
- cursorPositionXRight = inputTextX;
- }
- }
-
- if (state.TypingEnabled && cursorVisible)
- {
- float cursorWidth = cursorPositionXRight - cursorPositionXLeft;
- float cursorHeight = cursorPositionYBottom - cursorPositionYTop;
-
- if (cursorWidth == 0)
- {
- PointF[] points = new PointF[]
- {
- new PointF(cursorPositionXLeft, cursorPositionYTop),
- new PointF(cursorPositionXLeft, cursorPositionYBottom),
- };
-
- context.DrawLines(cursorPen, points);
- }
- else
- {
- var cursorRectangle = new RectangleF(cursorPositionXLeft, cursorPositionYTop, cursorWidth, cursorHeight);
-
- context.Draw(cursorPen , cursorRectangle);
- context.Fill(cursorBrush, cursorRectangle);
-
- Image<Argb32> textOverCursor = new Image<Argb32>((int)cursorRectangle.Width, (int)cursorRectangle.Height);
- textOverCursor.Mutate(context =>
- {
- var textRelativePosition = new PointF(inputTextPosition.X - cursorRectangle.X, inputTextPosition.Y - cursorRectangle.Y);
- context.DrawText(state.InputText, _inputTextFont, cursorTextColor, textRelativePosition);
- });
-
- var cursorPosition = new Point((int)cursorRectangle.X, (int)cursorRectangle.Y);
- context.DrawImage(textOverCursor, cursorPosition, 1);
- }
- }
- else if (!state.TypingEnabled)
- {
- // Just draw a semi-transparent rectangle on top to fade the component with the background.
- // TODO (caian): This will not work if one decides to add make background semi-transparent as well.
-
- context.Fill(_disabledBrush, boundRectangle);
- }
- }
-
- private void DrawPadButton(IImageProcessingContext context, PointF point, Image icon, string label, bool pressed, bool enabled)
- {
- // Use relative positions so we can center the the entire drawing later.
-
- float iconX = 0;
- float iconY = 0;
- float iconWidth = icon.Width;
- float iconHeight = icon.Height;
-
- var labelRectangle = MeasureString(label, _labelsTextFont);
-
- float labelPositionX = iconWidth + 8 - labelRectangle.X;
- float labelPositionY = 3;
-
- float fullWidth = labelPositionX + labelRectangle.Width + labelRectangle.X;
- float fullHeight = iconHeight;
-
- // Convert all relative positions into absolute.
-
- float originX = (int)(point.X - fullWidth / 2);
- float originY = (int)(point.Y - fullHeight / 2);
-
- iconX += originX;
- iconY += originY;
-
- var iconPosition = new Point((int)iconX, (int)iconY);
- var labelPosition = new PointF(labelPositionX + originX, labelPositionY + originY);
-
- var selectedRectangle = new RectangleF(originX - 2 * _padPressedPenWidth, originY - 2 * _padPressedPenWidth,
- fullWidth + 4 * _padPressedPenWidth, fullHeight + 4 * _padPressedPenWidth);
-
- var boundRectangle = new RectangleF(originX, originY, fullWidth, fullHeight);
- boundRectangle.Inflate(4 * _padPressedPenWidth, 4 * _padPressedPenWidth);
-
- context.Fill(_panelBrush, boundRectangle);
- context.DrawImage(icon, iconPosition, 1);
- context.DrawText(label, _labelsTextFont, _textNormalColor, labelPosition);
-
- if (enabled)
- {
- if (pressed)
- {
- context.Draw(_padPressedPen, selectedRectangle);
- }
- }
- else
- {
- // Just draw a semi-transparent rectangle on top to fade the component with the background.
- // TODO (caian): This will not work if one decides to add make background semi-transparent as well.
-
- context.Fill(_disabledBrush, boundRectangle);
- }
- }
-
- private void DrawControllerToggle(IImageProcessingContext context, PointF point)
- {
- var labelRectangle = MeasureString(ControllerToggleText, _labelsTextFont);
-
- // Use relative positions so we can center the the entire drawing later.
-
- float keyWidth = _keyModeIcon.Width;
- float keyHeight = _keyModeIcon.Height;
-
- float labelPositionX = keyWidth + 8 - labelRectangle.X;
- float labelPositionY = -labelRectangle.Y - 1;
-
- float keyX = 0;
- float keyY = (int)((labelPositionY + labelRectangle.Height - keyHeight) / 2);
-
- float fullWidth = labelPositionX + labelRectangle.Width;
- float fullHeight = Math.Max(labelPositionY + labelRectangle.Height, keyHeight);
-
- // Convert all relative positions into absolute.
-
- float originX = (int)(point.X - fullWidth / 2);
- float originY = (int)(point.Y - fullHeight / 2);
-
- keyX += originX;
- keyY += originY;
-
- var labelPosition = new PointF(labelPositionX + originX, labelPositionY + originY);
- var overlayPosition = new Point((int)keyX, (int)keyY);
-
- context.DrawImage(_keyModeIcon, overlayPosition, 1);
- context.DrawText(ControllerToggleText, _labelsTextFont, _textNormalColor, labelPosition);
- }
-
- public void CopyImageToBuffer()
- {
- lock (_bufferLock)
- {
- if (_surface == null)
- {
- return;
- }
-
- // Convert the pixel format used in the image to the one used in the Switch surface.
-
- if (!_surface.TryGetSinglePixelSpan(out Span<Argb32> pixels))
- {
- return;
- }
-
- _bufferData = MemoryMarshal.AsBytes(pixels).ToArray();
- Span<uint> dataConvert = MemoryMarshal.Cast<byte, uint>(_bufferData);
-
- Debug.Assert(_bufferData.Length == _surfaceInfo.Size);
-
- for (int i = 0; i < dataConvert.Length; i++)
- {
- dataConvert[i] = BitOperations.RotateRight(dataConvert[i], 8);
- }
- }
- }
-
- public bool WriteBufferToMemory(IVirtualMemoryManager destination, ulong position)
- {
- lock (_bufferLock)
- {
- if (_bufferData == null)
- {
- return false;
- }
-
- try
- {
- destination.Write(position, _bufferData);
- }
- catch
- {
- return false;
- }
-
- return true;
- }
- }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs
deleted file mode 100644
index 0f66fc9b..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardState.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Identifies the software keyboard state.
- /// </summary>
- enum SoftwareKeyboardState
- {
- /// <summary>
- /// swkbd is uninitialized.
- /// </summary>
- Uninitialized,
-
- /// <summary>
- /// swkbd is ready to process data.
- /// </summary>
- Ready,
-
- /// <summary>
- /// swkbd is awaiting an interactive reply with a validation status.
- /// </summary>
- ValidationPending,
-
- /// <summary>
- /// swkbd has completed.
- /// </summary>
- Complete
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiArgs.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiArgs.cs
deleted file mode 100644
index d24adec3..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiArgs.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets
-{
- public struct SoftwareKeyboardUiArgs
- {
- public string HeaderText;
- public string SubtitleText;
- public string InitialText;
- public string GuideText;
- public string SubmitText;
- public int StringLengthMin;
- public int StringLengthMax;
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs
deleted file mode 100644
index e6131e62..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUiState.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using Ryujinx.HLE.Ui;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// TODO
- /// </summary>
- internal class SoftwareKeyboardUiState
- {
- public string InputText = "";
- public int CursorBegin = 0;
- public int CursorEnd = 0;
- public bool AcceptPressed = false;
- public bool CancelPressed = false;
- public bool OverwriteMode = false;
- public bool TypingEnabled = true;
- public bool ControllerEnabled = true;
- public int TextBoxBlinkCounter = 0;
-
- public RenderingSurfaceInfo SurfaceInfo = null;
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs
deleted file mode 100644
index f1bfec2b..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardUserWord.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A structure used by SetUserWordInfo request to the software keyboard.
- /// </summary>
- [StructLayout(LayoutKind.Sequential, Size = 0x64)]
- struct SoftwareKeyboardUserWord
- {
- // Unknown
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs
deleted file mode 100644
index 53746e74..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TRef.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// Wraps a type in a class so it gets stored in the GC managed heap. This is used as communication mechanism
- /// between classed that need to be disposed and, thus, can't share their references.
- /// </summary>
- /// <typeparam name="T">The internal type.</typeparam>
- class TRef<T>
- {
- public T Value;
-
- public TRef() { }
-
- public TRef(T value)
- {
- Value = value;
- }
- }
-}
diff --git a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs b/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs
deleted file mode 100644
index 0de78a0e..00000000
--- a/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/TimedAction.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-using System;
-using System.Threading;
-
-namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
-{
- /// <summary>
- /// A threaded executor of periodic actions that can be cancelled. The total execution time is optional
- /// and, in this case, a progress is reported back to the action.
- /// </summary>
- class TimedAction
- {
- public const int MaxThreadSleep = 100;
-
- private class SleepSubstepData
- {
- public readonly int SleepMilliseconds;
- public readonly int SleepCount;
- public readonly int SleepRemainderMilliseconds;
-
- public SleepSubstepData(int sleepMilliseconds)
- {
- SleepMilliseconds = Math.Min(sleepMilliseconds, MaxThreadSleep);
- SleepCount = sleepMilliseconds / SleepMilliseconds;
- SleepRemainderMilliseconds = sleepMilliseconds - SleepCount * SleepMilliseconds;
- }
- }
-
- private TRef<bool> _cancelled = null;
- private Thread _thread = null;
- private object _lock = new object();
-
- public bool IsRunning
- {
- get
- {
- lock (_lock)
- {
- if (_thread == null)
- {
- return false;
- }
-
- return _thread.IsAlive;
- }
- }
- }
-
- public void RequestCancel()
- {
- lock (_lock)
- {
- if (_cancelled != null)
- {
- Volatile.Write(ref _cancelled.Value, true);
- }
- }
- }
-
- public TimedAction() { }
-
- private void Reset(Thread thread, TRef<bool> cancelled)
- {
- lock (_lock)
- {
- // Cancel the current task.
- if (_cancelled != null)
- {
- Volatile.Write(ref _cancelled.Value, true);
- }
-
- _cancelled = cancelled;
-
- _thread = thread;
- _thread.IsBackground = true;
- _thread.Start();
- }
- }
-
- public void Reset(Action<float> action, int totalMilliseconds, int sleepMilliseconds)
- {
- // Create a dedicated cancel token for each task.
- var cancelled = new TRef<bool>(false);
-
- Reset(new Thread(() =>
- {
- var substepData = new SleepSubstepData(sleepMilliseconds);
-
- int totalCount = totalMilliseconds / sleepMilliseconds;
- int totalRemainder = totalMilliseconds - totalCount * sleepMilliseconds;
-
- if (Volatile.Read(ref cancelled.Value))
- {
- action(-1);
-
- return;
- }
-
- action(0);
-
- for (int i = 1; i <= totalCount; i++)
- {
- if (SleepWithSubstep(substepData, cancelled))
- {
- action(-1);
-
- return;
- }
-
- action((float)(i * sleepMilliseconds) / totalMilliseconds);
- }
-
- if (totalRemainder > 0)
- {
- if (SleepWithSubstep(substepData, cancelled))
- {
- action(-1);
-
- return;
- }
-
- action(1);
- }
- }), cancelled);
- }
-
- public void Reset(Action action, int sleepMilliseconds)
- {
- // Create a dedicated cancel token for each task.
- var cancelled = new TRef<bool>(false);
-
- Reset(new Thread(() =>
- {
- var substepData = new SleepSubstepData(sleepMilliseconds);
-
- while (!Volatile.Read(ref cancelled.Value))
- {
- action();
-
- if (SleepWithSubstep(substepData, cancelled))
- {
- return;
- }
- }
- }), cancelled);
- }
-
- public void Reset(Action action)
- {
- // Create a dedicated cancel token for each task.
- var cancelled = new TRef<bool>(false);
-
- Reset(new Thread(() =>
- {
- while (!Volatile.Read(ref cancelled.Value))
- {
- action();
- }
- }), cancelled);
- }
-
- private static bool SleepWithSubstep(SleepSubstepData substepData, TRef<bool> cancelled)
- {
- for (int i = 0; i < substepData.SleepCount; i++)
- {
- if (Volatile.Read(ref cancelled.Value))
- {
- return true;
- }
-
- Thread.Sleep(substepData.SleepMilliseconds);
- }
-
- if (substepData.SleepRemainderMilliseconds > 0)
- {
- if (Volatile.Read(ref cancelled.Value))
- {
- return true;
- }
-
- Thread.Sleep(substepData.SleepRemainderMilliseconds);
- }
-
- return Volatile.Read(ref cancelled.Value);
- }
- }
-}