diff options
author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
---|---|---|
committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs | |
parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) |
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs')
-rw-r--r-- | src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs b/src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs new file mode 100644 index 00000000..f17612a6 --- /dev/null +++ b/src/Ryujinx.Common/SystemInterop/ForceDpiAware.cs @@ -0,0 +1,96 @@ +using Ryujinx.Common.Logging; +using System; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace Ryujinx.Common.SystemInterop +{ + public static partial class ForceDpiAware + { + [LibraryImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool SetProcessDPIAware(); + + private const string X11LibraryName = "libX11.so.6"; + + [LibraryImport(X11LibraryName)] + private static partial IntPtr XOpenDisplay([MarshalAs(UnmanagedType.LPStr)] string display); + + [LibraryImport(X11LibraryName)] + private static partial IntPtr XGetDefault(IntPtr display, [MarshalAs(UnmanagedType.LPStr)] string program, [MarshalAs(UnmanagedType.LPStr)] string option); + + [LibraryImport(X11LibraryName)] + private static partial int XDisplayWidth(IntPtr display, int screenNumber); + + [LibraryImport(X11LibraryName)] + private static partial int XDisplayWidthMM(IntPtr display, int screenNumber); + + [LibraryImport(X11LibraryName)] + private static partial 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); + } + } +} |