Skip to content

Commit

Permalink
NEW: Support full UTF-32 text input.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rene Damm committed Oct 3, 2018
1 parent 1b045d4 commit d9b7c25
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 11 deletions.
Expand Up @@ -13,8 +13,8 @@ public interface ITextInputReceiver
/// A single, fully-formed Unicode character has been typed on the device.
/// </summary>
/// <param name="character">Character that was typed. Note that in case the character is part of
/// a surrogate pair, this method is called first with the low surrogate and then with the
/// high surrogate character.</param>
/// a surrogate pair, this method is called first with the high surrogate and then with the
/// low surrogate character.</param>
void OnTextInput(char character);

/// <summary>
Expand Down
19 changes: 16 additions & 3 deletions Packages/com.unity.inputsystem/InputSystem/Events/TextEvent.cs
Expand Up @@ -39,9 +39,22 @@ public FourCC GetTypeStatic()

public static TextEvent Create(int deviceId, char character, double time)
{
var inputEvent = new TextEvent();
inputEvent.baseEvent = new InputEvent(Type, InputEvent.kBaseEventSize + 4, deviceId, time);
inputEvent.character = character;
////TODO: detect and throw when if character is surrogate
var inputEvent = new TextEvent
{
baseEvent = new InputEvent(Type, InputEvent.kBaseEventSize + 4, deviceId, time),
character = character
};
return inputEvent;
}

public static TextEvent Create(int deviceId, int character, double time)
{
var inputEvent = new TextEvent
{
baseEvent = new InputEvent(Type, InputEvent.kBaseEventSize + 4, deviceId, time),
character = character
};
return inputEvent;
}
}
Expand Down
20 changes: 14 additions & 6 deletions Packages/com.unity.inputsystem/InputSystem/InputManager.cs
Expand Up @@ -2216,13 +2216,21 @@ internal unsafe void OnUpdate(InputUpdateType updateType, int eventCount, IntPtr
var textInputReceiver = device as ITextInputReceiver;
if (textInputReceiver != null)
{
var ch = (char)textEventPtr->character;
textInputReceiver.OnTextInput(ch);
if (char.IsSurrogate(ch))
var utf32Char = textEventPtr->character;
if (utf32Char >= 0x10000)
{
// Get high-surrogate char of pair.
ch = (char)(textEventPtr->character >> 16);
textInputReceiver.OnTextInput(ch);
// Send surrogate pair.
utf32Char -= 0x10000;
var highSurrogate = 0xD800 + ((utf32Char >> 10) & 0x3FF);
var lowSurrogate = 0xDC00 + (utf32Char & 0x3FF);

textInputReceiver.OnTextInput((char)highSurrogate);
textInputReceiver.OnTextInput((char)lowSurrogate);
}
else
{
// Send single, plain character.
textInputReceiver.OnTextInput((char)utf32Char);
}
}
break;
Expand Down
Expand Up @@ -1790,6 +1790,27 @@ public void Devices_CanGetTextInputFromKeyboard()
Assert.That(textReceived, Is.EqualTo("abc"));
}

[Test]
[Category("Devices")]
public void Devices_CanHandleUTF32CharactersInTextInputOnKeyboard()
{
var keyboard = InputSystem.AddDevice<Keyboard>();

var charsReceived = new List<char>();
keyboard.onTextInput += ch => charsReceived.Add(ch);

const int highBits = 0x12;
const int lowBits = 0x21;

var inputEvent = TextEvent.Create(keyboard.id, 0x10000 + (highBits << 10 | lowBits), 123);
InputSystem.QueueEvent(ref inputEvent);
InputSystem.Update();

Assert.That(charsReceived, Has.Count.EqualTo(2));
Assert.That(charsReceived[0], Is.EqualTo(0xD800 + highBits));
Assert.That(charsReceived[1], Is.EqualTo(0xDC00 + lowBits));
}

[Test]
[Category("Devices")]
public void Devices_CanGetDisplayNameFromKeyboardKey()
Expand Down

0 comments on commit d9b7c25

Please sign in to comment.