1 //
2 // Copyright (c) 2010-2021 Antmicro
3 // Copyright (c) 2021 Sean "xobs" Cross
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using Antmicro.Renode.Peripherals.Input;
9 using System.Collections.Generic;
10 using Xwt;
11 
12 namespace Antmicro.Renode.Extensions.Analyzers.Video.Events
13 {
14     internal class WPFToKeyScanCodeConverter
15     {
WPFToKeyScanCodeConverter()16         static WPFToKeyScanCodeConverter()
17         {
18             Instance = new WPFToKeyScanCodeConverter();
19         }
20 
21         public static WPFToKeyScanCodeConverter Instance { get; private set; }
22 
GetScanCode(int fromValue, Key untranslatedCode)23         public KeyScanCode? GetScanCode(int fromValue, Key untranslatedCode)
24         {
25             KeyScanCode result;
26 
27             // This value shows up for both Return and Minus, so use the
28             // untranslated code.
29             if(ScanCodesToIgnore.TryGetValue(untranslatedCode, out result))
30             {
31                 return result;
32             }
33             if(fromValue == 0)
34             {
35                 return UntranslatedScanCode.TryGetValue(untranslatedCode, out result) ? (KeyScanCode?)result : null;
36             }
37             return ToScanCode.TryGetValue(fromValue, out result) ? (KeyScanCode?)result : null;
38         }
39 
40         // These all share a scancode with a letter key, so don't bother
41         // trying to read the FromValue
42         private readonly Dictionary<Key, KeyScanCode> ScanCodesToIgnore = new Dictionary<Key, KeyScanCode>
43         {
44             { Key.ShiftLeft /*53*/, KeyScanCode.ShiftL },
45             { Key.ControlLeft /*53*/, KeyScanCode.CtrlL },
46             { Key.ShiftRight /*53*/, KeyScanCode.ShiftR  },
47             { Key.ControlRight /*53*/, KeyScanCode.CtrlR },
48 
49             { Key.Equal /*53*/, KeyScanCode.OemPlus },
50             { Key.Slash /*53*/, KeyScanCode.OemQuestion },
51 
52             { Key.BackSpace /*10*/, KeyScanCode.BackSpace },
53             { Key.Tab /*11*/, KeyScanCode.Tab },
54             { Key.Return /*12*/, KeyScanCode.Enter },
55             { Key.CapsLock /*53*/, KeyScanCode.CapsLock },
56 
57             { Key.Escape /*39*/, KeyScanCode.Escape },
58             { Key.ScrollLock /*5*/, KeyScanCode.ScrollLock },
59             { Key.Pause /*4*/, KeyScanCode.Pause },
60 
61             { Key.Home /*25*/, KeyScanCode.Home },
62             { Key.PageUp /*22*/, KeyScanCode.PageUp },
63             { Key.End /*17*/, KeyScanCode.End },
64             { Key.PageDown /*47*/, KeyScanCode.PageDown },
65             { Key.Insert /*53*/, KeyScanCode.Insert },
66             { Key.Delete /*53*/, KeyScanCode.Delete },
67 
68             { Key.Up /*19*/, KeyScanCode.Up },
69             { Key.Down /*20*/, KeyScanCode.Down },
70             { Key.Left /*16*/, KeyScanCode.Left },
71             { Key.Right /*31*/, KeyScanCode.Right },
72 
73             { Key.NumLock /*53*/, KeyScanCode.NumLock },
74             { Key.NumPad0 /*53*/, KeyScanCode.Keypad0 },
75             { Key.NumPad1 /*53*/, KeyScanCode.Keypad1 },
76             { Key.NumPad2 /*53*/, KeyScanCode.Keypad2 },
77             { Key.NumPad3 /*53*/, KeyScanCode.Keypad3 },
78             { Key.NumPad4 /*53*/, KeyScanCode.Keypad4 },
79             { Key.NumPad5 /*53*/, KeyScanCode.Keypad5 },
80             { Key.NumPad6 /*53*/, KeyScanCode.Keypad6 },
81             { Key.NumPad7 /*53*/, KeyScanCode.Keypad7 },
82             { Key.NumPad8 /*53*/, KeyScanCode.Keypad8 },
83             { Key.NumPad9 /*53*/, KeyScanCode.Keypad9 },
84             { Key.NumPadDivide /*53*/, KeyScanCode.KeypadDivide },
85             { Key.NumPadMultiply /*53*/, KeyScanCode.KeypadMultiply },
86             { Key.NumPadSubtract /*53*/, KeyScanCode.KeypadMinus },
87             { Key.NumPadAdd /*53*/, KeyScanCode.KeypadPlus },
88             { Key.NumPadDecimal /*53*/, KeyScanCode.KeypadComma },
89             { Key.NumPadEnter /*12*/, KeyScanCode.KeypadEnter },
90             { Key.Space /*57*/, KeyScanCode.Space },
91 
92             { Key.F1 /*53*/, KeyScanCode.F1 },
93             { Key.F2 /*53*/, KeyScanCode.F2 },
94             { Key.F3 /*53*/, KeyScanCode.F3 },
95             { Key.F4 /*53*/, KeyScanCode.F4 },
96             { Key.F5 /*53*/, KeyScanCode.F5 },
97             { Key.F6 /*53*/, KeyScanCode.F6 },
98             { Key.F7 /*53*/, KeyScanCode.F7 },
99             { Key.F8 /*53*/, KeyScanCode.F8 },
100             { Key.F9 /*53*/, KeyScanCode.F9 },
101             { Key.F10 /*53*/, KeyScanCode.F10 },
102         };
103 
104         private readonly Dictionary<Key, KeyScanCode> UntranslatedScanCode = new Dictionary<Key, KeyScanCode>
105         {
106             { Key.AltLeft, KeyScanCode.AltL },
107             { Key.MetaLeft, KeyScanCode.WinL },
108             { Key.Space, KeyScanCode.Space },
109             { Key.AltRight, KeyScanCode.AltR },
110             { Key.MetaRight, KeyScanCode.WinR },
111             { Key.Menu, KeyScanCode.WinMenu },
112             { Key.Z, KeyScanCode.Z },
113             { Key.z, KeyScanCode.Z },
114             { Key.X, KeyScanCode.X },
115             { Key.x, KeyScanCode.X },
116             { Key.C, KeyScanCode.C },
117             { Key.c, KeyScanCode.C },
118             { Key.V, KeyScanCode.V },
119             { Key.v, KeyScanCode.V },
120             { Key.B, KeyScanCode.B },
121             { Key.b, KeyScanCode.B },
122             { Key.N, KeyScanCode.N },
123             { Key.n, KeyScanCode.N },
124             { Key.M, KeyScanCode.M },
125             { Key.m, KeyScanCode.M },
126             { Key.Period, KeyScanCode.OemPeriod },
127             { Key.Comma, KeyScanCode.OemComma },
128             { Key.Question, KeyScanCode.OemQuestion },
129             { Key.ShiftRight, KeyScanCode.ShiftR },
130 
131             { Key.CapsLock, KeyScanCode.CapsLock },
132             { Key.A, KeyScanCode.A },
133             { Key.a, KeyScanCode.A },
134             { Key.S, KeyScanCode.S },
135             { Key.s, KeyScanCode.S },
136             { Key.D, KeyScanCode.D },
137             { Key.d, KeyScanCode.D },
138             { Key.F, KeyScanCode.F },
139             { Key.f, KeyScanCode.F },
140             { Key.G, KeyScanCode.G },
141             { Key.g, KeyScanCode.G },
142             { Key.H, KeyScanCode.H },
143             { Key.h, KeyScanCode.H },
144             { Key.J, KeyScanCode.J },
145             { Key.j, KeyScanCode.J },
146             { Key.K, KeyScanCode.K },
147             { Key.k, KeyScanCode.K },
148             { Key.L, KeyScanCode.L },
149             { Key.l, KeyScanCode.L },
150             { Key.Semicolon, KeyScanCode.OemSemicolon },
151             { Key.Quote, KeyScanCode.OemQuotes },
152             { Key.Return, KeyScanCode.Enter },
153 
154             { Key.Tab, KeyScanCode.Tab },
155             { Key.Q, KeyScanCode.Q },
156             { Key.q, KeyScanCode.Q },
157             { Key.W, KeyScanCode.W },
158             { Key.w, KeyScanCode.W },
159             { Key.E, KeyScanCode.E },
160             { Key.e, KeyScanCode.E },
161             { Key.R, KeyScanCode.R },
162             { Key.r, KeyScanCode.R },
163             { Key.T, KeyScanCode.T },
164             { Key.t, KeyScanCode.T },
165             { Key.Y, KeyScanCode.Y },
166             { Key.y, KeyScanCode.Y },
167             { Key.U, KeyScanCode.U },
168             { Key.u, KeyScanCode.U },
169             { Key.I, KeyScanCode.I },
170             { Key.i, KeyScanCode.I },
171             { Key.O, KeyScanCode.O },
172             { Key.o, KeyScanCode.O },
173             { Key.P, KeyScanCode.P },
174             { Key.p, KeyScanCode.P },
175             { Key.OpenCurlyBracket, KeyScanCode.OemOpenBrackets },
176             { Key.OpenSquareBracket, KeyScanCode.OemOpenBrackets },
177             { Key.CloseCurlyBracket, KeyScanCode.OemCloseBrackets },
178             { Key.CloseSquareBracket, KeyScanCode.OemCloseBrackets },
179 
180             { Key.Tilde, KeyScanCode.Tilde },
181             { Key.BackQuote, KeyScanCode.Tilde },
182             { Key.K1, KeyScanCode.Number1 },
183             { Key.K2, KeyScanCode.Number2 },
184             { Key.K3, KeyScanCode.Number3 },
185             { Key.K4, KeyScanCode.Number4 },
186             { Key.K5, KeyScanCode.Number5 },
187             { Key.K6, KeyScanCode.Number6 },
188             { Key.K7, KeyScanCode.Number7 },
189             { Key.K8, KeyScanCode.Number8 },
190             { Key.K9, KeyScanCode.Number9 },
191             { Key.K0, KeyScanCode.Number0 },
192             { Key.Minus, KeyScanCode.OemMinus },
193             { Key.Underscore, KeyScanCode.OemMinus },
194             { Key.Plus, KeyScanCode.OemPlus },
195             { Key.Equal, KeyScanCode.OemPlus },
196             { Key.Backslash, KeyScanCode.OemPipe },
197             { Key.Pipe, KeyScanCode.OemPipe },
198             { Key.BackSpace, KeyScanCode.BackSpace },
199 
200             { Key.Escape, KeyScanCode.Escape },
201             { Key.F1, KeyScanCode.F1 },
202             { Key.F2, KeyScanCode.F2 },
203             { Key.F3, KeyScanCode.F3 },
204             { Key.F4, KeyScanCode.F4 },
205             { Key.F5, KeyScanCode.F5 },
206             { Key.F6, KeyScanCode.F6 },
207             { Key.F7, KeyScanCode.F7 },
208             { Key.F8, KeyScanCode.F8 },
209             { Key.F9, KeyScanCode.F9 },
210             { Key.F10, KeyScanCode.F10 },
211             { Key.Print, KeyScanCode.PrtSc },
212             { Key.ScrollLock, KeyScanCode.ScrollLock },
213             { Key.Pause, KeyScanCode.Pause },
214 
215             { Key.Insert, KeyScanCode.Insert },
216             { Key.Home, KeyScanCode.Home },
217             { Key.PageUp, KeyScanCode.PageUp },
218             { Key.Delete, KeyScanCode.Delete },
219             { Key.End, KeyScanCode.End },
220             { Key.PageDown, KeyScanCode.PageDown },
221 
222             { Key.Up, KeyScanCode.Up },
223             { Key.Down, KeyScanCode.Down },
224             { Key.Left, KeyScanCode.Left },
225             { Key.Right, KeyScanCode.Right },
226 
227             { Key.NumLock, KeyScanCode.NumLock },
228             { Key.NumPad0, KeyScanCode.Keypad0 },
229             { Key.NumPad1, KeyScanCode.Keypad1 },
230             { Key.NumPad2, KeyScanCode.Keypad2 },
231             { Key.NumPad3, KeyScanCode.Keypad3 },
232             { Key.NumPad4, KeyScanCode.Keypad4 },
233             { Key.NumPad5, KeyScanCode.Keypad5 },
234             { Key.NumPad6, KeyScanCode.Keypad6 },
235             { Key.NumPad7, KeyScanCode.Keypad7 },
236             { Key.NumPad8, KeyScanCode.Keypad8 },
237             { Key.NumPad9, KeyScanCode.Keypad9 },
238             { Key.NumPadDivide, KeyScanCode.KeypadDivide },
239             { Key.NumPadMultiply, KeyScanCode.KeypadMultiply },
240             { Key.NumPadSubtract, KeyScanCode.KeypadMinus },
241             { Key.NumPadAdd, KeyScanCode.KeypadPlus },
242             { Key.NumPadDecimal, KeyScanCode.KeypadComma },
243             { Key.NumPadEnter, KeyScanCode.KeypadEnter },
244         };
245 
246         private readonly Dictionary<int, KeyScanCode> ToScanCode = new Dictionary<int, KeyScanCode>
247         {
248             { 2, KeyScanCode.Number1 },
249             { 3, KeyScanCode.Number2 },
250             { 4, KeyScanCode.Number3 },
251             { 5, KeyScanCode.Number4 },
252             { 6, KeyScanCode.Number5 },
253             { 7, KeyScanCode.Number6 },
254             { 8, KeyScanCode.Number7 },
255             { 9, KeyScanCode.Number8 },
256             { 10, KeyScanCode.Number9 },
257             { 11, KeyScanCode.Number0 },
258             { 12, KeyScanCode.OemMinus },
259             { 13, KeyScanCode.OemPlus },
260 
261             { 16, KeyScanCode.Q },
262             { 17, KeyScanCode.W },
263             { 18, KeyScanCode.E },
264             { 19, KeyScanCode.R },
265             { 20, KeyScanCode.T },
266             { 21, KeyScanCode.Y },
267             { 22, KeyScanCode.U },
268             { 23, KeyScanCode.I },
269             { 24, KeyScanCode.O },
270             { 25, KeyScanCode.P },
271             { 26, KeyScanCode.OemOpenBrackets },
272             { 27, KeyScanCode.OemCloseBrackets },
273 
274             { 30, KeyScanCode.A },
275             { 31, KeyScanCode.S },
276             { 32, KeyScanCode.D },
277             { 33, KeyScanCode.F },
278             { 34, KeyScanCode.G },
279             { 35, KeyScanCode.H },
280             { 36, KeyScanCode.J },
281             { 37, KeyScanCode.K },
282             { 38, KeyScanCode.L },
283             { 39, KeyScanCode.OemSemicolon },
284             { 40, KeyScanCode.OemQuotes },
285 
286             { 41, KeyScanCode.Tilde },
287 
288             { 43, KeyScanCode.OemPipe },
289 
290             { 44, KeyScanCode.Z },
291             { 45, KeyScanCode.X },
292             { 46, KeyScanCode.C },
293             { 47, KeyScanCode.V },
294             { 48, KeyScanCode.B },
295             { 49, KeyScanCode.N },
296             { 50, KeyScanCode.M },
297             { 51, KeyScanCode.OemComma },
298             { 52, KeyScanCode.OemPeriod },
299             { 53, KeyScanCode.OemQuestion },
300 
301             { 57, KeyScanCode.BackSpace },
302         };
303     }
304 }
305 
306