[linux] Receives the unmodified characters obtained from GLFW (#34752)

diff --git a/dev/manual_tests/lib/raw_keyboard.dart b/dev/manual_tests/lib/raw_keyboard.dart
index 8507bf2..9499b0f 100644
--- a/dev/manual_tests/lib/raw_keyboard.dart
+++ b/dev/manual_tests/lib/raw_keyboard.dart
@@ -105,7 +105,7 @@
           } else if (data is RawKeyEventDataLinux) {
             dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})'));
             dataText.add(Text('scanCode: ${data.scanCode}'));
-            dataText.add(Text('codePoint: ${data.codePoint}'));
+            dataText.add(Text('unicodeScalarValues: ${data.unicodeScalarValues}'));
             dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})'));
           }
           dataText.add(Text('logical: ${_event.logicalKey}'));
diff --git a/packages/flutter/lib/src/services/raw_keyboard.dart b/packages/flutter/lib/src/services/raw_keyboard.dart
index 3522db4..8427a69 100644
--- a/packages/flutter/lib/src/services/raw_keyboard.dart
+++ b/packages/flutter/lib/src/services/raw_keyboard.dart
@@ -279,7 +279,7 @@
       case 'linux':
         data = RawKeyEventDataLinux(
             keyHelper: KeyHelper(message['toolkit'] ?? ''),
-            codePoint: message['codePoint'] ?? 0,
+            unicodeScalarValues: message['unicodeScalarValues'] ?? 0,
             keyCode: message['keyCode'] ?? 0,
             scanCode: message['scanCode'] ?? 0,
             modifiers: message['modifiers'] ?? 0);
diff --git a/packages/flutter/lib/src/services/raw_keyboard_linux.dart b/packages/flutter/lib/src/services/raw_keyboard_linux.dart
index 3f4ea2c..fd09600 100644
--- a/packages/flutter/lib/src/services/raw_keyboard_linux.dart
+++ b/packages/flutter/lib/src/services/raw_keyboard_linux.dart
@@ -19,16 +19,17 @@
 class RawKeyEventDataLinux extends RawKeyEventData {
   /// Creates a key event data structure specific for macOS.
   ///
-  /// The [toolkit], [scanCode], [codePoint], [keyCode], and [modifiers], arguments
-  /// must not be null.
+  /// The [toolkit], [scanCode], [unicodeScalarValues], [keyCode], and [modifiers],
+  /// arguments must not be null.
   const RawKeyEventDataLinux({
     @required this.keyHelper,
+    this.unicodeScalarValues = 0,
     this.scanCode = 0,
-    this.codePoint = 0,
     this.keyCode = 0,
     this.modifiers = 0,
   }) : assert(scanCode != null),
-       assert(codePoint != null),
+       assert(unicodeScalarValues != null),
+       assert((unicodeScalarValues & ~LogicalKeyboardKey.valueMask) == 0),
        assert(keyCode != null),
        assert(modifiers != null),
        assert(keyHelper != null);
@@ -39,32 +40,32 @@
   /// (GLFW, GTK, QT, etc) may have a different key code mapping.
   final KeyHelper keyHelper;
 
+  /// An int with up to two Unicode scalar values generated by a single keystroke. An assertion
+  /// will fire if more than two values are encoded in a single keystroke.
+  ///
+  /// This is typically the character that [keyCode] would produce without any modifier keys.
+  /// For dead keys, it is typically the diacritic it would add to a character. Defaults to 0,
+  /// asserted to be not null.
+  final int unicodeScalarValues;
+
   /// The hardware scan code id corresponding to this key event.
   ///
   /// These values are not reliable and vary from device to device, so this
   /// information is mainly useful for debugging.
   final int scanCode;
 
-  /// The Unicode code point represented by the key event, if any.
-  ///
-  /// If there is no Unicode code point, this value is zero.
-  ///
-  /// Dead keys are represented as Unicode combining characters.
-  final int codePoint;
-
   /// The hardware key code corresponding to this key event.
   ///
   /// This is the physical key that was pressed, not the Unicode character.
-  /// See [codePoint] for the Unicode character. This value may be different depending
-  /// on the window toolkit used (See [toolkit]).
+  /// This value may be different depending on the window toolkit used. See [KeyHelper].
   final int keyCode;
 
   /// A mask of the current modifiers using the values in Modifier Flags.
-  /// This value may be different depending on the window toolkit used (See [toolkit]).
+  /// This value may be different depending on the window toolkit used. See [KeyHelper].
   final int modifiers;
 
   @override
-  String get keyLabel => codePoint == 0 ? null : String.fromCharCode(codePoint);
+  String get keyLabel => unicodeScalarValues == 0 ? null : String.fromCharCode(unicodeScalarValues);
 
   @override
   PhysicalKeyboardKey get physicalKey => kLinuxToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;
@@ -85,7 +86,7 @@
     // plane.
     if (keyLabel != null &&
         !LogicalKeyboardKey.isControlCharacter(keyLabel)) {
-      final int keyId = LogicalKeyboardKey.unicodePlane | (codePoint & LogicalKeyboardKey.valueMask);
+      final int keyId = LogicalKeyboardKey.unicodePlane | (unicodeScalarValues & LogicalKeyboardKey.valueMask);
       return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
         keyId,
         keyLabel: keyLabel,
@@ -123,7 +124,7 @@
   @override
   String toString() {
     return '$runtimeType(keyLabel: $keyLabel, keyCode: $keyCode, scanCode: $scanCode,'
-        ' codePoint: $codePoint, modifiers: $modifiers, '
+        ' unicodeScalarValues: $unicodeScalarValues, modifiers: $modifiers, '
         'modifiers down: $modifiersPressed)';
   }
 }
diff --git a/packages/flutter/test/services/raw_keyboard_test.dart b/packages/flutter/test/services/raw_keyboard_test.dart
index 0cb5cce..1643957 100644
--- a/packages/flutter/test/services/raw_keyboard_test.dart
+++ b/packages/flutter/test/services/raw_keyboard_test.dart
@@ -467,9 +467,9 @@
           'type': 'keydown',
           'keymap': 'linux',
           'toolkit': 'glfw',
-          'keyCode': 0x04,
-          'scanCode': 0x01,
-          'codePoint': 0x10,
+          'keyCode': 65,
+          'scanCode': 0x00000026,
+          'unicodeScalarValues': 97,
           'modifiers': modifier,
         });
         final RawKeyEventDataLinux data = event.data;
@@ -501,9 +501,9 @@
           'type': 'keydown',
           'keymap': 'linux',
           'toolkit': 'glfw',
-          'keyCode': 0x04,
-          'scanCode': 0x64,
-          'codePoint': 0x1,
+          'keyCode': 65,
+          'scanCode': 0x00000026,
+          'unicodeScalarValues': 97,
           'modifiers': modifier | GLFWKeyHelper.modifierControl,
         });
         final RawKeyEventDataLinux data = event.data;
@@ -538,13 +538,44 @@
         'toolkit': 'glfw',
         'keyCode': 65,
         'scanCode': 0x00000026,
-        'codePoint': 97,
+        'unicodeScalarValues': 113,
         'modifiers': 0x0,
       });
       final RawKeyEventDataLinux data = keyAEvent.data;
       expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
-      expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
-      expect(data.keyLabel, equals('a'));
+      expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
+      expect(data.keyLabel, equals('q'));
+    });
+    test('Code points with two Unicode scalar values are allowed', () {
+      final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
+        'type': 'keydown',
+        'keymap': 'linux',
+        'toolkit': 'glfw',
+        'keyCode': 65,
+        'scanCode': 0x00000026,
+        'unicodeScalarValues': 0x10FFFF,
+        'modifiers': 0x0,
+      });
+      final RawKeyEventDataLinux data = keyAEvent.data;
+      expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
+      expect(data.logicalKey.keyId, equals(0x10FFFF));
+      expect(data.keyLabel, equals('􏿿'));
+    });
+
+    test('Code points with more than three Unicode scalar values are not allowed', () {
+      // |keyCode| and |scanCode| are arbitrary values. This test should fail due to an invalid |unicodeScalarValues|.
+      void _createFailingKey() {
+        RawKeyEvent.fromMessage(const <String, dynamic>{
+          'type': 'keydown',
+          'keymap': 'linux',
+          'toolkit': 'glfw',
+          'keyCode': 65,
+          'scanCode': 0x00000026,
+          'unicodeScalarValues': 0x1F00000000,
+          'modifiers': 0x0,
+        });
+      }
+      expect(() => _createFailingKey(), throwsAssertionError);
     });
     test('Control keyboard keys are correctly translated', () {
       final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
@@ -553,7 +584,7 @@
         'toolkit': 'glfw',
         'keyCode': 256,
         'scanCode': 0x00000009,
-        'codePoint': 0,
+        'unicodeScalarValues': 0,
         'modifiers': 0x0,
       });
       final RawKeyEventDataLinux data = escapeKeyEvent.data;
@@ -568,7 +599,7 @@
         'toolkit': 'glfw',
         'keyCode': 340,
         'scanCode': 0x00000032,
-        'codePoint': 0,
+        'unicodeScalarValues': 0,
       });
       final RawKeyEventDataLinux data = shiftLeftKeyEvent.data;
       expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));