private void WindowKeyDownHandler(CoreWindow sender, KeyEventArgs args) { short key = KeyboardHelper.TranslateVirtualKey(args.VirtualKey); if (key != 0) { LimelightCommonRuntimeComponent.SendKeyboardEvent(key, (byte)KeyAction.Down, KeyboardHelper.GetModifierFlags()); args.Handled = true; } }
/// <summary> /// Send mouse click event to the streaming PC /// </summary> private void MouseUp(object sender, PointerRoutedEventArgs e) { PointerPoint ptrPt = e.GetCurrentPoint(StreamDisplay); if (e.Pointer.PointerDeviceType != PointerDeviceType.Mouse) { if (!hasMoved) { // We haven't moved so send a click LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Press, (int)MouseButton.Left); // Sleep here because some games do input detection by polling using (EventWaitHandle tmpEvent = new ManualResetEvent(false)) { tmpEvent.WaitOne(TimeSpan.FromMilliseconds(100)); } // Raise the mouse button LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Release, (int)MouseButton.Left); } } else { // Send changes and update the current state int deltaButtons = mouseButtonFlag ^ GetButtonFlags(ptrPt); if ((deltaButtons & MOUSE_BUTTON_LEFT) != 0) { LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Release, (int)MouseButton.Left); } if ((deltaButtons & MOUSE_BUTTON_MIDDLE) != 0) { LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Release, (int)MouseButton.Middle); } if ((deltaButtons & MOUSE_BUTTON_RIGHT) != 0) { LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Release, (int)MouseButton.Right); } mouseButtonFlag = GetButtonFlags(ptrPt); } e.Handled = true; }
/// <summary> /// Send mouse move event to the streaming PC /// </summary> private void MouseMove(object sender, PointerRoutedEventArgs e) { var pointerCollection = e.GetIntermediatePoints(null); // TODO what the heck is this even giving me // TODO check for default value?? var first = pointerCollection.FirstOrDefault(); var last = pointerCollection.LastOrDefault(); // TODO is this check redundant? Will the event trigger lie to me frequently enough (if ever) that it'll be an issue? if (first.Position.X != last.Position.X || first.Position.Y != last.Position.Y) { short x = (short)(last.Position.X - first.Position.X); short y = (short)(last.Position.Y - first.Position.Y); Debug.WriteLine(x + " and " + y); hasMoved = true; // Send the values to the streaming PC so it can register mouse movement LimelightCommonRuntimeComponent.SendMouseMoveEvent((short)(x), (short)(y)); } // TODO what even am I doing }
/// <summary> /// Send mouse move event to the streaming PC /// </summary> private void MouseMove(object sender, PointerRoutedEventArgs e) { PointerPoint ptrPt = e.GetCurrentPoint(StreamDisplay); short eventX = (short)ptrPt.Position.X; short eventY = (short)ptrPt.Position.Y; if (eventX != lastX || eventY != lastY) { hasMoved = true; short xToSend = (short)(eventX - lastX); short yToSend = (short)(eventY - lastY); // Send the values to the streaming PC so it can register mouse movement LimelightCommonRuntimeComponent.SendMouseMoveEvent(xToSend, yToSend); lastX = eventX; lastY = eventY; } // Prevent most handlers along the event route from handling the same event again. e.Handled = true; }
/// <summary> /// Send mouse click event to the streaming PC /// </summary> private void MouseUp(object sender, PointerRoutedEventArgs e) { if (!hasMoved) { // We haven't moved so send a click // TODO what even is this pointer crap. How do I send a click? LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Press, (int)MouseButton.Left); // Sleep here because some games do input detection by polling try { // TODO how do we sleep //Thread.Sleep(100); } catch (Exception ex) { Debug.WriteLine("Thread.sleep threw exception " + ex.StackTrace); } // Raise the mouse button LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Release, (int)MouseButton.Left); } }
/// <summary> /// Send mouse down event to the streaming PC /// </summary> private void MouseDown(object sender, PointerRoutedEventArgs e) { Pointer ptr = e.Pointer; PointerPoint ptrPt = e.GetCurrentPoint(StreamDisplay); // If using a mouse, then get the correct button if (ptr.PointerDeviceType == PointerDeviceType.Mouse) { // Send changes and update the current state int deltaButtons = mouseButtonFlag ^ GetButtonFlags(ptrPt); if ((deltaButtons & MOUSE_BUTTON_LEFT) != 0) { LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Press, (int)MouseButton.Left); } if ((deltaButtons & MOUSE_BUTTON_MIDDLE) != 0) { LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Press, (int)MouseButton.Middle); } if ((deltaButtons & MOUSE_BUTTON_RIGHT) != 0) { LimelightCommonRuntimeComponent.SendMouseButtonEvent((byte)MouseButtonAction.Press, (int)MouseButton.Right); } mouseButtonFlag = GetButtonFlags(ptrPt); } else { // We haven't moved yet hasMoved = false; lastX = (short)ptrPt.Position.X; lastY = (short)ptrPt.Position.Y; } e.Handled = true; }
/// <summary> /// Starts the connection by calling into Limelight Common /// </summary> private async Task StartConnection(LimelightStreamConfiguration streamConfig) { NvHttp nv = null; await SetStateText("Resolving hostname..."); try { nv = new NvHttp(selected.IpAddress); } catch (ArgumentNullException) { stageFailureText = "Error resolving hostname"; ConnectionFailed(); return; } try { await nv.ServerIPAddress(); } catch (Exception) { stageFailureText = "Error resolving hostname"; ConnectionFailed(); return; } // Set up callbacks LimelightDecoderRenderer drCallbacks = new LimelightDecoderRenderer(DrSetup, DrStart, DrStop, DrRelease, DrSubmitDecodeUnit); LimelightAudioRenderer arCallbacks = new LimelightAudioRenderer(ArInit, ArStart, ArStop, ArRelease, ArPlaySample); LimelightConnectionListener clCallbacks = new LimelightConnectionListener(ClStageStarting, ClStageComplete, ClStageFailed, ClConnectionStarted, ClConnectionTerminated, ClDisplayMessage, ClDisplayTransientMessage); XmlQuery launchApp; // Launch Steam await SetStateText("Launching Steam"); try { launchApp = StartOrResumeApp(nv, streamConfig); } catch (Exception) { Debug.WriteLine("Can't find steam"); stageFailureText = "Error launching Steam"; ConnectionFailed(); return; } // Call into Common to start the connection Debug.WriteLine("Starting connection"); Regex r = new Regex(@"^(?<octet1>\d+).(?<octet2>\d+).(?<octet3>\d+).(?<octet4>\d+)"); Match m = r.Match(selected.IpAddress); uint addr = (uint)(Convert.ToByte(m.Groups["octet4"].Value) << 24 | Convert.ToByte(m.Groups["octet3"].Value) << 16 | Convert.ToByte(m.Groups["octet2"].Value) << 8 | Convert.ToByte(m.Groups["octet1"].Value)); LimelightCommonRuntimeComponent.StartConnection(addr, streamConfig, clCallbacks, drCallbacks, arCallbacks); if (stageFailureText != null) { Debug.WriteLine("Stage failed"); ConnectionFailed(); return; } else { ConnectionSuccess(); } }
/// <summary> /// Clean up resources /// </summary> private void Cleanup() { // TODO will this be okay if we haven't started a connection? LimelightCommonRuntimeComponent.StopConnection(); hasMoved = false; }