#![cfg(windows)]
use std::io;
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::System::Console::{
ClosePseudoConsole, CreatePseudoConsole, ResizePseudoConsole, COORD, HPCON,
PSEUDOCONSOLE_INHERIT_CURSOR,
};
use super::PSEUDOCONSOLE_PASSTHROUGH_MODE;
const PSEUDOCONSOLE_RESIZE_QUIRK: u32 = 0x2;
const PSEUDOCONSOLE_WIN32_INPUT_MODE: u32 = 0x4;
pub(super) struct PseudoConsole {
handle: HPCON,
}
unsafe impl Send for PseudoConsole {}
unsafe impl Sync for PseudoConsole {}
impl PseudoConsole {
pub(super) fn new(size: COORD, input: HANDLE, output: HANDLE) -> io::Result<Self> {
let mut hpc: HPCON = 0;
let flags = PSEUDOCONSOLE_INHERIT_CURSOR
| PSEUDOCONSOLE_RESIZE_QUIRK
| PSEUDOCONSOLE_WIN32_INPUT_MODE
| PSEUDOCONSOLE_PASSTHROUGH_MODE;
let hr = unsafe { CreatePseudoConsole(size, input, output, flags, &mut hpc) };
if hr != 0 {
return Err(io::Error::other(format!(
"CreatePseudoConsole failed: HRESULT 0x{:08x}",
hr as u32
)));
}
if hpc == 0 {
return Err(io::Error::other(
"CreatePseudoConsole returned S_OK but null HPCON",
));
}
Ok(Self { handle: hpc })
}
pub(super) fn as_handle(&self) -> HPCON {
self.handle
}
pub(super) fn resize(&self, size: COORD) -> io::Result<()> {
let hr = unsafe { ResizePseudoConsole(self.handle, size) };
if hr != 0 {
return Err(io::Error::other(format!(
"ResizePseudoConsole failed: HRESULT 0x{:08x}",
hr as u32
)));
}
Ok(())
}
}
impl Drop for PseudoConsole {
fn drop(&mut self) {
if self.handle != 0 {
unsafe { ClosePseudoConsole(self.handle) };
self.handle = 0;
}
}
}