From 7c8cc5f74651b568dc0b95bdd33b59af5d66b474 Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Thu, 14 Nov 2013 09:02:47 +0100 Subject: [PATCH] Scale window size on hi-dpi mode Follow high-dpi guidelines for scaling a window on high-dpi modes. --- Source/OpenTK/Platform/Windows/WinGLNative.cs | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/Source/OpenTK/Platform/Windows/WinGLNative.cs b/Source/OpenTK/Platform/Windows/WinGLNative.cs index e1d3f948..d4726a34 100644 --- a/Source/OpenTK/Platform/Windows/WinGLNative.cs +++ b/Source/OpenTK/Platform/Windows/WinGLNative.cs @@ -125,10 +125,20 @@ namespace OpenTK.Platform.Windows // To avoid issues with Ati drivers on Windows 6+ with compositing enabled, the context will not be // bound to the top-level window, but rather to a child window docked in the parent. + int scale_width = ScaleX(width); + int scale_height = ScaleY(height); + int scale_x = x - UnscaleX(scale_width - width); + int scale_y = y - UnscaleY(scale_height - height); window = new WinWindowInfo( - CreateWindow(x, y, width, height, title, options, device, IntPtr.Zero), null); + CreateWindow( + scale_x, scale_y, scale_width, scale_height, + title, options, device, IntPtr.Zero), + null); child_window = new WinWindowInfo( - CreateWindow(0, 0, ClientSize.Width, ClientSize.Height, title, options, device, window.Handle), window); + CreateWindow( + 0, 0, ClientSize.Width, ClientSize.Height, + title, options, device, window.Handle), + window); exists = true; @@ -150,6 +160,68 @@ namespace OpenTK.Platform.Windows #region Private Members + #region Scale + + enum ScaleDirection { X, Y } + + // Scales a value according according + // to the DPI of the specified direction + static int Scale(int v, ScaleDirection direction) + { + IntPtr dc = Functions.GetDC(IntPtr.Zero); + if (dc != IntPtr.Zero) + { + int dpi = Functions.GetDeviceCaps(dc, + direction == ScaleDirection.X ? DeviceCaps.LogPixelsX : DeviceCaps.LogPixelsY); + if (dpi > 0) + { + float scale = dpi / 96.0f; + v = (int)Math.Round(v * scale); + } + Functions.ReleaseDC(IntPtr.Zero, dc); + } + return v; + } + + static int ScaleX(int x) + { + return Scale(x, ScaleDirection.X); + } + + static int ScaleY(int y) + { + return Scale(y, ScaleDirection.Y); + } + + static int Unscale(int v, ScaleDirection direction) + { + IntPtr dc = Functions.GetDC(IntPtr.Zero); + if (dc != IntPtr.Zero) + { + int dpi = Functions.GetDeviceCaps(dc, + direction == ScaleDirection.X ? DeviceCaps.LogPixelsX : DeviceCaps.LogPixelsY); + if (dpi > 0) + { + float scale = dpi / 96.0f; + v = (int)Math.Round(v / scale); + } + Functions.ReleaseDC(IntPtr.Zero, dc); + } + return v; + } + + static int UnscaleX(int x) + { + return Unscale(x, ScaleDirection.X); + } + + static int UnscaleY(int y) + { + return Unscale(y, ScaleDirection.Y); + } + + #endregion + #region WindowProcedure IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)