Fix Windows crate 0.58 API compatibility

- Define XBUTTON1/XBUTTON2 constants (removed from windows crate)
- Update D3D11_CPU_ACCESS_FLAG usage
- Fix CreateTexture2D output parameter
- Fix BitBlt/EnumDisplayMonitors return type handling
- Fix encode_utf16 iterator usage
This commit is contained in:
AZ Computer Guru
2025-12-28 12:39:33 -07:00
parent 33893ea73b
commit 09223cf97a
5 changed files with 29 additions and 17 deletions

View File

@@ -78,12 +78,15 @@ pub fn enumerate_displays() -> Result<Vec<Display>> {
// Collect all monitor handles // Collect all monitor handles
let mut monitors: Vec<(windows::Win32::Graphics::Gdi::HMONITOR, u32)> = Vec::new(); let mut monitors: Vec<(windows::Win32::Graphics::Gdi::HMONITOR, u32)> = Vec::new();
unsafe { unsafe {
EnumDisplayMonitors( let result = EnumDisplayMonitors(
None, None,
None, None,
Some(enum_callback), Some(enum_callback),
LPARAM(&mut monitors as *mut _ as isize), LPARAM(&mut monitors as *mut _ as isize),
)?; );
if !result.as_bool() {
anyhow::bail!("EnumDisplayMonitors failed");
}
} }
// Get detailed info for each monitor // Get detailed info for each monitor

View File

@@ -13,7 +13,7 @@ use std::time::Instant;
use windows::Win32::Graphics::Direct3D::D3D_DRIVER_TYPE_UNKNOWN; use windows::Win32::Graphics::Direct3D::D3D_DRIVER_TYPE_UNKNOWN;
use windows::Win32::Graphics::Direct3D11::{ use windows::Win32::Graphics::Direct3D11::{
D3D11CreateDevice, ID3D11Device, ID3D11DeviceContext, ID3D11Texture2D, D3D11CreateDevice, ID3D11Device, ID3D11DeviceContext, ID3D11Texture2D,
D3D11_CPU_ACCESS_READ, D3D11_SDK_VERSION, D3D11_TEXTURE2D_DESC, D3D11_CPU_ACCESS_FLAG, D3D11_SDK_VERSION, D3D11_TEXTURE2D_DESC,
D3D11_USAGE_STAGING, D3D11_MAPPED_SUBRESOURCE, D3D11_MAP_READ, D3D11_USAGE_STAGING, D3D11_MAPPED_SUBRESOURCE, D3D11_MAP_READ,
}; };
use windows::Win32::Graphics::Dxgi::{ use windows::Win32::Graphics::Dxgi::{
@@ -169,12 +169,15 @@ impl DxgiCapturer {
desc.Usage = D3D11_USAGE_STAGING; desc.Usage = D3D11_USAGE_STAGING;
desc.BindFlags = Default::default(); desc.BindFlags = Default::default();
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG(0x20000); // D3D11_CPU_ACCESS_READ
desc.MiscFlags = Default::default(); desc.MiscFlags = Default::default();
let staging = self.device.CreateTexture2D(&desc, None) let mut staging: Option<ID3D11Texture2D> = None;
self.device.CreateTexture2D(&desc, None, Some(&mut staging))
.context("Failed to create staging texture")?; .context("Failed to create staging texture")?;
let staging = staging.context("Staging texture is None")?;
// Set high priority // Set high priority
let resource: IDXGIResource = staging.cast()?; let resource: IDXGIResource = staging.cast()?;
resource.SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM.0)?; resource.SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM.0)?;

View File

@@ -4,7 +4,7 @@
//! Slower than DXGI but works on older systems and edge cases. //! Slower than DXGI but works on older systems and edge cases.
use super::{CapturedFrame, Capturer, Display}; use super::{CapturedFrame, Capturer, Display};
use anyhow::{Context, Result}; use anyhow::Result;
use std::time::Instant; use std::time::Instant;
use windows::Win32::Graphics::Gdi::{ use windows::Win32::Graphics::Gdi::{
@@ -58,7 +58,7 @@ impl GdiCapturer {
let old_bitmap = SelectObject(mem_dc, bitmap); let old_bitmap = SelectObject(mem_dc, bitmap);
// Copy screen to memory DC // Copy screen to memory DC
let result = BitBlt( if let Err(e) = BitBlt(
mem_dc, mem_dc,
0, 0,
0, 0,
@@ -68,14 +68,12 @@ impl GdiCapturer {
self.display.x, self.display.x,
self.display.y, self.display.y,
SRCCOPY, SRCCOPY,
); ) {
if !result.as_bool() {
SelectObject(mem_dc, old_bitmap); SelectObject(mem_dc, old_bitmap);
DeleteObject(bitmap); DeleteObject(bitmap);
DeleteDC(mem_dc); DeleteDC(mem_dc);
ReleaseDC(HWND::default(), screen_dc); ReleaseDC(HWND::default(), screen_dc);
anyhow::bail!("BitBlt failed"); anyhow::bail!("BitBlt failed: {}", e);
} }
// Prepare bitmap info for GetDIBits // Prepare bitmap info for GetDIBits

View File

@@ -81,9 +81,11 @@ impl KeyboardController {
#[cfg(windows)] #[cfg(windows)]
pub fn type_char(&mut self, ch: char) -> Result<()> { pub fn type_char(&mut self, ch: char) -> Result<()> {
let mut inputs = Vec::new(); let mut inputs = Vec::new();
let mut buf = [0u16; 2];
let encoded = ch.encode_utf16(&mut buf);
// For characters that fit in a single u16 // For characters that fit in a single u16
for code_unit in ch.encode_utf16(&mut [0; 2]) { for &code_unit in encoded {
// Key down // Key down
inputs.push(INPUT { inputs.push(INPUT {
r#type: INPUT_KEYBOARD, r#type: INPUT_KEYBOARD,

View File

@@ -8,9 +8,15 @@ use windows::Win32::UI::Input::KeyboardAndMouse::{
SendInput, INPUT, INPUT_0, INPUT_MOUSE, MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_HWHEEL, SendInput, INPUT, INPUT_0, INPUT_MOUSE, MOUSEEVENTF_ABSOLUTE, MOUSEEVENTF_HWHEEL,
MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP,
MOUSEEVENTF_MOVE, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_VIRTUALDESK, MOUSEEVENTF_MOVE, MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_VIRTUALDESK,
MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP, MOUSEINPUT, XBUTTON1, XBUTTON2, MOUSEEVENTF_WHEEL, MOUSEEVENTF_XDOWN, MOUSEEVENTF_XUP, MOUSEINPUT,
}; };
// X button constants (not exported in windows crate 0.58+)
#[cfg(windows)]
const XBUTTON1: u32 = 0x0001;
#[cfg(windows)]
const XBUTTON2: u32 = 0x0002;
#[cfg(windows)] #[cfg(windows)]
use windows::Win32::UI::WindowsAndMessaging::{ use windows::Win32::UI::WindowsAndMessaging::{
GetSystemMetrics, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, GetSystemMetrics, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN,
@@ -86,8 +92,8 @@ impl MouseController {
MouseButton::Left => (MOUSEEVENTF_LEFTDOWN, 0), MouseButton::Left => (MOUSEEVENTF_LEFTDOWN, 0),
MouseButton::Right => (MOUSEEVENTF_RIGHTDOWN, 0), MouseButton::Right => (MOUSEEVENTF_RIGHTDOWN, 0),
MouseButton::Middle => (MOUSEEVENTF_MIDDLEDOWN, 0), MouseButton::Middle => (MOUSEEVENTF_MIDDLEDOWN, 0),
MouseButton::X1 => (MOUSEEVENTF_XDOWN, XBUTTON1 as u32), MouseButton::X1 => (MOUSEEVENTF_XDOWN, XBUTTON1),
MouseButton::X2 => (MOUSEEVENTF_XDOWN, XBUTTON2 as u32), MouseButton::X2 => (MOUSEEVENTF_XDOWN, XBUTTON2),
}; };
let input = INPUT { let input = INPUT {
@@ -114,8 +120,8 @@ impl MouseController {
MouseButton::Left => (MOUSEEVENTF_LEFTUP, 0), MouseButton::Left => (MOUSEEVENTF_LEFTUP, 0),
MouseButton::Right => (MOUSEEVENTF_RIGHTUP, 0), MouseButton::Right => (MOUSEEVENTF_RIGHTUP, 0),
MouseButton::Middle => (MOUSEEVENTF_MIDDLEUP, 0), MouseButton::Middle => (MOUSEEVENTF_MIDDLEUP, 0),
MouseButton::X1 => (MOUSEEVENTF_XUP, XBUTTON1 as u32), MouseButton::X1 => (MOUSEEVENTF_XUP, XBUTTON1),
MouseButton::X2 => (MOUSEEVENTF_XUP, XBUTTON2 as u32), MouseButton::X2 => (MOUSEEVENTF_XUP, XBUTTON2),
}; };
let input = INPUT { let input = INPUT {