diff --git a/VDash/MainWindow.xaml.cs b/VDash/MainWindow.xaml.cs index 82d925d..76a4100 100644 --- a/VDash/MainWindow.xaml.cs +++ b/VDash/MainWindow.xaml.cs @@ -35,12 +35,24 @@ namespace VDash throw new Exception($"Error connecting to VR: {initError.ToString()}"); } - var discordSelector = new WindowSelectors.FromWindowTitle("Discord", WindowSelectors.FromWindowTitle.TitleSearchType.Contains); - Overlay.WindowOverlay discordOverlay = new Overlay.WindowOverlay("discord", "Discord", discordSelector, true); - discordOverlay.Create(); + //ulong desktopOverlay = 0; - Overlay.WindowOverlay obsOverlay = new Overlay.WindowOverlay("obs", "OBS", new WindowSelectors.FromProcessName("obs64"), false); - obsOverlay.Create(); + //var err = OpenVR.Overlay.FindOverlay("valve.steam.desktop", ref desktopOverlay); + + //HmdVector2_t vec = new HmdVector2_t(); + + //OpenVR.Overlay.GetOverlayMouseScale(desktopOverlay, ref vec); + + //var discordSelector = new WindowSelectors.FromWindowTitle("Discord", WindowSelectors.FromWindowTitle.TitleSearchType.Contains); + //Overlay.WindowOverlay discordOverlay = new Overlay.WindowOverlay("discord", "Discord", discordSelector, true); + //discordOverlay.Create(); + + var vsSelector = new WindowSelectors.FromWindowTitle("Microsoft Visual Studio", WindowSelectors.FromWindowTitle.TitleSearchType.Contains); + Overlay.WindowOverlay vsOverlay = new Overlay.WindowOverlay("vs", "Visual Studio", vsSelector, true); + vsOverlay.Create(); + + //Overlay.WindowOverlay obsOverlay = new Overlay.WindowOverlay("obs", "OBS", new WindowSelectors.FromProcessName("obs64"), false); + //obsOverlay.Create(); } } diff --git a/VDash/Overlay/WindowOverlay.cs b/VDash/Overlay/WindowOverlay.cs index ec09f2b..7f12b94 100644 --- a/VDash/Overlay/WindowOverlay.cs +++ b/VDash/Overlay/WindowOverlay.cs @@ -2,6 +2,7 @@ using SharpDX.Direct3D11; using SharpDX.DXGI; using System; +using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; @@ -53,7 +54,7 @@ namespace VDash.Overlay public void Create() { if (m_Created) { throw new Exception("This overlay has already been created."); } - ConsoleManager.Show(); + //ConsoleManager.Show(); ulong thumbHandle = OpenVR.k_ulOverlayHandleInvalid; //Actually create the overlay @@ -64,8 +65,6 @@ namespace VDash.Overlay { throw new Exception($"Error creating overlay: {err}"); } - - overlay.SetOverlayWidthInMeters(m_Handle, 2.5f); overlay.SetOverlayInputMethod(m_Handle, VROverlayInputMethod.Mouse); m_Running = true; @@ -136,12 +135,23 @@ namespace VDash.Overlay } //Skip rendering if overlay isn't visible - //if ((m_Handle == OpenVR.k_ulOverlayHandleInvalid) || overlay == null || (!overlay.IsOverlayVisible(m_Handle))) - //{ - // Thread.Sleep(100); - // continue; - //} +#if !DEBUG + if ((m_Handle == Openvr.k_uloverlayhandleinvalid) || overlay == null || (!overlay.isoverlayvisible(m_handle))) + { + thread.sleep(100); + continue; + } +#endif + IntPtr windowHandle = IntPtr.Zero; + try + { + windowHandle = m_Selector.GetWindowHandle(); + } + catch (WindowNotFoundException) + { + //Console.WriteLine($"[{m_Key}] {m_Name}: Window not found."); + } #region VR Events VREvent_t vrEvent = new VREvent_t(); @@ -152,20 +162,92 @@ namespace VDash.Overlay { case EVREventType.VREvent_MouseMove: { - var x = vrEvent.data.mouse.x; - var y = vrEvent.data.mouse.y; + if (windowHandle != IntPtr.Zero) + { + var vrX = vrEvent.data.mouse.x; + var vrY = vrEvent.data.mouse.y; + + var rect = new User32.Rect(); + User32.GetWindowRect(windowHandle, ref rect); + + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; + + var point = new User32.POINT() { x = (int)vrX, y = height - (int)vrY }; + var succ = User32.ClientToScreen(windowHandle, ref point); + + if (!succ) + { + Console.WriteLine("ClientToScreen failed."); + } + + + succ = User32.SetCursorPos((int)point.x, (int)point.y); + + if (!succ) + { + Console.WriteLine("SetCursorPos failed."); + } + } break; } case EVREventType.VREvent_MouseButtonDown: { var clickType = (EVRMouseButton)vrEvent.data.mouse.button; + Console.WriteLine($"Mouse button down: {clickType}"); + + var winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTDOWN; + + switch (clickType) + { + case EVRMouseButton.Left: + { + winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTDOWN; + break; + } + case EVRMouseButton.Middle: + { + winClickType = User32.MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN; + break; + } + case EVRMouseButton.Right: + { + winClickType = User32.MouseEventFlags.MOUSEEVENTF_RIGHTDOWN; + break; + } + } + + User32.mouse_event(winClickType, 0, 0, 0, UIntPtr.Zero); break; } case EVREventType.VREvent_MouseButtonUp: { var clickType = (EVRMouseButton)vrEvent.data.mouse.button; + Console.WriteLine($"Mouse button up: {clickType}"); + var winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTUP; + + switch (clickType) + { + case EVRMouseButton.Left: + { + winClickType = User32.MouseEventFlags.MOUSEEVENTF_LEFTUP; + break; + } + case EVRMouseButton.Middle: + { + winClickType = User32.MouseEventFlags.MOUSEEVENTF_MIDDLEUP; + break; + } + case EVRMouseButton.Right: + { + winClickType = User32.MouseEventFlags.MOUSEEVENTF_RIGHTUP; + break; + } + } + + User32.mouse_event(winClickType, 0, 0, 0, UIntPtr.Zero); break; } case EVREventType.VREvent_OverlayShown: @@ -181,18 +263,9 @@ namespace VDash.Overlay } } - #endregion +#endregion - #region Acutally Render - IntPtr windowHandle = IntPtr.Zero; - try - { - windowHandle = m_Selector.GetWindowHandle(); - } - catch (WindowNotFoundException) - { - //Console.WriteLine($"[{m_Key}] {m_Name}: Window not found."); - } +#region Acutally Render if (windowHandle != IntPtr.Zero) { @@ -210,6 +283,36 @@ namespace VDash.Overlay { graphics.CopyFromScreen(rect.left, rect.top, 0, 0, new Size(width, height), CopyPixelOperation.SourceCopy); + //Draw cursor + User32.CURSORINFO pci; + pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(User32.CURSORINFO)); + + if (User32.GetCursorInfo(out pci)) + { + + User32.POINT cursorPoint = new User32.POINT() { x = pci.ptScreenPos.X, y = pci.ptScreenPos.Y}; + + if (User32.ScreenToClient(windowHandle, ref cursorPoint)) + { + + if (pci.flags == User32.CURSOR_SHOWING) + { + User32.DrawIcon(graphics.GetHdc(), (int)cursorPoint.x, (int)cursorPoint.y, pci.hCursor); + graphics.ReleaseHdc(); + } + } + else + { + Console.WriteLine("Error getting coords to draw cursor."); + } + } + else + { + string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message; + Console.WriteLine($"Error getting cursor info: {errorMessage}"); + } + + var data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); @@ -244,6 +347,10 @@ namespace VDash.Overlay screenTexture = new Texture2D(device, textureDesc); stream = new DataStream(4 * width * height, true, true); + overlay.SetOverlayWidthInMeters(m_Handle, 2.5f); + + HmdVector2_t vecWindowSize = new HmdVector2_t() { v0 = width, v1 = height }; + OpenVR.Overlay.SetOverlayMouseScale(m_Handle, ref vecWindowSize); Console.WriteLine("Updated!"); @@ -252,7 +359,6 @@ namespace VDash.Overlay //using () { - var screenView = new ShaderResourceView(device, screenTexture); device.ImmediateContext.PixelShader.SetShaderResource(0, screenView); @@ -293,6 +399,10 @@ namespace VDash.Overlay } } + + VRTextureBounds_t bounds = new VRTextureBounds_t(); + OpenVR.Overlay.GetOverlayTextureBounds(m_Handle, ref bounds); + var texture = new Texture_t(); texture.handle = screenTexture.NativePointer; texture.eType = ETextureType.DirectX; @@ -300,6 +410,7 @@ namespace VDash.Overlay EVROverlayError result = overlay.SetOverlayTexture(m_Handle, ref texture); if (result != EVROverlayError.None) { + Console.WriteLine($"Error rendering: {result}"); } @@ -314,13 +425,13 @@ namespace VDash.Overlay } } } - #endregion +#endregion Thread.Sleep(20); if (DateTime.Now.Subtract(lastFps).TotalMilliseconds > 1000) { - Console.WriteLine($"{frames} fps."); + //Console.WriteLine($"{frames} fps."); frames = 0; lastFps = DateTime.Now; } @@ -343,8 +454,59 @@ namespace VDash.Overlay public int bottom; } + [StructLayout(LayoutKind.Sequential)] + public struct POINT + { + public long x; + public long y; + } + + [StructLayout(LayoutKind.Sequential)] + public struct CURSORINFO + { + public Int32 cbSize; + public Int32 flags; + public IntPtr hCursor; + public Point ptScreenPos; + } + public const Int32 CURSOR_SHOWING = 0x00000001; + [DllImport("user32.dll")] public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetCursorPos(int x, int y); + + [DllImport("user32.dll")] + public static extern bool ClientToScreen(IntPtr hwnd, ref POINT lpPoint); + + [DllImport("user32.dll")] + public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint); + + [DllImport("user32.dll")] + public static extern bool GetCursorInfo(out CURSORINFO pci); + + [DllImport("user32.dll")] + public static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon); + + [DllImport("user32.dll")] + public static extern void mouse_event(MouseEventFlags dwFlags, int dx, int dy, uint dwData, UIntPtr dwExtraInfo); + public enum MouseEventFlags + { + MOUSEEVENTF_ABSOLUTE = 0x8000, + MOUSEEVENTF_LEFTDOWN = 0x0002, + MOUSEEVENTF_LEFTUP = 0x0004, + MOUSEEVENTF_MIDDLEDOWN = 0x0020, + MOUSEEVENTF_MIDDLEUP = 0x0040, + MOUSEEVENTF_MOVE = 0x0001, + MOUSEEVENTF_RIGHTDOWN = 0x0008, + MOUSEEVENTF_RIGHTUP = 0x0010, + MOUSEEVENTF_XDOWN = 0x0080, + MOUSEEVENTF_XUP = 0x0100, + MOUSEEVENTF_WHEEL = 0x0800, + MOUSEEVENTF_HWHEEL = 0x01000 + } } public void Dispose()