forked from Mirror/Ryujinx
872f036d64
We only used it in one spot for DPI scaling factor. This implements the same behaviour using gdiplus. This remove 700KB of dependency to download and around 170KB unpacked.
95 lines
3.5 KiB
C#
95 lines
3.5 KiB
C#
using Ryujinx.Common.Logging;
|
|
using System;
|
|
using System.Globalization;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Ryujinx.Common.System
|
|
{
|
|
public static class ForceDpiAware
|
|
{
|
|
[DllImport("user32.dll")]
|
|
private static extern bool SetProcessDPIAware();
|
|
|
|
private const string X11LibraryName = "libX11.so.6";
|
|
|
|
[DllImport(X11LibraryName)]
|
|
private static extern IntPtr XOpenDisplay(string display);
|
|
|
|
[DllImport(X11LibraryName)]
|
|
private static extern IntPtr XGetDefault(IntPtr display, string program, string option);
|
|
|
|
[DllImport(X11LibraryName)]
|
|
private static extern int XDisplayWidth(IntPtr display, int screenNumber);
|
|
|
|
[DllImport(X11LibraryName)]
|
|
private static extern int XDisplayWidthMM(IntPtr display, int screenNumber);
|
|
|
|
[DllImport(X11LibraryName)]
|
|
private static extern int XCloseDisplay(IntPtr display);
|
|
|
|
private static readonly double _standardDpiScale = 96.0;
|
|
private static readonly double _maxScaleFactor = 1.25;
|
|
|
|
/// <summary>
|
|
/// Marks the application as DPI-Aware when running on the Windows operating system.
|
|
/// </summary>
|
|
public static void Windows()
|
|
{
|
|
// Make process DPI aware for proper window sizing on high-res screens.
|
|
if (OperatingSystem.IsWindowsVersionAtLeast(6))
|
|
{
|
|
SetProcessDPIAware();
|
|
}
|
|
}
|
|
|
|
public static double GetActualScaleFactor()
|
|
{
|
|
double userDpiScale = 96.0;
|
|
|
|
try
|
|
{
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
userDpiScale = GdiPlusHelper.GetDpiX(IntPtr.Zero);
|
|
}
|
|
else if (OperatingSystem.IsLinux())
|
|
{
|
|
string xdgSessionType = Environment.GetEnvironmentVariable("XDG_SESSION_TYPE")?.ToLower();
|
|
|
|
if (xdgSessionType == null || xdgSessionType == "x11")
|
|
{
|
|
IntPtr display = XOpenDisplay(null);
|
|
string dpiString = Marshal.PtrToStringAnsi(XGetDefault(display, "Xft", "dpi"));
|
|
if (dpiString == null || !double.TryParse(dpiString, NumberStyles.Any, CultureInfo.InvariantCulture, out userDpiScale))
|
|
{
|
|
userDpiScale = (double)XDisplayWidth(display, 0) * 25.4 / (double)XDisplayWidthMM(display, 0);
|
|
}
|
|
XCloseDisplay(display);
|
|
}
|
|
else if (xdgSessionType == "wayland")
|
|
{
|
|
// TODO
|
|
Logger.Warning?.Print(LogClass.Application, $"Couldn't determine monitor DPI: Wayland not yet supported");
|
|
}
|
|
else
|
|
{
|
|
Logger.Warning?.Print(LogClass.Application, $"Couldn't determine monitor DPI: Unrecognised XDG_SESSION_TYPE: {xdgSessionType}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Logger.Warning?.Print(LogClass.Application, $"Couldn't determine monitor DPI: {e.Message}");
|
|
}
|
|
|
|
return userDpiScale;
|
|
}
|
|
|
|
public static double GetWindowScaleFactor()
|
|
{
|
|
double userDpiScale = GetActualScaleFactor();
|
|
|
|
return Math.Min(userDpiScale / _standardDpiScale, _maxScaleFactor);
|
|
}
|
|
}
|
|
}
|