Skip to content

Commit

Permalink
RustAudio#145 Add support for Windows 7 and 8
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Apr 16, 2023
1 parent c129b12 commit 15c06e0
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ nix = "0.22.0"
[target.'cfg(target_os="windows")'.dependencies]
winapi = { version = "0.3.8", features = ["libloaderapi", "winuser", "windef", "minwindef", "guiddef", "combaseapi", "wingdi", "errhandlingapi"] }
uuid = { version = "0.8", features = ["v4"], optional = true }
libloading = "0.8.0"

[target.'cfg(target_os="macos")'.dependencies]
cocoa = "0.24.0"
Expand Down
35 changes: 35 additions & 0 deletions src/win/dynamic_win_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use libloading::{Library, Symbol};
use winapi::shared::minwindef::{BOOL, UINT};
use winapi::shared::windef::{DPI_AWARENESS_CONTEXT, HWND};

/// Provides access to some Win32 API functions that are not available in older Windows versions.
///
/// This is better than eagerly linking to these functions because then the resulting binary
/// wouldn't work *at all* in the older Windows versions, whereas with this approach, we can
/// fall back to alternative logic or alternative values on a case-by-case basis.
pub struct DynamicWinApi {
user32_library: Library,
}

impl DynamicWinApi {
/// Loads the dynamic windows API, in particular "user32.dll".
pub fn load() -> Self {
unsafe { Self { user32_library: Library::new("user32.dll").unwrap() } }
}

/// Should be available from Windows 10 onwards.
pub fn set_process_dpi_awareness_context(
&self,
) -> Option<Symbol<SetProcessDpiAwarenessContext>> {
unsafe { self.user32_library.get(b"SetProcessDpiAwarenessContext").ok() }
}

/// Should be available from Windows 10 onwards.
pub fn get_dpi_for_window(&self) -> Option<Symbol<GetDpiForWindow>> {
unsafe { self.user32_library.get(b"GetDpiForWindow").ok() }
}
}

type SetProcessDpiAwarenessContext = extern "stdcall" fn(value: DPI_AWARENESS_CONTEXT) -> BOOL;

type GetDpiForWindow = extern "stdcall" fn(hwnd: HWND) -> UINT;
1 change: 1 addition & 0 deletions src/win/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod dynamic_win_api;
mod keyboard;
mod window;

Expand Down
32 changes: 16 additions & 16 deletions src/win/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ use winapi::shared::windef::{HWND, RECT};
use winapi::um::combaseapi::CoCreateGuid;
use winapi::um::winuser::{
AdjustWindowRectEx, CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW,
GetDpiForWindow, GetMessageW, GetWindowLongPtrW, LoadCursorW, PostMessageW, RegisterClassW,
ReleaseCapture, SetCapture, SetProcessDpiAwarenessContext, SetTimer, SetWindowLongPtrW,
SetWindowPos, TranslateMessage, UnregisterClassW, CS_OWNDC, GET_XBUTTON_WPARAM, GWLP_USERDATA,
IDC_ARROW, MSG, SWP_NOMOVE, SWP_NOZORDER, WHEEL_DELTA, WM_CHAR, WM_CLOSE, WM_CREATE,
WM_DPICHANGED, WM_INPUTLANGCHANGE, WM_KEYDOWN, WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP,
WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_NCDESTROY,
WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SHOWWINDOW, WM_SIZE, WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP,
WM_TIMER, WM_USER, WM_XBUTTONDOWN, WM_XBUTTONUP, WNDCLASSW, WS_CAPTION, WS_CHILD,
WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE,
XBUTTON1, XBUTTON2,
GetMessageW, GetWindowLongPtrW, LoadCursorW, PostMessageW, RegisterClassW, ReleaseCapture,
SetCapture, SetTimer, SetWindowLongPtrW, SetWindowPos, TranslateMessage, UnregisterClassW,
CS_OWNDC, GET_XBUTTON_WPARAM, GWLP_USERDATA, IDC_ARROW, MSG, SWP_NOMOVE, SWP_NOZORDER,
WHEEL_DELTA, WM_CHAR, WM_CLOSE, WM_CREATE, WM_DPICHANGED, WM_INPUTLANGCHANGE, WM_KEYDOWN,
WM_KEYUP, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, WM_MOUSEHWHEEL,
WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_NCDESTROY, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_SHOWWINDOW,
WM_SIZE, WM_SYSCHAR, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_TIMER, WM_USER, WM_XBUTTONDOWN,
WM_XBUTTONUP, WNDCLASSW, WS_CAPTION, WS_CHILD, WS_CLIPSIBLINGS, WS_MAXIMIZEBOX, WS_MINIMIZEBOX,
WS_POPUPWINDOW, WS_SIZEBOX, WS_VISIBLE, XBUTTON1, XBUTTON2,
};

use std::cell::{Cell, RefCell};
Expand All @@ -35,6 +34,7 @@ use crate::{

use super::keyboard::KeyboardState;

use crate::win::dynamic_win_api::DynamicWinApi;
#[cfg(feature = "opengl")]
use crate::{gl::GlContext, window::RawWindowHandleWrapper};

Expand Down Expand Up @@ -681,15 +681,15 @@ impl Window<'_> {
};
*window_state.handler.borrow_mut() = Some(Box::new(handler));

// Only works on Windows 10 unfortunately.
SetProcessDpiAwarenessContext(
winapi::shared::windef::DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE,
);
let dynamic_win_api = DynamicWinApi::load();
if let Some(f) = dynamic_win_api.set_process_dpi_awareness_context() {
f(winapi::shared::windef::DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
}

// Now we can get the actual dpi of the window.
let new_rect = if let WindowScalePolicy::SystemScaleFactor = options.scale {
// Only works on Windows 10 unfortunately.
let dpi = GetDpiForWindow(hwnd);
let dpi =
if let Some(f) = dynamic_win_api.get_dpi_for_window() { f(hwnd) } else { 96 };
let scale_factor = dpi as f64 / 96.0;

let mut window_info = window_state.window_info.borrow_mut();
Expand Down

0 comments on commit 15c06e0

Please sign in to comment.