using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Timers; using VirtualBox; namespace VirtualComputerSender //Copyright © NorbiPeti 2015-2016 { public class NetFrameBuffer : IFramebuffer { private IDisplay Display; private Timer LastFullUpdateTimer; private UdpClient Client; public NetFrameBuffer(IDisplay display) { //address = Marshal.AllocHGlobal(1440 * 900 * 4); Display = display; LastFullUpdateTimer = new Timer(); LastFullUpdateTimer.Interval = 60000; LastFullUpdateTimer.Elapsed += UpdateScreen; Client = new UdpClient(); Client.Connect(new IPEndPoint(IPAddress.Loopback, 5896)); LastFullUpdateTimer.Start(); } private void UpdateScreen(object sender, EventArgs args) { Display.InvalidateAndUpdateScreen(0); } public IntPtr Address { get { return IntPtr.Zero; } } public const uint CBitsPerPixel = 32; public uint BitsPerPixel { get { return CBitsPerPixel; } } public uint BytesPerLine { get { return ScreenWidth; } } public uint Height { get { return ScreenHeight; } } public uint HeightReduction { get { return 2; } } public IFramebufferOverlay Overlay { get { return null; } } public BitmapFormat PixelFormat { get { return BitmapFormat.BitmapFormat_RGBA; } } public uint Width { get { return ScreenWidth; } } public long WinId { get { return 0; } } public Array Capabilities { get { return new FramebufferCapabilities[] { FramebufferCapabilities.FramebufferCapabilities_UpdateImage }; } } public uint GetVisibleRegion(ref byte aRectangles, uint aCount) { throw new InvalidOperationException("This should not be used."); } public void NotifyUpdate(uint aX, uint aY, uint aWidth, uint aHeight) { //throw new InvalidOperationException("This should not be used. (Only UpdateImage.)"); } public void ProcessVHWACommand(ref byte aCommand) { } public void SetVisibleRegion(ref byte aRectangles, uint aCount) { } public int VideoModeSupported(uint aWidth, uint aHeight, uint aBpp) { return 1; } public const int ScreenWidth = 640; public const int ScreenHeight = 480; private Color[,] Screen = new Color[640, 480]; public void NotifyUpdateImage(uint aX, uint aY, uint aWidth, uint aHeight, Array aImage) { var img = aImage.Cast().ToArray(); int x = 0; //if (aImage.Length > 1152000) //Form1.Screen.Clear(Color.Black); //else //{ //Display.SetSeamlessMode(1); /*if (aWidth == 800 && aHeight == 600) Display.SetVideoModeHint(0, 1, 0, 0, 0, NetFrameBuffer.ScreenWidth, NetFrameBuffer.ScreenHeight, NetFrameBuffer.CBitsPerPixel);*/ for (int j = (int)aY; j < aHeight && j < ScreenHeight; j++) { for (int i = (int)aX; i < aWidth && i < ScreenWidth; i++) { if (x + 4 > aImage.Length) return; //Form1.Screen.FillRectangle(new SolidBrush(Color.FromArgb(255, img[x + 2], img[x + 1], img[x])), i, j, 1, 1); Screen[i, j] = Color.FromArgb(img[x + 2], img[x + 1], img[x]); x += 4; } x += (int)aX * 4; int add = ((int)(aX + aWidth) - ScreenWidth); if (add > 0) x += add * 4; } /*var ms = new MemoryStream(); var bw = new BinaryWriter(ms); bw.Write(Convert.ToInt32(aX)); bw.Write(Convert.ToInt32(aY)); bw.Write(Convert.ToInt32(aWidth)); bw.Write(Convert.ToInt32(aHeight)); bw.Write(img); bw.Flush(); Client.Send(BitConverter.GetBytes(Convert.ToInt32(ms.Length)), 4); Client.Send(ms.ToArray(), Convert.ToInt32(ms.Length)); bw.Close();*/ //} } public void NotifyChange(uint aScreenId, uint aXOrigin, uint aYOrigin, uint aWidth, uint aHeight) { } public void Notify3DEvent(uint aType, Array aData) { } } }