#![cfg(feature = "consoleapi")]
use super::*;
use winapi::um::consoleapi::{
AllocConsole, ClosePseudoConsole, CreatePseudoConsole, GetConsoleCP,
GetConsoleMode, GetConsoleOutputCP, GetNumberOfConsoleInputEvents,
ReadConsoleInputW, ReadConsoleW, ResizePseudoConsole, SetConsoleCtrlHandler,
SetConsoleMode, WriteConsoleW,
};
#[inline]
pub fn alloc_console() -> Result<(), ErrorCode> {
if unsafe { AllocConsole() } != 0 {
Ok(())
} else {
Err(get_last_error())
}
}
#[inline]
pub unsafe fn close_pseudo_console(hpc: HPCON) {
ClosePseudoConsole(hpc)
}
#[inline]
pub unsafe fn create_pseudo_console(
size: COORD,
input: HANDLE,
output: HANDLE,
flags: u32,
) -> Result<HPCON, HRESULT> {
let mut hpc = null_mut();
let hresult = CreatePseudoConsole(size, input, output, flags, &mut hpc);
if hresult == S_OK {
Ok(hpc)
} else {
Err(hresult)
}
}
#[inline]
pub fn get_console_cp() -> Result<u32, ErrorCode> {
let page = unsafe { GetConsoleCP() };
if page != 0 {
Ok(page)
} else {
Err(get_last_error())
}
}
#[inline]
pub unsafe fn get_console_mode(handle: HANDLE) -> Result<u32, ErrorCode> {
let mut mode: u32 = 0;
if GetConsoleMode(handle, &mut mode) != 0 {
Ok(mode)
} else {
Err(get_last_error())
}
}
#[inline]
pub fn get_console_output_cp() -> Result<u32, ErrorCode> {
let out = unsafe { GetConsoleOutputCP() };
if out != 0 {
Ok(out)
} else {
Err(get_last_error())
}
}
#[inline]
pub unsafe fn get_number_of_console_input_events(
console_input: HANDLE,
) -> Result<u32, ErrorCode> {
let mut out: u32 = 0;
if GetNumberOfConsoleInputEvents(console_input, &mut out) != 0 {
Ok(out)
} else {
Err(get_last_error())
}
}
#[inline]
pub unsafe fn read_console(
console_input: HANDLE,
buffer: &mut [u16],
mut opt_control: Option<CONSOLE_READCONSOLE_CONTROL>,
) -> Result<usize, ErrorCode> {
let mut units_read: u32 = 0;
let m: Option<&mut CONSOLE_READCONSOLE_CONTROL> = opt_control.as_mut();
if ReadConsoleW(
console_input,
buffer.as_mut_ptr() as *mut _,
buffer.len().min(core::u32::MAX as usize) as u32,
&mut units_read,
opt_to_mut_ptr(m),
) != 0
{
Ok(units_read as usize)
} else {
Err(get_last_error())
}
}
#[inline]
pub unsafe fn read_console_input(
console_input: HANDLE,
buffer: &mut [INPUT_RECORD],
) -> Result<usize, ErrorCode> {
let mut num_read: u32 = 0;
if ReadConsoleInputW(
console_input,
buffer.as_mut_ptr(),
buffer.len().min(core::u32::MAX as usize) as u32,
&mut num_read,
) != 0
{
Ok(num_read as usize)
} else {
Err(get_last_error())
}
}
#[inline]
pub unsafe fn resize_pseudo_console(hpc: HPCON, size: COORD) -> Result<(), HRESULT> {
let h = ResizePseudoConsole(hpc, size);
if h == S_OK {
Ok(())
} else {
Err(h)
}
}
#[inline]
pub unsafe fn set_console_ctrl_handler(
routine: Option<unsafe extern "system" fn(u32) -> i32>,
add: bool,
) -> Result<(), ErrorCode> {
if SetConsoleCtrlHandler(routine, add as i32) != 0 {
Ok(())
} else {
Err(get_last_error())
}
}
#[inline]
pub unsafe fn set_console_mode(handle: HANDLE, mode: u32) -> Result<(), ErrorCode> {
if SetConsoleMode(handle, mode) != 0 {
Ok(())
} else {
Err(get_last_error())
}
}
#[inline]
pub fn write_console(
console_output: HANDLE,
message: &[u16],
) -> Result<usize, ErrorCode> {
let mut units_written: u32 = 0;
let write_status = unsafe {
WriteConsoleW(
console_output,
message.as_ptr() as *const _,
message.len().min(core::u32::MAX as usize) as u32,
&mut units_written,
null_mut(),
)
};
if write_status != 0 {
Ok(units_written as usize)
} else {
Err(get_last_error())
}
}