VirtualComputer/VirtualComputerSender/MCFrameBuffer.cs

179 lines
4.3 KiB
C#

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 MCFrameBuffer : IFramebuffer
{
private IDisplay Display;
private Timer LastFullUpdateTimer;
private UdpClient Client;
public MCFrameBuffer(IDisplay display)
{
Display = display;
LastFullUpdateTimer = new Timer();
LastFullUpdateTimer.Interval = 5000;
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
{
Console.WriteLine("Screen height queried.");
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
{
Console.WriteLine("Screen width queried.");
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)
{
}
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;
public volatile int[] Screen = new int[640 * 480];
public void NotifyUpdateImage(uint aX, uint aY, uint aWidth, uint aHeight, Array aImage)
{
Task.Run(() =>
{
var img = (byte[])aImage;
int x = 0;
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;
Screen[640 * j + i] = Color.FromArgb(img[x + 2], img[x + 1], img[x]).ToArgb();
x += 4;
}
x += (int)aX * 4;
int add = ((int)(aX + aWidth) - ScreenWidth);
if (add > 0)
x += add * 4;
}
});
}
public void NotifyChange(uint aScreenId, uint aXOrigin, uint aYOrigin, uint aWidth, uint aHeight)
{
}
public void Notify3DEvent(uint aType, Array aData)
{
}
}
}