//#define COSMOSDEBUG
using System;
using System.Collections.Generic;
using System.Drawing;
using Cosmos.Debug.Kernel;
using Cosmos.HAL.Drivers.PCI.Video;
namespace Cosmos.System.Graphics
{
///
/// SVGAIIScreen class. Used to draw ractengales to the screen. See also: .
///
public class SVGAIICanvas : Canvas
{
///
/// Disables the SVGA driver, parent method returns to VGA text mode
///
public override void Disable()
{
_xSVGADriver.Disable();
}
///
/// Debugger.
///
internal Debugger mSVGAIIDebugger = new Debugger("System", "SVGAIIScreen");
private static readonly Mode _DefaultMode = new Mode(1024, 768, ColorDepth.ColorDepth32);
///
/// Graphics mode.
///
private Mode _Mode;
///
/// VMWare SVGA 2 driver.
///
private readonly VMWareSVGAII _xSVGADriver;
///
/// Create new instance of the class.
///
/// Thrown if default graphics mode is not suppoted.
public SVGAIICanvas()
: this(_DefaultMode)
{
}
///
/// Create new instance of the class.
///
/// A graphics mode.
/// Thrown if mode is not suppoted.
public SVGAIICanvas(Mode aMode)
{
mSVGAIIDebugger.SendInternal($"Called ctor with mode {aMode}");
ThrowIfModeIsNotValid(aMode);
_xSVGADriver = new VMWareSVGAII();
Mode = aMode;
}
///
/// Get and set graphics mode.
///
/// (set) Thrown if mode is not suppoted.
public override Mode Mode
{
get => _Mode;
set
{
_Mode = value;
mSVGAIIDebugger.SendInternal($"Called Mode set property with mode {_Mode}");
SetGraphicsMode(_Mode);
}
}
///
/// Override canvas dufault graphics mode.
///
public override Mode DefaultGraphicMode => _DefaultMode;
///
/// Draw point.
///
/// Pen to draw with.
/// X coordinate.
/// Y coordinate.
/// Thrown on memory access violation.
public override void DrawPoint(Pen aPen, int aX, int aY)
{
Color xColor = aPen.Color;
if (xColor.A == 0)
{
return;
}
else if (xColor.A < 255)
{
xColor = AlphaBlend(xColor, GetPointColor(aX, aY), xColor.A);
}
mSVGAIIDebugger.SendInternal($"Drawing point to x:{aX}, y:{aY} with {xColor.Name} Color");
_xSVGADriver.SetPixel((uint)aX, (uint)aY, (uint)xColor.ToArgb());
mSVGAIIDebugger.SendInternal($"Done drawing point");
/* No need to refresh all the screen to make the point appear on Screen! */
//xSVGAIIDriver.Update((uint)x, (uint)y, (uint)mode.Columns, (uint)mode.Rows);
_xSVGADriver.Update((uint)aX, (uint)aY, 1, 1);
}
///
/// Draw array of colors.
/// Not implemented.
///
/// Array of colors.
/// X coordinate.
/// Y coordinate.
/// Width.
/// Height.
/// Thrown always.
public override void DrawArray(Color[] aColors, int aX, int aY, int aWidth, int aHeight)
{
throw new NotImplementedException();
//xSVGAIIDriver.
}
///
/// Draw point.
/// Not implemented.
///
/// Pen to draw with.
/// X coordinate.
/// Y coordinate.
/// Thrown always (only int coordinates supported).
public override void DrawPoint(Pen aPen, float aX, float aY)
{
//xSVGAIIDriver.
throw new NotImplementedException();
}
///
/// Draw filled rectangle.
///
/// Pen to draw with.
/// starting X coordinate.
/// starting Y coordinate.
/// Width.
/// Height.
/// Thrown on memory access violation.
/// Thrown if VMWare SVGA 2 has no rectange copy capability
public override void DrawFilledRectangle(Pen aPen, int aX_start, int aY_start, int aWidth, int aHeight)
{
_xSVGADriver.Fill((uint)aX_start, (uint)aY_start, (uint)aWidth, (uint)aHeight, (uint)aPen.Color.ToArgb());
}
//public override IReadOnlyList AvailableModes { get; } = new List
///
/// Available SVGA 2 supported video modes.
///
/// SD:
///
/// - 320x200x32.
/// - 320x240x32.
/// - 640x480x32.
/// - 720x480x32.
/// - 800x600x32.
/// - 1024x768x32.
/// - 1152x768x32.
///
///
///
/// HD:
///
/// - 1280x720x32.
/// - 1280x768x32.
/// - 1280x800x32.
/// - 1280x1024x32.
///
///
///
/// HDR:
///
/// - 1360x768x32.
/// - 1366x768x32.
/// - 1440x900x32.
/// - 1400x1050x32.
/// - 1600x1200x32.
/// - 1680x1050x32.
///
///
///
/// HDTV:
///
/// - 1920x1080x32.
/// - 1920x1200x32.
///
///
///
/// 2K:
///
/// - 2048x1536x32.
/// - 2560x1080x32.
/// - 2560x1600x32.
/// - 2560x2048x32.
/// - 3200x2048x32.
/// - 3200x2400x32.
/// - 3840x2400x32.
///
///
///
public override List AvailableModes { get; } = new List
{
/* VmWare maybe supports 16 bit resolutions but CGS not yet (we should need to do RGB32->RGB16 conversion) */
#if false
/* 16-bit Depth Resolutions*/
/* SD Resolutions */
new Mode(320, 200, ColorDepth.ColorDepth16),
new Mode(320, 240, ColorDepth.ColorDepth16),
new Mode(640, 480, ColorDepth.ColorDepth16),
new Mode(720, 480, ColorDepth.ColorDepth16),
new Mode(800, 600, ColorDepth.ColorDepth16),
new Mode(1024, 768, ColorDepth.ColorDepth16),
new Mode(1152, 768, ColorDepth.ColorDepth16),
/* Old HD-Ready Resolutions */
new Mode(1280, 720, ColorDepth.ColorDepth16),
new Mode(1280, 768, ColorDepth.ColorDepth16),
new Mode(1280, 800, ColorDepth.ColorDepth16), // WXGA
new Mode(1280, 1024, ColorDepth.ColorDepth16), // SXGA
/* Better HD-Ready Resolutions */
new Mode(1360, 768, ColorDepth.ColorDepth16),
new Mode(1366, 768, ColorDepth.ColorDepth16), // Original Laptop Resolution
new Mode(1440, 900, ColorDepth.ColorDepth16), // WXGA+
new Mode(1400, 1050, ColorDepth.ColorDepth16), // SXGA+
new Mode(1600, 1200, ColorDepth.ColorDepth16), // UXGA
new Mode(1680, 1050, ColorDepth.ColorDepth16), // WXGA++
/* HDTV Resolutions */
new Mode(1920, 1080, ColorDepth.ColorDepth16),
new Mode(1920, 1200, ColorDepth.ColorDepth16), // WUXGA
/* 2K Resolutions */
new Mode(2048, 1536, ColorDepth.ColorDepth16), // QXGA
new Mode(2560, 1080, ColorDepth.ColorDepth16), // UW-UXGA
new Mode(2560, 1600, ColorDepth.ColorDepth16), // WQXGA
new Mode(2560, 2048, ColorDepth.ColorDepth16), // QXGA+
new Mode(3200, 2048, ColorDepth.ColorDepth16), // WQXGA+
new Mode(3200, 2400, ColorDepth.ColorDepth16), // QUXGA
new Mode(3840, 2400, ColorDepth.ColorDepth16), // WQUXGA
#endif
/* 32-bit Depth Resolutions*/
/* SD Resolutions */
new Mode(320, 200, ColorDepth.ColorDepth32),
new Mode(320, 240, ColorDepth.ColorDepth32),
new Mode(640, 480, ColorDepth.ColorDepth32),
new Mode(720, 480, ColorDepth.ColorDepth32),
new Mode(800, 600, ColorDepth.ColorDepth32),
new Mode(1024, 768, ColorDepth.ColorDepth32),
new Mode(1152, 768, ColorDepth.ColorDepth32),
/* Old HD-Ready Resolutions */
new Mode(1280, 720, ColorDepth.ColorDepth32),
new Mode(1280, 768, ColorDepth.ColorDepth32),
new Mode(1280, 800, ColorDepth.ColorDepth32), // WXGA
new Mode(1280, 1024, ColorDepth.ColorDepth32), // SXGA
/* Better HD-Ready Resolutions */
new Mode(1360, 768, ColorDepth.ColorDepth32),
//new Mode(1366, 768, ColorDepth.ColorDepth32), // Original Laptop Resolution - this one is for some reason broken in vmware
new Mode(1440, 900, ColorDepth.ColorDepth32), // WXGA+
new Mode(1400, 1050, ColorDepth.ColorDepth32), // SXGA+
new Mode(1600, 1200, ColorDepth.ColorDepth32), // UXGA
new Mode(1680, 1050, ColorDepth.ColorDepth32), // WXGA++
/* HDTV Resolutions */
new Mode(1920, 1080, ColorDepth.ColorDepth32),
new Mode(1920, 1200, ColorDepth.ColorDepth32), // WUXGA
/* 2K Resolutions */
new Mode(2048, 1536, ColorDepth.ColorDepth32), // QXGA
new Mode(2560, 1080, ColorDepth.ColorDepth32), // UW-UXGA
new Mode(2560, 1600, ColorDepth.ColorDepth32), // WQXGA
new Mode(2560, 2048, ColorDepth.ColorDepth32), // QXGA+
new Mode(3200, 2048, ColorDepth.ColorDepth32), // WQXGA+
new Mode(3200, 2400, ColorDepth.ColorDepth32), // QUXGA
new Mode(3840, 2400, ColorDepth.ColorDepth32), // WQUXGA
};
///
/// Set graphics mode.
///
/// A mode.
/// Thrown if mode is not suppoted.
private void SetGraphicsMode(Mode aMode)
{
ThrowIfModeIsNotValid(aMode);
var xWidth = (uint)aMode.Columns;
var xHeight = (uint)aMode.Rows;
var xColorDepth = (uint)aMode.ColorDepth;
_xSVGADriver.SetMode(xWidth, xHeight, xColorDepth);
}
///
/// Clear screen to specified color.
///
/// Color.
/// Thrown on memory access violation.
/// Thrown if VMWare SVGA 2 has no rectange copy capability
public override void Clear(Color aColor)
{
_xSVGADriver.Fill(0, 0, (uint)Mode.Columns, (uint)Mode.Rows, (uint)aColor.ToArgb());
}
///
/// Get pixel color.
///
/// A X coordinate.
/// A Y coordinate.
/// Color value.
/// Thrown on memory access violation.
public Color GetPixel(int aX, int aY)
{
var xColorARGB = _xSVGADriver.GetPixel((uint)aX, (uint)aY);
return Color.FromArgb((int)xColorARGB);
}
///
/// Set cursor.
///
/// Visible.
/// A X coordinate.
/// A Y coordinate.
public void SetCursor(bool aVisible, int aX, int aY)
{
_xSVGADriver.SetCursor(aVisible, (uint)aX, (uint)aY);
}
///
/// Create cursor.
///
public void CreateCursor()
{
_xSVGADriver.DefineCursor();
}
///
/// Copy pixel
///
/// A source X coordinate.
/// A source Y coordinate.
/// A destination X coordinate.
/// A destination Y coordinate.
/// A width.
/// A height.
/// Thrown if VMWare SVGA 2 has no rectangle copy capability
public void CopyPixel(int aX, int aY, int aNewX, int aNewY, int aWidth = 1, int aHeight = 1)
{
_xSVGADriver.Copy((uint)aX, (uint)aY, (uint)aNewX, (uint)aNewY, (uint)aWidth, (uint)aHeight);
}
///
/// Move pixel
///
/// A X coordinate.
/// A Y coordinate.
/// A new X coordinate.
/// A new Y coordinate.
/// Thrown if VMWare SVGA 2 has no rectange copy capability
/// Thrown on memory access violation.
public void MovePixel(int aX, int aY, int aNewX, int aNewY)
{
_xSVGADriver.Copy((uint)aX, (uint)aY, (uint)aNewX, (uint)aNewY, 1, 1);
_xSVGADriver.SetPixel((uint)aX, (uint)aY, 0);
}
///
/// Get point color.
///
/// X coordinate.
/// Y coordinate.
/// Color value.
/// Thrown on memory access violation.
public override Color GetPointColor(int aX, int aY)
{
return Color.FromArgb((int)_xSVGADriver.GetPixel((uint)aX, (uint)aY));
}
public override void Display()
{
}
}
}