Implement Software Keyboard GTK frontend (#1434)
* Implement SwKbd GUI * Relocate UI handler to Emu Context from Config Also create a common interface for UI handlers in the context and specialize for Gtk Add basic input length validation in InputDialog * Add Transfer Memory support to AppletCreator Read Initial Text for SwKbd using Transfer Memory * Improve InputDialog widget Improve length validation Has extra label to show validition info Handle potential errors and log them * Misc improvements * Improve string validation * Improve error handling * Remove tuple in struct * Address formatting nits * Add proper Cancel functionality Also handle GUI errors in UI handler * Address jD's comments * Fix _uiHandler init * Address AcK's comments
This commit is contained in:
parent
f0c91d9efb
commit
c11855565e
8 changed files with 245 additions and 15 deletions
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.HLE.HOS.Applets.SoftwareKeyboard;
|
||||
using Ryujinx.HLE.HOS.Services.Am.AppletAE;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
@ -9,9 +10,10 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
{
|
||||
internal class SoftwareKeyboardApplet : IApplet
|
||||
{
|
||||
private const string DefaultNumb = "1";
|
||||
private const string DefaultText = "Ryujinx";
|
||||
|
||||
private readonly Switch _device;
|
||||
|
||||
private const int StandardBufferSize = 0x7D8;
|
||||
private const int InteractiveBufferSize = 0x7D4;
|
||||
|
||||
|
@ -21,13 +23,18 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
private AppletSession _interactiveSession;
|
||||
|
||||
private SoftwareKeyboardConfig _keyboardConfig;
|
||||
private byte[] _transferMemory;
|
||||
|
||||
private string _textValue = DefaultText;
|
||||
private string _textValue = null;
|
||||
private bool _okPressed = false;
|
||||
private Encoding _encoding = Encoding.Unicode;
|
||||
|
||||
public event EventHandler AppletStateChanged;
|
||||
|
||||
public SoftwareKeyboardApplet(Horizon system) { }
|
||||
public SoftwareKeyboardApplet(Horizon system)
|
||||
{
|
||||
_device = system.Device;
|
||||
}
|
||||
|
||||
public ResultCode Start(AppletSession normalSession,
|
||||
AppletSession interactiveSession)
|
||||
|
@ -39,9 +46,20 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
|
||||
var launchParams = _normalSession.Pop();
|
||||
var keyboardConfig = _normalSession.Pop();
|
||||
var transferMemory = _normalSession.Pop();
|
||||
|
||||
_keyboardConfig = ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
|
||||
if (keyboardConfig.Length < Marshal.SizeOf<SoftwareKeyboardConfig>())
|
||||
{
|
||||
Logger.PrintError(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_keyboardConfig = ReadStruct<SoftwareKeyboardConfig>(keyboardConfig);
|
||||
}
|
||||
|
||||
if (!_normalSession.TryPop(out _transferMemory))
|
||||
{
|
||||
Logger.PrintError(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
|
||||
}
|
||||
|
||||
if (_keyboardConfig.UseUtf8)
|
||||
{
|
||||
|
@ -62,11 +80,13 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
|
||||
private void Execute()
|
||||
{
|
||||
// If the keyboard type is numbers only, we swap to a default
|
||||
// text that only contains numbers.
|
||||
if (_keyboardConfig.Mode == KeyboardMode.NumbersOnly)
|
||||
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 && _keyboardConfig.InitialStringLength > 0)
|
||||
{
|
||||
_textValue = DefaultNumb;
|
||||
initialText = Encoding.Unicode.GetString(_transferMemory, _keyboardConfig.InitialStringOffset, 2 * _keyboardConfig.InitialStringLength);
|
||||
}
|
||||
|
||||
// If the max string length is 0, we set it to a large default
|
||||
|
@ -76,6 +96,30 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
_keyboardConfig.StringLengthMax = 100;
|
||||
}
|
||||
|
||||
var args = new SoftwareKeyboardUiArgs
|
||||
{
|
||||
HeaderText = _keyboardConfig.HeaderText,
|
||||
SubtitleText = _keyboardConfig.SubtitleText,
|
||||
GuideText = _keyboardConfig.GuideText,
|
||||
SubmitText = (!string.IsNullOrWhiteSpace(_keyboardConfig.SubmitText) ? _keyboardConfig.SubmitText : "OK"),
|
||||
StringLengthMin = _keyboardConfig.StringLengthMin,
|
||||
StringLengthMax = _keyboardConfig.StringLengthMax,
|
||||
InitialText = initialText
|
||||
};
|
||||
|
||||
// Call the configured GUI handler to get user's input
|
||||
if (_device.UiHandler == null)
|
||||
{
|
||||
Logger.PrintWarning(LogClass.Application, $"GUI Handler is not set. Falling back to default");
|
||||
_okPressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_okPressed = _device.UiHandler.DisplayInputDialog(args, out _textValue);
|
||||
}
|
||||
|
||||
_textValue ??= initialText ?? DefaultText;
|
||||
|
||||
// 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.
|
||||
|
@ -162,7 +206,7 @@ namespace Ryujinx.HLE.HOS.Applets
|
|||
if (!interactive)
|
||||
{
|
||||
// Result Code
|
||||
writer.Write((uint)0);
|
||||
writer.Write(_okPressed ? 0U : 1U);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue