diff options
| author | Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com> | 2022-12-15 12:07:31 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-12-15 18:07:31 +0100 |
| commit | 0fbcd630bc57885d6b94fd3c4b3546493e09059e (patch) | |
| tree | 8e1f74775d3393d85e86a845c119a43907459884 /Ryujinx.Common/SystemInterop/ForceDpiAware.cs | |
| parent | f4d731ae2094128dcd1dc4a4be60b068047a77a7 (diff) | |
Replace `DllImport` usage with `LibraryImport` (#4084)
* Replace usage of `DllImport` with `LibraryImport`
* Mark methods as `partial`
* Marshalling
* More `partial` & marshalling
* More `partial` and marshalling
* More partial and marshalling
* Update GdiPlusHelper to LibraryImport
* Unicorn
* More Partial
* Marshal
* Specify EntryPoint
* Specify EntryPoint
* Change GlobalMemoryStatusEx to LibraryImport
* Change RegisterClassEx to LibraryImport
* Define EntryPoints
* Update Ryujinx.Ava/Ui/Controls/Win32NativeInterop.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFmpegApi.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Move return mashal
* Remove calling convention specification
* Remove calling conventions
* Update Ryujinx.Common/SystemInfo/WindowsSystemInfo.cs
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
* Update Ryujinx/Modules/Updater/Updater.cs
Co-authored-by: Mary-nyan <thog@protonmail.com>
* Update Ryujinx.Ava/Modules/Updater/Updater.cs
Co-authored-by: Mary-nyan <thog@protonmail.com>
Co-authored-by: TSRBerry <20988865+TSRBerry@users.noreply.github.com>
Co-authored-by: Mary-nyan <thog@protonmail.com>
Diffstat (limited to 'Ryujinx.Common/SystemInterop/ForceDpiAware.cs')
| -rw-r--r-- | Ryujinx.Common/SystemInterop/ForceDpiAware.cs | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/Ryujinx.Common/SystemInterop/ForceDpiAware.cs b/Ryujinx.Common/SystemInterop/ForceDpiAware.cs new file mode 100644 index 00000000..f17612a6 --- /dev/null +++ b/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); + } + } +} |
