WingMan – Blame information for rev 10

Subversion Repositories:
Rev:
Rev Author Line No. Line
10 office 1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Threading;
6 using System.Threading.Tasks;
7 using System.Windows.Forms;
8 using Gma.System.MouseKeyHook;
9 using WingMan.Communication;
10  
11 namespace WingMan.MouseKey
12 {
13 public class KeyInterceptor : IDisposable
14 {
15 public delegate void MouseKeyBindingMatched(object sender, KeyBindingMatchedEventArgs args);
16  
17 public KeyInterceptor(RemoteKeyBindings remoteKeyBindings, MqttCommunication mqttCommunication,
18 TaskScheduler taskScheduler, CancellationToken cancellationToken)
19 {
20 RemoteKeyBindings = remoteKeyBindings;
21 MqttCommunication = mqttCommunication;
22 TaskScheduler = taskScheduler;
23 CancellationToken = cancellationToken;
24  
25 KeyCombo = new List<string>();
26  
27 MouseKeyGloalHook = Hook.GlobalEvents();
28 MouseKeyGloalHook.KeyUp += MouseKeyGloalHookOnKeyUp;
29 MouseKeyGloalHook.KeyDown += MouseKeyGloalHookOnKeyDown;
30 }
31  
32 private RemoteKeyBindings RemoteKeyBindings { get; }
33 private MqttCommunication MqttCommunication { get; }
34 private TaskScheduler TaskScheduler { get; }
35 private CancellationToken CancellationToken { get; }
36  
37 private IKeyboardMouseEvents MouseKeyGloalHook { get; }
38  
39 public List<string> KeyCombo { get; set; }
40  
41 public void Dispose()
42 {
43 MouseKeyGloalHook.KeyUp -= MouseKeyGloalHookOnKeyUp;
44 MouseKeyGloalHook.KeyDown -= MouseKeyGloalHookOnKeyDown;
45  
46 MouseKeyGloalHook.Dispose();
47 }
48  
49 public event MouseKeyBindingMatched OnMouseKeyBindingMatched;
50  
51 private void MouseKeyGloalHookOnKeyDown(object sender, KeyEventArgs e)
52 {
53 e.SuppressKeyPress = false;
54  
55 if (KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key)) KeyCombo.Add(key);
56 }
57  
58 private void MouseKeyGloalHookOnKeyUp(object sender, KeyEventArgs e)
59 {
60 e.SuppressKeyPress = false;
61  
62 var combo = new List<string>(KeyCombo);
63  
64 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
65 Task.Run(() => SimulateMouseKey(new List<string>(combo)), CancellationToken);
66 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
67  
68 KeyCombo.Clear();
69 }
70  
71 private async Task SimulateMouseKey(List<string> mouseKeyCombo)
72 {
73 foreach (var binding in RemoteKeyBindings.Bindings)
74 {
75 if (!binding.Keys.SequenceEqual(mouseKeyCombo))
76 continue;
77  
78 // Raise the match event.
79 await Task.Delay(0, CancellationToken)
80 .ContinueWith(
81 _ => OnMouseKeyBindingMatched?.Invoke(this,
82 new KeyBindingMatchedEventArgs(binding.Nick, binding.Name, binding.Keys)),
83 CancellationToken,
84 TaskContinuationOptions.None, TaskScheduler);
85  
86 using (var memoryStream = new MemoryStream())
87 {
88 ExecuteKeyBinding.XmlSerializer.Serialize(memoryStream,
89 new ExecuteKeyBinding(binding.Nick, binding.Name));
90  
91 memoryStream.Position = 0L;
92  
93 await MqttCommunication.Broadcast("execute", memoryStream.ToArray());
94 }
95 }
96 }
97 }
98 }