Unverified Commit 8c3b826e authored by Robert Ancell's avatar Robert Ancell Committed by GitHub

Support GTK keycodes (#59961)

parent 8ae71a0e
...@@ -49,6 +49,11 @@ Future<String> getGlfwKeyCodes() async { ...@@ -49,6 +49,11 @@ Future<String> getGlfwKeyCodes() async {
return await http.read(keyCodesUri); return await http.read(keyCodesUri);
} }
Future<String> getGtkKeyCodes() async {
final Uri keyCodesUri = Uri.parse('https://gitlab.gnome.org/GNOME/gtk/-/raw/master/gdk/gdkkeysyms.h');
return await http.read(keyCodesUri);
}
Future<void> main(List<String> rawArguments) async { Future<void> main(List<String> rawArguments) async {
final ArgParser argParser = ArgParser(); final ArgParser argParser = ArgParser();
argParser.addOption( argParser.addOption(
...@@ -90,6 +95,13 @@ Future<void> main(List<String> rawArguments) async { ...@@ -90,6 +95,13 @@ Future<void> main(List<String> rawArguments) async {
'If --glfw-keycodes is not specified, the input will be read from the ' 'If --glfw-keycodes is not specified, the input will be read from the '
'correct file in the GLFW github repository.', 'correct file in the GLFW github repository.',
); );
argParser.addOption(
'gtk-keycodes',
defaultsTo: null,
help: 'The path to where the GTK keycodes header file should be read. '
'If --gtk-keycodes is not specified, the input will be read from the '
'correct file in the GTK repository.',
);
argParser.addOption( argParser.addOption(
'windows-keycodes', 'windows-keycodes',
defaultsTo: null, defaultsTo: null,
...@@ -107,6 +119,11 @@ Future<void> main(List<String> rawArguments) async { ...@@ -107,6 +119,11 @@ Future<void> main(List<String> rawArguments) async {
defaultsTo: path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'key_name_to_glfw_name.json'), defaultsTo: path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'key_name_to_glfw_name.json'),
help: 'The path to where the GLFW keycode to DomKey mapping is.', help: 'The path to where the GLFW keycode to DomKey mapping is.',
); );
argParser.addOption(
'gtk-domkey',
defaultsTo: path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'key_name_to_gtk_name.json'),
help: 'The path to where the GTK keycode to DomKey mapping is.',
);
argParser.addOption( argParser.addOption(
'data', 'data',
defaultsTo: path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'key_data.json'), defaultsTo: path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'key_data.json'),
...@@ -187,6 +204,13 @@ Future<void> main(List<String> rawArguments) async { ...@@ -187,6 +204,13 @@ Future<void> main(List<String> rawArguments) async {
glfwKeyCodes = File(parsedArguments['glfw-keycodes'] as String).readAsStringSync(); glfwKeyCodes = File(parsedArguments['glfw-keycodes'] as String).readAsStringSync();
} }
String gtkKeyCodes;
if (parsedArguments['gtk-keycodes'] == null) {
gtkKeyCodes = await getGtkKeyCodes();
} else {
gtkKeyCodes = File(parsedArguments['gtk-keycodes'] as String).readAsStringSync();
}
String windowsKeyCodes; String windowsKeyCodes;
if (parsedArguments['windows-keycodes'] == null) { if (parsedArguments['windows-keycodes'] == null) {
windowsKeyCodes = await getWindowsKeyCodes(); windowsKeyCodes = await getWindowsKeyCodes();
...@@ -196,9 +220,10 @@ Future<void> main(List<String> rawArguments) async { ...@@ -196,9 +220,10 @@ Future<void> main(List<String> rawArguments) async {
final String windowsToDomKey = File(parsedArguments['windows-domkey'] as String).readAsStringSync(); final String windowsToDomKey = File(parsedArguments['windows-domkey'] as String).readAsStringSync();
final String glfwToDomKey = File(parsedArguments['glfw-domkey'] as String).readAsStringSync(); final String glfwToDomKey = File(parsedArguments['glfw-domkey'] as String).readAsStringSync();
final String gtkToDomKey = File(parsedArguments['gtk-domkey'] as String).readAsStringSync();
final String androidToDomKey = File(parsedArguments['android-domkey'] as String).readAsStringSync(); final String androidToDomKey = File(parsedArguments['android-domkey'] as String).readAsStringSync();
data = KeyData(hidCodes, androidScanCodes, androidKeyCodes, androidToDomKey, glfwKeyCodes, glfwToDomKey, windowsKeyCodes, windowsToDomKey); data = KeyData(hidCodes, androidScanCodes, androidKeyCodes, androidToDomKey, glfwKeyCodes, glfwToDomKey, gtkKeyCodes, gtkToDomKey, windowsKeyCodes, windowsToDomKey);
const JsonEncoder encoder = JsonEncoder.withIndent(' '); const JsonEncoder encoder = JsonEncoder.withIndent(' ');
File(parsedArguments['data'] as String).writeAsStringSync(encoder.convert(data.toJson())); File(parsedArguments['data'] as String).writeAsStringSync(encoder.convert(data.toJson()));
...@@ -221,7 +246,7 @@ Future<void> main(List<String> rawArguments) async { ...@@ -221,7 +246,7 @@ Future<void> main(List<String> rawArguments) async {
await mapsFile.writeAsString(generator.generateKeyboardMaps()); await mapsFile.writeAsString(generator.generateKeyboardMaps());
final CcCodeGenerator ccCodeGenerator = CcCodeGenerator(data); final CcCodeGenerator ccCodeGenerator = CcCodeGenerator(data);
for (final String platform in <String>['android', 'darwin', 'glfw', 'fuchsia', 'linux', 'windows']) { for (final String platform in <String>['android', 'darwin', 'glfw', 'gtk', 'fuchsia', 'linux', 'windows']) {
final File platformFile = File(path.join(flutterRoot.path, '..', path.join('engine', 'src', 'flutter', 'shell', 'platform', platform, 'keycodes', 'keyboard_map_$platform.h'))); final File platformFile = File(path.join(flutterRoot.path, '..', path.join('engine', 'src', 'flutter', 'shell', 'platform', platform, 'keycodes', 'keyboard_map_$platform.h')));
if (!platformFile.existsSync()) { if (!platformFile.existsSync()) {
platformFile.createSync(recursive: true); platformFile.createSync(recursive: true);
......
This diff is collapsed.
{
"altLeft": ["Alt_L"],
"altRight": ["Alt_R"],
"arrowDown": ["Down", "KP_Down"],
"arrowLeft": ["Left", "KP_Left"],
"arrowRight": ["Right", "KP_Right"],
"arrowUp": ["Up", "KP_Up"],
"audioVolumeDown": ["AudioLowerVolume"],
"audioVolumeMute": ["AudioMute"],
"audioVolumeUp": ["AudioRaiseVolume"],
"backquote": ["quoteleft"],
"backslash": ["backslash"],
"backspace": ["BackSpace"],
"bracketLeft": ["bracketleft"],
"bracketRight": ["bracketright"],
"brightnessDown": ["MonBrightnessDown"],
"brightnessUp": ["MonBrightnessUp"],
"browserBack": ["Back"],
"browserFavorites": ["Favorites"],
"browserFavourites": ["Favourites"],
"browserForward": ["Forward"],
"browserHome": ["HomePage"],
"browserRefresh": ["Refresh"],
"browserSearch": ["Search"],
"browserStop": ["Stop"],
"capsLock": ["Caps_Lock"],
"close": ["Close"],
"comma": ["comma"],
"contextMenu": ["Menu"],
"controlLeft": ["Control_L"],
"controlRight": ["Control_R"],
"copy": ["Copy", "3270_Copy"],
"delete": ["Delete", "KP_Delete"],
"digit0": ["0"],
"digit1": ["1"],
"digit2": ["2"],
"digit3": ["3"],
"digit4": ["4"],
"digit5": ["5"],
"digit6": ["6"],
"digit7": ["7"],
"digit8": ["8"],
"digit9": ["9"],
"eject": ["Eject"],
"end": ["End", "KP_End"],
"enter": ["Return", "Enter"],
"equal": ["equal"],
"escape": ["Escape"],
"f1": ["F1", "KP_F1"],
"f2": ["F2", "KP_F2"],
"f3": ["F3", "KP_F3"],
"f4": ["F4", "KP_F4"],
"f5": ["F5"],
"f6": ["F6"],
"f7": ["F7"],
"f8": ["F8"],
"f9": ["F9"],
"f10": ["F10"],
"f11": ["F11"],
"f12": ["F12"],
"f13": ["F13"],
"f14": ["F14"],
"f15": ["F15"],
"f16": ["F16"],
"f17": ["F17"],
"f18": ["F18"],
"f19": ["F19"],
"f20": ["F20"],
"f21": ["F21"],
"f22": ["F22"],
"f23": ["F23"],
"f24": ["F24"],
"f25": ["F25"],
"find": ["Find"],
"help": ["Help"],
"home": ["Home", "KP_Home"],
"hyper": ["Hyper_L", "Hyper_R"],
"insert": ["Insert", "KP_Insert"],
"intlYen": ["yen"],
"kanaMode": ["kana_switch"],
"kbdIllumDown": ["KbdBrightnessDown"],
"kbdIllumUp": ["KbdBrightnessUp"],
"keyA": ["A"],
"keyB": ["B"],
"keyC": ["C"],
"keyD": ["D"],
"keyE": ["E"],
"keyF": ["F"],
"keyG": ["G"],
"keyH": ["H"],
"keyI": ["I"],
"keyJ": ["J"],
"keyK": ["K"],
"keyL": ["L"],
"keyM": ["M"],
"keyN": ["N"],
"keyO": ["O"],
"keyP": ["P"],
"keyQ": ["Q"],
"keyR": ["R"],
"keyS": ["S"],
"keyT": ["T"],
"keyU": ["U"],
"keyV": ["V"],
"keyW": ["W"],
"keyX": ["X"],
"keyY": ["Y"],
"keyZ": ["Z"],
"launchAudioBrowser": ["Music"],
"launchCalendar": ["Calendar"],
"launchDocuments": ["Document"],
"launchInternetBrowser": ["WWW"],
"launchMail": ["Mail"],
"launchPhone": ["Phone"],
"launchScreenSaver": ["ScreenSaver"],
"logOff": ["LogOff"],
"mailForward": ["MailForward"],
"mailReply": ["Reply"],
"mailSend": ["Send"],
"mediaFastForward": ["AudioForward"],
"mediaPause": ["AudioPause"],
"mediaPlay": ["AudioPlay", "3270_Play"],
"mediaRecord": ["AudioRecord"],
"mediaRewind": ["AudioRewind"],
"mediaStop": ["AudioStop"],
"mediaTrackNext": ["AudioNext"],
"mediaTrackPrevious": ["AudioPrev"],
"metaLeft": ["Meta_L"],
"metaRight": ["Meta_R"],
"minus": ["minus"],
"newKey": ["New"],
"numLock": ["Num_Lock"],
"numpad0": ["KP_0"],
"numpad1": ["KP_1"],
"numpad2": ["KP_2"],
"numpad3": ["KP_3"],
"numpad4": ["KP_4"],
"numpad5": ["KP_5"],
"numpad6": ["KP_6"],
"numpad7": ["KP_7"],
"numpad8": ["KP_8"],
"numpad9": ["KP_9"],
"numpadAdd": ["KP_Add"],
"numpadDecimal": ["KP_Decimal"],
"numpadDivide": ["KP_Divide"],
"numpadEnter": ["KP_Enter"],
"numpadEqual": ["KP_Equal"],
"numpadMultiply": ["KP_Multiply"],
"numpadSubtract": ["KP_Subtract"],
"open": ["Open"],
"pageDown": ["Page_Down", "KP_Page_Down"],
"pageUp": ["Page_Up", "KP_Page_Up"],
"paste": ["Paste"],
"pause": ["Pause"],
"period": ["period"],
"power": ["PowerOff"],
"print": ["Print"],
"printScreen": ["3270_PrintScreen"],
"quote": ["apostrophe"],
"redo": ["Redo"],
"resume": ["Resume"],
"save": ["Save"],
"scrollLock": ["Scroll_Lock"],
"select": ["Select"],
"semicolon": ["semicolon"],
"shiftLeft": ["Shift_L"],
"shiftRight": ["Shift_R"],
"slash": ["slash"],
"sleep": ["Sleep"],
"space": ["space", "KP_Space"],
"spellCheck": ["Spell"],
"superKey": ["Super_L", "Super_R"],
"suspend": ["Suspend"],
"tab": ["Tab", "KP_Tab"],
"undo": ["Undo"],
"wakeUp": ["WakeUp"],
"zoomIn": ["ZoomIn"],
"zoomOut": ["ZoomOut"]
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <map>
// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
// This file is generated by flutter/flutter@dev/tools/gen_keycodes/bin/gen_keycodes.dart and
// should not be edited directly.
//
// Edit the template dev/tools/gen_keycodes/data/keyboard_maps_gtk_cxx.tmpl instead.
// See dev/tools/gen_keycodes/README.md for more information.
/// Maps GTK-specific key codes to the matching [LogicalKeyboardKey].
const std::map<int, int> g_gtk_to_logical_key = {
@@@GTK_KEY_CODE_MAP@@@
};
/// A map of GTK key codes which have printable representations, but appear
/// on the number pad. Used to provide different key objects for keys like
/// KEY_EQUALS and NUMPAD_EQUALS.
const std::map<int, int> g_gtk_numpad_map = {
@@@GTK_NUMPAD_MAP@@@
};
...@@ -71,6 +71,18 @@ const Map<int, LogicalKeyboardKey> kGlfwNumpadMap = <int, LogicalKeyboardKey>{ ...@@ -71,6 +71,18 @@ const Map<int, LogicalKeyboardKey> kGlfwNumpadMap = <int, LogicalKeyboardKey>{
@@@GLFW_NUMPAD_MAP@@@ @@@GLFW_NUMPAD_MAP@@@
}; };
/// Maps GTK-specific key codes to the matching [LogicalKeyboardKey].
const Map<int, LogicalKeyboardKey> kGtkToLogicalKey = <int, LogicalKeyboardKey>{
@@@GTK_KEY_CODE_MAP@@@
};
/// A map of GTK key codes which have printable representations, but appear
/// on the number pad. Used to provide different key objects for keys like
/// KEY_EQUALS and NUMPAD_EQUALS.
const Map<int, LogicalKeyboardKey> kGtkNumpadMap = <int, LogicalKeyboardKey>{
@@@GTK_NUMPAD_MAP@@@
};
/// Maps XKB specific key code values representing [PhysicalKeyboardKey]. /// Maps XKB specific key code values representing [PhysicalKeyboardKey].
const Map<int, PhysicalKeyboardKey> kLinuxToPhysicalKey = <int, PhysicalKeyboardKey>{ const Map<int, PhysicalKeyboardKey> kLinuxToPhysicalKey = <int, PhysicalKeyboardKey>{
@@@XKB_SCAN_CODE_MAP@@@ @@@XKB_SCAN_CODE_MAP@@@
......
...@@ -175,6 +175,32 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK ...@@ -175,6 +175,32 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
return glfwKeyCodeMap.toString().trimRight(); return glfwKeyCodeMap.toString().trimRight();
} }
/// This generates the map of GTK number pad key codes to logical keys.
String get gtkNumpadMap {
final StringBuffer gtkNumpadMap = StringBuffer();
for (final Key entry in numpadKeyData) {
if (entry.gtkKeyCodes != null) {
for (final int code in entry.gtkKeyCodes.cast<int>()) {
gtkNumpadMap.writeln(' $code: LogicalKeyboardKey.${entry.constantName},');
}
}
}
return gtkNumpadMap.toString().trimRight();
}
/// This generates the map of GTK key codes to logical keys.
String get gtkKeyCodeMap {
final StringBuffer gtkKeyCodeMap = StringBuffer();
for (final Key entry in keyData.data) {
if (entry.gtkKeyCodes != null) {
for (final int code in entry.gtkKeyCodes.cast<int>()) {
gtkKeyCodeMap.writeln(' $code: LogicalKeyboardKey.${entry.constantName},');
}
}
}
return gtkKeyCodeMap.toString().trimRight();
}
/// This generates the map of XKB USB HID codes to physical keys. /// This generates the map of XKB USB HID codes to physical keys.
String get xkbScanCodeMap { String get xkbScanCodeMap {
final StringBuffer xkbScanCodeMap = StringBuffer(); final StringBuffer xkbScanCodeMap = StringBuffer();
...@@ -414,6 +440,8 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK ...@@ -414,6 +440,8 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
'MACOS_FUNCTION_KEY_MAP': macOsFunctionKeyMap, 'MACOS_FUNCTION_KEY_MAP': macOsFunctionKeyMap,
'GLFW_KEY_CODE_MAP': glfwKeyCodeMap, 'GLFW_KEY_CODE_MAP': glfwKeyCodeMap,
'GLFW_NUMPAD_MAP': glfwNumpadMap, 'GLFW_NUMPAD_MAP': glfwNumpadMap,
'GTK_KEY_CODE_MAP': gtkKeyCodeMap,
'GTK_NUMPAD_MAP': gtkNumpadMap,
'XKB_SCAN_CODE_MAP': xkbScanCodeMap, 'XKB_SCAN_CODE_MAP': xkbScanCodeMap,
'WEB_LOGICAL_KEY_MAP': webLogicalKeyMap, 'WEB_LOGICAL_KEY_MAP': webLogicalKeyMap,
'WEB_PHYSICAL_KEY_MAP': webPhysicalKeyMap, 'WEB_PHYSICAL_KEY_MAP': webPhysicalKeyMap,
......
...@@ -28,6 +28,8 @@ class KeyData { ...@@ -28,6 +28,8 @@ class KeyData {
String androidNameMap, String androidNameMap,
String glfwKeyCodeHeader, String glfwKeyCodeHeader,
String glfwNameMap, String glfwNameMap,
String gtkKeyCodeHeader,
String gtkNameMap,
String windowsKeyCodeHeader, String windowsKeyCodeHeader,
String windowsNameMap, String windowsNameMap,
) : assert(chromiumHidCodes != null), ) : assert(chromiumHidCodes != null),
...@@ -36,11 +38,14 @@ class KeyData { ...@@ -36,11 +38,14 @@ class KeyData {
assert(androidNameMap != null), assert(androidNameMap != null),
assert(glfwKeyCodeHeader != null), assert(glfwKeyCodeHeader != null),
assert(glfwNameMap != null), assert(glfwNameMap != null),
assert(gtkKeyCodeHeader != null),
assert(gtkNameMap != null),
assert(windowsKeyCodeHeader != null), assert(windowsKeyCodeHeader != null),
assert(windowsNameMap != null) { assert(windowsNameMap != null) {
_nameToAndroidScanCodes = _readAndroidScanCodes(androidKeyboardLayout); _nameToAndroidScanCodes = _readAndroidScanCodes(androidKeyboardLayout);
_nameToAndroidKeyCode = _readAndroidKeyCodes(androidKeyCodeHeader); _nameToAndroidKeyCode = _readAndroidKeyCodes(androidKeyCodeHeader);
_nameToGlfwKeyCode = _readGlfwKeyCodes(glfwKeyCodeHeader); _nameToGlfwKeyCode = _readGlfwKeyCodes(glfwKeyCodeHeader);
_nameToGtkKeyCode = _readGtkKeyCodes(gtkKeyCodeHeader);
_nameToWindowsKeyCode = _readWindowsKeyCodes(windowsKeyCodeHeader); _nameToWindowsKeyCode = _readWindowsKeyCodes(windowsKeyCodeHeader);
// Cast Android dom map // Cast Android dom map
final Map<String, List<dynamic>> dynamicAndroidNames = (json.decode(androidNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>(); final Map<String, List<dynamic>> dynamicAndroidNames = (json.decode(androidNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>();
...@@ -52,6 +57,11 @@ class KeyData { ...@@ -52,6 +57,11 @@ class KeyData {
_nameToGlfwName = dynamicGlfwNames.map<String, List<String>>((String key, List<dynamic> value) { _nameToGlfwName = dynamicGlfwNames.map<String, List<String>>((String key, List<dynamic> value) {
return MapEntry<String, List<String>>(key, value.cast<String>()); return MapEntry<String, List<String>>(key, value.cast<String>());
}); });
// Cast GTK dom map
final Map<String, List<dynamic>> dynamicGtkNames = (json.decode(gtkNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>();
_nameToGtkName = dynamicGtkNames.map<String, List<String>>((String key, List<dynamic> value) {
return MapEntry<String, List<String>>(key, value.cast<String>());
});
// Cast Windows dom map // Cast Windows dom map
final Map<String, List<dynamic>> dynamicWindowsNames = (json.decode(windowsNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>(); final Map<String, List<dynamic>> dynamicWindowsNames = (json.decode(windowsNameMap) as Map<String, dynamic>).cast<String, List<dynamic>>();
_nameToWindowsName = dynamicWindowsNames.map<String, List<String>>((String key, List<dynamic> value) { _nameToWindowsName = dynamicWindowsNames.map<String, List<String>>((String key, List<dynamic> value) {
...@@ -97,6 +107,17 @@ class KeyData { ...@@ -97,6 +107,17 @@ class KeyData {
} }
} }
// GTK key names
entry.gtkKeyNames = _nameToGtkName[entry.constantName]?.cast<String>();
if (entry.gtkKeyNames != null && entry.gtkKeyNames.isNotEmpty) {
for (final String gtkKeyName in entry.gtkKeyNames) {
if (_nameToGtkKeyCode[gtkKeyName] != null) {
entry.gtkKeyCodes ??= <int>[];
entry.gtkKeyCodes.add(_nameToGtkKeyCode[gtkKeyName]);
}
}
}
// Windows key names // Windows key names
entry.windowsKeyNames = _nameToWindowsName[entry.constantName]?.cast<String>(); entry.windowsKeyNames = _nameToWindowsName[entry.constantName]?.cast<String>();
if (entry.windowsKeyNames != null && entry.windowsKeyNames.isNotEmpty) { if (entry.windowsKeyNames != null && entry.windowsKeyNames.isNotEmpty) {
...@@ -133,6 +154,13 @@ class KeyData { ...@@ -133,6 +154,13 @@ class KeyData {
/// JSON. /// JSON.
Map<String, List<String>> _nameToGlfwName; Map<String, List<String>> _nameToGlfwName;
/// The mapping from the Flutter name (e.g. "eject") to the GTK name (e.g.
/// "GDK_KEY_Eject").
///
/// Only populated if data is parsed from the source files, not if parsed from
/// JSON.
Map<String, List<String>> _nameToGtkName;
/// The mapping from the Android name (e.g. "MEDIA_EJECT") to the integer scan /// The mapping from the Android name (e.g. "MEDIA_EJECT") to the integer scan
/// code (physical location) of the key. /// code (physical location) of the key.
/// ///
...@@ -154,6 +182,13 @@ class KeyData { ...@@ -154,6 +182,13 @@ class KeyData {
/// JSON. /// JSON.
Map<String, int> _nameToGlfwKeyCode; Map<String, int> _nameToGlfwKeyCode;
/// The mapping from GTK name (e.g. "GTK_KEY_comma") to the integer key code
/// (logical meaning) of the key.
///
/// Only populated if data is parsed from the source files, not if parsed from
/// JSON.
Map<String, int> _nameToGtkKeyCode;
/// The mapping from Widows name (e.g. "RETURN") to the integer key code /// The mapping from Widows name (e.g. "RETURN") to the integer key code
/// (logical meaning) of the key. /// (logical meaning) of the key.
/// ///
...@@ -244,6 +279,20 @@ class KeyData { ...@@ -244,6 +279,20 @@ class KeyData {
return result; return result;
} }
/// Parses entries from GTK's gdkkeysyms.h key code data file.
///
/// Lines in this file look like this (without the ///):
/// /** Space key. */
/// #define GDK_KEY_space 0x020
Map<String, int> _readGtkKeyCodes(String headerFile) {
final RegExp definedCodes = RegExp(r'#define GDK_KEY_([a-zA-Z0-9_]+)\s*0x([0-9a-f]+),?');
final Map<String, int> replaced = <String, int>{};
for (final Match match in definedCodes.allMatches(headerFile)) {
replaced[match.group(1)] = int.parse(match.group(2), radix: 16);
}
return replaced;
}
Map<String, int> _readWindowsKeyCodes(String headerFile) { Map<String, int> _readWindowsKeyCodes(String headerFile) {
final RegExp definedCodes = RegExp(r'define VK_([A-Z0-9_]+)\s*([A-Z0-9_x]+),?'); final RegExp definedCodes = RegExp(r'define VK_([A-Z0-9_]+)\s*([A-Z0-9_x]+),?');
final Map<String, int> replaced = <String, int>{}; final Map<String, int> replaced = <String, int>{};
...@@ -332,6 +381,8 @@ class Key { ...@@ -332,6 +381,8 @@ class Key {
this.androidKeyCodes, this.androidKeyCodes,
this.glfwKeyNames, this.glfwKeyNames,
this.glfwKeyCodes, this.glfwKeyCodes,
this.gtkKeyNames,
this.gtkKeyCodes,
}) : assert(usbHidCode != null), }) : assert(usbHidCode != null),
assert(chromiumName != null), assert(chromiumName != null),
_constantName = enumName; _constantName = enumName;
...@@ -354,6 +405,8 @@ class Key { ...@@ -354,6 +405,8 @@ class Key {
macOsScanCode: map['scanCodes']['macos'] as int, macOsScanCode: map['scanCodes']['macos'] as int,
glfwKeyNames: (map['names']['glfw'] as List<dynamic>)?.cast<String>(), glfwKeyNames: (map['names']['glfw'] as List<dynamic>)?.cast<String>(),
glfwKeyCodes: (map['keyCodes']['glfw'] as List<dynamic>)?.cast<int>(), glfwKeyCodes: (map['keyCodes']['glfw'] as List<dynamic>)?.cast<int>(),
gtkKeyNames: (map['names']['gtk'] as List<dynamic>)?.cast<String>(),
gtkKeyCodes: (map['keyCodes']['gtk'] as List<dynamic>)?.cast<int>(),
); );
} }
...@@ -402,6 +455,15 @@ class Key { ...@@ -402,6 +455,15 @@ class Key {
/// value. /// value.
List<int> glfwKeyCodes; List<int> glfwKeyCodes;
/// The list of names that GTK gives to this key (symbol names minus the
/// prefix).
List<String> gtkKeyNames;
/// The list of GTK key codes matching this key, created by looking up the
/// Linux name in the GTK data, and substituting the GTK key code
/// value.
List<int> gtkKeyCodes;
/// Creates a JSON map from the key data. /// Creates a JSON map from the key data.
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return <String, dynamic>{ return <String, dynamic>{
...@@ -411,6 +473,7 @@ class Key { ...@@ -411,6 +473,7 @@ class Key {
'english': commentName, 'english': commentName,
'chromium': chromiumName, 'chromium': chromiumName,
'glfw': glfwKeyNames, 'glfw': glfwKeyNames,
'gtk': gtkKeyNames,
'windows': windowsKeyNames, 'windows': windowsKeyNames,
}, },
'scanCodes': <String, dynamic>{ 'scanCodes': <String, dynamic>{
...@@ -424,6 +487,7 @@ class Key { ...@@ -424,6 +487,7 @@ class Key {
'keyCodes': <String, List<int>>{ 'keyCodes': <String, List<int>>{
'android': androidKeyCodes, 'android': androidKeyCodes,
'glfw': glfwKeyCodes, 'glfw': glfwKeyCodes,
'gtk': gtkKeyCodes,
'windows': windowsKeyCodes, 'windows': windowsKeyCodes,
}, },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment