Skip to content

Commit

Permalink
Use windows crate instead of windows-sys
Browse files Browse the repository at this point in the history
This avoids having to maintain code that handles errors, and various
other simplifications provided by the higher level crate.

From the windows crate documentation:

> The windows-sys crate is a zero-overhead fallback for the most
> demanding situations and primarily where the absolute best compile
> time is essential. It only includes function declarations (externs),
> structs, and constants. No convenience helpers, traits, or wrappers
> are provided.
  • Loading branch information
joshka committed Jun 22, 2024
1 parent 6fa15ec commit 3a7e0f4
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 162 deletions.
8 changes: 3 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,11 @@ edition = "2021"
rust-version = "1.60.0"

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.52.0", features = [
"Win32_Foundation",
windows = { version = "0.57.0", features = [
"Win32_Security",
"Win32_System_Threading",
"Win32_System_Console",
"Win32_Storage_FileSystem",
"Win32_System_Console",
"Win32_System_Threading",
] }

[package.metadata.docs.rs]
default-target = "x86_64-pc-windows-msvc"
2 changes: 1 addition & 1 deletion src/cfi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt;
use std::mem::zeroed;

use windows_sys::Win32::System::Console::CONSOLE_FONT_INFO;
use windows::Win32::System::Console::CONSOLE_FONT_INFO;

use crate::Size;

Expand Down
61 changes: 17 additions & 44 deletions src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ use std::iter;
use std::slice;
use std::str;

use std::ffi::c_void;
use windows_sys::Win32::System::Console::{
use windows::Win32::System::Console::{
FillConsoleOutputAttribute, FillConsoleOutputCharacterA, GetLargestConsoleWindowSize,
GetNumberOfConsoleInputEvents, ReadConsoleInputW, SetConsoleTextAttribute,
SetConsoleWindowInfo, WriteConsoleW, COORD, INPUT_RECORD, SMALL_RECT,
SetConsoleWindowInfo, WriteConsoleW, CONSOLE_CHARACTER_ATTRIBUTES, COORD, INPUT_RECORD,
SMALL_RECT,
};
const NULL: *mut c_void = 0 as *mut c_void;

use super::{result, Coord, Handle, HandleType, InputRecord, WindowPositions};
use super::{Coord, Handle, HandleType, InputRecord, WindowPositions};

/// A wrapper around a screen buffer.
#[derive(Debug, Clone)]
Expand All @@ -38,7 +37,7 @@ impl Console {
/// This wraps
/// [`SetConsoleTextAttribute`](https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute).
pub fn set_text_attribute(&self, value: u16) -> Result<()> {
result(unsafe { SetConsoleTextAttribute(*self.handle, value) })?;
unsafe { SetConsoleTextAttribute(*self.handle, CONSOLE_CHARACTER_ATTRIBUTES(value)) }?;
Ok(())
}

Expand All @@ -47,14 +46,8 @@ impl Console {
/// This wraps
/// [`SetConsoleWindowInfo`](https://docs.microsoft.com/en-us/windows/console/setconsolewindowinfo).
pub fn set_console_info(&self, absolute: bool, rect: WindowPositions) -> Result<()> {
let absolute = match absolute {
true => 1,
false => 0,
};
let a = SMALL_RECT::from(rect);

result(unsafe { SetConsoleWindowInfo(*self.handle, absolute, &a) })?;

unsafe { SetConsoleWindowInfo(*self.handle, absolute, &a) }?;
Ok(())
}

Expand All @@ -63,23 +56,23 @@ impl Console {
///
/// This wraps
/// [`FillConsoleOutputCharacterA`](https://docs.microsoft.com/en-us/windows/console/fillconsoleoutputcharacter).
pub fn fill_whit_character(
pub fn fill_with_character(
&self,
start_location: Coord,
cells_to_write: u32,
filling_char: char,
) -> Result<u32> {
let mut chars_written = 0;
result(unsafe {
unsafe {
// fill the cells in console with blanks
FillConsoleOutputCharacterA(
*self.handle,
filling_char as u8,
filling_char as i8,
cells_to_write,
COORD::from(start_location),
&mut chars_written,
)
})?;
}?;

Ok(chars_written)
}
Expand All @@ -97,15 +90,15 @@ impl Console {
) -> Result<u32> {
let mut cells_written = 0;
// Get the position of the current console window
result(unsafe {
unsafe {
FillConsoleOutputAttribute(
*self.handle,
dw_attribute,
cells_to_write,
COORD::from(start_location),
&mut cells_written,
)
})?;
}?;

Ok(cells_written)
}
Expand Down Expand Up @@ -133,20 +126,9 @@ impl Console {
}
};

let utf16: Vec<u16> = utf8.encode_utf16().collect();
let utf16_ptr: *const c_void = utf16.as_ptr() as *const _ as *const c_void;
let cells_written: Option<*mut u32> = None;

let mut cells_written: u32 = 0;

result(unsafe {
WriteConsoleW(
*self.handle,
utf16_ptr,
utf16.len() as u32,
&mut cells_written,
NULL,
)
})?;
unsafe { WriteConsoleW(*self.handle, buf, cells_written, None) }?;

Ok(utf8.as_bytes().len())
}
Expand All @@ -156,7 +138,7 @@ impl Console {
/// This wraps
/// [`ReadConsoleInputW`](https://docs.microsoft.com/en-us/windows/console/readconsoleinput).
pub fn read_single_input_event(&self) -> Result<InputRecord> {
let mut record: INPUT_RECORD = unsafe { ::std::mem::zeroed() };
let mut record: INPUT_RECORD = INPUT_RECORD::default();

{
// Convert an INPUT_RECORD to an &mut [INPUT_RECORD] of length 1
Expand Down Expand Up @@ -203,7 +185,7 @@ impl Console {
/// [`GetNumberOfConsoleInputEvents`](https://docs.microsoft.com/en-us/windows/console/getnumberofconsoleinputevents).
pub fn number_of_console_input_events(&self) -> Result<u32> {
let mut buf_len = 0;
result(unsafe { GetNumberOfConsoleInputEvents(*self.handle, &mut buf_len) })?;
unsafe { GetNumberOfConsoleInputEvents(*self.handle, &mut buf_len) }?;
Ok(buf_len)
}

Expand All @@ -214,16 +196,7 @@ impl Console {
fn read_input(&self, buf: &mut [INPUT_RECORD]) -> Result<usize> {
let mut num_records = 0;
debug_assert!(buf.len() < u32::MAX as usize);

result(unsafe {
ReadConsoleInputW(
*self.handle,
buf.as_mut_ptr(),
buf.len() as u32,
&mut num_records,
)
})?;

unsafe { ReadConsoleInputW(*self.handle, buf, &mut num_records) }?;
Ok(num_records as usize)
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/console_mode.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::io::Result;

use windows_sys::Win32::System::Console::{GetConsoleMode, SetConsoleMode};
use windows::Win32::System::Console::{GetConsoleMode, SetConsoleMode, CONSOLE_MODE};

use super::{result, Handle, HandleType};
use super::{Handle, HandleType};

/// A wrapper around a screen buffer, focusing on calls to get and set the console mode.
///
Expand Down Expand Up @@ -32,7 +32,8 @@ impl ConsoleMode {
/// This wraps
/// [`SetConsoleMode`](https://docs.microsoft.com/en-us/windows/console/setconsolemode).
pub fn set_mode(&self, console_mode: u32) -> Result<()> {
result(unsafe { SetConsoleMode(*self.handle, console_mode) })
unsafe { SetConsoleMode(*self.handle, CONSOLE_MODE(console_mode)) }?;
Ok(())
}

/// Get the console mode.
Expand All @@ -42,9 +43,9 @@ impl ConsoleMode {
/// This wraps
/// [`GetConsoleMode`](https://docs.microsoft.com/en-us/windows/console/getconsolemode).
pub fn mode(&self) -> Result<u32> {
let mut console_mode = 0;
result(unsafe { GetConsoleMode(*self.handle, &mut console_mode) })?;
Ok(console_mode)
let mut console_mode = CONSOLE_MODE(0);
unsafe { GetConsoleMode(*self.handle, &mut console_mode) }?;
Ok(console_mode.0)
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/csbi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt;
use std::mem::zeroed;

use windows_sys::Win32::System::Console::CONSOLE_SCREEN_BUFFER_INFO;
use windows::Win32::System::Console::CONSOLE_SCREEN_BUFFER_INFO;

use super::{Coord, Size, WindowPositions};

Expand Down Expand Up @@ -64,7 +64,7 @@ impl ScreenBufferInfo {
///
/// Will take `wAttributes` from the current screen buffer.
pub fn attributes(&self) -> u16 {
self.0.wAttributes
self.0.wAttributes.0
}

/// Get the current column and row of the terminal cursor in the screen buffer.
Expand Down
47 changes: 22 additions & 25 deletions src/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@
use std::io::Result;
use std::ops::Deref;
use std::ptr::{null, null_mut};
use std::sync::Arc;

use windows_sys::Win32::Foundation::{
CloseHandle, GENERIC_READ, GENERIC_WRITE, HANDLE, INVALID_HANDLE_VALUE,
};
use windows_sys::Win32::Storage::FileSystem::{
use windows::Win32::Storage::FileSystem::{
CreateFileW, FILE_SHARE_READ, FILE_SHARE_WRITE, OPEN_EXISTING,
};
use windows_sys::Win32::System::Console::{
use windows::Win32::System::Console::{
GetStdHandle, STD_HANDLE, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
};

use super::handle_result;
use windows::Win32::{
Foundation::{CloseHandle, GENERIC_READ, GENERIC_WRITE, HANDLE, INVALID_HANDLE_VALUE},
Storage::FileSystem::FILE_FLAGS_AND_ATTRIBUTES,
};

/// The standard handles of a process.
///
Expand Down Expand Up @@ -65,7 +63,7 @@ impl Drop for Inner {
fn drop(&mut self) {
if self.is_exclusive {
assert!(
unsafe { CloseHandle(self.handle) != 0 },
unsafe { CloseHandle(self.handle).is_ok() },
"failed to close handle"
)
}
Expand Down Expand Up @@ -115,17 +113,17 @@ impl Handle {
/// This wraps
/// [`CreateFileW`](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew).
pub fn current_out_handle() -> Result<Handle> {
let handle = handle_result(unsafe {
let handle = unsafe {
CreateFileW(
::windows_sys::w!("CONOUT$"),
GENERIC_READ | GENERIC_WRITE,
::windows::core::w!("CONOUT$"),
(GENERIC_READ | GENERIC_WRITE).0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
null(),
None, // no security attributes
OPEN_EXISTING,
0,
0,
FILE_FLAGS_AND_ATTRIBUTES::default(),
None, // no template file
)
})?;
}?;

Ok(Handle {
handle: Arc::new(Inner::new_exclusive(handle)),
Expand All @@ -139,17 +137,17 @@ impl Handle {
/// This wraps
/// [`CreateFileW`](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew).
pub fn current_in_handle() -> Result<Handle> {
let handle = handle_result(unsafe {
let handle = unsafe {
CreateFileW(
::windows_sys::w!("CONIN$"),
GENERIC_READ | GENERIC_WRITE,
::windows::core::w!("CONIN$"),
(GENERIC_READ | GENERIC_WRITE).0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
null_mut(),
None, // no security attributes
OPEN_EXISTING,
0,
0,
FILE_FLAGS_AND_ATTRIBUTES::default(),
None, // no template file
)
})?;
}?;

Ok(Handle {
handle: Arc::new(Inner::new_exclusive(handle)),
Expand Down Expand Up @@ -177,8 +175,7 @@ impl Handle {
}

fn std_handle(which_std: STD_HANDLE) -> Result<Handle> {
let handle = handle_result(unsafe { GetStdHandle(which_std) })?;

let handle = unsafe { GetStdHandle(which_std) }?;
Ok(Handle {
handle: Arc::new(Inner::new_shared(handle)),
})
Expand Down
33 changes: 1 addition & 32 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@

use std::io;

use windows_sys::Win32::Foundation::{BOOL, HANDLE, INVALID_HANDLE_VALUE};
use windows_sys::Win32::System::Console::COORD;
use windows::Win32::System::Console::COORD;

pub use self::{
cfi::FontInfo,
Expand All @@ -29,16 +28,6 @@ mod screen_buffer;
mod semaphore;
mod structs;

/// Get the result of a call to WinAPI as an [`io::Result`].
#[inline]
pub fn result(return_value: BOOL) -> io::Result<()> {
if return_value != 0 {
Ok(())
} else {
Err(io::Error::last_os_error())
}
}

/// Get the result of a call to WinAPI that returns a
/// [`COORD`](https://docs.microsoft.com/en-us/windows/console/coord-str) as an [`io::Result`].
#[inline]
Expand All @@ -49,23 +38,3 @@ pub fn coord_result(return_value: COORD) -> io::Result<Coord> {
Err(io::Error::last_os_error())
}
}

/// Get the result of a call to WinAPI that returns a handle or `INVALID_HANDLE_VALUE`.
#[inline]
pub fn handle_result(return_value: HANDLE) -> io::Result<HANDLE> {
if return_value != INVALID_HANDLE_VALUE {
Ok(return_value)
} else {
Err(io::Error::last_os_error())
}
}

/// Get the result of a call to WinAPI that returns a handle or `NULL`.
#[inline]
pub fn nonnull_handle_result(return_value: HANDLE) -> io::Result<HANDLE> {
if return_value == 0 {
Err(io::Error::last_os_error())
} else {
Ok(return_value)
}
}
Loading

0 comments on commit 3a7e0f4

Please sign in to comment.