using WindowsInput; namespace SteamController.Devices { public class KeyboardController : IDisposable { public static readonly TimeSpan FirstRepeat = TimeSpan.FromMilliseconds(400); public static readonly TimeSpan NextRepeats = TimeSpan.FromMilliseconds(45); InputSimulator simulator = new InputSimulator(); Dictionary keyCodes = new Dictionary(); Dictionary lastKeyCodes = new Dictionary(); public KeyboardController() { } public void Dispose() { } public bool this[ProfilesSettings.VirtualKeyCode key] { get { return this[(VirtualKeyCode)key]; } set { this[(VirtualKeyCode)key] = value; } } public bool this[System.Windows.Input.Key key] { get { return this[(VirtualKeyCode)System.Windows.Input.KeyInterop.VirtualKeyFromKey(key)]; } set { this[(VirtualKeyCode)System.Windows.Input.KeyInterop.VirtualKeyFromKey(key)] = value; } } public bool this[System.Windows.Forms.Keys key] { get { if (key.HasFlag(System.Windows.Forms.Keys.Shift) && !this[VirtualKeyCode.SHIFT]) return false; if (key.HasFlag(System.Windows.Forms.Keys.Alt) && !this[VirtualKeyCode.MENU]) return false; if (key.HasFlag(System.Windows.Forms.Keys.Control) && !this[VirtualKeyCode.CONTROL]) return false; return this[(VirtualKeyCode)(key & System.Windows.Forms.Keys.KeyCode)]; } set { if (value) { this[VirtualKeyCode.SHIFT] = key.HasFlag(System.Windows.Forms.Keys.Shift); this[VirtualKeyCode.MENU] = key.HasFlag(System.Windows.Forms.Keys.Alt); this[VirtualKeyCode.CONTROL] = key.HasFlag(System.Windows.Forms.Keys.Control); this[(VirtualKeyCode)(key & System.Windows.Forms.Keys.KeyCode)] = true; } } } public bool this[VirtualKeyCode key] { get { return keyCodes.ContainsKey(key); } set { if (key == VirtualKeyCode.None) return; if (value) { if (keyCodes.ContainsKey(key)) return; if (!lastKeyCodes.TryGetValue(key, out var keyRepeat)) keyRepeat = DateTime.Now.Add(FirstRepeat); keyCodes.Add(key, keyRepeat); } } } public VirtualKeyCode[] DownKeys { get { return keyCodes.Keys.ToArray(); } } internal void BeforeUpdate() { lastKeyCodes = keyCodes; keyCodes = new Dictionary(); } internal void Update() { // Key Up: it is missing now foreach (var keyUp in lastKeyCodes.Except(keyCodes)) { try { simulator.Keyboard.KeyUp(keyUp.Key); } catch (InvalidOperationException) { } } // Key Down: new keys being down foreach (var keyDown in keyCodes.Except(lastKeyCodes)) { try { simulator.Keyboard.KeyDown(keyDown.Key); } catch (InvalidOperationException) { } } // Key Repeats var now = DateTime.Now; foreach (var keyPress in keyCodes) { if (keyPress.Value > now) continue; try { simulator.Keyboard.KeyPress(keyPress.Key); } catch (InvalidOperationException) { } keyCodes[keyPress.Key] = DateTime.Now.Add(NextRepeats); } } public void KeyPress(params VirtualKeyCode[] keyCodes) { try { simulator.Keyboard.KeyPress(keyCodes); } catch (InvalidOperationException) { } } public void KeyPress(VirtualKeyCode modifierKey, params VirtualKeyCode[] keyCodes) { try { simulator.Keyboard.ModifiedKeyStroke(modifierKey, keyCodes); } catch (InvalidOperationException) { } } public void KeyPress(IEnumerable modifierKeys, params VirtualKeyCode[] keyCodes) { try { simulator.Keyboard.ModifiedKeyStroke(modifierKeys, keyCodes); } catch (InvalidOperationException) { } } } }