protected override void Initialize(IObservable <EventPattern <WMEventArgs> > windowMessages, IObservable <bool> disabled) { var keyNotifications = windowMessages .Select <EventPattern <WMEventArgs>, KeyNotification>(e => { var a = e.EventArgs; switch (a.Message) { case WM.KEYDOWN: case WM.SYSKEYDOWN: return(new KeyDownNotification((Keys)a.WParam, this)); case WM.CHAR: case WM.SYSCHAR: return(new KeyPressNotification((char)a.WParam, this)); case WM.KEYUP: case WM.SYSKEYUP: return(new KeyUpNotification((Keys)a.WParam, this)); } return(null); } ) .OfType <KeyNotification>(); var keyboard = new Keyboard(keyNotifications); FKeyboardOut[0] = keyboard; // Subscribe to the keyboard so we can write the legacy keyboard string output FKeyboardSubscription = keyboard.KeyNotifications .OfType <KeyCodeNotification>() .Subscribe(keyNotification => { var keyCode = keyNotification.KeyCode; var keyName = LegacyKeyboardHelper.VirtualKeycodeToString(keyCode); switch (keyNotification.Kind) { case KeyNotificationKind.KeyDown: if (!FLegacyKeyStringOut.Contains(keyName)) { FLegacyKeyStringOut.Add(keyName); } break; case KeyNotificationKind.KeyUp: FLegacyKeyStringOut.Remove(keyName); break; default: break; } } ); // Create a keyboard split node for us and connect our keyboard out to its keyboard in var nodeInfo = FIOFactory.NodeInfos.First(n => n.Name == "KeyboardState" && n.Category == "System" && n.Version == "Split Legacy"); FKeyboardSplitNode = FIOFactory.CreatePlugin(nodeInfo, c => c.IOAttribute.Name == "Keyboard", c => FKeyboardOut); }
protected override void Evaluate(int spreadMax, bool enabled) { if (enabled) { // To support old keyboard node if (FLegacyKeyStringIn.SliceCount > 0) { var keys = FLegacyKeyStringIn.Select(keyAsString => LegacyKeyboardHelper.StringToVirtualKeycode(keyAsString)); FKeyboardIn.SliceCount = 1; FKeyboardIn[0] = new KeyboardState(keys); } if (FKeyboardIn.SliceCount > 0) { var currentKeyboardIn = FKeyboardIn[0] ?? KeyboardState.Empty; if (currentKeyboardIn != FLastKeyboardIn) { var modifierKeys = currentKeyboardIn.ModifierKeys.Select(k => (VirtualKeyCode)k); var keys = currentKeyboardIn.KeyCodes.Select(k => (VirtualKeyCode)k).Except(modifierKeys); InputSimulator.SimulateModifiedKeyStroke(modifierKeys, keys); } FLastKeyboardIn = currentKeyboardIn; } // Works when we call GetKeyState before calling GetKeyboardState ?! //if (FHost.IsRunningInBackground) // FKeysOut[0] = KeyboardState.CurrentAsync; //else var keyboard = KeyboardState.Current; if (keyboard != KeyboardState.Empty && keyboard == FLastKeyboard) { // Keyboard stayed the same if (FStopwatch.ElapsedMilliseconds > 500) { // Simulate key repeat by generating a new keyboard with different time code var time = FStopwatch.ElapsedMilliseconds / 50; var isNewKeyDown = time != FKeyboardOut[0].Time; FKeyboardOut[0] = new KeyboardState(keyboard.KeyCodes, keyboard.CapsLock, (int)time); // Simulate legacy output if (isNewKeyDown) { FLegacyKeyBufferOut.AssignFrom(FKeyDowns); } else { FLegacyKeyBufferOut.SliceCount = 1; FLegacyKeyBufferOut[0] = string.Empty; } // Evaluate our split plugin FKeyboardSplitNode.Evaluate(spreadMax); } else { // Simulate legacy output FLegacyKeyBufferOut.SliceCount = 1; FLegacyKeyBufferOut[0] = string.Empty; } } else { FStopwatch.Restart(); FKeyboardOut[0] = keyboard; // Simulate legacy output FLegacyKeyStringOut.AssignFrom(keyboard.KeyCodes.Select(k => LegacyKeyboardHelper.VirtualKeycodeToString(k))); FKeyDowns = keyboard.KeyCodes .Except(FLastKeyboard.KeyCodes) .Select(k => LegacyKeyboardHelper.VirtualKeycodeToString(k)) .ToList(); if (FKeyDowns.Count > 0) { FLegacyKeyBufferOut.AssignFrom(FKeyDowns); } else { FLegacyKeyBufferOut.SliceCount = 1; FLegacyKeyBufferOut[0] = string.Empty; } // Evaluate our split plugin FKeyboardSplitNode.Evaluate(spreadMax); } FLastKeyboard = keyboard; } }
protected override void Evaluate(int spreadMax, bool enabled) { if (enabled) { if (FKeyboardOut[0] != FKeyboardState) { FKeyboardOut[0] = FKeyboardState; FLegacyKeyStringOut.AssignFrom(FKeyboardState.KeyCodes.Select(k => LegacyKeyboardHelper.VirtualKeycodeToString(k))); FKeyboardSplitNode.Evaluate(spreadMax); } } }
protected override void Evaluate(int spreadMax, bool enabled) { if (enabled) { Keyboard inputKeyboard; if (FKeyboardIn.SliceCount > 0 && FKeyboardIn[0] != null) { inputKeyboard = FKeyboardIn[0]; } else { // To support old keyboard node var keys = FLegacyKeyStringIn.Select(keyAsString => LegacyKeyboardHelper.StringToVirtualKeycode(keyAsString)) .ToList(); var keyDowns = keys.Except(FLastLegacyInputKeys); foreach (var keyDown in keyDowns) { FLegacyInputKeyboardSubject.OnNext(new KeyDownNotification(keyDown)); } var keyUps = FLastLegacyInputKeys.Except(keys); foreach (var keyUp in keyUps) { FLegacyInputKeyboardSubject.OnNext(new KeyUpNotification(keyUp)); } FLastLegacyInputKeys = keys; inputKeyboard = FLegacyInputKeyboard; } FInputKeyboardSubscription.Update(inputKeyboard); // Works when we call GetKeyState before calling GetKeyboardState ?! //if (FHost.IsRunningInBackground) // FKeysOut[0] = KeyboardState.CurrentAsync; //else var keyboardState = KeyboardState.Current; if (keyboardState != KeyboardState.Empty && keyboardState == FLastKeyboardState) { // Keyboard stayed the same if (FStopwatch.ElapsedMilliseconds > 500) { // Simulate key repeat by generating a new keyboard with different time code var time = FStopwatch.ElapsedMilliseconds / 50; var isNewKeyDown = time != FLastTime; // Simulate legacy output if (isNewKeyDown) { foreach (var keyDown in FKeyDowns) { FKeyNotificationSubject.OnNext(new KeyDownNotification(keyDown)); } FLegacyKeyBufferOut.AssignFrom(FKeyDowns.Select(k => LegacyKeyboardHelper.VirtualKeycodeToString(k))); } else { FLegacyKeyBufferOut.SliceCount = 1; FLegacyKeyBufferOut[0] = string.Empty; } FLastTime = time; // Evaluate our split plugin FKeyboardSplitNode.Evaluate(spreadMax); } else { // Simulate legacy output FLegacyKeyBufferOut.SliceCount = 1; FLegacyKeyBufferOut[0] = string.Empty; } } else { FStopwatch.Restart(); var keyDowns = keyboardState.KeyCodes.Except(FLastKeyboardState.KeyCodes); foreach (var keyDown in keyDowns) { FKeyNotificationSubject.OnNext(new KeyDownNotification(keyDown)); } var keyUps = FLastKeyboardState.KeyCodes.Except(keyboardState.KeyCodes); foreach (var keyUp in keyUps) { FKeyNotificationSubject.OnNext(new KeyUpNotification(keyUp)); } FKeyboardOut[0].CapsLock = Control.IsKeyLocked(Keys.CapsLock); // Simulate legacy output FLegacyKeyStringOut.AssignFrom(keyboardState.KeyCodes.Select(k => LegacyKeyboardHelper.VirtualKeycodeToString(k))); FKeyDowns = keyboardState.KeyCodes .Except(FLastKeyboardState.KeyCodes) .ToList(); if (FKeyDowns.Count > 0) { FLegacyKeyBufferOut.AssignFrom(FKeyDowns.Select(k => LegacyKeyboardHelper.VirtualKeycodeToString(k))); } else { FLegacyKeyBufferOut.SliceCount = 1; FLegacyKeyBufferOut[0] = string.Empty; } // Evaluate our split plugin FKeyboardSplitNode.Evaluate(spreadMax); } FLastKeyboardState = keyboardState; } }