aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteDesktop/DefaultRemoteDesktopService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteDesktop/DefaultRemoteDesktopService.cs')
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteDesktop/DefaultRemoteDesktopService.cs198
1 files changed, 198 insertions, 0 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteDesktop/DefaultRemoteDesktopService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteDesktop/DefaultRemoteDesktopService.cs
new file mode 100644
index 000000000..9099e6346
--- /dev/null
+++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteDesktop/DefaultRemoteDesktopService.cs
@@ -0,0 +1,198 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Tango.Core;
+using Tango.Core.DI;
+using Tango.Integration.ExternalBridge;
+using Tango.PPC.Common.Application;
+using Tango.PPC.Common.ExternalBridge;
+using Tango.RemoteDesktop;
+using Tango.RemoteDesktop.CaptureMethods;
+using Tango.RemoteDesktop.Encoders;
+using Tango.RemoteDesktop.Engines;
+using Tango.RemoteDesktop.Frames;
+using Tango.RemoteDesktop.Network;
+using Tango.Settings;
+using Tango.Transport;
+
+namespace Tango.PPC.Common.RemoteDesktop
+{
+ [TangoCreateWhenRegistered]
+ public class DefaultRemoteDesktopService : ExtendedObject, IRemoteDesktopService, IExternalBridgeRequestHandler
+ {
+ private class RemoteDesktopClient
+ {
+ public String Token { get; set; }
+ public ExternalBridgeReceiver Receiver { get; set; }
+ public bool InitialPacketSent { get; set; }
+ }
+
+ private RemoteDesktopPacket _initialPacket;
+ private RasterScreenCaptureEngine _engine;
+ private PPCSettings _settings;
+ private List<RemoteDesktopClient> _clients;
+
+ public DefaultRemoteDesktopService(IPPCApplicationManager applicationManager, IPPCExternalBridgeService externalBridge)
+ {
+ _settings = SettingsManager.Default.GetOrCreate<PPCSettings>();
+ applicationManager.ApplicationReady += ApplicationManager_ApplicationReady;
+
+ externalBridge.RegisterRequestHandler(this);
+
+ _clients = new List<RemoteDesktopClient>();
+ _engine = new RasterScreenCaptureEngine();
+
+ _engine.FrameRate = Math.Min(Math.Max(_settings.RemoteDesktopFrameRate, 1), 20);
+ _engine.FrameReceived += _engine_FrameReceived;
+ }
+
+ private void ApplicationManager_ApplicationReady(object sender, EventArgs e)
+ {
+
+#if DEBUG
+ _engine.CaptureMethod.Dispose();
+
+ var mainWindow = System.Windows.Application.Current.MainWindow;
+
+ _engine.CaptureRegion = new CaptureRegion()
+ {
+ Left = (int)mainWindow.Left,
+ Top = (int)mainWindow.Top,
+ Width = (int)mainWindow.Width,
+ Height = (int)mainWindow.Height
+ };
+ _engine.CaptureMethod = new GdiScreenCapture();
+#endif
+
+ if (_settings.EnableRemoteDesktop)
+ {
+ Start();
+ }
+ }
+
+ private bool _isStarted;
+ public bool IsStarted
+ {
+ get { return _isStarted; }
+ private set { _isStarted = value; RaisePropertyChangedAuto(); }
+ }
+
+ public void Start()
+ {
+ if (!IsStarted)
+ {
+ _engine.Start();
+ IsStarted = true;
+ }
+ }
+
+ public void Stop()
+ {
+ if (IsStarted)
+ {
+ _engine.Stop();
+ IsStarted = false;
+ }
+ }
+
+ [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteDesktopSessionRequest))]
+ public async void OnStartRemoteDesktopSessionRequestReceived(StartRemoteDesktopSessionRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ var client = _clients.SingleOrDefault(x => x.Receiver == receiver);
+
+ if (client != null)
+ {
+ _clients.Remove(client);
+ }
+
+ _clients.Add(new RemoteDesktopClient()
+ {
+ Receiver = receiver,
+ Token = token
+ });
+
+ await receiver.SendGenericResponse(new StartRemoteDesktopSessionResponse()
+ {
+ FrameRate = _engine.FrameRate
+ }, token, new TransportResponseConfig()
+ {
+ Immediate = true,
+ });
+ }
+
+ private async void _engine_FrameReceived(object sender, ScreenCaptureFrameReceivedEventArgs<RasterFrame> e)
+ {
+ _initialPacket = new RemoteDesktopPacket()
+ {
+ Bitmap = e.Frame.ToEncoder<PngEncoder>().ToArray(),
+ };
+
+ foreach (var client in _clients.ToList().Where(x => !x.InitialPacketSent))
+ {
+ try
+ {
+ await client.Receiver.SendGenericResponse(new StartRemoteDesktopSessionResponse()
+ {
+ Packet = _initialPacket,
+ }, client.Token, new TransportResponseConfig()
+ {
+ Immediate = true,
+ });
+
+ client.InitialPacketSent = true;
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
+ }
+
+ if (e.Frame.DifferenceAvailable && e.Frame.DifferenceCount > 0)
+ {
+ var diffFrame = e.Frame.ToDifference();
+ diffFrame = diffFrame.OptimizeBounds();
+
+ RemoteDesktopPacket packet = new RemoteDesktopPacket()
+ {
+ Bitmap = diffFrame.ToEncoder<PngEncoder>().ToArray(),
+ IsPartial = true,
+ PartialRegion = new CaptureRegion(diffFrame.Left, diffFrame.Top, diffFrame.Width, diffFrame.Height),
+ };
+
+ diffFrame.Dispose();
+ e.Frame.Dispose();
+
+ foreach (var client in _clients.ToList().Where(x => x.InitialPacketSent))
+ {
+ try
+ {
+ await client.Receiver.SendGenericResponse(new StartRemoteDesktopSessionResponse()
+ {
+ Packet = packet
+ }, client.Token, new TransportResponseConfig()
+ {
+ Immediate = false,
+ });
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex);
+ }
+ }
+ }
+ }
+
+ public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
+ {
+ var client = _clients.SingleOrDefault(x => x.Receiver == receiver);
+
+ if (client != null)
+ {
+ _clients.Remove(client);
+ }
+ }
+ }
+}