mirror of
https://github.com/amerkoleci/Vortice.Win32.git
synced 2026-01-14 16:16:04 +08:00
Generator: Completed initial step of Com Types generation and various improvements.
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Generator;
|
namespace Generator;
|
||||||
|
|
||||||
public class ApiDataArrayShape
|
public class ApiDataArrayShape
|
||||||
@@ -20,6 +22,11 @@ public class ApiDataType
|
|||||||
// Kind == Array
|
// Kind == Array
|
||||||
public ApiDataArrayShape Shape { get; set; }
|
public ApiDataArrayShape Shape { get; set; }
|
||||||
public ApiDataType Child { get; set; }
|
public ApiDataType Child { get; set; }
|
||||||
|
|
||||||
|
// Kind == LPArray
|
||||||
|
public bool NullNullTerm { get; set; }
|
||||||
|
public int CountParamIndex { get; set; }
|
||||||
|
public int CountConst { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ApiDataConstant
|
public class ApiDataConstant
|
||||||
@@ -46,6 +53,7 @@ public class ApiParameter
|
|||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public ApiDataType Type { get; set; }
|
public ApiDataType Type { get; set; }
|
||||||
|
public List<object> Attrs { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ApiFunction
|
public class ApiFunction
|
||||||
@@ -55,6 +63,34 @@ public class ApiFunction
|
|||||||
public ApiDataType ReturnType { get; set; }
|
public ApiDataType ReturnType { get; set; }
|
||||||
public IList<ApiParameter> Params { get; set; } = new List<ApiParameter>();
|
public IList<ApiParameter> Params { get; set; } = new List<ApiParameter>();
|
||||||
public List<object> Attrs { get; set; }
|
public List<object> Attrs { get; set; }
|
||||||
|
|
||||||
|
private string _toString = default;
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_toString))
|
||||||
|
{
|
||||||
|
StringBuilder builder = new();
|
||||||
|
builder.Append(ReturnType.Name).Append(' ');
|
||||||
|
builder.Append(Name).Append('(');
|
||||||
|
int parameterIndex = 0;
|
||||||
|
foreach (var parameter in Params)
|
||||||
|
{
|
||||||
|
// TODO: Handle PointerTo, Array etc
|
||||||
|
builder.Append(parameter.Type.Name).Append(' ').Append(parameter.Name);
|
||||||
|
if (parameterIndex < Params.Count - 1)
|
||||||
|
{
|
||||||
|
builder.Append(", ");
|
||||||
|
}
|
||||||
|
parameterIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.Append(')');
|
||||||
|
_toString = builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _toString;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ApiType
|
public class ApiType
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
// Copyright © Amer Koleci and Contributors.
|
// Copyright © Amer Koleci and Contributors.
|
||||||
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||||
|
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Generator;
|
namespace Generator;
|
||||||
|
|
||||||
public sealed class CodeWriter : IDisposable
|
public sealed class CodeWriter : IDisposable
|
||||||
{
|
{
|
||||||
|
private readonly string _fileName;
|
||||||
private bool _shouldIndent = true;
|
private bool _shouldIndent = true;
|
||||||
private readonly string[] _indentStrings;
|
private readonly string[] _indentStrings;
|
||||||
private string _indentString = "";
|
private string _indentString = "";
|
||||||
private readonly StreamWriter _writer;
|
private readonly StringBuilder _builder = new();
|
||||||
|
|
||||||
public int IndentLevel { get; private set; }
|
public int IndentLevel { get; private set; }
|
||||||
public string Api { get; }
|
public string Api { get; }
|
||||||
@@ -16,6 +19,7 @@ public sealed class CodeWriter : IDisposable
|
|||||||
|
|
||||||
public CodeWriter(string fileName, string api, string docFileName, string ns, params string[] usingNamespaces)
|
public CodeWriter(string fileName, string api, string docFileName, string ns, params string[] usingNamespaces)
|
||||||
{
|
{
|
||||||
|
_fileName = fileName;
|
||||||
Api = api;
|
Api = api;
|
||||||
DocFileName = docFileName;
|
DocFileName = docFileName;
|
||||||
|
|
||||||
@@ -25,40 +29,40 @@ public sealed class CodeWriter : IDisposable
|
|||||||
_indentStrings[i] = new string('\t', i);
|
_indentStrings[i] = new string('\t', i);
|
||||||
}
|
}
|
||||||
|
|
||||||
_writer = File.CreateText(fileName);
|
_builder.AppendLine("// ------------------------------------------------------------------------------");
|
||||||
_writer.WriteLine("// ------------------------------------------------------------------------------");
|
_builder.AppendLine("// <auto-generated>");
|
||||||
_writer.WriteLine("// <auto-generated>");
|
_builder.AppendLine("// This code was generated by a tool.");
|
||||||
_writer.WriteLine("// This code was generated by a tool.");
|
_builder.AppendLine("//");
|
||||||
_writer.WriteLine("//");
|
_builder.AppendLine("// Changes to this file may cause incorrect behavior and will be lost if");
|
||||||
_writer.WriteLine("// Changes to this file may cause incorrect behavior and will be lost if");
|
_builder.AppendLine("// the code is regenerated.");
|
||||||
_writer.WriteLine("// the code is regenerated.");
|
_builder.AppendLine("// </auto-generated>");
|
||||||
_writer.WriteLine("// </auto-generated>");
|
_builder.AppendLine("// ------------------------------------------------------------------------------");
|
||||||
_writer.WriteLine("// ------------------------------------------------------------------------------");
|
_builder.AppendLine();
|
||||||
_writer.WriteLine();
|
|
||||||
|
|
||||||
_writer.WriteLine($"using System;");
|
_builder.AppendLine($"using System;");
|
||||||
_writer.WriteLine($"using System.Diagnostics;");
|
_builder.AppendLine($"using System.Diagnostics;");
|
||||||
_writer.WriteLine($"using System.Runtime.CompilerServices;");
|
_builder.AppendLine($"using System.Runtime.CompilerServices;");
|
||||||
_writer.WriteLine($"using System.Diagnostics.CodeAnalysis;");
|
_builder.AppendLine($"using System.Diagnostics.CodeAnalysis;");
|
||||||
|
|
||||||
foreach (string usingNamespace in usingNamespaces)
|
foreach (string usingNamespace in usingNamespaces)
|
||||||
{
|
{
|
||||||
_writer.WriteLine($"using {usingNamespace};");
|
_builder.AppendLine($"using {usingNamespace};");
|
||||||
}
|
}
|
||||||
_writer.WriteLine();
|
_builder.AppendLine();
|
||||||
|
|
||||||
_writer.WriteLine("#if !NET6_0_OR_GREATER");
|
_builder.AppendLine("#if !NET6_0_OR_GREATER");
|
||||||
_writer.WriteLine("using MemoryMarshal = Win32.MemoryMarshal;");
|
_builder.AppendLine("using MemoryMarshal = Win32.MemoryMarshal;");
|
||||||
_writer.WriteLine("#endif");
|
_builder.AppendLine("#endif");
|
||||||
_writer.WriteLine();
|
_builder.AppendLine();
|
||||||
|
|
||||||
_writer.WriteLine($"namespace {ns};");
|
_builder.AppendLine($"namespace {ns};");
|
||||||
_writer.WriteLine();
|
_builder.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_writer.Dispose();
|
string content = _builder.ToString();
|
||||||
|
File.WriteAllText(_fileName, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(char chr)
|
public void Write(char chr)
|
||||||
@@ -73,20 +77,20 @@ public sealed class CodeWriter : IDisposable
|
|||||||
|
|
||||||
public void WriteLine()
|
public void WriteLine()
|
||||||
{
|
{
|
||||||
_writer.WriteLine();
|
_builder.AppendLine();
|
||||||
_shouldIndent = true;
|
_shouldIndent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteLine(string @string)
|
public void WriteLine(string @string)
|
||||||
{
|
{
|
||||||
WriteIndented(@string);
|
WriteIndented(@string);
|
||||||
_writer.WriteLine();
|
_builder.AppendLine();
|
||||||
_shouldIndent = true;
|
_shouldIndent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteLineUndindented(string @string)
|
public void WriteLineUndindented(string @string)
|
||||||
{
|
{
|
||||||
_writer.WriteLine(@string);
|
_builder.AppendLine(@string);
|
||||||
_shouldIndent = true;
|
_shouldIndent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,22 +143,22 @@ public sealed class CodeWriter : IDisposable
|
|||||||
{
|
{
|
||||||
if (_shouldIndent)
|
if (_shouldIndent)
|
||||||
{
|
{
|
||||||
_writer.Write(_indentString);
|
_builder.Append(_indentString);
|
||||||
_shouldIndent = false;
|
_shouldIndent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_writer.Write(chr);
|
_builder.Append(chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WriteIndented(string @string)
|
private void WriteIndented(string @string)
|
||||||
{
|
{
|
||||||
if (_shouldIndent)
|
if (_shouldIndent)
|
||||||
{
|
{
|
||||||
_writer.Write(_indentString);
|
_builder.Append(_indentString);
|
||||||
_shouldIndent = false;
|
_shouldIndent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_writer.Write(@string);
|
_builder.Append(@string);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CodeBlock : IDisposable
|
private class CodeBlock : IDisposable
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright © Amer Koleci and Contributors.
|
// Copyright © Amer Koleci and Contributors.
|
||||||
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||||
|
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
@@ -66,6 +67,7 @@ public static class Program
|
|||||||
{ "Foundation.SIZE", "System.Drawing.Size" },
|
{ "Foundation.SIZE", "System.Drawing.Size" },
|
||||||
|
|
||||||
{ "Graphics.Gdi.HMONITOR", "IntPtr" },
|
{ "Graphics.Gdi.HMONITOR", "IntPtr" },
|
||||||
|
{ "Graphics.Gdi.HDC", "IntPtr" },
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly Dictionary<string, string> s_knownTypesPrefixes = new()
|
private static readonly Dictionary<string, string> s_knownTypesPrefixes = new()
|
||||||
@@ -130,6 +132,9 @@ public static class Program
|
|||||||
{ "DXGI_SWAP_CHAIN_DESC1::Flags", "DXGI_SWAP_CHAIN_FLAG" },
|
{ "DXGI_SWAP_CHAIN_DESC1::Flags", "DXGI_SWAP_CHAIN_FLAG" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static readonly HashSet<string> s_visitedEnums = new();
|
||||||
|
private static readonly HashSet<string> s_visitedStructs = new();
|
||||||
|
|
||||||
private static bool s_generateUnmanagedDocs = true;
|
private static bool s_generateUnmanagedDocs = true;
|
||||||
|
|
||||||
public static int Main(string[] args)
|
public static int Main(string[] args)
|
||||||
@@ -443,7 +448,10 @@ public static class Program
|
|||||||
foreach (ApiType enumType in api.Types.Where(item => item.Kind.ToLowerInvariant() == "enum"))
|
foreach (ApiType enumType in api.Types.Where(item => item.Kind.ToLowerInvariant() == "enum"))
|
||||||
{
|
{
|
||||||
GenerateEnum(writer, enumType, false);
|
GenerateEnum(writer, enumType, false);
|
||||||
|
|
||||||
|
s_visitedEnums.Add($"{writer.Api}.{enumType.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine($"#endregion Enums");
|
writer.WriteLine($"#endregion Enums");
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
|
|
||||||
@@ -504,6 +512,8 @@ public static class Program
|
|||||||
foreach (ApiType structType in api.Types.Where(item => item.Kind.ToLowerInvariant() == "struct"))
|
foreach (ApiType structType in api.Types.Where(item => item.Kind.ToLowerInvariant() == "struct"))
|
||||||
{
|
{
|
||||||
GenerateStruct(writer, structType);
|
GenerateStruct(writer, structType);
|
||||||
|
|
||||||
|
s_visitedStructs.Add($"{writer.Api}.{structType.Name}");
|
||||||
}
|
}
|
||||||
writer.WriteLine($"#endregion Structs");
|
writer.WriteLine($"#endregion Structs");
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
@@ -512,10 +522,35 @@ public static class Program
|
|||||||
writer.WriteLine($"#region COM Types");
|
writer.WriteLine($"#region COM Types");
|
||||||
foreach (ApiType comType in api.Types.Where(item => item.Kind.ToLowerInvariant() == "com"))
|
foreach (ApiType comType in api.Types.Where(item => item.Kind.ToLowerInvariant() == "com"))
|
||||||
{
|
{
|
||||||
GenerateComType(writer, comType);
|
//if (comType.Name != "IDXGIObject" &&
|
||||||
|
// comType.Name != "IDXGIDeviceSubObject")
|
||||||
|
//{
|
||||||
|
// break;
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Generate methods
|
||||||
|
List<KeyValuePair<ApiFunction, string>> methodsToGenerate = new();
|
||||||
|
ApiType iterateType = comType;
|
||||||
|
while (iterateType.Interface != null && iterateType.Interface.Name != "IUnknown")
|
||||||
|
{
|
||||||
|
iterateType = api.Types.First(item => item.Name == iterateType.Interface.Name);
|
||||||
|
|
||||||
|
foreach (var method in iterateType.Methods)
|
||||||
|
{
|
||||||
|
methodsToGenerate.Add(new(method, iterateType.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var method in comType.Methods)
|
||||||
|
{
|
||||||
|
methodsToGenerate.Add(new(method, comType.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateComType(api, writer, comType, methodsToGenerate);
|
||||||
}
|
}
|
||||||
writer.WriteLine($"#endregion COM Types");
|
|
||||||
writer.WriteLine();
|
writer.WriteLine($"#endregion Com Types");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateEnum(CodeWriter writer, ApiType enumType, bool autoGenerated)
|
private static void GenerateEnum(CodeWriter writer, ApiType enumType, bool autoGenerated)
|
||||||
@@ -671,20 +706,20 @@ public static class Program
|
|||||||
|
|
||||||
writer.WriteLine($"public {unsafePrefix}{fieldTypeName} {fieldValueName};");
|
writer.WriteLine($"public {unsafePrefix}{fieldTypeName} {fieldValueName};");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writer.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GenerateComType(CodeWriter writer, ApiType comType)
|
private static void GenerateComType(
|
||||||
|
ApiData api,
|
||||||
|
CodeWriter writer,
|
||||||
|
ApiType comType,
|
||||||
|
List<KeyValuePair<ApiFunction, string>> methodsToGenerate)
|
||||||
{
|
{
|
||||||
if (comType.Name != "IDXGIObject" /*&&
|
|
||||||
comType.Name != "IDXGIDeviceSubObject"*/)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string csTypeName = comType.Name;
|
string csTypeName = comType.Name;
|
||||||
//AddCsMapping(writer.Api, comType.Name, csTypeName);
|
//AddCsMapping(writer.Api, comType.Name, csTypeName);
|
||||||
|
|
||||||
@@ -701,7 +736,6 @@ public static class Program
|
|||||||
using (writer.PushBlock($"public unsafe partial struct {csTypeName} : {csTypeName}.Interface"))
|
using (writer.PushBlock($"public unsafe partial struct {csTypeName} : {csTypeName}.Interface"))
|
||||||
{
|
{
|
||||||
// Generate IID
|
// Generate IID
|
||||||
writer.WriteLine($"[NativeTypeName(\"const GUID\")]");
|
|
||||||
using (writer.PushBlock($"public static ref readonly Guid IID_{csTypeName}"))
|
using (writer.PushBlock($"public static ref readonly Guid IID_{csTypeName}"))
|
||||||
{
|
{
|
||||||
writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
|
writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
|
||||||
@@ -756,7 +790,17 @@ public static class Program
|
|||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
|
|
||||||
int vtblIndex = 0;
|
int vtblIndex = 0;
|
||||||
if (comType.Interface.Name == "IUnknown")
|
|
||||||
|
bool generateIUnknown = false;
|
||||||
|
var iterateType = comType;
|
||||||
|
|
||||||
|
while (iterateType != null)
|
||||||
|
{
|
||||||
|
generateIUnknown = iterateType.Interface.Name == "IUnknown";
|
||||||
|
iterateType = api.Types.FirstOrDefault(item => item.Name == iterateType.Interface.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (generateIUnknown)
|
||||||
{
|
{
|
||||||
writer.WriteLine("/// <inheritdoc cref=\"IUnknown.QueryInterface\" />");
|
writer.WriteLine("/// <inheritdoc cref=\"IUnknown.QueryInterface\" />");
|
||||||
writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
|
writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
|
||||||
@@ -791,8 +835,11 @@ public static class Program
|
|||||||
vtblIndex = 3;
|
vtblIndex = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var method in comType.Methods)
|
foreach (var methodPair in methodsToGenerate)
|
||||||
{
|
{
|
||||||
|
var method = methodPair.Key;
|
||||||
|
string docName = methodPair.Value;
|
||||||
|
|
||||||
// TODO: Handle inherit
|
// TODO: Handle inherit
|
||||||
string returnType = GetTypeName(method.ReturnType);
|
string returnType = GetTypeName(method.ReturnType);
|
||||||
|
|
||||||
@@ -801,12 +848,43 @@ public static class Program
|
|||||||
StringBuilder argumentsNameBuilder = new();
|
StringBuilder argumentsNameBuilder = new();
|
||||||
int parameterIndex = 0;
|
int parameterIndex = 0;
|
||||||
|
|
||||||
|
if (method.Name == "SetEvictionPriority")
|
||||||
|
{
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var parameter in method.Params)
|
foreach (var parameter in method.Params)
|
||||||
{
|
{
|
||||||
string parameterType = GetTypeName(parameter.Type);
|
bool asPointer = false;
|
||||||
|
if (parameter.Type.Kind == "ApiRef")
|
||||||
|
{
|
||||||
|
string fullTypeName = $"{parameter.Type.Api}.{parameter.Type.Name}";
|
||||||
|
if (!IsEnum(fullTypeName))
|
||||||
|
{
|
||||||
|
asPointer = true;
|
||||||
|
}
|
||||||
|
//string typeName = GetTypeName($"{dataType.Api}.{dataType.Name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
string parameterType = GetTypeName(parameter.Type, asPointer);
|
||||||
|
parameterType = NormalizeTypeName(writer.Api, parameterType);
|
||||||
string parameterName = parameter.Name;
|
string parameterName = parameter.Name;
|
||||||
|
|
||||||
|
bool isOptional = parameter.Attrs.Any(item => item is string str && str == "Optional");
|
||||||
|
if (parameter.Attrs.Any(item => item is string str && str == "ComOutPtr"))
|
||||||
|
{
|
||||||
|
if (!IsPrimitive(parameter.Type))
|
||||||
|
{
|
||||||
|
parameterType += "*";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
argumentBuilder.Append(parameterType).Append(' ').Append(parameterName);
|
argumentBuilder.Append(parameterType).Append(' ').Append(parameterName);
|
||||||
|
if (isOptional == true)
|
||||||
|
{
|
||||||
|
//argumentBuilder.Append(" = default");
|
||||||
|
}
|
||||||
|
|
||||||
argumentsTypesBuilder.Append(parameterType);
|
argumentsTypesBuilder.Append(parameterType);
|
||||||
argumentsNameBuilder.Append(parameterName);
|
argumentsNameBuilder.Append(parameterName);
|
||||||
|
|
||||||
@@ -827,13 +905,30 @@ public static class Program
|
|||||||
returnMarshalType = "int";
|
returnMarshalType = "int";
|
||||||
}
|
}
|
||||||
|
|
||||||
argumentsTypesBuilder.Append(", ").Append(returnMarshalType);
|
if (method.Params.Count > 0)
|
||||||
|
{
|
||||||
|
argumentsTypesBuilder.Append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
argumentsTypesBuilder.Append(returnMarshalType);
|
||||||
|
|
||||||
string argumentsString = argumentBuilder.ToString();
|
string argumentsString = argumentBuilder.ToString();
|
||||||
string argumentTypesString = argumentsTypesBuilder.ToString();
|
string argumentTypesString = argumentsTypesBuilder.ToString();
|
||||||
string argumentNamesString = argumentsNameBuilder.ToString();
|
string argumentNamesString = argumentsNameBuilder.ToString();
|
||||||
|
if (method.Params.Count > 0)
|
||||||
|
{
|
||||||
|
argumentNamesString = ", " + argumentNamesString;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comType.Name == docName)
|
||||||
|
{
|
||||||
|
writer.WriteLine($"/// <include file='../{writer.DocFileName}.xml' path='doc/member[@name=\"{comType.Name}::{method.Name}\"]/*' />");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.WriteLine($"/// <inheritdoc cref=\"{docName}.{method.Name}\" />");
|
||||||
|
}
|
||||||
|
|
||||||
writer.WriteLine($"/// <include file='../{writer.DocFileName}.xml' path='doc/member[@name=\"{comType.Name}::{method.Name}\"]/*' />");
|
|
||||||
writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
|
writer.WriteLine("[MethodImpl(MethodImplOptions.AggressiveInlining)]");
|
||||||
writer.WriteLine($"[VtblIndex({vtblIndex})]");
|
writer.WriteLine($"[VtblIndex({vtblIndex})]");
|
||||||
using (writer.PushBlock($"public {returnType} {method.Name}({argumentsString})"))
|
using (writer.PushBlock($"public {returnType} {method.Name}({argumentsString})"))
|
||||||
@@ -841,14 +936,13 @@ public static class Program
|
|||||||
writer.WriteLineUndindented("#if NET6_0_OR_GREATER");
|
writer.WriteLineUndindented("#if NET6_0_OR_GREATER");
|
||||||
if (returnType != "void")
|
if (returnType != "void")
|
||||||
writer.Write("return ");
|
writer.Write("return ");
|
||||||
writer.WriteLine($"((delegate* unmanaged<{comType.Name}*, {argumentTypesString}>)(lpVtbl[{vtblIndex}]))(({comType.Name}*)Unsafe.AsPointer(ref this), {argumentNamesString});");
|
writer.WriteLine($"((delegate* unmanaged<{comType.Name}*, {argumentTypesString}>)(lpVtbl[{vtblIndex}]))(({comType.Name}*)Unsafe.AsPointer(ref this){argumentNamesString});");
|
||||||
writer.WriteLineUndindented("#else");
|
writer.WriteLineUndindented("#else");
|
||||||
if (returnType != "void")
|
if (returnType != "void")
|
||||||
writer.Write("return ");
|
writer.Write("return ");
|
||||||
writer.WriteLine($"((delegate* unmanaged[Stdcall]<{comType.Name}*, {argumentTypesString}>)(lpVtbl[{vtblIndex}]))(({comType.Name}*)Unsafe.AsPointer(ref this), {argumentNamesString});");
|
writer.WriteLine($"((delegate* unmanaged[Stdcall]<{comType.Name}*, {argumentTypesString}>)(lpVtbl[{vtblIndex}]))(({comType.Name}*)Unsafe.AsPointer(ref this){argumentNamesString});");
|
||||||
writer.WriteLineUndindented("#endif");
|
writer.WriteLineUndindented("#endif");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
|
|
||||||
vtblIndex++;
|
vtblIndex++;
|
||||||
@@ -857,7 +951,7 @@ public static class Program
|
|||||||
using (writer.PushBlock($"public interface Interface : {comType.Interface.Name}.Interface"))
|
using (writer.PushBlock($"public interface Interface : {comType.Interface.Name}.Interface"))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
writer.WriteLine();
|
//writer.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.WriteLine();
|
writer.WriteLine();
|
||||||
@@ -877,7 +971,9 @@ public static class Program
|
|||||||
private static string NormalizeTypeName(string api, string typeName)
|
private static string NormalizeTypeName(string api, string typeName)
|
||||||
{
|
{
|
||||||
if (!typeName.StartsWith(api))
|
if (!typeName.StartsWith(api))
|
||||||
|
{
|
||||||
return typeName;
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
return typeName.Replace(api + ".", "");
|
return typeName.Replace(api + ".", "");
|
||||||
}
|
}
|
||||||
@@ -1084,17 +1180,21 @@ public static class Program
|
|||||||
return $"new Guid({a}, {b}, {c}, {d}, {e}, {f}, {g}, {h}, {i}, {j}, {k})";
|
return $"new Guid({a}, {b}, {c}, {d}, {e}, {f}, {g}, {h}, {i}, {j}, {k})";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetTypeName(ApiDataType dataType, bool asPointer = false)
|
||||||
private static string GetTypeName(ApiDataType dataType)
|
|
||||||
{
|
{
|
||||||
if (dataType.Kind == "ApiRef")
|
if (dataType.Kind == "ApiRef")
|
||||||
{
|
{
|
||||||
return GetTypeName($"{dataType.Api}.{dataType.Name}");
|
string typeName = GetTypeName($"{dataType.Api}.{dataType.Name}");
|
||||||
|
return asPointer ? typeName + "*" : typeName;
|
||||||
}
|
}
|
||||||
else if (dataType.Kind == "Array")
|
else if (dataType.Kind == "Array")
|
||||||
{
|
{
|
||||||
return "Array";
|
return "Array";
|
||||||
}
|
}
|
||||||
|
else if (dataType.Kind == "LPArray")
|
||||||
|
{
|
||||||
|
return GetTypeName(dataType.Child) + "*";
|
||||||
|
}
|
||||||
else if (dataType.Kind == "PointerTo")
|
else if (dataType.Kind == "PointerTo")
|
||||||
{
|
{
|
||||||
return GetTypeName(dataType.Child) + "*";
|
return GetTypeName(dataType.Child) + "*";
|
||||||
@@ -1103,6 +1203,48 @@ public static class Program
|
|||||||
return GetTypeName(dataType.Name);
|
return GetTypeName(dataType.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsPrimitive(ApiDataType dataType)
|
||||||
|
{
|
||||||
|
if (dataType.Kind == "ApiRef")
|
||||||
|
{
|
||||||
|
string apiRefType = GetTypeName($"{dataType.Api}.{dataType.Name}");
|
||||||
|
}
|
||||||
|
else if (dataType.Kind == "PointerTo")
|
||||||
|
{
|
||||||
|
return IsPrimitive(dataType.Child);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataType.Kind != "Native")
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string typeName = GetTypeName(dataType.Name);
|
||||||
|
switch (typeName)
|
||||||
|
{
|
||||||
|
case "void":
|
||||||
|
case "int":
|
||||||
|
case "uint":
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case "nint":
|
||||||
|
case "nuint":
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsEnum(string typeName)
|
||||||
|
{
|
||||||
|
return s_visitedEnums.Contains(typeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsStruct(string typeName)
|
||||||
|
{
|
||||||
|
return s_visitedStructs.Contains(typeName);
|
||||||
|
}
|
||||||
|
|
||||||
private static void AddCsMapping(string api, string typeName, string csTypeName)
|
private static void AddCsMapping(string api, string typeName, string csTypeName)
|
||||||
{
|
{
|
||||||
s_csNameMappings[$"{api}.{typeName}"] = $"{api}.{csTypeName}";
|
s_csNameMappings[$"{api}.{typeName}"] = $"{api}.{csTypeName}";
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace Win32;
|
namespace Win32;
|
||||||
|
|
||||||
public readonly partial struct Bool32 : IComparable, IComparable<Bool32>, IEquatable<Bool32>, IFormattable
|
public readonly partial struct Bool32 : IComparable, IComparable<Bool32>, IEquatable<Bool32>
|
||||||
{
|
{
|
||||||
public readonly int Value;
|
public readonly int Value;
|
||||||
|
|
||||||
@@ -93,7 +93,5 @@ public readonly partial struct Bool32 : IComparable, IComparable<Bool32>, IEquat
|
|||||||
|
|
||||||
public override int GetHashCode() => Value.GetHashCode();
|
public override int GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
public override string ToString() => Value.ToString();
|
public override string ToString() => Value != 0 ? "True" : "False";
|
||||||
|
|
||||||
public string ToString(string? format, IFormatProvider? formatProvider) => Value.ToString(format, formatProvider);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -577,8 +577,10 @@ public partial struct Rational
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RATIONAL::Numerator"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RATIONAL::Numerator"]/*' />
|
||||||
public uint Numerator;
|
public uint Numerator;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RATIONAL::Denominator"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RATIONAL::Denominator"]/*' />
|
||||||
public uint Denominator;
|
public uint Denominator;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_SAMPLE_DESC"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_SAMPLE_DESC"]/*' />
|
||||||
@@ -587,8 +589,10 @@ public partial struct SampleDescription
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_SAMPLE_DESC::Count"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_SAMPLE_DESC::Count"]/*' />
|
||||||
public uint Count;
|
public uint Count;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_SAMPLE_DESC::Quality"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_SAMPLE_DESC::Quality"]/*' />
|
||||||
public uint Quality;
|
public uint Quality;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB"]/*' />
|
||||||
@@ -597,10 +601,13 @@ public partial struct Rgb
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB::Red"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB::Red"]/*' />
|
||||||
public float Red;
|
public float Red;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB::Green"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB::Green"]/*' />
|
||||||
public float Green;
|
public float Green;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB::Blue"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_RGB::Blue"]/*' />
|
||||||
public float Blue;
|
public float Blue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL"]/*' />
|
||||||
@@ -609,8 +616,10 @@ public partial struct GammaControl
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL::Scale"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL::Scale"]/*' />
|
||||||
public Rgb Scale;
|
public Rgb Scale;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL::Offset"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL::Offset"]/*' />
|
||||||
public Rgb Offset;
|
public Rgb Offset;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL::GammaCurve"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL::GammaCurve"]/*' />
|
||||||
public GammaCurve__FixedBuffer GammaCurve;
|
public GammaCurve__FixedBuffer GammaCurve;
|
||||||
|
|
||||||
@@ -1659,6 +1668,7 @@ public partial struct GammaControl
|
|||||||
return MemoryMarshal.CreateSpan(ref e0, 1025);
|
return MemoryMarshal.CreateSpan(ref e0, 1025);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES"]/*' />
|
||||||
@@ -1667,14 +1677,19 @@ public partial struct GammaControlCapabilities
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::ScaleAndOffsetSupported"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::ScaleAndOffsetSupported"]/*' />
|
||||||
public Bool32 ScaleAndOffsetSupported;
|
public Bool32 ScaleAndOffsetSupported;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::MaxConvertedValue"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::MaxConvertedValue"]/*' />
|
||||||
public float MaxConvertedValue;
|
public float MaxConvertedValue;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::MinConvertedValue"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::MinConvertedValue"]/*' />
|
||||||
public float MinConvertedValue;
|
public float MinConvertedValue;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::NumGammaControlPoints"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::NumGammaControlPoints"]/*' />
|
||||||
public uint NumGammaControlPoints;
|
public uint NumGammaControlPoints;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::ControlPointPositions"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_GAMMA_CONTROL_CAPABILITIES::ControlPointPositions"]/*' />
|
||||||
public unsafe fixed float ControlPointPositions[1025];
|
public unsafe fixed float ControlPointPositions[1025];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC"]/*' />
|
||||||
@@ -1683,16 +1698,22 @@ public partial struct ModeDescription
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Width"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Width"]/*' />
|
||||||
public uint Width;
|
public uint Width;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Height"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Height"]/*' />
|
||||||
public uint Height;
|
public uint Height;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::RefreshRate"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::RefreshRate"]/*' />
|
||||||
public Rational RefreshRate;
|
public Rational RefreshRate;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Format"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Format"]/*' />
|
||||||
public Format Format;
|
public Format Format;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::ScanlineOrdering"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::ScanlineOrdering"]/*' />
|
||||||
public ModeScanlineOrder ScanlineOrdering;
|
public ModeScanlineOrder ScanlineOrdering;
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Scaling"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_MODE_DESC::Scaling"]/*' />
|
||||||
public ModeScaling Scaling;
|
public ModeScaling Scaling;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_DC_HUFFMAN_TABLE"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_DC_HUFFMAN_TABLE"]/*' />
|
||||||
@@ -1701,8 +1722,10 @@ public partial struct JpegDcHuffmanTable
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_DC_HUFFMAN_TABLE::CodeCounts"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_DC_HUFFMAN_TABLE::CodeCounts"]/*' />
|
||||||
public unsafe fixed byte CodeCounts[12];
|
public unsafe fixed byte CodeCounts[12];
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_DC_HUFFMAN_TABLE::CodeValues"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_DC_HUFFMAN_TABLE::CodeValues"]/*' />
|
||||||
public unsafe fixed byte CodeValues[12];
|
public unsafe fixed byte CodeValues[12];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_AC_HUFFMAN_TABLE"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_AC_HUFFMAN_TABLE"]/*' />
|
||||||
@@ -1711,8 +1734,10 @@ public partial struct JpegAcHuffmanTable
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_AC_HUFFMAN_TABLE::CodeCounts"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_AC_HUFFMAN_TABLE::CodeCounts"]/*' />
|
||||||
public unsafe fixed byte CodeCounts[16];
|
public unsafe fixed byte CodeCounts[16];
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_AC_HUFFMAN_TABLE::CodeValues"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_AC_HUFFMAN_TABLE::CodeValues"]/*' />
|
||||||
public unsafe fixed byte CodeValues[162];
|
public unsafe fixed byte CodeValues[162];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_QUANTIZATION_TABLE"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_QUANTIZATION_TABLE"]/*' />
|
||||||
@@ -1721,10 +1746,10 @@ public partial struct JpegQuantizationTable
|
|||||||
{
|
{
|
||||||
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_QUANTIZATION_TABLE::Elements"]/*' />
|
/// <include file='../DXGI.xml' path='doc/member[@name="DXGI_JPEG_QUANTIZATION_TABLE::Elements"]/*' />
|
||||||
public unsafe fixed byte Elements[64];
|
public unsafe fixed byte Elements[64];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Structs
|
#endregion Structs
|
||||||
|
|
||||||
#region COM Types
|
#region COM Types
|
||||||
#endregion COM Types
|
#endregion Com Types
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -4,3 +4,36 @@
|
|||||||
using static Win32.Graphics.Dxgi.Apis;
|
using static Win32.Graphics.Dxgi.Apis;
|
||||||
|
|
||||||
namespace Win32.Graphics.Dxgi;
|
namespace Win32.Graphics.Dxgi;
|
||||||
|
|
||||||
|
public unsafe partial struct IDXGIFactory5
|
||||||
|
{
|
||||||
|
public TFeature CheckFeatureSupport<TFeature>(Feature feature)
|
||||||
|
where TFeature : unmanaged
|
||||||
|
{
|
||||||
|
TFeature featureData = default;
|
||||||
|
CheckFeatureSupport(feature, &featureData, (uint)sizeof(TFeature)).ThrowIfFailed();
|
||||||
|
return featureData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe partial struct IDXGIFactory6
|
||||||
|
{
|
||||||
|
public TFeature CheckFeatureSupport<TFeature>(Feature feature)
|
||||||
|
where TFeature : unmanaged
|
||||||
|
{
|
||||||
|
TFeature featureData = default;
|
||||||
|
CheckFeatureSupport(feature, &featureData, (uint)sizeof(TFeature)).ThrowIfFailed();
|
||||||
|
return featureData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe partial struct IDXGIFactory7
|
||||||
|
{
|
||||||
|
public TFeature CheckFeatureSupport<TFeature>(Feature feature)
|
||||||
|
where TFeature : unmanaged
|
||||||
|
{
|
||||||
|
TFeature featureData = default;
|
||||||
|
CheckFeatureSupport(feature, &featureData, (uint)sizeof(TFeature)).ThrowIfFailed();
|
||||||
|
return featureData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
// Copyright © Amer Koleci and Contributors.
|
// Copyright © Amer Koleci and Contributors.
|
||||||
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Win32;
|
namespace Win32;
|
||||||
|
|
||||||
public readonly partial struct HResult : IComparable, IComparable<HResult>, IEquatable<HResult>, IFormattable
|
public readonly partial struct HResult : IComparable, IComparable<HResult>, IEquatable<HResult>, IFormattable
|
||||||
@@ -89,4 +92,22 @@ public readonly partial struct HResult : IComparable, IComparable<HResult>, IEqu
|
|||||||
public bool Failure => Value < 0;
|
public bool Failure => Value < 0;
|
||||||
|
|
||||||
public bool Success => Value >= 0;
|
public bool Success => Value >= 0;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void ThrowIfFailed([CallerMemberName] string? method = null)
|
||||||
|
{
|
||||||
|
if (Failure)
|
||||||
|
{
|
||||||
|
ThrowExternalException(method ?? "Method", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
[DoesNotReturn]
|
||||||
|
#endif
|
||||||
|
private static void ThrowExternalException(string methodName, int errorCode)
|
||||||
|
{
|
||||||
|
string message = string.Format("'{0}' failed with an error code of '{1}'", methodName, errorCode);
|
||||||
|
throw new ExternalException(message, errorCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public unsafe partial struct IUnknown : IUnknown.Interface
|
|||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
[VtblIndex(0)]
|
[VtblIndex(0)]
|
||||||
public HResult QueryInterface([NativeTypeName("const IID &")] Guid* riid, void** ppvObject)
|
public HResult QueryInterface(Guid* riid, void** ppvObject)
|
||||||
{
|
{
|
||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
return ((delegate* unmanaged<IUnknown*, Guid*, void**, int>)(lpVtbl[0]))((IUnknown*)Unsafe.AsPointer(ref this), riid, ppvObject);
|
return ((delegate* unmanaged<IUnknown*, Guid*, void**, int>)(lpVtbl[0]))((IUnknown*)Unsafe.AsPointer(ref this), riid, ppvObject);
|
||||||
@@ -26,7 +26,6 @@ public unsafe partial struct IUnknown : IUnknown.Interface
|
|||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
[VtblIndex(1)]
|
[VtblIndex(1)]
|
||||||
[return: NativeTypeName("ULONG")]
|
|
||||||
public uint AddRef()
|
public uint AddRef()
|
||||||
{
|
{
|
||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
@@ -38,7 +37,6 @@ public unsafe partial struct IUnknown : IUnknown.Interface
|
|||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
[VtblIndex(2)]
|
[VtblIndex(2)]
|
||||||
[return: NativeTypeName("ULONG")]
|
|
||||||
public uint Release()
|
public uint Release()
|
||||||
{
|
{
|
||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
@@ -51,14 +49,12 @@ public unsafe partial struct IUnknown : IUnknown.Interface
|
|||||||
public interface Interface
|
public interface Interface
|
||||||
{
|
{
|
||||||
[VtblIndex(0)]
|
[VtblIndex(0)]
|
||||||
HResult QueryInterface([NativeTypeName("const IID &")] Guid* riid, void** ppvObject);
|
HResult QueryInterface(Guid* riid, void** ppvObject);
|
||||||
|
|
||||||
[VtblIndex(1)]
|
[VtblIndex(1)]
|
||||||
[return: NativeTypeName("ULONG")]
|
|
||||||
uint AddRef();
|
uint AddRef();
|
||||||
|
|
||||||
[VtblIndex(2)]
|
[VtblIndex(2)]
|
||||||
[return: NativeTypeName("ULONG")]
|
|
||||||
uint Release();
|
uint Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,22 +62,16 @@ public unsafe partial struct IUnknown : IUnknown.Interface
|
|||||||
where TSelf : unmanaged, Interface
|
where TSelf : unmanaged, Interface
|
||||||
{
|
{
|
||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
[NativeTypeName("HRESULT (const IID &, void **) __attribute__((stdcall))")]
|
|
||||||
public delegate* unmanaged<TSelf*, Guid*, void**, int> QueryInterface;
|
public delegate* unmanaged<TSelf*, Guid*, void**, int> QueryInterface;
|
||||||
|
|
||||||
[NativeTypeName("ULONG () __attribute__((stdcall))")]
|
|
||||||
public delegate* unmanaged<TSelf*, uint> AddRef;
|
public delegate* unmanaged<TSelf*, uint> AddRef;
|
||||||
|
|
||||||
[NativeTypeName("ULONG () __attribute__((stdcall))")]
|
|
||||||
public delegate* unmanaged<TSelf*, uint> Release;
|
public delegate* unmanaged<TSelf*, uint> Release;
|
||||||
#else
|
#else
|
||||||
[NativeTypeName("HRESULT (const IID &, void **) __attribute__((stdcall))")]
|
|
||||||
public delegate* unmanaged[Stdcall]<TSelf*, Guid*, void**, int> QueryInterface;
|
public delegate* unmanaged[Stdcall]<TSelf*, Guid*, void**, int> QueryInterface;
|
||||||
|
|
||||||
[NativeTypeName("ULONG () __attribute__((stdcall))")]
|
|
||||||
public delegate* unmanaged[Stdcall]<TSelf*, uint> AddRef;
|
public delegate* unmanaged[Stdcall]<TSelf*, uint> AddRef;
|
||||||
|
|
||||||
[NativeTypeName("ULONG () __attribute__((stdcall))")]
|
|
||||||
public delegate* unmanaged[Stdcall]<TSelf*, uint> Release;
|
public delegate* unmanaged[Stdcall]<TSelf*, uint> Release;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/Vortice.Win32/Security/Security.Manual.cs
Normal file
17
src/Vortice.Win32/Security/Security.Manual.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright © Amer Koleci and Contributors.
|
||||||
|
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||||
|
|
||||||
|
namespace Win32.Security;
|
||||||
|
|
||||||
|
public unsafe partial struct SECURITY_ATTRIBUTES
|
||||||
|
{
|
||||||
|
[NativeTypeName("DWORD")]
|
||||||
|
public uint nLength;
|
||||||
|
|
||||||
|
[NativeTypeName("LPVOID")]
|
||||||
|
public void* lpSecurityDescriptor;
|
||||||
|
|
||||||
|
[NativeTypeName("BOOL")]
|
||||||
|
public Bool32 bInheritHandle;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -20,4 +20,8 @@
|
|||||||
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
|
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Security\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
// Copyright © Amer Koleci and Contributors.
|
// Copyright © Amer Koleci and Contributors.
|
||||||
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
|
||||||
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Win32;
|
||||||
using Win32.Graphics.Dxgi;
|
using Win32.Graphics.Dxgi;
|
||||||
using Win32.Graphics.Dxgi.Common;
|
using static Win32.Apis;
|
||||||
|
|
||||||
namespace ClearScreen;
|
namespace ClearScreen;
|
||||||
|
|
||||||
@@ -10,5 +12,29 @@ public static unsafe class Program
|
|||||||
{
|
{
|
||||||
public static void Main()
|
public static void Main()
|
||||||
{
|
{
|
||||||
|
using ComPtr<IDXGIFactory1> factory = default;
|
||||||
|
HResult hr = CreateDXGIFactory1(__uuidof<IDXGIFactory4>(), (void**)&factory);
|
||||||
|
|
||||||
|
{
|
||||||
|
using ComPtr<IDXGIFactory5> factory5 = default;
|
||||||
|
if (factory.CopyTo(&factory5).Success)
|
||||||
|
{
|
||||||
|
Bool32 isTearingSupported = factory5.Get()->CheckFeatureSupport<Bool32>(Feature.PresentAllowTearing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using ComPtr<IDXGIAdapter1> adapter = default;
|
||||||
|
for (uint adapterIndex = 0;
|
||||||
|
factory.Get()->EnumAdapters1(adapterIndex, adapter.ReleaseAndGetAddressOf()).Success;
|
||||||
|
adapterIndex++)
|
||||||
|
{
|
||||||
|
AdapterDescription1 desc = default;
|
||||||
|
adapter.Get()->GetDesc1(&desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DllImport("dxgi", ExactSpelling = true)]
|
||||||
|
public static extern HResult CreateDXGIFactory1(Guid* riid, void** ppFactory);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user