Game controller button support (#33868)

This adds support for game controller buttons. It adds some supplemental USB HID codes that aren't available from the Chromium source code, and maps those on Android to the game pad buttons that Android supports. Other platforms are not supported yet.
This commit is contained in:
Greg Spencer 2019-06-05 16:23:17 -07:00 committed by GitHub
parent 4e4d3a5de4
commit f0978c225a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1613 additions and 8 deletions

View File

@ -36,10 +36,11 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
super.dispose(); super.dispose();
} }
void _handleKeyEvent(RawKeyEvent event) { bool _handleKeyEvent(FocusNode node, RawKeyEvent event) {
setState(() { setState(() {
_event = event; _event = event;
}); });
return false;
} }
String _asHex(int value) => value != null ? '0x${value.toRadixString(16)}' : 'null'; String _asHex(int value) => value != null ? '0x${value.toRadixString(16)}' : 'null';
@ -53,9 +54,10 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final TextTheme textTheme = Theme.of(context).textTheme; final TextTheme textTheme = Theme.of(context).textTheme;
return RawKeyboardListener( return Focus(
focusNode: _focusNode, focusNode: _focusNode,
onKey: _handleKeyEvent, onKey: _handleKeyEvent,
autofocus: true,
child: AnimatedBuilder( child: AnimatedBuilder(
animation: _focusNode, animation: _focusNode,
builder: (BuildContext context, Widget child) { builder: (BuildContext context, Widget child) {
@ -87,6 +89,9 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})')); dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})'));
dataText.add(Text('scanCode: ${data.scanCode} (${_asHex(data.scanCode)})')); dataText.add(Text('scanCode: ${data.scanCode} (${_asHex(data.scanCode)})'));
dataText.add(Text('metaState: ${data.metaState} (${_asHex(data.metaState)})')); dataText.add(Text('metaState: ${data.metaState} (${_asHex(data.metaState)})'));
dataText.add(Text('source: ${data.eventSource} (${_asHex(data.eventSource)})'));
dataText.add(Text('vendorId: ${data.vendorId} (${_asHex(data.vendorId)})'));
dataText.add(Text('productId: ${data.productId} (${_asHex(data.productId)})'));
dataText.add(Text('flags: ${data.flags} (${_asHex(data.flags)})')); dataText.add(Text('flags: ${data.flags} (${_asHex(data.flags)})'));
} else if (data is RawKeyEventDataFuchsia) { } else if (data is RawKeyEventDataFuchsia) {
dataText.add(Text('codePoint: ${data.codePoint} (${_asHex(data.codePoint)})')); dataText.add(Text('codePoint: ${data.codePoint} (${_asHex(data.codePoint)})'));
@ -118,7 +123,7 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
} }
} }
return DefaultTextStyle( return DefaultTextStyle(
style: textTheme.headline, style: textTheme.subhead,
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: dataText, children: dataText,

View File

@ -52,6 +52,12 @@ Future<void> main(List<String> rawArguments) async {
'read. If --chromium-hid-codes is not specified, the input will be read ' 'read. If --chromium-hid-codes is not specified, the input will be read '
'from the correct file in the Chromium repository.', 'from the correct file in the Chromium repository.',
); );
argParser.addOption(
'supplemental-hid-codes',
defaultsTo: path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'supplemental_hid_codes.inc'),
help: "The path to where the supplemental HID codes that don't appear in the "
'Chromium map should be read.',
);
argParser.addOption( argParser.addOption(
'android-keycodes', 'android-keycodes',
defaultsTo: null, defaultsTo: null,
@ -140,6 +146,9 @@ Future<void> main(List<String> rawArguments) async {
hidCodes = File(parsedArguments['chromium-hid-codes']).readAsStringSync(); hidCodes = File(parsedArguments['chromium-hid-codes']).readAsStringSync();
} }
final String supplementalHidCodes = File(parsedArguments['supplemental-hid-codes']).readAsStringSync();
hidCodes = '$hidCodes\n$supplementalHidCodes';
String androidKeyCodes; String androidKeyCodes;
if (parsedArguments['android-keycodes'] == null) { if (parsedArguments['android-keycodes'] == null) {
androidKeyCodes = await getAndroidKeyCodes(); androidKeyCodes = await getAndroidKeyCodes();

View File

@ -3794,13 +3794,17 @@
"select": { "select": {
"names": { "names": {
"domkey": "Select", "domkey": "Select",
"android": null, "android": [
"DPAD_CENTER"
],
"english": "Select", "english": "Select",
"chromium": "select", "chromium": "select",
"glfw": null "glfw": null
}, },
"scanCodes": { "scanCodes": {
"android": null, "android": [
353
],
"usb": 458871, "usb": 458871,
"linux": 132, "linux": 132,
"xkb": 140, "xkb": 140,
@ -3808,7 +3812,9 @@
"macos": null "macos": null
}, },
"keyCodes": { "keyCodes": {
"android": null, "android": [
23
],
"glfw": null "glfw": null
} }
}, },
@ -6355,5 +6361,858 @@
"android": null, "android": null,
"glfw": null "glfw": null
} }
},
"gameButton1": {
"names": {
"domkey": "GameButton1",
"android": [
"BUTTON_1"
],
"english": "Game Button 1",
"chromium": "button1",
"glfw": null
},
"scanCodes": {
"android": [
256,
288
],
"usb": 341761,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
188
],
"glfw": null
}
},
"gameButton2": {
"names": {
"domkey": "GameButton2",
"android": [
"BUTTON_2"
],
"english": "Game Button 2",
"chromium": "button2",
"glfw": null
},
"scanCodes": {
"android": [
257,
289
],
"usb": 341762,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
189
],
"glfw": null
}
},
"gameButton3": {
"names": {
"domkey": "GameButton3",
"android": [
"BUTTON_3"
],
"english": "Game Button 3",
"chromium": "button3",
"glfw": null
},
"scanCodes": {
"android": [
258,
290
],
"usb": 341763,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
190
],
"glfw": null
}
},
"gameButton4": {
"names": {
"domkey": "GameButton4",
"android": [
"BUTTON_4"
],
"english": "Game Button 4",
"chromium": "button4",
"glfw": null
},
"scanCodes": {
"android": [
259,
291
],
"usb": 341764,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
191
],
"glfw": null
}
},
"gameButton5": {
"names": {
"domkey": "GameButton5",
"android": [
"BUTTON_5"
],
"english": "Game Button 5",
"chromium": "button5",
"glfw": null
},
"scanCodes": {
"android": [
260,
292
],
"usb": 341765,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
192
],
"glfw": null
}
},
"gameButton6": {
"names": {
"domkey": "GameButton6",
"android": [
"BUTTON_6"
],
"english": "Game Button 6",
"chromium": "button6",
"glfw": null
},
"scanCodes": {
"android": [
261,
293
],
"usb": 341766,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
193
],
"glfw": null
}
},
"gameButton7": {
"names": {
"domkey": "GameButton7",
"android": [
"BUTTON_7"
],
"english": "Game Button 7",
"chromium": "button7",
"glfw": null
},
"scanCodes": {
"android": [
262,
294
],
"usb": 341767,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
194
],
"glfw": null
}
},
"gameButton8": {
"names": {
"domkey": "GameButton8",
"android": [
"BUTTON_8"
],
"english": "Game Button 8",
"chromium": "button8",
"glfw": null
},
"scanCodes": {
"android": [
263,
295
],
"usb": 341768,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
195
],
"glfw": null
}
},
"gameButton9": {
"names": {
"domkey": "GameButton9",
"android": [
"BUTTON_9"
],
"english": "Game Button 9",
"chromium": "button9",
"glfw": null
},
"scanCodes": {
"android": [
264,
296
],
"usb": 341769,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
196
],
"glfw": null
}
},
"gameButton10": {
"names": {
"domkey": "GameButton10",
"android": [
"BUTTON_10"
],
"english": "Game Button 10",
"chromium": "button10",
"glfw": null
},
"scanCodes": {
"android": [
265,
297
],
"usb": 341770,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
197
],
"glfw": null
}
},
"gameButton11": {
"names": {
"domkey": "GameButton11",
"android": [
"BUTTON_11"
],
"english": "Game Button 11",
"chromium": "button11",
"glfw": null
},
"scanCodes": {
"android": [
266,
298
],
"usb": 341771,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
198
],
"glfw": null
}
},
"gameButton12": {
"names": {
"domkey": "GameButton12",
"android": [
"BUTTON_12"
],
"english": "Game Button 12",
"chromium": "button12",
"glfw": null
},
"scanCodes": {
"android": [
267,
299
],
"usb": 341772,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
199
],
"glfw": null
}
},
"gameButton13": {
"names": {
"domkey": "GameButton13",
"android": [
"BUTTON_13"
],
"english": "Game Button 13",
"chromium": "button13",
"glfw": null
},
"scanCodes": {
"android": [
268,
300
],
"usb": 341773,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
200
],
"glfw": null
}
},
"gameButton14": {
"names": {
"domkey": "GameButton14",
"android": [
"BUTTON_14"
],
"english": "Game Button 14",
"chromium": "button14",
"glfw": null
},
"scanCodes": {
"android": [
269,
301
],
"usb": 341774,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
201
],
"glfw": null
}
},
"gameButton15": {
"names": {
"domkey": "GameButton15",
"android": [
"BUTTON_15"
],
"english": "Game Button 15",
"chromium": "button15",
"glfw": null
},
"scanCodes": {
"android": [
270,
302
],
"usb": 341775,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
202
],
"glfw": null
}
},
"gameButton16": {
"names": {
"domkey": "GameButton16",
"android": [
"BUTTON_16"
],
"english": "Game Button 16",
"chromium": "button16",
"glfw": null
},
"scanCodes": {
"android": [
271,
303
],
"usb": 341776,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
203
],
"glfw": null
}
},
"gameButtonA": {
"names": {
"domkey": "GameButtonA",
"android": [
"BUTTON_A"
],
"english": "Game Button A",
"chromium": "buttonA",
"glfw": null
},
"scanCodes": {
"android": [
304
],
"usb": 341777,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
96
],
"glfw": null
}
},
"gameButtonB": {
"names": {
"domkey": "GameButtonB",
"android": [
"BUTTON_B"
],
"english": "Game Button B",
"chromium": "buttonB",
"glfw": null
},
"scanCodes": {
"android": [
305
],
"usb": 341778,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
97
],
"glfw": null
}
},
"gameButtonC": {
"names": {
"domkey": "GameButtonC",
"android": [
"BUTTON_C"
],
"english": "Game Button C",
"chromium": "buttonC",
"glfw": null
},
"scanCodes": {
"android": [
306
],
"usb": 341779,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
98
],
"glfw": null
}
},
"gameButtonLeft1": {
"names": {
"domkey": "GameButtonLeft1",
"android": [
"BUTTON_L1"
],
"english": "Game Button Left 1",
"chromium": "buttonL1",
"glfw": null
},
"scanCodes": {
"android": [
310
],
"usb": 341780,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
102
],
"glfw": null
}
},
"gameButtonLeft2": {
"names": {
"domkey": "GameButtonLeft2",
"android": [
"BUTTON_L2"
],
"english": "Game Button Left 2",
"chromium": "buttonL2",
"glfw": null
},
"scanCodes": {
"android": [
312
],
"usb": 341781,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
104
],
"glfw": null
}
},
"gameButtonMode": {
"names": {
"domkey": "GameButtonMode",
"android": [
"BUTTON_MODE"
],
"english": "Game Button Mode",
"chromium": "buttonMode",
"glfw": null
},
"scanCodes": {
"android": [
316
],
"usb": 341782,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
110
],
"glfw": null
}
},
"gameButtonRight1": {
"names": {
"domkey": "GameButtonRight1",
"android": [
"BUTTON_R1"
],
"english": "Game Button Right 1",
"chromium": "buttonR1",
"glfw": null
},
"scanCodes": {
"android": [
311
],
"usb": 341783,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
103
],
"glfw": null
}
},
"gameButtonRight2": {
"names": {
"domkey": "GameButtonRight2",
"android": [
"BUTTON_R2"
],
"english": "Game Button Right 2",
"chromium": "buttonR2",
"glfw": null
},
"scanCodes": {
"android": [
313
],
"usb": 341784,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
105
],
"glfw": null
}
},
"gameButtonSelect": {
"names": {
"domkey": "GameButtonSelect",
"android": [
"BUTTON_SELECT"
],
"english": "Game Button Select",
"chromium": "buttonSelect",
"glfw": null
},
"scanCodes": {
"android": [
314
],
"usb": 341785,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
109
],
"glfw": null
}
},
"gameButtonStart": {
"names": {
"domkey": "GameButtonStart",
"android": [
"BUTTON_START"
],
"english": "Game Button Start",
"chromium": "buttonStart",
"glfw": null
},
"scanCodes": {
"android": [
315
],
"usb": 341786,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
108
],
"glfw": null
}
},
"gameButtonThumbLeft": {
"names": {
"domkey": "GameButtonThumbLeft",
"android": [
"BUTTON_THUMBL"
],
"english": "Game Button Thumb Left",
"chromium": "buttonThumbl",
"glfw": null
},
"scanCodes": {
"android": [
317
],
"usb": 341787,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
106
],
"glfw": null
}
},
"gameButtonThumbRight": {
"names": {
"domkey": "GameButtonThumbRight",
"android": [
"BUTTON_THUMBR"
],
"english": "Game Button Thumb Right",
"chromium": "buttonThumbr",
"glfw": null
},
"scanCodes": {
"android": [
318
],
"usb": 341788,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
107
],
"glfw": null
}
},
"gameButtonX": {
"names": {
"domkey": "GameButtonX",
"android": [
"BUTTON_X"
],
"english": "Game Button X",
"chromium": "buttonX",
"glfw": null
},
"scanCodes": {
"android": [
307
],
"usb": 341789,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
99
],
"glfw": null
}
},
"gameButtonY": {
"names": {
"domkey": "GameButtonY",
"android": [
"BUTTON_Y"
],
"english": "Game Button Y",
"chromium": "buttonY",
"glfw": null
},
"scanCodes": {
"android": [
308
],
"usb": 341790,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
100
],
"glfw": null
}
},
"gameButtonZ": {
"names": {
"domkey": "GameButtonZ",
"android": [
"BUTTON_Z"
],
"english": "Game Button Z",
"chromium": "buttonZ",
"glfw": null
},
"scanCodes": {
"android": [
309
],
"usb": 341791,
"linux": null,
"xkb": null,
"windows": null,
"macos": null
},
"keyCodes": {
"android": [
101
],
"glfw": null
}
} }
} }

View File

@ -90,6 +90,37 @@
"f24": ["F24"], "f24": ["F24"],
"find": ["FIND"], "find": ["FIND"],
"fn": ["FUNCTION"], "fn": ["FUNCTION"],
"gameButton1": ["BUTTON_1"],
"gameButton2": ["BUTTON_2"],
"gameButton3": ["BUTTON_3"],
"gameButton4": ["BUTTON_4"],
"gameButton5": ["BUTTON_5"],
"gameButton6": ["BUTTON_6"],
"gameButton7": ["BUTTON_7"],
"gameButton8": ["BUTTON_8"],
"gameButton9": ["BUTTON_9"],
"gameButton10": ["BUTTON_10"],
"gameButton11": ["BUTTON_11"],
"gameButton12": ["BUTTON_12"],
"gameButton13": ["BUTTON_13"],
"gameButton14": ["BUTTON_14"],
"gameButton15": ["BUTTON_15"],
"gameButton16": ["BUTTON_16"],
"gameButtonA": ["BUTTON_A"],
"gameButtonB": ["BUTTON_B"],
"gameButtonC": ["BUTTON_C"],
"gameButtonLeft1": ["BUTTON_L1"],
"gameButtonLeft2": ["BUTTON_L2"],
"gameButtonMode": ["BUTTON_MODE"],
"gameButtonRight1": ["BUTTON_R1"],
"gameButtonRight2": ["BUTTON_R2"],
"gameButtonSelect": ["BUTTON_SELECT"],
"gameButtonStart": ["BUTTON_START"],
"gameButtonThumbLeft": ["BUTTON_THUMBL"],
"gameButtonThumbRight": ["BUTTON_THUMBR"],
"gameButtonX": ["BUTTON_X"],
"gameButtonY": ["BUTTON_Y"],
"gameButtonZ": ["BUTTON_Z"],
"goBack": ["BACK"], "goBack": ["BACK"],
"goHome": ["HOME"], "goHome": ["HOME"],
"groupNext": ["LANGUAGE_SWITCH"], "groupNext": ["LANGUAGE_SWITCH"],
@ -200,6 +231,7 @@
"quote": ["APOSTROPHE"], "quote": ["APOSTROPHE"],
"redo": ["REDO"], "redo": ["REDO"],
"scrollLock": ["SCROLL_LOCK"], "scrollLock": ["SCROLL_LOCK"],
"select": ["DPAD_CENTER"],
"semicolon": ["SEMICOLON"], "semicolon": ["SEMICOLON"],
"settings": ["SETTINGS"], "settings": ["SETTINGS"],
"shiftLeft": ["SHIFT_LEFT"], "shiftLeft": ["SHIFT_LEFT"],

View File

@ -0,0 +1,45 @@
// These are supplemental key codes to be added to those that Chromium
// defines. Since the web doesn't have game controller buttons defined in the
// same way, these map USB HID codes for game controller buttons to
// Android/Linux button names.
//
// The HID codes here are not real USB HID codes, because the USB HID standard
// doesn't define game controller buttons in this way. It defines only two
// button "collections" (fire/jump and trigger), with the button number for
// each collection sent as extra data. Since we're just using USB HID as a
// convenient namespace, and not using these HID codes for interfacing with a
// USB protocol, we can define new ones to enumerate the buttons. These don't
// collide with any currently defined HID codes.
//
// USB HID evdev XKB Win Mac DOMKey Code
USB_KEYMAP(0x05ff01, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton1", BUTTON_1),
USB_KEYMAP(0x05ff02, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton2", BUTTON_2),
USB_KEYMAP(0x05ff03, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton3", BUTTON_3),
USB_KEYMAP(0x05ff04, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton4", BUTTON_4),
USB_KEYMAP(0x05ff05, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton5", BUTTON_5),
USB_KEYMAP(0x05ff06, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton6", BUTTON_6),
USB_KEYMAP(0x05ff07, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton7", BUTTON_7),
USB_KEYMAP(0x05ff08, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton8", BUTTON_8),
USB_KEYMAP(0x05ff09, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton9", BUTTON_9),
USB_KEYMAP(0x05ff0a, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton10", BUTTON_10),
USB_KEYMAP(0x05ff0b, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton11", BUTTON_11),
USB_KEYMAP(0x05ff0c, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton12", BUTTON_12),
USB_KEYMAP(0x05ff0d, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton13", BUTTON_13),
USB_KEYMAP(0x05ff0e, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton14", BUTTON_14),
USB_KEYMAP(0x05ff0f, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton15", BUTTON_15),
USB_KEYMAP(0x05ff10, 0x0000, 0x0000, 0x0000, 0xffff, "GameButton16", BUTTON_16),
USB_KEYMAP(0x05ff11, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonA", BUTTON_A),
USB_KEYMAP(0x05ff12, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonB", BUTTON_B),
USB_KEYMAP(0x05ff13, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonC", BUTTON_C),
USB_KEYMAP(0x05ff14, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonLeft1", BUTTON_L1),
USB_KEYMAP(0x05ff15, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonLeft2", BUTTON_L2),
USB_KEYMAP(0x05ff16, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonMode", BUTTON_MODE),
USB_KEYMAP(0x05ff17, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonRight1", BUTTON_R1),
USB_KEYMAP(0x05ff18, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonRight2", BUTTON_R2),
USB_KEYMAP(0x05ff19, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonSelect", BUTTON_SELECT),
USB_KEYMAP(0x05ff1a, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonStart", BUTTON_START),
USB_KEYMAP(0x05ff1b, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonThumbLeft", BUTTON_THUMBL),
USB_KEYMAP(0x05ff1c, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonThumbRight", BUTTON_THUMBR),
USB_KEYMAP(0x05ff1d, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonX", BUTTON_X),
USB_KEYMAP(0x05ff1e, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonY", BUTTON_Y),
USB_KEYMAP(0x05ff1f, 0x0000, 0x0000, 0x0000, 0xffff, "GameButtonZ", BUTTON_Z),

View File

@ -375,7 +375,7 @@ class Key {
static String getCommentName(String constantName) { static String getCommentName(String constantName) {
String upperCamel = lowerCamelToUpperCamel(constantName); String upperCamel = lowerCamelToUpperCamel(constantName);
upperCamel = upperCamel.replaceAllMapped(RegExp(r'(Digit|Numpad|Lang)([0-9]+)'), (Match match) => '${match.group(1)} ${match.group(2)}'); upperCamel = upperCamel.replaceAllMapped(RegExp(r'(Digit|Numpad|Lang|Button|Left|Right)([0-9]+)'), (Match match) => '${match.group(1)} ${match.group(2)}');
return upperCamel.replaceAllMapped(RegExp(r'([A-Z])'), (Match match) => ' ${match.group(1)}').trim(); return upperCamel.replaceAllMapped(RegExp(r'([A-Z])'), (Match match) => ' ${match.group(1)}').trim();
} }

View File

@ -1455,6 +1455,161 @@ class LogicalKeyboardKey extends KeyboardKey {
/// See the function [RawKeyEvent.logicalKey] for more information. /// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey showAllWindows = LogicalKeyboardKey(0x001000c029f, debugName: kReleaseMode ? null : 'Show All Windows'); static const LogicalKeyboardKey showAllWindows = LogicalKeyboardKey(0x001000c029f, debugName: kReleaseMode ? null : 'Show All Windows');
/// Represents the logical "Game Button 1" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton1 = LogicalKeyboardKey(0x00100053701, debugName: kReleaseMode ? null : 'Game Button 1');
/// Represents the logical "Game Button 2" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton2 = LogicalKeyboardKey(0x00100053702, debugName: kReleaseMode ? null : 'Game Button 2');
/// Represents the logical "Game Button 3" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton3 = LogicalKeyboardKey(0x00100053703, debugName: kReleaseMode ? null : 'Game Button 3');
/// Represents the logical "Game Button 4" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton4 = LogicalKeyboardKey(0x00100053704, debugName: kReleaseMode ? null : 'Game Button 4');
/// Represents the logical "Game Button 5" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton5 = LogicalKeyboardKey(0x00100053705, debugName: kReleaseMode ? null : 'Game Button 5');
/// Represents the logical "Game Button 6" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton6 = LogicalKeyboardKey(0x00100053706, debugName: kReleaseMode ? null : 'Game Button 6');
/// Represents the logical "Game Button 7" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton7 = LogicalKeyboardKey(0x00100053707, debugName: kReleaseMode ? null : 'Game Button 7');
/// Represents the logical "Game Button 8" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton8 = LogicalKeyboardKey(0x00100053708, debugName: kReleaseMode ? null : 'Game Button 8');
/// Represents the logical "Game Button 9" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton9 = LogicalKeyboardKey(0x00100053709, debugName: kReleaseMode ? null : 'Game Button 9');
/// Represents the logical "Game Button 10" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton10 = LogicalKeyboardKey(0x0010005370a, debugName: kReleaseMode ? null : 'Game Button 10');
/// Represents the logical "Game Button 11" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton11 = LogicalKeyboardKey(0x0010005370b, debugName: kReleaseMode ? null : 'Game Button 11');
/// Represents the logical "Game Button 12" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton12 = LogicalKeyboardKey(0x0010005370c, debugName: kReleaseMode ? null : 'Game Button 12');
/// Represents the logical "Game Button 13" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton13 = LogicalKeyboardKey(0x0010005370d, debugName: kReleaseMode ? null : 'Game Button 13');
/// Represents the logical "Game Button 14" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton14 = LogicalKeyboardKey(0x0010005370e, debugName: kReleaseMode ? null : 'Game Button 14');
/// Represents the logical "Game Button 15" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton15 = LogicalKeyboardKey(0x0010005370f, debugName: kReleaseMode ? null : 'Game Button 15');
/// Represents the logical "Game Button 16" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButton16 = LogicalKeyboardKey(0x00100053710, debugName: kReleaseMode ? null : 'Game Button 16');
/// Represents the logical "Game Button A" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonA = LogicalKeyboardKey(0x00100053711, debugName: kReleaseMode ? null : 'Game Button A');
/// Represents the logical "Game Button B" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonB = LogicalKeyboardKey(0x00100053712, debugName: kReleaseMode ? null : 'Game Button B');
/// Represents the logical "Game Button C" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonC = LogicalKeyboardKey(0x00100053713, debugName: kReleaseMode ? null : 'Game Button C');
/// Represents the logical "Game Button Left 1" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonLeft1 = LogicalKeyboardKey(0x00100053714, debugName: kReleaseMode ? null : 'Game Button Left 1');
/// Represents the logical "Game Button Left 2" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonLeft2 = LogicalKeyboardKey(0x00100053715, debugName: kReleaseMode ? null : 'Game Button Left 2');
/// Represents the logical "Game Button Mode" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonMode = LogicalKeyboardKey(0x00100053716, debugName: kReleaseMode ? null : 'Game Button Mode');
/// Represents the logical "Game Button Right 1" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonRight1 = LogicalKeyboardKey(0x00100053717, debugName: kReleaseMode ? null : 'Game Button Right 1');
/// Represents the logical "Game Button Right 2" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonRight2 = LogicalKeyboardKey(0x00100053718, debugName: kReleaseMode ? null : 'Game Button Right 2');
/// Represents the logical "Game Button Select" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonSelect = LogicalKeyboardKey(0x00100053719, debugName: kReleaseMode ? null : 'Game Button Select');
/// Represents the logical "Game Button Start" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonStart = LogicalKeyboardKey(0x0010005371a, debugName: kReleaseMode ? null : 'Game Button Start');
/// Represents the logical "Game Button Thumb Left" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonThumbLeft = LogicalKeyboardKey(0x0010005371b, debugName: kReleaseMode ? null : 'Game Button Thumb Left');
/// Represents the logical "Game Button Thumb Right" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonThumbRight = LogicalKeyboardKey(0x0010005371c, debugName: kReleaseMode ? null : 'Game Button Thumb Right');
/// Represents the logical "Game Button X" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonX = LogicalKeyboardKey(0x0010005371d, debugName: kReleaseMode ? null : 'Game Button X');
/// Represents the logical "Game Button Y" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonY = LogicalKeyboardKey(0x0010005371e, debugName: kReleaseMode ? null : 'Game Button Y');
/// Represents the logical "Game Button Z" key on the keyboard.
///
/// See the function [RawKeyEvent.logicalKey] for more information.
static const LogicalKeyboardKey gameButtonZ = LogicalKeyboardKey(0x0010005371f, debugName: kReleaseMode ? null : 'Game Button Z');
/// Represents the logical "Shift" key on the keyboard. /// Represents the logical "Shift" key on the keyboard.
/// ///
/// This key represents the union of the keys {shiftLeft, shiftRight} when /// This key represents the union of the keys {shiftLeft, shiftRight} when
@ -1720,6 +1875,37 @@ class LogicalKeyboardKey extends KeyboardKey {
0x01000c028c: mailSend, 0x01000c028c: mailSend,
0x01000c029d: keyboardLayoutSelect, 0x01000c029d: keyboardLayoutSelect,
0x01000c029f: showAllWindows, 0x01000c029f: showAllWindows,
0x0100053701: gameButton1,
0x0100053702: gameButton2,
0x0100053703: gameButton3,
0x0100053704: gameButton4,
0x0100053705: gameButton5,
0x0100053706: gameButton6,
0x0100053707: gameButton7,
0x0100053708: gameButton8,
0x0100053709: gameButton9,
0x010005370a: gameButton10,
0x010005370b: gameButton11,
0x010005370c: gameButton12,
0x010005370d: gameButton13,
0x010005370e: gameButton14,
0x010005370f: gameButton15,
0x0100053710: gameButton16,
0x0100053711: gameButtonA,
0x0100053712: gameButtonB,
0x0100053713: gameButtonC,
0x0100053714: gameButtonLeft1,
0x0100053715: gameButtonLeft2,
0x0100053716: gameButtonMode,
0x0100053717: gameButtonRight1,
0x0100053718: gameButtonRight2,
0x0100053719: gameButtonSelect,
0x010005371a: gameButtonStart,
0x010005371b: gameButtonThumbLeft,
0x010005371c: gameButtonThumbRight,
0x010005371d: gameButtonX,
0x010005371e: gameButtonY,
0x010005371f: gameButtonZ,
0x201000700e1: shift, 0x201000700e1: shift,
0x201000700e3: meta, 0x201000700e3: meta,
0x201000700e2: alt, 0x201000700e2: alt,
@ -3139,6 +3325,192 @@ class PhysicalKeyboardKey extends KeyboardKey {
/// See the function [RawKeyEvent.physicalKey] for more information. /// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey showAllWindows = PhysicalKeyboardKey(0x000c029f, debugName: kReleaseMode ? null : 'Show All Windows'); static const PhysicalKeyboardKey showAllWindows = PhysicalKeyboardKey(0x000c029f, debugName: kReleaseMode ? null : 'Show All Windows');
/// Represents the location of the "Game Button 1" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton1 = PhysicalKeyboardKey(0x00053701, debugName: kReleaseMode ? null : 'Game Button 1');
/// Represents the location of the "Game Button 2" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton2 = PhysicalKeyboardKey(0x00053702, debugName: kReleaseMode ? null : 'Game Button 2');
/// Represents the location of the "Game Button 3" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton3 = PhysicalKeyboardKey(0x00053703, debugName: kReleaseMode ? null : 'Game Button 3');
/// Represents the location of the "Game Button 4" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton4 = PhysicalKeyboardKey(0x00053704, debugName: kReleaseMode ? null : 'Game Button 4');
/// Represents the location of the "Game Button 5" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton5 = PhysicalKeyboardKey(0x00053705, debugName: kReleaseMode ? null : 'Game Button 5');
/// Represents the location of the "Game Button 6" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton6 = PhysicalKeyboardKey(0x00053706, debugName: kReleaseMode ? null : 'Game Button 6');
/// Represents the location of the "Game Button 7" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton7 = PhysicalKeyboardKey(0x00053707, debugName: kReleaseMode ? null : 'Game Button 7');
/// Represents the location of the "Game Button 8" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton8 = PhysicalKeyboardKey(0x00053708, debugName: kReleaseMode ? null : 'Game Button 8');
/// Represents the location of the "Game Button 9" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton9 = PhysicalKeyboardKey(0x00053709, debugName: kReleaseMode ? null : 'Game Button 9');
/// Represents the location of the "Game Button 10" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton10 = PhysicalKeyboardKey(0x0005370a, debugName: kReleaseMode ? null : 'Game Button 10');
/// Represents the location of the "Game Button 11" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton11 = PhysicalKeyboardKey(0x0005370b, debugName: kReleaseMode ? null : 'Game Button 11');
/// Represents the location of the "Game Button 12" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton12 = PhysicalKeyboardKey(0x0005370c, debugName: kReleaseMode ? null : 'Game Button 12');
/// Represents the location of the "Game Button 13" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton13 = PhysicalKeyboardKey(0x0005370d, debugName: kReleaseMode ? null : 'Game Button 13');
/// Represents the location of the "Game Button 14" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton14 = PhysicalKeyboardKey(0x0005370e, debugName: kReleaseMode ? null : 'Game Button 14');
/// Represents the location of the "Game Button 15" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton15 = PhysicalKeyboardKey(0x0005370f, debugName: kReleaseMode ? null : 'Game Button 15');
/// Represents the location of the "Game Button 16" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButton16 = PhysicalKeyboardKey(0x00053710, debugName: kReleaseMode ? null : 'Game Button 16');
/// Represents the location of the "Game Button A" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonA = PhysicalKeyboardKey(0x00053711, debugName: kReleaseMode ? null : 'Game Button A');
/// Represents the location of the "Game Button B" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonB = PhysicalKeyboardKey(0x00053712, debugName: kReleaseMode ? null : 'Game Button B');
/// Represents the location of the "Game Button C" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonC = PhysicalKeyboardKey(0x00053713, debugName: kReleaseMode ? null : 'Game Button C');
/// Represents the location of the "Game Button Left 1" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonLeft1 = PhysicalKeyboardKey(0x00053714, debugName: kReleaseMode ? null : 'Game Button Left 1');
/// Represents the location of the "Game Button Left 2" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonLeft2 = PhysicalKeyboardKey(0x00053715, debugName: kReleaseMode ? null : 'Game Button Left 2');
/// Represents the location of the "Game Button Mode" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonMode = PhysicalKeyboardKey(0x00053716, debugName: kReleaseMode ? null : 'Game Button Mode');
/// Represents the location of the "Game Button Right 1" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonRight1 = PhysicalKeyboardKey(0x00053717, debugName: kReleaseMode ? null : 'Game Button Right 1');
/// Represents the location of the "Game Button Right 2" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonRight2 = PhysicalKeyboardKey(0x00053718, debugName: kReleaseMode ? null : 'Game Button Right 2');
/// Represents the location of the "Game Button Select" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonSelect = PhysicalKeyboardKey(0x00053719, debugName: kReleaseMode ? null : 'Game Button Select');
/// Represents the location of the "Game Button Start" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonStart = PhysicalKeyboardKey(0x0005371a, debugName: kReleaseMode ? null : 'Game Button Start');
/// Represents the location of the "Game Button Thumb Left" key on a
/// generalized keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonThumbLeft = PhysicalKeyboardKey(0x0005371b, debugName: kReleaseMode ? null : 'Game Button Thumb Left');
/// Represents the location of the "Game Button Thumb Right" key on a
/// generalized keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonThumbRight = PhysicalKeyboardKey(0x0005371c, debugName: kReleaseMode ? null : 'Game Button Thumb Right');
/// Represents the location of the "Game Button X" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonX = PhysicalKeyboardKey(0x0005371d, debugName: kReleaseMode ? null : 'Game Button X');
/// Represents the location of the "Game Button Y" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonY = PhysicalKeyboardKey(0x0005371e, debugName: kReleaseMode ? null : 'Game Button Y');
/// Represents the location of the "Game Button Z" key on a generalized
/// keyboard.
///
/// See the function [RawKeyEvent.physicalKey] for more information.
static const PhysicalKeyboardKey gameButtonZ = PhysicalKeyboardKey(0x0005371f, debugName: kReleaseMode ? null : 'Game Button Z');
// A list of all the predefined constant PhysicalKeyboardKeys so that they // A list of all the predefined constant PhysicalKeyboardKeys so that they
// can be searched. // can be searched.
static const Map<int, PhysicalKeyboardKey> _knownPhysicalKeys = <int, PhysicalKeyboardKey>{ static const Map<int, PhysicalKeyboardKey> _knownPhysicalKeys = <int, PhysicalKeyboardKey>{
@ -3376,5 +3748,36 @@ class PhysicalKeyboardKey extends KeyboardKey {
0x000c028c: mailSend, 0x000c028c: mailSend,
0x000c029d: keyboardLayoutSelect, 0x000c029d: keyboardLayoutSelect,
0x000c029f: showAllWindows, 0x000c029f: showAllWindows,
0x00053701: gameButton1,
0x00053702: gameButton2,
0x00053703: gameButton3,
0x00053704: gameButton4,
0x00053705: gameButton5,
0x00053706: gameButton6,
0x00053707: gameButton7,
0x00053708: gameButton8,
0x00053709: gameButton9,
0x0005370a: gameButton10,
0x0005370b: gameButton11,
0x0005370c: gameButton12,
0x0005370d: gameButton13,
0x0005370e: gameButton14,
0x0005370f: gameButton15,
0x00053710: gameButton16,
0x00053711: gameButtonA,
0x00053712: gameButtonB,
0x00053713: gameButtonC,
0x00053714: gameButtonLeft1,
0x00053715: gameButtonLeft2,
0x00053716: gameButtonMode,
0x00053717: gameButtonRight1,
0x00053718: gameButtonRight2,
0x00053719: gameButtonSelect,
0x0005371a: gameButtonStart,
0x0005371b: gameButtonThumbLeft,
0x0005371c: gameButtonThumbRight,
0x0005371d: gameButtonX,
0x0005371e: gameButtonY,
0x0005371f: gameButtonZ,
}; };
} }

View File

@ -116,6 +116,7 @@ const Map<int, LogicalKeyboardKey> kAndroidToLogicalKey = <int, LogicalKeyboardK
26: LogicalKeyboardKey.power, 26: LogicalKeyboardKey.power,
161: LogicalKeyboardKey.numpadEqual, 161: LogicalKeyboardKey.numpadEqual,
259: LogicalKeyboardKey.help, 259: LogicalKeyboardKey.help,
23: LogicalKeyboardKey.select,
277: LogicalKeyboardKey.cut, 277: LogicalKeyboardKey.cut,
278: LogicalKeyboardKey.copy, 278: LogicalKeyboardKey.copy,
279: LogicalKeyboardKey.paste, 279: LogicalKeyboardKey.paste,
@ -162,6 +163,37 @@ const Map<int, LogicalKeyboardKey> kAndroidToLogicalKey = <int, LogicalKeyboardK
168: LogicalKeyboardKey.zoomIn, 168: LogicalKeyboardKey.zoomIn,
169: LogicalKeyboardKey.zoomOut, 169: LogicalKeyboardKey.zoomOut,
255: LogicalKeyboardKey.zoomToggle, 255: LogicalKeyboardKey.zoomToggle,
188: LogicalKeyboardKey.gameButton1,
189: LogicalKeyboardKey.gameButton2,
190: LogicalKeyboardKey.gameButton3,
191: LogicalKeyboardKey.gameButton4,
192: LogicalKeyboardKey.gameButton5,
193: LogicalKeyboardKey.gameButton6,
194: LogicalKeyboardKey.gameButton7,
195: LogicalKeyboardKey.gameButton8,
196: LogicalKeyboardKey.gameButton9,
197: LogicalKeyboardKey.gameButton10,
198: LogicalKeyboardKey.gameButton11,
199: LogicalKeyboardKey.gameButton12,
200: LogicalKeyboardKey.gameButton13,
201: LogicalKeyboardKey.gameButton14,
202: LogicalKeyboardKey.gameButton15,
203: LogicalKeyboardKey.gameButton16,
96: LogicalKeyboardKey.gameButtonA,
97: LogicalKeyboardKey.gameButtonB,
98: LogicalKeyboardKey.gameButtonC,
102: LogicalKeyboardKey.gameButtonLeft1,
104: LogicalKeyboardKey.gameButtonLeft2,
110: LogicalKeyboardKey.gameButtonMode,
103: LogicalKeyboardKey.gameButtonRight1,
105: LogicalKeyboardKey.gameButtonRight2,
109: LogicalKeyboardKey.gameButtonSelect,
108: LogicalKeyboardKey.gameButtonStart,
106: LogicalKeyboardKey.gameButtonThumbLeft,
107: LogicalKeyboardKey.gameButtonThumbRight,
99: LogicalKeyboardKey.gameButtonX,
100: LogicalKeyboardKey.gameButtonY,
101: LogicalKeyboardKey.gameButtonZ,
}; };
/// Maps Android-specific scan codes to the matching [PhysicalKeyboardKey]. /// Maps Android-specific scan codes to the matching [PhysicalKeyboardKey].
@ -288,6 +320,7 @@ const Map<int, PhysicalKeyboardKey> kAndroidToPhysicalKey = <int, PhysicalKeyboa
194: PhysicalKeyboardKey.f24, 194: PhysicalKeyboardKey.f24,
134: PhysicalKeyboardKey.open, 134: PhysicalKeyboardKey.open,
138: PhysicalKeyboardKey.help, 138: PhysicalKeyboardKey.help,
353: PhysicalKeyboardKey.select,
129: PhysicalKeyboardKey.again, 129: PhysicalKeyboardKey.again,
131: PhysicalKeyboardKey.undo, 131: PhysicalKeyboardKey.undo,
137: PhysicalKeyboardKey.cut, 137: PhysicalKeyboardKey.cut,
@ -345,6 +378,53 @@ const Map<int, PhysicalKeyboardKey> kAndroidToPhysicalKey = <int, PhysicalKeyboa
159: PhysicalKeyboardKey.browserForward, 159: PhysicalKeyboardKey.browserForward,
156: PhysicalKeyboardKey.browserFavorites, 156: PhysicalKeyboardKey.browserFavorites,
182: PhysicalKeyboardKey.redo, 182: PhysicalKeyboardKey.redo,
256: PhysicalKeyboardKey.gameButton1,
288: PhysicalKeyboardKey.gameButton1,
257: PhysicalKeyboardKey.gameButton2,
289: PhysicalKeyboardKey.gameButton2,
258: PhysicalKeyboardKey.gameButton3,
290: PhysicalKeyboardKey.gameButton3,
259: PhysicalKeyboardKey.gameButton4,
291: PhysicalKeyboardKey.gameButton4,
260: PhysicalKeyboardKey.gameButton5,
292: PhysicalKeyboardKey.gameButton5,
261: PhysicalKeyboardKey.gameButton6,
293: PhysicalKeyboardKey.gameButton6,
262: PhysicalKeyboardKey.gameButton7,
294: PhysicalKeyboardKey.gameButton7,
263: PhysicalKeyboardKey.gameButton8,
295: PhysicalKeyboardKey.gameButton8,
264: PhysicalKeyboardKey.gameButton9,
296: PhysicalKeyboardKey.gameButton9,
265: PhysicalKeyboardKey.gameButton10,
297: PhysicalKeyboardKey.gameButton10,
266: PhysicalKeyboardKey.gameButton11,
298: PhysicalKeyboardKey.gameButton11,
267: PhysicalKeyboardKey.gameButton12,
299: PhysicalKeyboardKey.gameButton12,
268: PhysicalKeyboardKey.gameButton13,
300: PhysicalKeyboardKey.gameButton13,
269: PhysicalKeyboardKey.gameButton14,
301: PhysicalKeyboardKey.gameButton14,
270: PhysicalKeyboardKey.gameButton15,
302: PhysicalKeyboardKey.gameButton15,
271: PhysicalKeyboardKey.gameButton16,
303: PhysicalKeyboardKey.gameButton16,
304: PhysicalKeyboardKey.gameButtonA,
305: PhysicalKeyboardKey.gameButtonB,
306: PhysicalKeyboardKey.gameButtonC,
310: PhysicalKeyboardKey.gameButtonLeft1,
312: PhysicalKeyboardKey.gameButtonLeft2,
316: PhysicalKeyboardKey.gameButtonMode,
311: PhysicalKeyboardKey.gameButtonRight1,
313: PhysicalKeyboardKey.gameButtonRight2,
314: PhysicalKeyboardKey.gameButtonSelect,
315: PhysicalKeyboardKey.gameButtonStart,
317: PhysicalKeyboardKey.gameButtonThumbLeft,
318: PhysicalKeyboardKey.gameButtonThumbRight,
307: PhysicalKeyboardKey.gameButtonX,
308: PhysicalKeyboardKey.gameButtonY,
309: PhysicalKeyboardKey.gameButtonZ,
}; };
/// A map of Android key codes which have printable representations, but appear /// A map of Android key codes which have printable representations, but appear
@ -608,6 +688,37 @@ const Map<int, LogicalKeyboardKey> kFuchsiaToLogicalKey = <int, LogicalKeyboardK
0x1000c028c: LogicalKeyboardKey.mailSend, 0x1000c028c: LogicalKeyboardKey.mailSend,
0x1000c029d: LogicalKeyboardKey.keyboardLayoutSelect, 0x1000c029d: LogicalKeyboardKey.keyboardLayoutSelect,
0x1000c029f: LogicalKeyboardKey.showAllWindows, 0x1000c029f: LogicalKeyboardKey.showAllWindows,
0x100053701: LogicalKeyboardKey.gameButton1,
0x100053702: LogicalKeyboardKey.gameButton2,
0x100053703: LogicalKeyboardKey.gameButton3,
0x100053704: LogicalKeyboardKey.gameButton4,
0x100053705: LogicalKeyboardKey.gameButton5,
0x100053706: LogicalKeyboardKey.gameButton6,
0x100053707: LogicalKeyboardKey.gameButton7,
0x100053708: LogicalKeyboardKey.gameButton8,
0x100053709: LogicalKeyboardKey.gameButton9,
0x10005370a: LogicalKeyboardKey.gameButton10,
0x10005370b: LogicalKeyboardKey.gameButton11,
0x10005370c: LogicalKeyboardKey.gameButton12,
0x10005370d: LogicalKeyboardKey.gameButton13,
0x10005370e: LogicalKeyboardKey.gameButton14,
0x10005370f: LogicalKeyboardKey.gameButton15,
0x100053710: LogicalKeyboardKey.gameButton16,
0x100053711: LogicalKeyboardKey.gameButtonA,
0x100053712: LogicalKeyboardKey.gameButtonB,
0x100053713: LogicalKeyboardKey.gameButtonC,
0x100053714: LogicalKeyboardKey.gameButtonLeft1,
0x100053715: LogicalKeyboardKey.gameButtonLeft2,
0x100053716: LogicalKeyboardKey.gameButtonMode,
0x100053717: LogicalKeyboardKey.gameButtonRight1,
0x100053718: LogicalKeyboardKey.gameButtonRight2,
0x100053719: LogicalKeyboardKey.gameButtonSelect,
0x10005371a: LogicalKeyboardKey.gameButtonStart,
0x10005371b: LogicalKeyboardKey.gameButtonThumbLeft,
0x10005371c: LogicalKeyboardKey.gameButtonThumbRight,
0x10005371d: LogicalKeyboardKey.gameButtonX,
0x10005371e: LogicalKeyboardKey.gameButtonY,
0x10005371f: LogicalKeyboardKey.gameButtonZ,
}; };
/// Maps Fuchsia-specific USB HID Usage IDs to the matching /// Maps Fuchsia-specific USB HID Usage IDs to the matching
@ -847,6 +958,37 @@ const Map<int, PhysicalKeyboardKey> kFuchsiaToPhysicalKey = <int, PhysicalKeyboa
0x000c028c: PhysicalKeyboardKey.mailSend, 0x000c028c: PhysicalKeyboardKey.mailSend,
0x000c029d: PhysicalKeyboardKey.keyboardLayoutSelect, 0x000c029d: PhysicalKeyboardKey.keyboardLayoutSelect,
0x000c029f: PhysicalKeyboardKey.showAllWindows, 0x000c029f: PhysicalKeyboardKey.showAllWindows,
0x00053701: PhysicalKeyboardKey.gameButton1,
0x00053702: PhysicalKeyboardKey.gameButton2,
0x00053703: PhysicalKeyboardKey.gameButton3,
0x00053704: PhysicalKeyboardKey.gameButton4,
0x00053705: PhysicalKeyboardKey.gameButton5,
0x00053706: PhysicalKeyboardKey.gameButton6,
0x00053707: PhysicalKeyboardKey.gameButton7,
0x00053708: PhysicalKeyboardKey.gameButton8,
0x00053709: PhysicalKeyboardKey.gameButton9,
0x0005370a: PhysicalKeyboardKey.gameButton10,
0x0005370b: PhysicalKeyboardKey.gameButton11,
0x0005370c: PhysicalKeyboardKey.gameButton12,
0x0005370d: PhysicalKeyboardKey.gameButton13,
0x0005370e: PhysicalKeyboardKey.gameButton14,
0x0005370f: PhysicalKeyboardKey.gameButton15,
0x00053710: PhysicalKeyboardKey.gameButton16,
0x00053711: PhysicalKeyboardKey.gameButtonA,
0x00053712: PhysicalKeyboardKey.gameButtonB,
0x00053713: PhysicalKeyboardKey.gameButtonC,
0x00053714: PhysicalKeyboardKey.gameButtonLeft1,
0x00053715: PhysicalKeyboardKey.gameButtonLeft2,
0x00053716: PhysicalKeyboardKey.gameButtonMode,
0x00053717: PhysicalKeyboardKey.gameButtonRight1,
0x00053718: PhysicalKeyboardKey.gameButtonRight2,
0x00053719: PhysicalKeyboardKey.gameButtonSelect,
0x0005371a: PhysicalKeyboardKey.gameButtonStart,
0x0005371b: PhysicalKeyboardKey.gameButtonThumbLeft,
0x0005371c: PhysicalKeyboardKey.gameButtonThumbRight,
0x0005371d: PhysicalKeyboardKey.gameButtonX,
0x0005371e: PhysicalKeyboardKey.gameButtonY,
0x0005371f: PhysicalKeyboardKey.gameButtonZ,
}; };
/// Maps macOS-specific key code values representing [PhysicalKeyboardKey]. /// Maps macOS-specific key code values representing [PhysicalKeyboardKey].

View File

@ -256,6 +256,9 @@ abstract class RawKeyEvent extends Diagnosticable {
plainCodePoint: message['plainCodePoint'] ?? 0, plainCodePoint: message['plainCodePoint'] ?? 0,
scanCode: message['scanCode'] ?? 0, scanCode: message['scanCode'] ?? 0,
metaState: message['metaState'] ?? 0, metaState: message['metaState'] ?? 0,
eventSource: message['source'] ?? 0,
vendorId: message['vendorId'] ?? 0,
productId: message['productId'] ?? 0,
); );
break; break;
case 'fuchsia': case 'fuchsia':

View File

@ -33,6 +33,9 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
this.keyCode = 0, this.keyCode = 0,
this.scanCode = 0, this.scanCode = 0,
this.metaState = 0, this.metaState = 0,
this.eventSource = 0,
this.vendorId = 0,
this.productId = 0,
}) : assert(flags != null), }) : assert(flags != null),
assert(codePoint != null), assert(codePoint != null),
assert(keyCode != null), assert(keyCode != null),
@ -105,12 +108,60 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
/// * [isMetaPressed], to see if a META key is pressed. /// * [isMetaPressed], to see if a META key is pressed.
final int metaState; final int metaState;
/// The source of the event.
///
/// See <https://developer.android.com/reference/android/view/KeyEvent.html#getSource()>
/// for the numerical values of the `source`. Many of these constants are also
/// replicated as static constants in this class.
final int eventSource;
/// The vendor ID of the device that produced the event.
///
/// See <https://developer.android.com/reference/android/view/InputDevice.html#getVendorId()>
/// for the numerical values of the `vendorId`.
final int vendorId;
/// The product ID of the device that produced the event.
///
/// See <https://developer.android.com/reference/android/view/InputDevice.html#getProductId()>
/// for the numerical values of the `productId`.
final int productId;
// The source code that indicates that an event came from a joystick.
// from https://developer.android.com/reference/android/view/InputDevice.html#SOURCE_JOYSTICK
static const int _sourceJoystick = 0x01000010;
// Android only reports a single code point for the key label. // Android only reports a single code point for the key label.
@override @override
String get keyLabel => plainCodePoint == 0 ? null : String.fromCharCode(plainCodePoint & _kCombiningCharacterMask); String get keyLabel => plainCodePoint == 0 ? null : String.fromCharCode(plainCodePoint & _kCombiningCharacterMask);
@override @override
PhysicalKeyboardKey get physicalKey => kAndroidToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none; PhysicalKeyboardKey get physicalKey {
if (kAndroidToPhysicalKey.containsKey(scanCode)) {
return kAndroidToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;
}
// Android sends DPAD_UP, etc. as the keyCode for joystick DPAD events, but
// it doesn't set the scanCode for those, so we have to detect this, and set
// our own DPAD physical keys. The logical key will still match "arrowUp",
// etc.
if (eventSource & _sourceJoystick == _sourceJoystick) {
final LogicalKeyboardKey foundKey = kAndroidToLogicalKey[keyCode];
if (foundKey == LogicalKeyboardKey.arrowUp) {
return PhysicalKeyboardKey.arrowUp;
}
if (foundKey == LogicalKeyboardKey.arrowDown) {
return PhysicalKeyboardKey.arrowDown;
}
if (foundKey == LogicalKeyboardKey.arrowLeft) {
return PhysicalKeyboardKey.arrowLeft;
}
if (foundKey == LogicalKeyboardKey.arrowRight) {
return PhysicalKeyboardKey.arrowRight;
}
}
return PhysicalKeyboardKey.none;
}
@override @override
LogicalKeyboardKey get logicalKey { LogicalKeyboardKey get logicalKey {

View File

@ -39,6 +39,7 @@ void main() {
'codePoint': 0x44, 'codePoint': 0x44,
'scanCode': 0x20, 'scanCode': 0x20,
'metaState': modifier, 'metaState': modifier,
'source': 0x101, // Keyboard source.
}); });
final RawKeyEventDataAndroid data = event.data; final RawKeyEventDataAndroid data = event.data;
for (ModifierKey key in ModifierKey.values) { for (ModifierKey key in ModifierKey.values) {
@ -73,6 +74,7 @@ void main() {
'codePoint': 0x44, 'codePoint': 0x44,
'scanCode': 0x20, 'scanCode': 0x20,
'metaState': modifier | RawKeyEventDataAndroid.modifierFunction, 'metaState': modifier | RawKeyEventDataAndroid.modifierFunction,
'source': 0x101, // Keyboard source.
}); });
final RawKeyEventDataAndroid data = event.data; final RawKeyEventDataAndroid data = event.data;
for (ModifierKey key in ModifierKey.values) { for (ModifierKey key in ModifierKey.values) {
@ -109,6 +111,7 @@ void main() {
'character': 'A', 'character': 'A',
'scanCode': 30, 'scanCode': 30,
'metaState': 0x0, 'metaState': 0x0,
'source': 0x101, // Keyboard source.
}); });
final RawKeyEventDataAndroid data = keyAEvent.data; final RawKeyEventDataAndroid data = keyAEvent.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA)); expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
@ -124,6 +127,7 @@ void main() {
'character': null, 'character': null,
'scanCode': 1, 'scanCode': 1,
'metaState': 0x0, 'metaState': 0x0,
'source': 0x101, // Keyboard source.
}); });
final RawKeyEventDataAndroid data = escapeKeyEvent.data; final RawKeyEventDataAndroid data = escapeKeyEvent.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape)); expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
@ -140,12 +144,64 @@ void main() {
'character': null, 'character': null,
'scanCode': 42, 'scanCode': 42,
'metaState': RawKeyEventDataAndroid.modifierLeftShift, 'metaState': RawKeyEventDataAndroid.modifierLeftShift,
'source': 0x101, // Keyboard source.
}); });
final RawKeyEventDataAndroid data = shiftLeftKeyEvent.data; final RawKeyEventDataAndroid data = shiftLeftKeyEvent.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft)); expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft)); expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull); expect(data.keyLabel, isNull);
}); });
test('DPAD keys from a joystick give physical key mappings', () {
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
'keymap': 'android',
'keyCode': 20,
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 0,
'metaState': 0,
'source': 0x1000010, // Joystick source.
});
final RawKeyEventDataAndroid data = joystickDpadDown.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
expect(data.keyLabel, isNull);
});
test('Arrow keys from a keyboard give correct physical key mappings', () {
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
'keymap': 'android',
'keyCode': 20,
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 108,
'metaState': 0,
'source': 0x101, // Keyboard source.
});
final RawKeyEventDataAndroid data = joystickDpadDown.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
expect(data.keyLabel, isNull);
});
test('DPAD center from a game pad gives physical key mappings', () {
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
'keymap': 'android',
'keyCode': 23, // DPAD_CENTER code.
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 317, // Left side thumb joystick center click button.
'metaState': 0,
'source': 0x501, // Gamepad and keyboard source.
});
final RawKeyEventDataAndroid data = joystickDpadCenter.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.gameButtonThumbLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.select));
expect(data.keyLabel, isNull);
});
}); });
group('RawKeyEventDataFuchsia', () { group('RawKeyEventDataFuchsia', () {
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{ const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{