using System;
using System.Runtime.InteropServices;
using NvAPIWrapper.Native.Helpers;
namespace NvAPIWrapper.Native.Display.Structures
{
///
/// Holds VESA scan out timing parameters
///
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct Timing : IEquatable
{
internal readonly ushort _HorizontalVisible;
internal readonly ushort _HorizontalBorder;
internal readonly ushort _HorizontalFrontPorch;
internal readonly ushort _HorizontalSyncWidth;
internal readonly ushort _HorizontalTotal;
internal readonly TimingHorizontalSyncPolarity _HorizontalSyncPolarity;
internal readonly ushort _VerticalVisible;
internal readonly ushort _VerticalBorder;
internal readonly ushort _VerticalFrontPorch;
internal readonly ushort _VerticalSyncWidth;
internal readonly ushort _VerticalTotal;
internal readonly TimingVerticalSyncPolarity _VerticalSyncPolarity;
internal readonly TimingScanMode _ScanMode;
internal readonly uint _PixelClockIn10KHertz;
internal readonly TimingExtra _Extra;
///
/// Creates an instance of structure.
///
/// The horizontal visible pixels
/// The vertical visible pixels
/// The horizontal border pixels
/// The vertical border pixels
/// The horizontal front porch pixels
/// The vertical front porch pixels
/// The horizontal sync width pixels
/// The vertical sync width pixels
/// The horizontal total pixels
/// The vertical total pixels
/// The horizontal sync polarity
/// The vertical sync polarity
/// The scan mode
/// The extra timing information
public Timing(
ushort horizontalVisible,
ushort verticalVisible,
ushort horizontalBorder,
ushort verticalBorder,
ushort horizontalFrontPorch,
ushort verticalFrontPorch,
ushort horizontalSyncWidth,
ushort verticalSyncWidth,
ushort horizontalTotal,
ushort verticalTotal,
TimingHorizontalSyncPolarity horizontalPolarity,
TimingVerticalSyncPolarity verticalPolarity,
TimingScanMode scanMode,
TimingExtra extra
)
{
this = typeof(Timing).Instantiate();
_HorizontalVisible = horizontalVisible;
_HorizontalBorder = horizontalBorder;
_HorizontalFrontPorch = horizontalFrontPorch;
_HorizontalSyncWidth = horizontalSyncWidth;
_HorizontalTotal = horizontalTotal;
_HorizontalSyncPolarity = horizontalPolarity;
_VerticalVisible = verticalVisible;
_VerticalBorder = verticalBorder;
_VerticalFrontPorch = verticalFrontPorch;
_VerticalSyncWidth = verticalSyncWidth;
_VerticalTotal = verticalTotal;
_VerticalSyncPolarity = verticalPolarity;
_ScanMode = scanMode;
_PixelClockIn10KHertz =
(uint) (horizontalTotal * verticalTotal * (extra.FrequencyInMillihertz / 1000d) / 10000);
_Extra = extra;
}
///
/// Creates an instance of structure.
///
/// The horizontal visible pixels
/// The vertical visible pixels
/// The horizontal border pixels
/// The vertical border pixels
/// The horizontal front porch pixels
/// The vertical front porch pixels
/// The horizontal sync width pixels
/// The vertical sync width pixels
/// The horizontal total pixels
/// The vertical total pixels
/// The horizontal sync polarity
/// The vertical sync polarity
/// The scan mode
/// The frequency in hertz
/// The number of identical horizontal pixels that are repeated; 1 = no repetition
public Timing(
ushort horizontalVisible,
ushort verticalVisible,
ushort horizontalBorder,
ushort verticalBorder,
ushort horizontalFrontPorch,
ushort verticalFrontPorch,
ushort horizontalSyncWidth,
ushort verticalSyncWidth,
ushort horizontalTotal,
ushort verticalTotal,
TimingHorizontalSyncPolarity horizontalPolarity,
TimingVerticalSyncPolarity verticalPolarity,
TimingScanMode scanMode,
double refreshRateFrequencyInHz,
ushort horizontalPixelRepetition = 1
) : this(
horizontalVisible, verticalVisible, horizontalBorder,
verticalBorder, horizontalFrontPorch, verticalFrontPorch,
horizontalSyncWidth, verticalSyncWidth, horizontalTotal,
verticalTotal, horizontalPolarity, verticalPolarity, scanMode,
new TimingExtra(
refreshRateFrequencyInHz,
$"CUST:{horizontalVisible}x{verticalVisible}x{refreshRateFrequencyInHz:F3}Hz",
0,
0,
horizontalPixelRepetition
)
)
{
}
///
public bool Equals(Timing other)
{
return _HorizontalVisible == other._HorizontalVisible &&
_HorizontalBorder == other._HorizontalBorder &&
_HorizontalFrontPorch == other._HorizontalFrontPorch &&
_HorizontalSyncWidth == other._HorizontalSyncWidth &&
_HorizontalTotal == other._HorizontalTotal &&
_HorizontalSyncPolarity == other._HorizontalSyncPolarity &&
_VerticalVisible == other._VerticalVisible &&
_VerticalBorder == other._VerticalBorder &&
_VerticalFrontPorch == other._VerticalFrontPorch &&
_VerticalSyncWidth == other._VerticalSyncWidth &&
_VerticalTotal == other._VerticalTotal &&
_VerticalSyncPolarity == other._VerticalSyncPolarity &&
_ScanMode == other._ScanMode &&
_PixelClockIn10KHertz == other._PixelClockIn10KHertz &&
_Extra.Equals(other._Extra);
}
///
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is Timing timing && Equals(timing);
}
///
public override int GetHashCode()
{
unchecked
{
var hashCode = _HorizontalVisible.GetHashCode();
hashCode = (hashCode * 397) ^ _HorizontalBorder.GetHashCode();
hashCode = (hashCode * 397) ^ _HorizontalFrontPorch.GetHashCode();
hashCode = (hashCode * 397) ^ _HorizontalSyncWidth.GetHashCode();
hashCode = (hashCode * 397) ^ _HorizontalTotal.GetHashCode();
hashCode = (hashCode * 397) ^ (int) _HorizontalSyncPolarity;
hashCode = (hashCode * 397) ^ _VerticalVisible.GetHashCode();
hashCode = (hashCode * 397) ^ _VerticalBorder.GetHashCode();
hashCode = (hashCode * 397) ^ _VerticalFrontPorch.GetHashCode();
hashCode = (hashCode * 397) ^ _VerticalSyncWidth.GetHashCode();
hashCode = (hashCode * 397) ^ _VerticalTotal.GetHashCode();
hashCode = (hashCode * 397) ^ (int) _VerticalSyncPolarity;
hashCode = (hashCode * 397) ^ (int) _ScanMode;
hashCode = (hashCode * 397) ^ (int) _PixelClockIn10KHertz;
hashCode = (hashCode * 397) ^ _Extra.GetHashCode();
return hashCode;
}
}
///
/// Checks two instance of for equality.
///
/// The first instance.
/// The second instance.
/// Returns a boolean value indicating if the two instances are equal; otherwise false
public static bool operator ==(Timing left, Timing right)
{
return left.Equals(right);
}
///
/// Checks two instance of for in equality.
///
/// The first instance.
/// The second instance.
/// Returns a boolean value indicating if the two instances are not equal; otherwise false
public static bool operator !=(Timing left, Timing right)
{
return !(left == right);
}
///
/// Get the horizontal visible pixels
///
public int HorizontalVisible
{
get => _HorizontalVisible;
}
///
/// Get the horizontal border pixels
///
public int HorizontalBorder
{
get => _HorizontalBorder;
}
///
/// Get the horizontal front porch pixels
///
public int HorizontalFrontPorch
{
get => _HorizontalFrontPorch;
}
///
/// Get the horizontal sync width pixels
///
public int HorizontalSyncWidth
{
get => _HorizontalSyncWidth;
}
///
/// Get the horizontal total pixels
///
public int HorizontalTotal
{
get => _HorizontalTotal;
}
///
/// Get the horizontal sync polarity
///
public TimingHorizontalSyncPolarity HorizontalSyncPolarity
{
get => _HorizontalSyncPolarity;
}
///
/// Get the vertical visible pixels
///
public int VerticalVisible
{
get => _VerticalVisible;
}
///
/// Get the vertical border pixels
///
public int VerticalBorder
{
get => _VerticalBorder;
}
///
/// Get the vertical front porch pixels
///
public int VerticalFrontPorch
{
get => _VerticalFrontPorch;
}
///
/// Get the vertical sync width pixels
///
public int VerticalSyncWidth
{
get => _VerticalSyncWidth;
}
///
/// Get the vertical total pixels
///
public int VerticalTotal
{
get => _VerticalTotal;
}
///
/// Get the vertical sync polarity
///
public TimingVerticalSyncPolarity VerticalSyncPolarity
{
get => _VerticalSyncPolarity;
}
///
/// Get the scan mode
///
public TimingScanMode ScanMode
{
get => _ScanMode;
}
///
/// Get the pixel clock in 10 kHz
///
public int PixelClockIn10KHertz
{
get => (int) _PixelClockIn10KHertz;
}
///
/// Get the other timing related extras
///
public TimingExtra Extra
{
get => _Extra;
}
///
/// Gets the horizontal active pixels
///
public int HorizontalActive
{
get => HorizontalVisible + HorizontalBorder;
}
///
/// Gets the vertical active pixels
///
public int VerticalActive
{
get => VerticalVisible + VerticalBorder;
}
///
/// Gets the horizontal back porch pixels
///
public int HorizontalBackPorch
{
get => HorizontalBlanking - (HorizontalFrontPorch + HorizontalSyncWidth);
}
///
/// Gets the horizontal blanking pixels
///
public int HorizontalBlanking
{
get => HorizontalTotal - (HorizontalActive + HorizontalBorder);
}
///
/// Gets vertical back porch pixels
///
public int VerticalBackPorch
{
get => VerticalBlanking - (VerticalFrontPorch + VerticalSyncWidth);
}
///
/// Gets the vertical blanking pixels
///
public int VerticalBlanking
{
get => VerticalTotal - (VerticalActive + VerticalBorder);
}
}
}