VkeyPacketSimulator.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using Terminal.Gui;
  6. namespace UICatalog.Scenarios {
  7. [ScenarioMetadata (Name: "VkeyPacketSimulator", Description: "Simulates the Virtual Key Packet")]
  8. [ScenarioCategory ("Mouse and Keyboard")]
  9. public class VkeyPacketSimulator : Scenario {
  10. List<int> _keyboardStrokes = new List<int> ();
  11. bool _outputStarted = false;
  12. bool _wasUnknown = false;
  13. static ManualResetEventSlim _stopOutput = new ManualResetEventSlim (false);
  14. public override void Setup ()
  15. {
  16. var label = new Label ("Input") {
  17. X = Pos.Center ()
  18. };
  19. Win.Add (label);
  20. var btnInput = new Button ("Select Input") {
  21. X = Pos.AnchorEnd (16),
  22. };
  23. Win.Add (btnInput);
  24. const string ruler = "|123456789";
  25. var inputHorizontalRuler = new Label ("") {
  26. Y = Pos.Bottom (btnInput),
  27. Width = Dim.Fill (),
  28. ColorScheme = Colors.Error,
  29. AutoSize = false
  30. };
  31. Win.Add (inputHorizontalRuler);
  32. var inputVerticalRuler = new Label ("", TextDirection.TopBottom_LeftRight) {
  33. Y = Pos.Bottom (btnInput),
  34. Width = 1,
  35. ColorScheme = Colors.Error,
  36. AutoSize = false
  37. };
  38. Win.Add (inputVerticalRuler);
  39. var tvInput = new TextView {
  40. X = 1,
  41. Y = Pos.Bottom (inputHorizontalRuler),
  42. Width = Dim.Fill (),
  43. Height = Dim.Percent (50) - 1
  44. };
  45. Win.Add (tvInput);
  46. label = new Label ("Output") {
  47. X = Pos.Center (),
  48. Y = Pos.Bottom (tvInput)
  49. };
  50. Win.Add (label);
  51. var btnOutput = new Button ("Select Output") {
  52. X = Pos.AnchorEnd (17),
  53. Y = Pos.Top (label)
  54. };
  55. Win.Add (btnOutput);
  56. var outputHorizontalRuler = new Label ("") {
  57. Y = Pos.Bottom (btnOutput),
  58. Width = Dim.Fill (),
  59. ColorScheme = Colors.Error,
  60. AutoSize = false
  61. };
  62. Win.Add (outputHorizontalRuler);
  63. var outputVerticalRuler = new Label ("", TextDirection.TopBottom_LeftRight) {
  64. Y = Pos.Bottom (btnOutput),
  65. Width = 1,
  66. Height = Dim.Fill (),
  67. ColorScheme = Colors.Error,
  68. AutoSize = false
  69. };
  70. Win.Add (outputVerticalRuler);
  71. var tvOutput = new TextView {
  72. X = 1,
  73. Y = Pos.Bottom (outputHorizontalRuler),
  74. Width = Dim.Fill (),
  75. Height = Dim.Fill (),
  76. ReadOnly = true
  77. };
  78. tvOutput.KeyDown += (e) => {
  79. //System.Diagnostics.Debug.WriteLine ($"Output - KeyDown: {e.KeyEvent.Key}");
  80. e.Handled = true;
  81. if (e.KeyEvent.Key == Key.Unknown) {
  82. _wasUnknown = true;
  83. }
  84. };
  85. tvOutput.KeyPress += (e) => {
  86. //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}");
  87. if (_outputStarted && _keyboardStrokes.Count > 0) {
  88. var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent);
  89. //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress: {ev}");
  90. if (!tvOutput.ProcessKey (e.KeyEvent)) {
  91. Application.MainLoop.Invoke (() => {
  92. MessageBox.Query ("Keys", $"'{ShortcutHelper.GetShortcutTag (ev)}' pressed!", "Ok");
  93. });
  94. }
  95. e.Handled = true;
  96. _stopOutput.Set ();
  97. }
  98. //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}");
  99. };
  100. Win.Add (tvOutput);
  101. tvInput.KeyDown += (e) => {
  102. //System.Diagnostics.Debug.WriteLine ($"Input - KeyDown: {e.KeyEvent.Key}");
  103. e.Handled = true;
  104. if (e.KeyEvent.Key == Key.Unknown) {
  105. _wasUnknown = true;
  106. }
  107. };
  108. View.KeyEventEventArgs unknownChar = null;
  109. tvInput.KeyPress += (e) => {
  110. if (e.KeyEvent.Key == (Key.Q | Key.CtrlMask)) {
  111. Application.RequestStop ();
  112. return;
  113. }
  114. if (e.KeyEvent.Key == Key.Unknown) {
  115. _wasUnknown = true;
  116. e.Handled = true;
  117. return;
  118. }
  119. if (_wasUnknown && _keyboardStrokes.Count == 1) {
  120. _wasUnknown = false;
  121. } else if (_wasUnknown && char.IsLetter ((char)e.KeyEvent.Key)) {
  122. _wasUnknown = false;
  123. } else if (!_wasUnknown && _keyboardStrokes.Count > 0) {
  124. e.Handled = true;
  125. return;
  126. }
  127. if (_keyboardStrokes.Count == 0) {
  128. AddKeyboardStrokes (e);
  129. } else {
  130. _keyboardStrokes.Insert (0, 0);
  131. }
  132. var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent);
  133. //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress: {ev}");
  134. //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}");
  135. };
  136. tvInput.KeyUp += (e) => {
  137. //System.Diagnostics.Debug.WriteLine ($"Input - KeyUp: {e.KeyEvent.Key}");
  138. //var ke = e.KeyEvent;
  139. var ke = ShortcutHelper.GetModifiersKey (e.KeyEvent);
  140. if (_wasUnknown && (int)ke - (int)(ke & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)) != 0) {
  141. unknownChar = e;
  142. }
  143. e.Handled = true;
  144. if (!_wasUnknown && _keyboardStrokes.Count > 0) {
  145. _outputStarted = true;
  146. tvOutput.ReadOnly = false;
  147. tvOutput.SetFocus ();
  148. tvOutput.SetNeedsDisplay ();
  149. Task.Run (() => {
  150. while (_outputStarted) {
  151. try {
  152. ConsoleModifiers mod = new ConsoleModifiers ();
  153. if (ke.HasFlag (Key.ShiftMask)) {
  154. mod |= ConsoleModifiers.Shift;
  155. }
  156. if (ke.HasFlag (Key.AltMask)) {
  157. mod |= ConsoleModifiers.Alt;
  158. }
  159. if (ke.HasFlag (Key.CtrlMask)) {
  160. mod |= ConsoleModifiers.Control;
  161. }
  162. for (int i = 0; i < _keyboardStrokes.Count; i++) {
  163. var consoleKey = ConsoleKeyMapping.GetConsoleKeyFromKey ((uint)_keyboardStrokes [i], mod, out _, out _);
  164. Application.Driver.SendKeys ((char)consoleKey, ConsoleKey.Packet, mod.HasFlag (ConsoleModifiers.Shift),
  165. mod.HasFlag (ConsoleModifiers.Alt), mod.HasFlag (ConsoleModifiers.Control));
  166. }
  167. //}
  168. } catch (Exception) {
  169. Application.MainLoop.Invoke (() => {
  170. MessageBox.ErrorQuery ("Error", "Couldn't send the keystrokes!", "Ok");
  171. Application.RequestStop ();
  172. });
  173. }
  174. _stopOutput.Wait ();
  175. _stopOutput.Reset ();
  176. _keyboardStrokes.RemoveAt (0);
  177. if (_keyboardStrokes.Count == 0) {
  178. _outputStarted = false;
  179. Application.MainLoop.Invoke (() => {
  180. tvOutput.ReadOnly = true;
  181. tvInput.SetFocus ();
  182. });
  183. }
  184. }
  185. //System.Diagnostics.Debug.WriteLine ($"_outputStarted: {_outputStarted}");
  186. });
  187. }
  188. };
  189. btnInput.Clicked += () => {
  190. if (!tvInput.HasFocus && _keyboardStrokes.Count == 0) {
  191. tvInput.SetFocus ();
  192. }
  193. };
  194. btnOutput.Clicked += () => {
  195. if (!tvOutput.HasFocus && _keyboardStrokes.Count == 0) {
  196. tvOutput.SetFocus ();
  197. }
  198. };
  199. tvInput.SetFocus ();
  200. Win.LayoutComplete += (_) => {
  201. inputHorizontalRuler.Text = outputHorizontalRuler.Text = ruler.Repeat ((int)Math.Ceiling ((double)(inputHorizontalRuler.Bounds.Width) / (double)ruler.Length)) [0..(inputHorizontalRuler.Bounds.Width)];
  202. inputVerticalRuler.Height = tvInput.Frame.Height + 1;
  203. inputVerticalRuler.Text = ruler.Repeat ((int)Math.Ceiling ((double)(inputVerticalRuler.Bounds.Height) / (double)ruler.Length)) [0..(inputVerticalRuler.Bounds.Height)];
  204. outputVerticalRuler.Text = ruler.Repeat ((int)Math.Ceiling ((double)(outputVerticalRuler.Bounds.Height) / (double)ruler.Length)) [0..(outputVerticalRuler.Bounds.Height)];
  205. };
  206. }
  207. private void AddKeyboardStrokes (View.KeyEventEventArgs e)
  208. {
  209. var ke = e.KeyEvent;
  210. var km = new KeyModifiers ();
  211. if (ke.IsShift) {
  212. km.Shift = true;
  213. }
  214. if (ke.IsAlt) {
  215. km.Alt = true;
  216. }
  217. if (ke.IsCtrl) {
  218. km.Ctrl = true;
  219. }
  220. var keyChar = ke.KeyValue;
  221. var mK = (int)((Key)ke.KeyValue & (Key.AltMask | Key.CtrlMask | Key.ShiftMask));
  222. keyChar &= ~mK;
  223. _keyboardStrokes.Add (keyChar);
  224. }
  225. }
  226. }