1 // 2 // Copyright (c) 2010-2021 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using System.Runtime.InteropServices; 10 using Xwt; 11 using Antmicro.Renode.Logging; 12 using Antmicro.Renode.Extensions.Analyzers.Video.Handlers; 13 14 namespace Antmicro.Renode.Extensions.Analyzers.Video.Events 15 { 16 internal class XWTEventSource : IEventSource 17 { XWTEventSource(Widget source)18 public XWTEventSource(Widget source) 19 { 20 this.source = source; 21 } 22 AttachHandler(IOHandler h)23 public void AttachHandler(IOHandler h) 24 { 25 handler = h; 26 27 source.MouseMoved += HandleMouseMoved; 28 source.ButtonPressed += HandleButtonPressed; 29 source.ButtonReleased += HandleButtonReleased; 30 source.KeyPressed += HandleKeyPressed; 31 source.KeyReleased += HandleKeyReleased; 32 } 33 HandleKeyReleased(object sender, KeyEventArgs e)34 private void HandleKeyReleased(object sender, KeyEventArgs e) 35 { 36 #if !GUI_DISABLED 37 e.Handled = true; 38 #if PLATFORM_WINDOWS 39 var keyboardLayout = GetKeyboardLayout(0); 40 var vks = VkKeyScanEx((char)e.Key, keyboardLayout); 41 var vsc = MapVirtualKeyEx((uint)vks & 0xff, MAPVK_VK_TO_VSC, keyboardLayout); 42 var key = WPFToKeyScanCodeConverter.Instance.GetScanCode((int)vsc, e.Key); 43 #else 44 var entryKey = Gdk.Keymap.Default.GetEntriesForKeyval((uint)e.Key)[0].Keycode; 45 46 var key = X11ToKeyScanCodeConverter.Instance.GetScanCode((int)entryKey); 47 #endif // !PLATFORM_WINDOWS 48 if(key != null) 49 { 50 handler.KeyReleased(key.Value); 51 return; 52 } 53 #endif // !GUI_DISABLED 54 Logger.LogAs(this, LogLevel.Warning, "Unhandled keycode: {0}", e.Key); 55 } 56 HandleKeyPressed(object sender, KeyEventArgs e)57 private void HandleKeyPressed(object sender, KeyEventArgs e) 58 { 59 #if !GUI_DISABLED 60 e.Handled = true; 61 #if PLATFORM_WINDOWS 62 var keyboardLayout = GetKeyboardLayout(0); 63 var vks = VkKeyScanEx((char)e.Key, keyboardLayout); 64 var vsc = MapVirtualKeyEx((uint)vks & 0xff, MAPVK_VK_TO_VSC, keyboardLayout); 65 var key = WPFToKeyScanCodeConverter.Instance.GetScanCode((int)vsc, e.Key); 66 #else 67 var entryKey = Gdk.Keymap.Default.GetEntriesForKeyval((uint)e.Key)[0].Keycode; 68 69 var key = X11ToKeyScanCodeConverter.Instance.GetScanCode((int)entryKey); 70 #endif // !PLATFORM_WINDOWS 71 if(key != null) 72 { 73 handler.KeyPressed(key.Value); 74 return; 75 } 76 #endif // !GUI_DISABLED 77 Logger.LogAs(this, LogLevel.Warning, "Unhandled keycode: {0}", e.Key); 78 } 79 HandleButtonReleased(object sender, ButtonEventArgs e)80 private void HandleButtonReleased(object sender, ButtonEventArgs e) 81 { 82 if(!e.Handled) 83 { 84 handler.ButtonReleased(e.Button); 85 e.Handled = true; 86 } 87 } 88 HandleButtonPressed(object sender, ButtonEventArgs e)89 private void HandleButtonPressed(object sender, ButtonEventArgs e) 90 { 91 if(!e.Handled) 92 { 93 handler.ButtonPressed(e.Button); 94 e.Handled = true; 95 } 96 } 97 HandleMouseMoved(object sender, MouseMovedEventArgs e)98 private void HandleMouseMoved(object sender, MouseMovedEventArgs e) 99 { 100 if(lastX == null || lastY == null) 101 { 102 lastX = (int)e.X; 103 lastY = (int)e.Y; 104 return; 105 } 106 107 handler.MouseMoved((int)e.X, (int)e.Y, lastX.Value - (int)e.X, lastY.Value - (int)e.Y); 108 lastX = (int)e.X; 109 lastY = (int)e.Y; 110 } 111 DetachHandler()112 public void DetachHandler() 113 { 114 source.MouseMoved -= HandleMouseMoved; 115 source.ButtonPressed -= HandleButtonPressed; 116 source.ButtonReleased -= HandleButtonReleased; 117 source.KeyPressed -= HandleKeyPressed; 118 source.KeyReleased -= HandleKeyReleased; 119 120 handler = null; 121 } 122 123 private Widget source; 124 private IOHandler handler; 125 126 private int? lastX; 127 private int? lastY; 128 129 public int X { get { return lastX ?? 0; } } 130 public int Y { get { return lastY ?? 0; } } 131 132 #if PLATFORM_WINDOWS 133 [DllImport("user32.dll")] MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl)134 private static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl); 135 [DllImport("user32.dll")] MapVirtualKeyW(uint uCode, uint uMapType)136 private static extern uint MapVirtualKeyW(uint uCode, uint uMapType); 137 [DllImport("user32.dll")] GetKeyboardLayout(uint idThread)138 private static extern IntPtr GetKeyboardLayout(uint idThread); 139 [System.Runtime.InteropServices.DllImport("user32.dll")] VkKeyScan(char ch)140 private static extern short VkKeyScan(char ch); 141 [System.Runtime.InteropServices.DllImport("user32.dll")] VkKeyScanEx(char ch, IntPtr dwhkl)142 private static extern short VkKeyScanEx(char ch, IntPtr dwhkl); 143 144 private const uint MAPVK_VK_TO_VSC = 0x00; 145 private const uint MAPVK_VSC_TO_VK = 0x01; 146 private const uint MAPVK_VK_TO_CHAR = 0x02; 147 private const uint MAPVK_VSC_TO_VK_EX = 0x03; 148 private const uint MAPVK_VK_TO_VSC_EX = 0x04; 149 #endif 150 } 151 } 152