diff --git a/src/Emulator/Main/Peripherals/Input/KeyScanCode.cs b/src/Emulator/Main/Peripherals/Input/KeyScanCode.cs
index 469b09d12..e3e168b6c 100644
--- a/src/Emulator/Main/Peripherals/Input/KeyScanCode.cs
+++ b/src/Emulator/Main/Peripherals/Input/KeyScanCode.cs
@@ -83,7 +83,7 @@ public enum KeyScanCode
OemSemicolon = 0x33,
OemQuotes = 0x34,
CapsLock = 0x39,
- OemPeriod= 0x36,
+ OemPeriod = 0x36,
OemComma = 0x37,
OemQuestion = 0x38,
NumLock = 0x53,
diff --git a/src/UI/UI.csproj b/src/UI/UI.csproj
index 0ae9f9d68..134f01e8b 100644
--- a/src/UI/UI.csproj
+++ b/src/UI/UI.csproj
@@ -86,6 +86,7 @@
+
diff --git a/src/UI/VideoAnalyzer/Events/OSXToKeyScanCodeConverter.cs b/src/UI/VideoAnalyzer/Events/OSXToKeyScanCodeConverter.cs
new file mode 100644
index 000000000..e05bb6131
--- /dev/null
+++ b/src/UI/VideoAnalyzer/Events/OSXToKeyScanCodeConverter.cs
@@ -0,0 +1,331 @@
+//
+// Copyright (c) 2010-2018 Antmicro
+// Copyright (c) 2011-2015 Realtime Embedded
+//
+// This file is licensed under the MIT License.
+// Full license text is available in 'licenses/MIT.txt'.
+//
+using Antmicro.Renode.Peripherals.Input;
+using System.Collections.Generic;
+using Xwt;
+
+namespace Antmicro.Renode.Extensions.Analyzers.Video.Events
+{
+ internal class OSXToKeyScanCodeConverter
+ {
+ static OSXToKeyScanCodeConverter()
+ {
+ Instance = new OSXToKeyScanCodeConverter();
+ }
+
+ public static OSXToKeyScanCodeConverter Instance { get; private set; }
+
+ public KeyScanCode? GetScanCode(Key key)
+ {
+ KeyScanCode result;
+ return UntranslatedScanCode.TryGetValue(key, out result) ? (KeyScanCode?)result : null;
+ }
+
+ /*
+ keycode: BackQuote 96 entryKey: 50
+ keycode: K1 49 entryKey: 18
+ keycode: K2 50 entryKey: 19
+ keycode: K3 51 entryKey: 20
+ keycode: K4 52 entryKey: 21
+ keycode: K5 53 entryKey: 23
+ keycode: K6 54 entryKey: 22
+ keycode: K7 55 entryKey: 26
+ keycode: K8 56 entryKey: 28
+ keycode: K9 57 entryKey: 25
+ keycode: K0 48 entryKey: 29
+ keycode: Minus 45 entryKey: 27
+ keycode: 61 61 entryKey: 24
+ keycode: BackSpace 65288 entryKey: 51
+ keycode: Tab 65289 entryKey: 48
+ keycode: q 113 entryKey: 12
+ keycode: w 119 entryKey: 13
+ keycode: e 101 entryKey: 14
+ keycode: r 114 entryKey: 15
+ keycode: t 116 entryKey: 17
+ keycode: y 121 entryKey: 16
+ keycode: u 117 entryKey: 32
+ keycode: i 105 entryKey: 34
+ keycode: o 111 entryKey: 31
+ keycode: p 112 entryKey: 35
+ keycode: OpenSquareBracket 91 entryKey: 33
+ keycode: CloseSquareBracket 93 entryKey: 30
+ keycode: Backslash 92 entryKey: 42
+ keycode: Escape 65307 entryKey: 53
+ keycode: a 97 entryKey: 0
+ keycode: s 115 entryKey: 1
+ keycode: d 100 entryKey: 2
+ keycode: f 102 entryKey: 3
+ keycode: g 103 entryKey: 5
+ keycode: h 104 entryKey: 4
+ keycode: j 106 entryKey: 38
+ keycode: k 107 entryKey: 40
+ keycode: l 108 entryKey: 37
+ keycode: Semicolon 59 entryKey: 41
+ keycode: SingleQuote 39 entryKey: 39
+ keycode: Return 65293 entryKey: 36
+ keycode: ShiftLeft 65505 entryKey: 56
+ keycode: ShiftLeft 65505 entryKey: 56
+ keycode: ShiftLeft 65505 entryKey: 56
+ keycode: z 122 entryKey: 6
+ keycode: x 120 entryKey: 7
+ keycode: c 99 entryKey: 8
+ keycode: v 118 entryKey: 9
+ keycode: b 98 entryKey: 11
+ keycode: n 110 entryKey: 45
+ keycode: m 109 entryKey: 46
+ keycode: Comma 44 entryKey: 43
+ keycode: Period 46 entryKey: 47
+ keycode: Slash 47 entryKey: 44
+ keycode: ShiftRight 65506 entryKey: 60
+ keycode: ControlLeft 65507 entryKey: 59
+ keycode: MetaLeft 65511 entryKey: 55
+ keycode: AltLeft 65513 entryKey: 58
+ keycode: Space 32 entryKey: 49
+ keycode: AltRight 65514 entryKey: 61
+ keycode: 16777232 16777232 entryKey: 108
+ keycode: ControlRight 65508 entryKey: 62
+ keycode: ShiftLeft 65505 entryKey: 56
+ keycode: Tilde 126 entryKey: 50
+ keycode: ShiftLeft 65505 entryKey: 56
+ keycode: Exclamation 33 entryKey: 18
+ keycode: At 64 entryKey: 19
+ keycode: Hash 35 entryKey: 20
+ keycode: Dollar 36 entryKey: 21
+ keycode: Percent 37 entryKey: 23
+ keycode: 94 94 entryKey: 22
+ keycode: Ampersand 38 entryKey: 26
+ keycode: Asterisk 42 entryKey: 28
+ keycode: LeftBracket 40 entryKey: 25
+ keycode: RightBracket 41 entryKey: 29
+ keycode: Underscore 95 entryKey: 27
+ keycode: Plus 43 entryKey: 24
+ keycode: BackSpace 65288 entryKey: 51
+ keycode: 65056 65056 entryKey: 48
+ keycode: Q 81 entryKey: 12
+ keycode: W 87 entryKey: 13
+ keycode: E 69 entryKey: 14
+ keycode: R 82 entryKey: 15
+ keycode: T 84 entryKey: 17
+ keycode: Y 89 entryKey: 16
+ keycode: U 85 entryKey: 32
+ keycode: I 73 entryKey: 34
+ keycode: O 79 entryKey: 31
+ keycode: P 80 entryKey: 35
+ keycode: OpenCurlyBracket 123 entryKey: 33
+ keycode: CloseCurlyBracket 125 entryKey: 30
+ keycode: Pipe 124 entryKey: 42
+ keycode: Escape 65307 entryKey: 53
+ keycode: A 65 entryKey: 0
+ keycode: S 83 entryKey: 1
+ keycode: D 68 entryKey: 2
+ keycode: F 70 entryKey: 3
+ keycode: G 71 entryKey: 5
+ keycode: H 72 entryKey: 4
+ keycode: J 74 entryKey: 38
+ keycode: K 75 entryKey: 40
+ keycode: L 76 entryKey: 37
+ keycode: Colon 58 entryKey: 41
+ keycode: Quote 34 entryKey: 39
+ keycode: Return 65293 entryKey: 36
+ keycode: Z 90 entryKey: 6
+ keycode: X 88 entryKey: 7
+ keycode: C 67 entryKey: 8
+ keycode: V 86 entryKey: 9
+ keycode: B 66 entryKey: 11
+ keycode: N 78 entryKey: 45
+ keycode: M 77 entryKey: 46
+ keycode: Less 60 entryKey: 43
+ keycode: Greater 62 entryKey: 47
+ keycode: Question 63 entryKey: 44
+ keycode: ShiftRight 65506 entryKey: 60
+ keycode: ShiftRight 65506 entryKey: 60
+ keycode: ControlLeft 65507 entryKey: 59
+ keycode: MetaLeft 65511 entryKey: 55
+ keycode: Left 65361 entryKey: 70
+ keycode: Up 65362 entryKey: 77
+ keycode: Right 65363 entryKey: 66
+ keycode: Down 65364 entryKey: 72
+ keycode: 16777221 16777221 entryKey: 114
+ keycode: Home 65360 entryKey: 115
+ keycode: PageUp 65365 entryKey: 116
+ keycode: Delete 65535 entryKey: 117
+ keycode: End 65367 entryKey: 119
+ keycode: PageDown 65366 entryKey: 121
+ keycode: NumPadDivide 65455 entryKey: 75
+ keycode: NumPadMultiply 65450 entryKey: 67
+ keycode: NumPadSubtract 65453 entryKey: 78
+ keycode: NumPad7 65463 entryKey: 89
+ keycode: NumPad8 65464 entryKey: 91
+ keycode: NumPad9 65465 entryKey: 92
+ keycode: NumPadAdd 65451 entryKey: 69
+ keycode: NumPad4 65460 entryKey: 86
+ keycode: NumPad5 65461 entryKey: 87
+ keycode: NumPad6 65462 entryKey: 88
+ keycode: NumPad1 65457 entryKey: 83
+ keycode: NumPad2 65458 entryKey: 84
+ keycode: NumPad3 65459 entryKey: 85
+ keycode: NumPad0 65456 entryKey: 82
+ keycode: NumPadEnter 65421 entryKey: 76
+ keycode: NumPadDecimal 65454 entryKey: 65
+ keycode: NumPadEnter 65421 entryKey: 76
+ keycode: F1 65470 entryKey: 122
+ keycode: F2 65471 entryKey: 120
+ keycode: F3 65472 entryKey: 99
+ keycode: F4 65473 entryKey: 118
+ keycode: F5 65474 entryKey: 96
+ keycode: F6 65475 entryKey: 97
+ keycode: F7 65476 entryKey: 98
+ keycode: F8 65477 entryKey: 100
+ keycode: F9 65478 entryKey: 101
+ keycode: F10 65479 entryKey: 109
+ keycode: 65481 65481 entryKey: 111
+ keycode: Escape 65307 entryKey: 53
+ */
+ private readonly Dictionary UntranslatedScanCode = new Dictionary
+ {
+ { Key.AltLeft, KeyScanCode.AltL },
+ { Key.MetaLeft, KeyScanCode.WinL },
+ { Key.Space, KeyScanCode.Space },
+ { Key.AltRight, KeyScanCode.AltR },
+ { Key.MetaRight, KeyScanCode.WinR },
+ { Key.Menu, KeyScanCode.WinMenu },
+ { Key.Z, KeyScanCode.Z },
+ { Key.z, KeyScanCode.Z },
+ { Key.X, KeyScanCode.X },
+ { Key.x, KeyScanCode.X },
+ { Key.C, KeyScanCode.C },
+ { Key.c, KeyScanCode.C },
+ { Key.V, KeyScanCode.V },
+ { Key.v, KeyScanCode.V },
+ { Key.B, KeyScanCode.B },
+ { Key.b, KeyScanCode.B },
+ { Key.N, KeyScanCode.N },
+ { Key.n, KeyScanCode.N },
+ { Key.M, KeyScanCode.M },
+ { Key.m, KeyScanCode.M },
+ { Key.Period, KeyScanCode.OemPeriod },
+ { Key.Comma, KeyScanCode.OemComma },
+ { Key.Question, KeyScanCode.OemQuestion },
+ { Key.ShiftRight, KeyScanCode.ShiftR },
+
+ { Key.CapsLock, KeyScanCode.CapsLock },
+ { Key.A, KeyScanCode.A },
+ { Key.a, KeyScanCode.A },
+ { Key.S, KeyScanCode.S },
+ { Key.s, KeyScanCode.S },
+ { Key.D, KeyScanCode.D },
+ { Key.d, KeyScanCode.D },
+ { Key.F, KeyScanCode.F },
+ { Key.f, KeyScanCode.F },
+ { Key.G, KeyScanCode.G },
+ { Key.g, KeyScanCode.G },
+ { Key.H, KeyScanCode.H },
+ { Key.h, KeyScanCode.H },
+ { Key.J, KeyScanCode.J },
+ { Key.j, KeyScanCode.J },
+ { Key.K, KeyScanCode.K },
+ { Key.k, KeyScanCode.K },
+ { Key.L, KeyScanCode.L },
+ { Key.l, KeyScanCode.L },
+ { Key.Semicolon, KeyScanCode.OemSemicolon },
+ { Key.Quote, KeyScanCode.OemQuotes },
+ { Key.Return, KeyScanCode.Enter },
+
+ { Key.Tab, KeyScanCode.Tab },
+ { Key.Q, KeyScanCode.Q },
+ { Key.q, KeyScanCode.Q },
+ { Key.W, KeyScanCode.W },
+ { Key.w, KeyScanCode.W },
+ { Key.E, KeyScanCode.E },
+ { Key.e, KeyScanCode.E },
+ { Key.R, KeyScanCode.R },
+ { Key.r, KeyScanCode.R },
+ { Key.T, KeyScanCode.T },
+ { Key.t, KeyScanCode.T },
+ { Key.Y, KeyScanCode.Y },
+ { Key.y, KeyScanCode.Y },
+ { Key.U, KeyScanCode.U },
+ { Key.u, KeyScanCode.U },
+ { Key.I, KeyScanCode.I },
+ { Key.i, KeyScanCode.I },
+ { Key.O, KeyScanCode.O },
+ { Key.o, KeyScanCode.O },
+ { Key.P, KeyScanCode.P },
+ { Key.p, KeyScanCode.P },
+ { Key.OpenCurlyBracket, KeyScanCode.OemOpenBrackets },
+ { Key.OpenSquareBracket, KeyScanCode.OemOpenBrackets },
+ { Key.CloseCurlyBracket, KeyScanCode.OemCloseBrackets },
+ { Key.CloseSquareBracket, KeyScanCode.OemCloseBrackets },
+
+ { Key.Tilde, KeyScanCode.Tilde },
+ { Key.BackQuote, KeyScanCode.Tilde },
+ { Key.K1, KeyScanCode.Number1 },
+ { Key.K2, KeyScanCode.Number2 },
+ { Key.K3, KeyScanCode.Number3 },
+ { Key.K4, KeyScanCode.Number4 },
+ { Key.K5, KeyScanCode.Number5 },
+ { Key.K6, KeyScanCode.Number6 },
+ { Key.K7, KeyScanCode.Number7 },
+ { Key.K8, KeyScanCode.Number8 },
+ { Key.K9, KeyScanCode.Number9 },
+ { Key.K0, KeyScanCode.Number0 },
+ { Key.Minus, KeyScanCode.OemMinus },
+ { Key.Underscore, KeyScanCode.OemMinus },
+ { Key.Plus, KeyScanCode.OemPlus },
+ { Key.Equal, KeyScanCode.OemPlus },
+ { Key.Backslash, KeyScanCode.OemPipe },
+ { Key.Pipe, KeyScanCode.OemPipe },
+ { Key.BackSpace, KeyScanCode.BackSpace },
+
+ { Key.Escape, KeyScanCode.Escape },
+ { Key.F1, KeyScanCode.F1 },
+ { Key.F2, KeyScanCode.F2 },
+ { Key.F3, KeyScanCode.F3 },
+ { Key.F4, KeyScanCode.F4 },
+ { Key.F5, KeyScanCode.F5 },
+ { Key.F6, KeyScanCode.F6 },
+ { Key.F7, KeyScanCode.F7 },
+ { Key.F8, KeyScanCode.F8 },
+ { Key.F9, KeyScanCode.F9 },
+ { Key.F10, KeyScanCode.F10 },
+ { Key.Print, KeyScanCode.PrtSc },
+ { Key.ScrollLock, KeyScanCode.ScrollLock },
+ { Key.Pause, KeyScanCode.Pause },
+
+ { Key.Insert, KeyScanCode.Insert },
+ { Key.Home, KeyScanCode.Home },
+ { Key.PageUp, KeyScanCode.PageUp },
+ { Key.Delete, KeyScanCode.Delete },
+ { Key.End, KeyScanCode.End },
+ { Key.PageDown, KeyScanCode.PageDown },
+
+ { Key.Up, KeyScanCode.Up },
+ { Key.Down, KeyScanCode.Down },
+ { Key.Left, KeyScanCode.Left },
+ { Key.Right, KeyScanCode.Right },
+
+ { Key.NumLock, KeyScanCode.NumLock },
+ { Key.NumPad0, KeyScanCode.Keypad0 },
+ { Key.NumPad1, KeyScanCode.Keypad1 },
+ { Key.NumPad2, KeyScanCode.Keypad2 },
+ { Key.NumPad3, KeyScanCode.Keypad3 },
+ { Key.NumPad4, KeyScanCode.Keypad4 },
+ { Key.NumPad5, KeyScanCode.Keypad5 },
+ { Key.NumPad6, KeyScanCode.Keypad6 },
+ { Key.NumPad7, KeyScanCode.Keypad7 },
+ { Key.NumPad8, KeyScanCode.Keypad8 },
+ { Key.NumPad9, KeyScanCode.Keypad9 },
+ { Key.NumPadDivide, KeyScanCode.KeypadDivide },
+ { Key.NumPadMultiply, KeyScanCode.KeypadMultiply },
+ { Key.NumPadSubtract, KeyScanCode.KeypadMinus },
+ { Key.NumPadAdd, KeyScanCode.KeypadPlus },
+ { Key.NumPadDecimal, KeyScanCode.KeypadComma },
+ { Key.NumPadEnter, KeyScanCode.KeypadEnter },
+ };
+ }
+}
diff --git a/src/UI/VideoAnalyzer/Events/XWTEventSource.cs b/src/UI/VideoAnalyzer/Events/XWTEventSource.cs
index c5ee018c1..c16717f43 100644
--- a/src/UI/VideoAnalyzer/Events/XWTEventSource.cs
+++ b/src/UI/VideoAnalyzer/Events/XWTEventSource.cs
@@ -40,11 +40,13 @@ private void HandleKeyReleased(object sender, KeyEventArgs e)
var vks = VkKeyScanEx((char)e.Key, keyboardLayout);
var vsc = MapVirtualKeyEx((uint)vks & 0xff, MAPVK_VK_TO_VSC, keyboardLayout);
var key = WPFToKeyScanCodeConverter.Instance.GetScanCode((int)vsc, e.Key);
+#elif PLATFORM_OSX
+ var key = OSXToKeyScanCodeConverter.Instance.GetScanCode(e.Key);
#else
var entryKey = Gdk.Keymap.Default.GetEntriesForKeyval((uint)e.Key)[0].Keycode;
var key = X11ToKeyScanCodeConverter.Instance.GetScanCode((int)entryKey);
-#endif // !PLATFORM_WINDOWS
+#endif // !(PLATFORM_WINDOWS || PLATFORM_OSX)
if(key != null)
{
handler.KeyReleased(key.Value);
@@ -63,11 +65,13 @@ private void HandleKeyPressed(object sender, KeyEventArgs e)
var vks = VkKeyScanEx((char)e.Key, keyboardLayout);
var vsc = MapVirtualKeyEx((uint)vks & 0xff, MAPVK_VK_TO_VSC, keyboardLayout);
var key = WPFToKeyScanCodeConverter.Instance.GetScanCode((int)vsc, e.Key);
+#elif PLATFORM_OSX
+ var key = OSXToKeyScanCodeConverter.Instance.GetScanCode(e.Key);
#else
var entryKey = Gdk.Keymap.Default.GetEntriesForKeyval((uint)e.Key)[0].Keycode;
var key = X11ToKeyScanCodeConverter.Instance.GetScanCode((int)entryKey);
-#endif // !PLATFORM_WINDOWS
+#endif // !(PLATFORM_WINDOWS || PLATFORM_OSX)
if(key != null)
{
handler.KeyPressed(key.Value);