75 lines
2.2 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace Ryujinx.Common.SystemInterop
{
[SupportedOSPlatform("windows")]
public static partial class GdiPlusHelper
{
private const string LibraryName = "gdiplus.dll";
private static readonly nint _initToken;
static GdiPlusHelper()
{
CheckStatus(GdiplusStartup(out _initToken, StartupInputEx.Default, out _));
}
private static void CheckStatus(int gdiStatus)
{
if (gdiStatus != 0)
{
throw new Exception($"GDI Status Error: {gdiStatus}");
}
}
private struct StartupInputEx
{
public int GdiplusVersion;
public nint DebugEventCallback;
public int SuppressBackgroundThread;
public int SuppressExternalCodecs;
public int StartupParameters;
public static StartupInputEx Default => new()
{
// We assume Windows 8 and upper
GdiplusVersion = 2,
DebugEventCallback = nint.Zero,
SuppressBackgroundThread = 0,
SuppressExternalCodecs = 0,
StartupParameters = 0,
};
}
private struct StartupOutput
{
public nint NotificationHook;
public nint NotificationUnhook;
}
[LibraryImport(LibraryName)]
private static partial int GdiplusStartup(out nint token, in StartupInputEx input, out StartupOutput output);
[LibraryImport(LibraryName)]
private static partial int GdipCreateFromHWND(nint hwnd, out nint graphics);
[LibraryImport(LibraryName)]
private static partial int GdipDeleteGraphics(nint graphics);
[LibraryImport(LibraryName)]
private static partial int GdipGetDpiX(nint graphics, out float dpi);
public static float GetDpiX(nint hwnd)
{
CheckStatus(GdipCreateFromHWND(hwnd, out nint graphicsHandle));
CheckStatus(GdipGetDpiX(graphicsHandle, out float result));
CheckStatus(GdipDeleteGraphics(graphicsHandle));
return result;
}
}
}