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:
@@ -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
|
||||||
|
|||||||
@@ -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)?;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user