#[cfg(windows)]
#[allow(non_camel_case_types, non_snake_case)]
mod windows_console {
use core::ffi::c_void;
type c_ulong = u32;
type c_int = i32;
type wchar_t = u16;
type DWORD = c_ulong;
type LPDWORD = *mut DWORD;
type HANDLE = *mut c_void;
type BOOL = c_int;
type LPCWSTR = *const WCHAR;
type WCHAR = wchar_t;
type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES;
type LPVOID = *mut c_void;
#[repr(C)]
pub struct SECURITY_ATTRIBUTES {
pub nLength: DWORD,
pub lpSecurityDescriptor: LPVOID,
pub bInheritHandle: BOOL,
}
const ENABLE_VIRTUAL_TERMINAL_PROCESSING: DWORD = 0x0004;
const INVALID_HANDLE_VALUE: HANDLE = -1isize as HANDLE;
const FALSE: BOOL = 0;
const TRUE: BOOL = 1;
const GENERIC_READ: DWORD = 0x80000000;
const GENERIC_WRITE: DWORD = 0x40000000;
const FILE_SHARE_READ: DWORD = 0x00000001;
const FILE_SHARE_WRITE: DWORD = 0x00000002;
const OPEN_EXISTING: DWORD = 3;
extern "system" {
fn CreateFileW(
lpFileName: LPCWSTR,
dwDesiredAccess: DWORD,
dwShareMode: DWORD,
lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
dwCreationDisposition: DWORD,
dwFlagsAndAttributes: DWORD,
hTemplateFile: HANDLE
) -> HANDLE;
fn GetLastError() -> DWORD;
fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL;
fn SetConsoleMode(hConsoleHandle: HANDLE, dwMode: DWORD) -> BOOL;
}
fn get_output_handle() -> Result<HANDLE, DWORD> {
const CONOUT: &[u16] = &[0x43, 0x4F, 0x4E, 0x4F, 0x55, 0x54, 0x24, 0x00];
let raw_handle = unsafe {
CreateFileW(
CONOUT.as_ptr(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
core::ptr::null_mut(),
OPEN_EXISTING,
0,
core::ptr::null_mut(),
)
};
if raw_handle == INVALID_HANDLE_VALUE {
return Err(6);
}
Ok(raw_handle)
}
unsafe fn enable_vt(handle: HANDLE) -> Result<(), DWORD> {
let mut dw_mode: DWORD = 0;
if GetConsoleMode(handle, &mut dw_mode) == FALSE {
return Err(GetLastError());
}
dw_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
match SetConsoleMode(handle, dw_mode) {
result if result == TRUE => Ok(()),
_ => Err(GetLastError())
}
}
unsafe fn enable_ansi_colors_raw() -> Result<bool, DWORD> {
enable_vt(get_output_handle()?)?;
Ok(true)
}
#[inline(always)]
pub fn enable() -> bool {
unsafe { enable_ansi_colors_raw().unwrap_or(false) }
}
pub fn cache_enable() -> bool {
use crate::condition::CachedBool;
static ENABLED: CachedBool = CachedBool::new();
ENABLED.get_or_init(enable)
}
}
#[cfg(not(windows))]
mod windows_console {
#[inline(always)]
#[allow(dead_code)]
pub fn enable() -> bool { true }
#[inline(always)]
pub fn cache_enable() -> bool { true }
}
pub use self::windows_console::cache_enable;