2022-12-09 17:00:53 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Runtime.Versioning;
|
|
|
|
|
|
2022-12-15 17:07:31 +00:00
|
|
|
|
namespace Ryujinx.Common.SystemInterop
|
2022-12-09 17:00:53 +00:00
|
|
|
|
{
|
|
|
|
|
[SupportedOSPlatform("windows")]
|
2022-12-15 17:07:31 +00:00
|
|
|
|
public static partial class GdiPlusHelper
|
2022-12-09 17:00:53 +00:00
|
|
|
|
{
|
|
|
|
|
private const string LibraryName = "gdiplus.dll";
|
|
|
|
|
|
|
|
|
|
private static readonly IntPtr _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;
|
|
|
|
|
|
|
|
|
|
#pragma warning disable CS0649
|
|
|
|
|
public IntPtr DebugEventCallback;
|
|
|
|
|
public int SuppressBackgroundThread;
|
|
|
|
|
public int SuppressExternalCodecs;
|
|
|
|
|
public int StartupParameters;
|
|
|
|
|
#pragma warning restore CS0649
|
|
|
|
|
|
|
|
|
|
public static StartupInputEx Default => new StartupInputEx
|
|
|
|
|
{
|
|
|
|
|
// We assume Windows 8 and upper
|
|
|
|
|
GdiplusVersion = 2,
|
|
|
|
|
DebugEventCallback = IntPtr.Zero,
|
|
|
|
|
SuppressBackgroundThread = 0,
|
|
|
|
|
SuppressExternalCodecs = 0,
|
|
|
|
|
StartupParameters = 0,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private struct StartupOutput
|
|
|
|
|
{
|
|
|
|
|
public IntPtr NotificationHook;
|
|
|
|
|
public IntPtr NotificationUnhook;
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-15 17:07:31 +00:00
|
|
|
|
[LibraryImport(LibraryName)]
|
|
|
|
|
private static partial int GdiplusStartup(out IntPtr token, in StartupInputEx input, out StartupOutput output);
|
2022-12-09 17:00:53 +00:00
|
|
|
|
|
2022-12-15 17:07:31 +00:00
|
|
|
|
[LibraryImport(LibraryName)]
|
|
|
|
|
private static partial int GdipCreateFromHWND(IntPtr hwnd, out IntPtr graphics);
|
2022-12-09 17:00:53 +00:00
|
|
|
|
|
2022-12-15 17:07:31 +00:00
|
|
|
|
[LibraryImport(LibraryName)]
|
|
|
|
|
private static partial int GdipDeleteGraphics(IntPtr graphics);
|
2022-12-09 17:00:53 +00:00
|
|
|
|
|
2022-12-15 17:07:31 +00:00
|
|
|
|
[LibraryImport(LibraryName)]
|
|
|
|
|
private static partial int GdipGetDpiX(IntPtr graphics, out float dpi);
|
2022-12-09 17:00:53 +00:00
|
|
|
|
|
|
|
|
|
public static float GetDpiX(IntPtr hwnd)
|
|
|
|
|
{
|
|
|
|
|
CheckStatus(GdipCreateFromHWND(hwnd, out IntPtr graphicsHandle));
|
|
|
|
|
CheckStatus(GdipGetDpiX(graphicsHandle, out float result));
|
|
|
|
|
CheckStatus(GdipDeleteGraphics(graphicsHandle));
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|