crossterm_winapi-0.6.1/.github/CODEOWNERS010077700017500001750000000000151361003340700162620ustar0000000000000000* @TimonPost crossterm_winapi-0.6.1/.gitignore010077700017500001750000000000721361003340700153220ustar0000000000000000**/target/ **/.idea/ **/.vscode/ **/*.rs.bk **/Cargo.lock crossterm_winapi-0.6.1/.travis.yml010077700017500001750000000007471361003340700154540ustar0000000000000000language: rust rust: - stable - nightly os: - linux - windows - osx git: depth: 1 quiet: true matrix: allow_failures: - rust: nightly before_script: - export PATH=$PATH:/home/travis/.cargo/bin - rustup component add rustfmt script: - cargo fmt --version - rustup --version - rustc --version - if [ "$TRAVIS_RUST_VERSION" = "stable" ]; then cargo fmt --all -- --check; fi - cargo build - cargo test --all-features -- --nocapture --test-threads 1 crossterm_winapi-0.6.1/Cargo.toml.orig010077700017500001750000000012701361410746400162330ustar0000000000000000[package] name = "crossterm_winapi" version = "0.6.1" authors = ["T. Post"] description = "WinAPI wrapper that provides some basic simple abstractions around common WinAPI calls" repository = "https://github.com/crossterm-rs/crossterm-winapi" documentation = "https://docs.rs/crossterm_winapi/" license = "MIT" keywords = ["winapi", "abstractions", "crossterm", "windows", "screen_buffer"] exclude = ["target", "Cargo.lock"] readme = "README.md" edition = "2018" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.8", features = ["winbase", "consoleapi", "processenv", "handleapi", "synchapi", "impl-default"] } [package.metadata.docs.rs] default-target = "x86_64-pc-windows-msvc" crossterm_winapi-0.6.1/Cargo.toml0000644000000022730000000000000124710ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "crossterm_winapi" version = "0.6.1" authors = ["T. Post"] exclude = ["target", "Cargo.lock"] description = "WinAPI wrapper that provides some basic simple abstractions around common WinAPI calls" documentation = "https://docs.rs/crossterm_winapi/" readme = "README.md" keywords = ["winapi", "abstractions", "crossterm", "windows", "screen_buffer"] license = "MIT" repository = "https://github.com/crossterm-rs/crossterm-winapi" [package.metadata.docs.rs] default-target = "x86_64-pc-windows-msvc" [target."cfg(windows)".dependencies.winapi] version = "0.3.8" features = ["winbase", "consoleapi", "processenv", "handleapi", "synchapi", "impl-default"] crossterm_winapi-0.6.1/CHANGELOG.md010077700017500001750000000023441361421740300151530ustar0000000000000000# Version 0.6.1 - Make semaphore `Send` and `Sync` again. - Make `Inner` `Send` and `Sync` again. # Version 0.6.0 - Added Common traits (`Debug`, `Clone`, etc) to many public facing types, especially data struct. - Significantly updated the `input` structs, so that winapi native types are no longer exposed to the library by crossterm_winapi structs. - Removed PartialOrd from types where it didn't really make sense - Reimplemented `Console::read_single_input_event` and `Console::read_console_input` to be more efficient, safe, and correct - Make `Console::read_console_input` not return a `u32`; the numbr of events is the length of the returned vector. # Version 0.5.1 - Make `Semaphore` implement `Clone`. # Version 0.5.0 - Add `Semaphore` object handling - Make `ButtonState` more flexible. # Version 0.4.0 - The `Handle` API has been reworked to make it `Send` + `Sync` and close the underlying `HANDLE` when dropped. # Version 0.3.0 - Make read sync block for windows systems ([PR #2](https://github.com/crossterm-rs/crossterm-winapi/pull/2)) # Version 0.2.1 - Maintenance release only - Moved to a [separate repository](https://github.com/crossterm-rs/crossterm-winapi) # Version 0.2.0 - `Console::get_handle` to `Console::handle` crossterm_winapi-0.6.1/docs/CONTRIBUTING.md010077700017500001750000000002251361003340700165130ustar0000000000000000# Contributing The `crossterm` crate [contributing guidelines](https://github.com/crossterm-rs/crossterm/blob/master/docs/CONTRIBUTING.md) applies. crossterm_winapi-0.6.1/docs/known-problems.md010077700017500001750000000010161361003340700175600ustar0000000000000000# Known problems There are some problems I discovered during development. I don't think it has to do anything with the crossterm, but it has to do whit how terminals handle ANSI or WinAPI. ## WinAPI - Power shell does not interpreter 'DarkYellow' and is instead using gray instead, cmd is working perfectly fine. - Power shell inserts an '\n' (enter) when the program starts, this enter is the one you pressed when running the command. - After the program ran, power shell will reset the background and foreground colors. crossterm_winapi-0.6.1/examples/coloring_example.rs010077700017500001750000000035501361003340700210510ustar0000000000000000#[cfg(windows)] use std::io::Result; #[cfg(windows)] use crossterm_winapi::{Console, ScreenBuffer}; #[cfg(windows)] fn set_background_color() -> Result<()> { // background value const BLUE_BACKGROUND: u16 = 0x0010; let screen_buffer = ScreenBuffer::current()?; let csbi = screen_buffer.info()?; // Notice that the color values are stored in wAttribute. // So wee need to use bitwise operators to check if the values exists or to get current console colors. let attrs = csbi.attributes(); let fg_color = attrs & 0x0007; // apply the blue background flag to the current attributes let new_color = fg_color | BLUE_BACKGROUND; // set the console text attribute to the new color value. Console::from(screen_buffer.handle().clone()).set_text_attribute(new_color)?; Ok(()) } #[cfg(windows)] fn set_foreground_color() -> Result<()> { // background value const BLUE_FOREGROUND: u16 = 0x0001; let screen_buffer = ScreenBuffer::current()?; let csbi = screen_buffer.info()?; // Notice that the color values are stored in wAttribute. // So we need to use bitwise operators to check if the values exists or to get current console colors. let attrs = csbi.attributes(); let bg_color = attrs & 0x0070; let mut color = BLUE_FOREGROUND | bg_color; // background intensity is a separate value in attrs, // wee need to check if this was applied to the current bg color. if (attrs & 0x0080 as u16) != 0 { color = color | 0x0080 as u16; } // set the console text attribute to the new color value. Console::from(screen_buffer.handle().clone()).set_text_attribute(color)?; Ok(()) } #[cfg(windows)] fn main() -> Result<()> { set_background_color()?; set_foreground_color() } #[cfg(not(windows))] fn main() { println!("This example is for the Windows platform only."); } crossterm_winapi-0.6.1/examples/console.rs010077700017500001750000000010411361003340700171550ustar0000000000000000#[cfg(windows)] use std::io::Result; #[cfg(windows)] use crossterm_winapi::ConsoleMode; #[cfg(windows)] fn change_console_mode() -> Result<()> { let console_mode = ConsoleMode::new()?; // get the current console mode: let _mode: u32 = console_mode.mode()?; // set the console mode (not sure if this is an actual value xp) console_mode.set_mode(10) } #[cfg(windows)] fn main() -> Result<()> { change_console_mode() } #[cfg(not(windows))] fn main() { println!("This example is for the Windows platform only."); } crossterm_winapi-0.6.1/examples/handle.rs010077700017500001750000000017031361003340700167530ustar0000000000000000#[cfg(windows)] use std::io::Result; #[cfg(windows)] use crossterm_winapi::{Handle, HandleType}; #[cfg(windows)] #[allow(unused_variables)] fn main() -> Result<()> { // see the description of the types to see what they do. let out_put_handle = Handle::new(HandleType::OutputHandle)?; let out_put_handle = Handle::new(HandleType::InputHandle)?; let curr_out_put_handle = Handle::new(HandleType::CurrentOutputHandle)?; let curr_out_put_handle = Handle::new(HandleType::CurrentInputHandle)?; // now you have this handle you might want to get the WinApi `HANDLE` it is wrapping. // you can do this by defencing. let handle /*:HANDLE*/ = *out_put_handle; // you can also pass you own `HANDLE` to create an instance of `Handle` let handle = unsafe { Handle::from_raw(handle) }; /* winapi::um::winnt::HANDLE */ Ok(()) } #[cfg(not(windows))] fn main() { println!("This example is for the Windows platform only."); } crossterm_winapi-0.6.1/examples/screen_buffer.rs010077700017500001750000000016751361003340700203400ustar0000000000000000#![allow(dead_code)] #[cfg(windows)] use std::io::Result; #[cfg(windows)] use crossterm_winapi::ScreenBuffer; #[cfg(windows)] fn print_screen_buffer_information() -> Result<()> { let screen_buffer = ScreenBuffer::current()?; // get console screen buffer information let csbi = screen_buffer.info()?; println!("cursor post: {:?}", csbi.cursor_pos()); println!("attributes: {:?}", csbi.attributes()); println!("terminal window dimentions {:?}", csbi.terminal_window()); println!("terminal size {:?}", csbi.terminal_size()); Ok(()) } #[cfg(windows)] fn multiple_screen_buffers() -> Result<()> { // create new screen buffer let screen_buffer = ScreenBuffer::create(); // which to this screen buffer screen_buffer.show() } #[cfg(windows)] fn main() -> Result<()> { print_screen_buffer_information() } #[cfg(not(windows))] fn main() { println!("This example is for the Windows platform only."); } crossterm_winapi-0.6.1/LICENSE010077700017500001750000000020461361003340700143420ustar0000000000000000MIT License Copyright (c) 2019 Timon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. crossterm_winapi-0.6.1/README.md010077700017500001750000000047571361003340700146270ustar0000000000000000![Lines of Code][s7] [![Latest Version][s1]][l1] [![MIT][s2]][l2] [![docs][s3]][l3] # Crossterm Windows API Abstractions This crate provides some wrappers aground common used WinAPI functions. The purpose of this library is originally meant for the [crossterm](https://github.com/crossterm-rs/crossterm), but could be used apart from it. Although, notice that it unstable right because some changes to the API could be expected. # Features This crate provides some abstractions over reading input, console screen buffer, and handle. The following WinApi calls: - CONSOLE_SCREEN_BUFFER_INFO (used to extract information like cursor pos, terminal size etc.) - HANDLE (the handle needed to run functions from WinApi) - SetConsoleActiveScreenBuffer (activate an other screen buffer) - Set/GetConsoleMode (e.g. console modes like disabling output) - SetConsoleTextAttribute (eg. coloring) - SetConsoleWindowInfo (changing the buffer location e.g. scrolling) - FillConsoleOutputAttribute, FillConsoleOutputCharacter (used to replace some block of cells with a color or character.) - SetConsoleInfo - ReadConsoleW - Semaphore object handling # Example The [examples](https://github.com/crossterm-rs/examples) repository has more complete and verbose examples. ## Screen buffer information ```rust use crossterm_winapi::{ScreenBuffer, Handle}; fn print_screen_buffer_information() { let screen_buffer = ScreenBuffer::current().unwrap(); // get console screen buffer information let csbi = screen_buffer.info().unwrap(); println!("cursor post: {:?}", csbi.cursor_pos()); println!("attributes: {:?}", csbi.attributes()); println!("terminal window dimentions {:?}", csbi.terminal_window()); println!("terminal size {:?}", csbi.terminal_size()); } ``` ## Handle ```rust use crossterm_winapi::{HandleType, Handle}; fn get_different_handle_types() { let out_put_handle = Handle::new(HandleType::OutputHandle).unwrap(); let out_put_handle = Handle::new(HandleType::InputHandle).unwrap(); let curr_out_put_handle = Handle::new(HandleType::CurrentOutputHandle).unwrap(); let curr_out_put_handle = Handle::new(HandleType::CurrentInputHandle).unwrap(); } ``` [s1]: https://img.shields.io/crates/v/crossterm_winapi.svg [l1]: https://crates.io/crates/crossterm_winapi [s2]: https://img.shields.io/badge/license-MIT-blue.svg [l2]: LICENSE [s3]: https://docs.rs/crossterm_winapi/badge.svg [l3]: https://docs.rs/crossterm_winapi/ [s7]: https://travis-ci.org/crossterm-rs/crossterm.svg?branch=master crossterm_winapi-0.6.1/src/console.rs010077700017500001750000000200641361003340700161340ustar0000000000000000use std::io::{self, Error, Result}; use std::iter; use std::slice; use std::str; use winapi::ctypes::c_void; use winapi::shared::minwindef::DWORD; use winapi::shared::ntdef::NULL; use winapi::um::consoleapi::{GetNumberOfConsoleInputEvents, ReadConsoleInputW, WriteConsoleW}; use winapi::um::wincon::{ FillConsoleOutputAttribute, FillConsoleOutputCharacterA, GetLargestConsoleWindowSize, SetConsoleTextAttribute, SetConsoleWindowInfo, COORD, INPUT_RECORD, SMALL_RECT, }; use super::{is_true, Coord, Handle, HandleType, InputRecord, WindowPositions}; /// Could be used to do some basic things with the console. #[derive(Debug, Clone)] pub struct Console { handle: Handle, } impl Console { /// Create new instance of `Console`. /// /// This created instance will use the default output handle (STD_OUTPUT_HANDLE) as handle for the function call it wraps. pub fn output() -> Result { Ok(Console { handle: Handle::new(HandleType::OutputHandle)?, }) } /// Sets the attributes of characters written to the console screen buffer by the WriteFile or WriteConsole function, or echoed by the ReadFile or ReadConsole function. /// This function affects text written after the function call. /// /// parameter: [wAttributes] /// Wraps the underlying function call: [SetConsoleTextAttribute] /// link: [https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute] pub fn set_text_attribute(&self, value: u16) -> Result<()> { unsafe { if !is_true(SetConsoleTextAttribute(*self.handle, value)) { return Err(Error::last_os_error()); } } Ok(()) } /// Sets the current size and position of a console screen buffer's window. /// /// Wraps the underlying function call: [SetConsoleTextAttribute] /// link: [https://docs.microsoft.com/en-us/windows/console/setconsoletextattribute] 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); unsafe { if !is_true(SetConsoleWindowInfo(*self.handle, absolute, &a)) { return Err(Error::last_os_error()); } } Ok(()) } /// Writes a character to the console screen buffer a specified number of times, beginning at the specified coordinates /// /// Wraps the underlying function call: [FillConsoleOutputCharacterA] /// link: [https://docs.microsoft.com/en-us/windows/console/fillconsoleoutputcharacter] pub fn fill_whit_character( &self, start_location: Coord, cells_to_write: u32, filling_char: char, ) -> Result { let mut chars_written = 0; unsafe { // fill the cells in console with blanks if !is_true(FillConsoleOutputCharacterA( *self.handle, filling_char as i8, cells_to_write, COORD::from(start_location), &mut chars_written, )) { return Err(Error::last_os_error()); } Ok(chars_written) } } /// Sets the character attributes for a specified number of character cells, beginning at the specified coordinates in a screen buffer. /// /// Wraps the underlying function call: [FillConsoleOutputAttribute] /// link: [https://docs.microsoft.com/en-us/windows/console/fillconsoleoutputattribute] pub fn fill_whit_attribute( &self, start_location: Coord, cells_to_write: u32, dw_attribute: u16, ) -> Result { let mut cells_written = 0; // Get the position of the current console window unsafe { if !is_true(FillConsoleOutputAttribute( *self.handle, dw_attribute, cells_to_write, COORD::from(start_location), &mut cells_written, )) { return Err(Error::last_os_error()); } } Ok(cells_written) } /// Retrieves the size of the largest possible console window, based on the current text and the size of the display. /// /// Wraps the underlying function call: [GetLargestConsoleWindowSize] /// link: [https://docs.microsoft.com/en-us/windows/console/getlargestconsolewindowsize] pub fn largest_window_size(&self) -> Coord { Coord::from(unsafe { GetLargestConsoleWindowSize(*self.handle) }) } /// Writes a character string to a console screen buffer beginning at the current cursor location. /// /// Wraps the underlying function call: [WriteConsoleW] /// link: [https://docs.microsoft.com/en-us/windows/console/writeconsole] pub fn write_char_buffer(&self, buf: &[u8]) -> Result { // get string from u8[] and parse it to an c_str let utf8 = match str::from_utf8(buf) { Ok(string) => string, Err(_) => { return Err(io::Error::new( io::ErrorKind::Other, "Could not parse to utf8 string", )); } }; let utf16: Vec = utf8.encode_utf16().collect(); let utf16_ptr: *const c_void = utf16.as_ptr() as *const _ as *const c_void; let mut cells_written: u32 = 0; // write to console unsafe { if !is_true(WriteConsoleW( *self.handle, utf16_ptr, utf16.len() as u32, &mut cells_written, NULL, )) { return Err(io::Error::last_os_error()); } } Ok(utf8.as_bytes().len()) } pub fn read_single_input_event(&self) -> Result { let mut record: INPUT_RECORD = INPUT_RECORD::default(); { // Convert an INPUT_RECORD to an &mut [INPUT_RECORD] of length 1 let buf = slice::from_mut(&mut record); let num_read = self.read_input(buf)?; // The windows API promises that ReadConsoleInput returns at least // 1 element debug_assert!(num_read == 1); } Ok(record.into()) } pub fn read_console_input(&self) -> Result> { let buf_len = self.number_of_console_input_events()?; // Fast-skipping all the code below if there is nothing to read at all if buf_len == 0 { return Ok(vec![]); } let mut buf: Vec = iter::repeat_with(INPUT_RECORD::default) .take(buf_len as usize) .collect(); let num_read = self.read_input(buf.as_mut_slice())?; Ok(buf .into_iter() .take(num_read) .map(InputRecord::from) .collect()) } pub fn number_of_console_input_events(&self) -> Result { let mut buf_len: DWORD = 0; if is_true(unsafe { GetNumberOfConsoleInputEvents(*self.handle, &mut buf_len) }) { Ok(buf_len) } else { Err(Error::last_os_error()) } } /// Read input (via ReadConsoleInputW) into buf and return the number /// of events read. ReadConsoleInputW guarantees that at least one event /// is read, even if it means blocking the thread. buf.len() must fit in /// a u32. fn read_input(&self, buf: &mut [INPUT_RECORD]) -> Result { let mut num_records = 0; debug_assert!(buf.len() < std::u32::MAX as usize); if !is_true(unsafe { ReadConsoleInputW( *self.handle, buf.as_mut_ptr(), buf.len() as u32, &mut num_records, ) }) { Err(Error::last_os_error()) } else { Ok(num_records as usize) } } } impl From for Console { /// Create a `Console` instance who's functions will be executed on the the given `Handle` fn from(handle: Handle) -> Self { Console { handle } } } crossterm_winapi-0.6.1/src/console_mode.rs010077700017500001750000000051631361003340700171430ustar0000000000000000use std::io::{Error, Result}; use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode}; use super::{is_true, Handle, HandleType}; /// This abstracts away some WinaApi calls to set and get the console mode. /// /// Wraps the underlying function call: [SetConsoleMode] /// link: [https://docs.microsoft.com/en-us/windows/console/setconsolemode] /// /// Wraps the underlying function call: [GetConsoleMode] /// link: [https://docs.microsoft.com/en-us/windows/console/getconsolemode] #[derive(Debug, Clone)] pub struct ConsoleMode { // the handle used for the functions of this type. handle: Handle, } impl ConsoleMode { /// Create a new `ConsoleMode` instance. /// /// This will use the `STD_OUTPUT_HANDLE` as default handle. /// When you explicitly want to specify the handle used for the function calls use `ConsoleMode::from(handle)` instead. pub fn new() -> Result { Ok(ConsoleMode { handle: Handle::new(HandleType::OutputHandle)?, }) } /// Set the console mode to the given console mode. /// /// This function sets the `dwMode`. /// /// Wraps the underlying function call: [SetConsoleMode] /// link: [https://docs.microsoft.com/en-us/windows/console/setconsolemode] pub fn set_mode(&self, console_mode: u32) -> Result<()> { unsafe { if !is_true(SetConsoleMode(*self.handle, console_mode)) { return Err(Error::last_os_error()); } } Ok(()) } /// Get the console mode. /// /// This function returns the `lpMode`. /// /// Wraps the underlying function call: [GetConsoleMode] /// link: [https://docs.microsoft.com/en-us/windows/console/getconsolemode] pub fn mode(&self) -> Result { let mut console_mode = 0; unsafe { if !is_true(GetConsoleMode(*self.handle, &mut console_mode)) { println!("Getting mode failed"); return Err(Error::last_os_error()); } } Ok(console_mode) } } impl From for ConsoleMode { fn from(handle: Handle) -> Self { ConsoleMode { handle } } } #[cfg(test)] mod tests { use super::ConsoleMode; // TODO - Test is ignored, because it's failing on Travis CI #[test] #[ignore] fn test_set_get_mode() { let mode = ConsoleMode::new().unwrap(); let original_mode = mode.mode().unwrap(); mode.set_mode(0x0004).unwrap(); let console_mode = mode.mode().unwrap(); assert_eq!(console_mode & 0x0004, mode.mode().unwrap()); mode.set_mode(original_mode).unwrap(); } } crossterm_winapi-0.6.1/src/csbi.rs010077700017500001750000000052151361003340700154130ustar0000000000000000use std::fmt; use std::mem::zeroed; use winapi::um::wincon::CONSOLE_SCREEN_BUFFER_INFO; use super::{Coord, Size, WindowPositions}; /// This type is a wrapper for `CONSOLE_SCREEN_BUFFER_INFO` and has some methods to extract information from it. /// /// Wraps the underlying type: [CONSOLE_SCREEN_BUFFER_INFO] /// link: [https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str] // TODO: replace the innards of this type with our own, more friendly types, like Coord. // This will obviously be a breaking change. #[derive(Clone)] pub struct ScreenBufferInfo(pub CONSOLE_SCREEN_BUFFER_INFO); // TODO: replace this with a derive ASAP impl fmt::Debug for ScreenBufferInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("ScreenBufferInfo") .field("dwSize", &self.buffer_size()) .field("dwCursorPosition", &self.cursor_pos()) .field("wAttributes", &self.attributes()) // TODO: hex print this .field("srWindow", &self.terminal_window()) .field( "dwMaximumWindowSize", &Size::from(self.0.dwMaximumWindowSize), ) .finish() } } impl ScreenBufferInfo { pub fn new() -> ScreenBufferInfo { ScreenBufferInfo(unsafe { zeroed() }) } /// This will return the buffer size. /// /// Will take `dwSize` from the current screen buffer and convert it into the `Size`. pub fn buffer_size(&self) -> Size { Size::from(self.0.dwSize) } /// This will return the terminal size. /// /// Will calculate the width and height from `srWindow` and convert it into a `Size`. pub fn terminal_size(&self) -> Size { (Size::new( self.0.srWindow.Right - self.0.srWindow.Left, self.0.srWindow.Bottom - self.0.srWindow.Top, )) } /// This will return the terminal window properties. /// /// Will take `srWindow` and convert it into the `WindowPositions` type. pub fn terminal_window(&self) -> WindowPositions { WindowPositions::from(self.0) } /// This will return the terminal window properties. /// /// Will take `wAttributes` from the current screen buffer. pub fn attributes(&self) -> u16 { self.0.wAttributes } /// This will return the current cursor position. /// /// Will take `dwCursorPosition` from the current screen buffer. pub fn cursor_pos(&self) -> Coord { Coord::from(self.0.dwCursorPosition) } } impl From for ScreenBufferInfo { fn from(csbi: CONSOLE_SCREEN_BUFFER_INFO) -> Self { ScreenBufferInfo(csbi) } } crossterm_winapi-0.6.1/src/handle.rs010077700017500001750000000167041361411322100157300ustar0000000000000000//! This module contains some logic for working with the console handle. use std::io::{self, Result}; use std::ops::Deref; use std::ptr::null_mut; use std::sync::Arc; use winapi::shared::minwindef::DWORD; use winapi::um::{ fileapi::{CreateFileW, OPEN_EXISTING}, handleapi::{CloseHandle, INVALID_HANDLE_VALUE}, processenv::GetStdHandle, winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE}, winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE, HANDLE}, }; /// This enum represents the different handles that could be requested. /// /// Some more details could be found [here](https://docs.microsoft.com/en-us/windows/console/getstdhandle#parameters) #[derive(Debug, Clone, Copy)] pub enum HandleType { /// This represents the `STD_OUTPUT_HANDLE` OutputHandle, /// This represents the `STD_INPUT_HANDLE` InputHandle, /// This represents the `CONOUT$` file handle /// When using multiple screen buffers this will always point to the to the current screen output buffer. CurrentOutputHandle, /// This represents the `CONIN$` file handle. /// When using multiple screen buffers this will always point to the to the current screen input buffer. CurrentInputHandle, } /// Inner structure for closing a handle on Drop. /// /// The second parameter indicates if the HANDLE is exclusively owned or not. /// A non-exclusive handle can be created using for example /// `Handle::input_handle` or `Handle::output_handle`, which corresponds to /// stdin and stdout respectively. #[derive(Debug)] struct Inner { handle: HANDLE, is_exclusive: bool, } impl Inner { fn new_exclusive(handle: HANDLE) -> Self { Inner { handle, is_exclusive: true, } } fn new_shared(handle: HANDLE) -> Self { Inner { handle, is_exclusive: false, } } } impl Drop for Inner { fn drop(&mut self) { if self.is_exclusive { assert!( unsafe { CloseHandle(self.handle) != 0 }, "failed to close handle" ) } } } unsafe impl Send for Inner {} unsafe impl Sync for Inner {} /// This abstracts away some WinaApi calls to set and get some console handles. /// // Wraps the underlying WinApi type: [HANDLE] #[derive(Debug, Clone)] pub struct Handle { handle: Arc, } impl Handle { pub fn new(handle: HandleType) -> Result { match handle { HandleType::OutputHandle => Handle::output_handle(), HandleType::InputHandle => Handle::input_handle(), HandleType::CurrentOutputHandle => Handle::current_out_handle(), HandleType::CurrentInputHandle => Handle::current_in_handle(), } } /// Construct a handle from a raw handle. /// /// # Safety /// /// This is unsafe since there is not guarantee that the underlying HANDLE is thread-safe to implement `Send` and `Sync`. /// Most HANDLE's however, are thread safe. pub unsafe fn from_raw(handle: HANDLE) -> Self { Self { handle: Arc::new(Inner::new_exclusive(handle)), } } /// Get the handle of the active screen buffer. /// When using multiple screen buffers this will always point to the to the current screen output buffer. /// /// On success this function returns the `HANDLE` to `STD_OUTPUT_HANDLE`. /// /// This function uses `CONOUT$` to create a file handle to the current output buffer. /// /// Wraps the underlying function call: [CreateFileW] /// link: [https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew] pub fn current_out_handle() -> Result { let utf16: Vec = "CONOUT$\0".encode_utf16().collect(); let utf16_ptr: *const u16 = utf16.as_ptr(); let handle = unsafe { CreateFileW( utf16_ptr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, null_mut(), OPEN_EXISTING, 0, null_mut(), ) }; if !Self::is_valid_handle(&handle) { println!("invalid!!"); return Err(io::Error::last_os_error()); } Ok(Handle { handle: Arc::new(Inner::new_exclusive(handle)), }) } /// Get the handle of the active input screen buffer. /// When using multiple screen buffers this will always point to the to the current screen input buffer. /// /// On success this function returns the `HANDLE` to `STD_INPUT_HANDLE`. /// /// This function uses `CONIN$` to create a file handle to the current input buffer. /// /// Wraps the underlying function call: [CreateFileW] /// link: [https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilew] pub fn current_in_handle() -> Result { let utf16: Vec = "CONIN$\0".encode_utf16().collect(); let utf16_ptr: *const u16 = utf16.as_ptr(); let handle = unsafe { CreateFileW( utf16_ptr, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, null_mut(), OPEN_EXISTING, 0, null_mut(), ) }; if !Handle::is_valid_handle(&handle) { return Err(io::Error::last_os_error()); } Ok(Handle { handle: Arc::new(Inner::new_exclusive(handle)), }) } /// Get the handle of the output screen buffer. /// /// On success this function returns the `HANDLE` to `STD_OUTPUT_HANDLE`. /// /// Wraps the underlying function call: [GetStdHandle] whit argument `STD_OUTPUT_HANDLE` /// link: [https://docs.microsoft.com/en-us/windows/console/getstdhandle] pub fn output_handle() -> Result { Self::std_handle(STD_OUTPUT_HANDLE) } /// Get the handle of the input screen buffer. /// /// On success this function returns the `HANDLE` to `STD_INPUT_HANDLE`. /// /// Wraps the underlying function call: [GetStdHandle] whit argument `STD_INPUT_HANDLE` /// link: [https://docs.microsoft.com/en-us/windows/console/getstdhandle] pub fn input_handle() -> Result { Self::std_handle(STD_INPUT_HANDLE) } fn std_handle(which_std: DWORD) -> Result { let handle = unsafe { GetStdHandle(which_std) }; if !Handle::is_valid_handle(&handle) { Err(io::Error::last_os_error()) } else { Ok(Handle { handle: Arc::new(Inner::new_shared(handle)), }) } } /// Checks if the console handle is an invalid handle value. /// /// This is done by checking if the passed `HANDLE` is equal to `INVALID_HANDLE_VALUE` pub fn is_valid_handle(handle: &HANDLE) -> bool { if *handle == INVALID_HANDLE_VALUE { false } else { true } } } impl Deref for Handle { type Target = HANDLE; fn deref(&self) -> &HANDLE { &self.handle.handle } } #[cfg(test)] mod tests { use super::{Handle, HandleType}; #[test] fn test_get_handle() { assert!(Handle::new(HandleType::OutputHandle).is_ok()); assert!(Handle::new(HandleType::InputHandle).is_ok()); assert!(Handle::new(HandleType::CurrentOutputHandle).is_ok()); assert!(Handle::new(HandleType::CurrentInputHandle).is_ok()); } } crossterm_winapi-0.6.1/src/lib.rs010077700017500001750000000014231361003340700152360ustar0000000000000000#![cfg(windows)] #![deny(unused_imports)] pub use self::{ console::Console, console_mode::ConsoleMode, csbi::ScreenBufferInfo, handle::{Handle, HandleType}, screen_buffer::ScreenBuffer, semaphore::Semaphore, structs::{ ButtonState, ControlKeyState, Coord, EventFlags, InputRecord, KeyEventRecord, MouseEvent, Size, WindowPositions, }, }; mod console; mod console_mode; mod csbi; mod handle; mod screen_buffer; mod semaphore; mod structs; /// Parses the given integer to an bool by checking if the value is 0 or 1. /// This is currently used for checking if a WinApi called succeeded, this might be moved into a macro at some time. /// So please don't use this :(. #[inline(always)] pub fn is_true(value: i32) -> bool { value != 0 } crossterm_winapi-0.6.1/src/screen_buffer.rs010077700017500001750000000102141361003340700172760ustar0000000000000000//! This contains the logic for working with the console buffer. use std::io::{Error, Result}; use std::mem::size_of; use winapi::{ shared::minwindef::TRUE, shared::ntdef::NULL, um::{ minwinbase::SECURITY_ATTRIBUTES, wincon::{ CreateConsoleScreenBuffer, GetConsoleScreenBufferInfo, SetConsoleActiveScreenBuffer, SetConsoleScreenBufferSize, CONSOLE_TEXTMODE_BUFFER, COORD, }, winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE}, }, }; use super::{is_true, Handle, HandleType, ScreenBufferInfo}; #[derive(Clone, Debug)] pub struct ScreenBuffer { handle: Handle, } impl ScreenBuffer { pub fn new(handle: Handle) -> Self { Self { handle } } /// Create an instance of `ScreenBuffer` where the `HANDLE`, used for the functions this type wraps, is the current output handle. pub fn current() -> Result { Ok(ScreenBuffer { handle: Handle::new(HandleType::CurrentOutputHandle)?, }) } /// Create new console screen buffer. /// /// Wraps the underlying function call: [CreateConsoleScreenBuffer] /// link: [https://docs.microsoft.com/en-us/windows/console/createconsolescreenbuffer] pub fn create() -> ScreenBuffer { let mut security_attr: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES { nLength: size_of::() as u32, lpSecurityDescriptor: NULL, bInheritHandle: TRUE, }; unsafe { let new_screen_buffer = CreateConsoleScreenBuffer( GENERIC_READ | // read/write access GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, // shared &mut security_attr, // default security attributes CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE NULL, ); ScreenBuffer { handle: Handle::from_raw(new_screen_buffer), } } } /// This will make this `ScreenBuffer` the active one. /// /// Wraps the underlying function call: [SetConsoleActiveScreenBuffer] /// link: [https://docs.microsoft.com/en-us/windows/console/setconsoleactivescreenbuffer] pub fn show(&self) -> Result<()> { unsafe { if !is_true(SetConsoleActiveScreenBuffer(*self.handle)) { return Err(Error::last_os_error()); } } Ok(()) } /// Get the screen buffer information like terminal size, cursor position, buffer size. /// /// Wraps the underlying function call: [GetConsoleScreenBufferInfo] /// link: [https://docs.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo] pub fn info(&self) -> Result { let mut csbi = ScreenBufferInfo::new(); unsafe { if !is_true(GetConsoleScreenBufferInfo(*self.handle, &mut csbi.0)) { return Err(Error::last_os_error()); } } Ok(csbi) } /// Set the console screen buffer size to the given size. /// /// Wraps the underlying function call: [SetConsoleScreenBufferSize] /// link: [https://docs.microsoft.com/en-us/windows/console/setconsolescreenbuffersize] pub fn set_size(&self, x: i16, y: i16) -> Result<()> { unsafe { if !is_true(SetConsoleScreenBufferSize( *self.handle, COORD { X: x, Y: y }, )) { return Err(Error::last_os_error()); } } Ok(()) } /// Get the underlining raw `HANDLE` used by this type to execute whit. pub fn handle(&self) -> &Handle { return &self.handle; } } impl From for ScreenBuffer { fn from(handle: Handle) -> Self { ScreenBuffer { handle } } } #[cfg(test)] mod tests { use super::ScreenBuffer; #[test] fn test_screen_buffer_info() { let buffer = ScreenBuffer::current().unwrap(); let info = buffer.info().unwrap(); info.terminal_size(); info.terminal_window(); info.attributes(); info.cursor_pos(); } } crossterm_winapi-0.6.1/src/semaphore.rs010077700017500001750000000017461361410744600164740ustar0000000000000000use crate::Handle; use std::{io, ptr}; use winapi::um::synchapi::{CreateSemaphoreW, ReleaseSemaphore}; #[derive(Clone, Debug)] pub struct Semaphore(Handle); impl Semaphore { /// Construct a new semaphore. pub fn new() -> io::Result { let handle = unsafe { CreateSemaphoreW(ptr::null_mut(), 0, 1, ptr::null_mut()) }; if handle == ptr::null_mut() { return Err(io::Error::last_os_error()); } let handle = unsafe { Handle::from_raw(handle) }; Ok(Self(handle)) } /// Release a permit on the semaphore. pub fn release(&self) -> io::Result<()> { let result = unsafe { ReleaseSemaphore(*self.0, 1, ptr::null_mut()) }; if result == 0 { return Err(io::Error::last_os_error()); } Ok(()) } /// Access the underlying handle to the semaphore. pub fn handle(&self) -> &Handle { &self.0 } } unsafe impl Send for Semaphore {} unsafe impl Sync for Semaphore {}crossterm_winapi-0.6.1/src/structs.rs010077700017500001750000000004111361003340700161730ustar0000000000000000pub use self::coord::Coord; pub use self::input::{ ButtonState, ControlKeyState, EventFlags, InputRecord, KeyEventRecord, MouseEvent, }; pub use self::size::Size; pub use self::window_coords::WindowPositions; mod coord; mod input; mod size; mod window_coords; crossterm_winapi-0.6.1/src/structs/coord.rs010077700017500001750000000021271361003340700173070ustar0000000000000000//! This module provides a type that represents some location/coordination. //! For example, in WinAPi we have `COORD` which looks and feels inconvenient. //! This module provides also some trait implementations who will make parsing and working whit `COORD` easier. use winapi::um::wincon::COORD; /// This is type represents the position of something on a certain 'x' and 'y'. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd)] pub struct Coord { /// the position on the x axis pub x: i16, /// the position on the y axis pub y: i16, } impl Coord { /// Create a new size instance by passing in the width and height. pub fn new(x: i16, y: i16) -> Coord { Coord { x, y } } } impl From for Coord { fn from(coord: COORD) -> Self { Coord::new(coord.X, coord.Y) } } impl From for COORD { fn from(location: Coord) -> Self { COORD { X: location.x, Y: location.y, } } } impl Into<(u16, u16)> for Coord { fn into(self) -> (u16, u16) { (self.x as u16, self.y as u16) } } crossterm_winapi-0.6.1/src/structs/input.rs010077700017500001750000000241621361003340700173430ustar0000000000000000//! This module provides a few structs to wrap common input struts to a rusty interface //! //! Types like: //! - `KEY_EVENT_RECORD` //! - `MOUSE_EVENT_RECORD` //! - `ControlKeyState` //! - `ButtonState` //! - `EventFlags` //! - `InputEventType` //! - `INPUT_RECORD` use winapi::shared::minwindef::DWORD; use winapi::um::wincon::{ FOCUS_EVENT, FOCUS_EVENT_RECORD, FROM_LEFT_1ST_BUTTON_PRESSED, FROM_LEFT_2ND_BUTTON_PRESSED, FROM_LEFT_3RD_BUTTON_PRESSED, FROM_LEFT_4TH_BUTTON_PRESSED, INPUT_RECORD, KEY_EVENT, KEY_EVENT_RECORD, MENU_EVENT, MENU_EVENT_RECORD, MOUSE_EVENT, MOUSE_EVENT_RECORD, RIGHTMOST_BUTTON_PRESSED, WINDOW_BUFFER_SIZE_EVENT, WINDOW_BUFFER_SIZE_RECORD, }; use super::Coord; /// Describes a keyboard input event in a console INPUT_RECORD structure. /// link: [https://docs.microsoft.com/en-us/windows/console/key-event-record-str] #[derive(Clone, Debug, Eq, PartialEq)] pub struct KeyEventRecord { /// If the key is pressed, this member is TRUE. Otherwise, this member is /// FALSE (the key is released). pub key_down: bool, /// The repeat count, which indicates that a key is being held down. /// For example, when a key is held down, you might get five events with /// this member equal to 1, one event with this member equal to 5, or /// multiple events with this member greater than or equal to 1. pub repeat_count: u16, /// A virtual-key code that identifies the given key in a /// device-independent manner. pub virtual_key_code: u16, /// The virtual scan code of the given key that represents the /// device-dependent value generated by the keyboard hardware. pub virtual_scan_code: u16, /// The translated Unicode character (as a WCHAR, or utf-16 value) pub u_char: u16, /// The state of the control keys. pub control_key_state: ControlKeyState, } impl KeyEventRecord { /// Convert a KEY_EVENT_RECORD to KeyEventRecord. This function is private /// because the KEY_EVENT_RECORD has several union fields for characters /// (u8 vs u16) that we always interpret as u16. We always use the wide /// versions of windows API calls to support this. #[inline] fn from_winapi(record: &KEY_EVENT_RECORD) -> Self { KeyEventRecord { key_down: record.bKeyDown != 0, repeat_count: record.wRepeatCount, virtual_key_code: record.wVirtualKeyCode, virtual_scan_code: record.wVirtualScanCode, u_char: unsafe { *record.uChar.UnicodeChar() }, control_key_state: ControlKeyState(record.dwControlKeyState), } } } #[derive(PartialEq, Debug, Copy, Clone, Eq)] pub struct MouseEvent { pub mouse_position: Coord, pub button_state: ButtonState, pub control_key_state: ControlKeyState, pub event_flags: EventFlags, } impl From for MouseEvent { #[inline] fn from(event: MOUSE_EVENT_RECORD) -> Self { MouseEvent { mouse_position: event.dwMousePosition.into(), button_state: event.dwButtonState.into(), control_key_state: ControlKeyState(event.dwControlKeyState), event_flags: event.dwEventFlags.into(), } } } /// The status of the mouse buttons. /// The least significant bit corresponds to the leftmost mouse button. /// The next least significant bit corresponds to the rightmost mouse button. /// The next bit indicates the next-to-leftmost mouse button. /// The bits then correspond left to right to the mouse buttons. /// A bit is 1 if the button was pressed. /// /// The state can be one of the following: /// Release = 0x0000, /// // The leftmost mouse button. /// FromLeft1stButtonPressed = 0x0001, /// // The second button from the left. /// FromLeft2ndButtonPressed = 0x0004, /// // The third button from the left. /// FromLeft3rdButtonPressed = 0x0008, /// // The fourth button from the left. /// FromLeft4thButtonPressed = 0x0010, /// // The rightmost mouse button. /// RightmostButtonPressed = 0x0002, /// // This button state is not recognized. /// Unknown = 0x0021, /// // The wheel was rotated backward, toward the user; this will only be activated for `MOUSE_WHEELED ` from `dwEventFlags` /// Negative = 0x0020, /// /// [Ms Docs](https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str#members) #[derive(PartialEq, Debug, Copy, Clone, Eq)] pub struct ButtonState { state: i32, } impl From for ButtonState { #[inline] fn from(event: DWORD) -> Self { let state = event as i32; ButtonState { state } } } impl ButtonState { pub fn release_button(&self) -> bool { self.state == 0 } /// Returns whether the left button was pressed. pub fn left_button(&self) -> bool { self.state as u32 & FROM_LEFT_1ST_BUTTON_PRESSED != 0 } /// Returns whether the right button was pressed. pub fn right_button(&self) -> bool { self.state as u32 & (RIGHTMOST_BUTTON_PRESSED | FROM_LEFT_3RD_BUTTON_PRESSED | FROM_LEFT_4TH_BUTTON_PRESSED) != 0 } /// Returns whether the right button was pressed. pub fn middle_button(&self) -> bool { self.state as u32 & FROM_LEFT_2ND_BUTTON_PRESSED != 0 } /// Returns whether there is a down scroll. pub fn scroll_down(&self) -> bool { self.state < 0 } /// Returns whether there is a up scroll. pub fn scroll_up(&self) -> bool { self.state > 0 } /// Returns the raw state. pub fn state(&self) -> i32 { self.state } } #[derive(PartialEq, Debug, Copy, Clone, Eq)] pub struct ControlKeyState(u32); impl ControlKeyState { pub fn has_state(&self, state: u32) -> bool { (state & self.0) != 0 } } /// The type of mouse event. /// If this value is zero, it indicates a mouse button being pressed or released. /// Otherwise, this member is one of the following values. /// /// [Ms Docs](https://docs.microsoft.com/en-us/windows/console/mouse-event-record-str#members) #[derive(PartialEq, Debug, Copy, Clone, Eq)] pub enum EventFlags { PressOrRelease = 0x0000, // The second click (button press) of a double-click occurred. The first click is returned as a regular button-press event. DoubleClick = 0x0002, // The horizontal mouse wheel was moved. MouseHwheeled = 0x0008, // If the high word of the dwButtonState member contains a positive value, the wheel was rotated to the right. Otherwise, the wheel was rotated to the left. MouseMoved = 0x0001, // A change in mouse position occurred. // The vertical mouse wheel was moved, if the high word of the dwButtonState member contains a positive value, the wheel was rotated forward, away from the user. // Otherwise, the wheel was rotated backward, toward the user. MouseWheeled = 0x0004, } // TODO: Replace with TryFrom. impl From for EventFlags { fn from(event: DWORD) -> Self { match event { 0x0000 => EventFlags::PressOrRelease, 0x0002 => EventFlags::DoubleClick, 0x0008 => EventFlags::MouseHwheeled, 0x0001 => EventFlags::MouseMoved, 0x0004 => EventFlags::MouseWheeled, _ => panic!("Event flag {} does not exist.", event), } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct WindowBufferSizeRecord { pub size: Coord, } impl From for WindowBufferSizeRecord { #[inline] fn from(record: WINDOW_BUFFER_SIZE_RECORD) -> Self { WindowBufferSizeRecord { size: record.dwSize.into(), } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct FocusEventRecord { pub set_focus: bool, } impl From for FocusEventRecord { #[inline] fn from(record: FOCUS_EVENT_RECORD) -> Self { FocusEventRecord { set_focus: record.bSetFocus != 0, } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct MenuEventRecord { pub command_id: u32, } impl From for MenuEventRecord { #[inline] fn from(record: MENU_EVENT_RECORD) -> Self { MenuEventRecord { command_id: record.dwCommandId, } } } /// Describes an input event in the console input buffer. /// These records can be read from the input buffer by using the `ReadConsoleInput` /// or `PeekConsoleInput` function, or written to the input buffer by using the /// `WriteConsoleInput` function. /// /// [Ms Docs](https://docs.microsoft.com/en-us/windows/console/input-record-str) #[derive(Clone, Debug, PartialEq, Eq)] pub enum InputRecord { /// The Event member contains a `KEY_EVENT_RECORD` structure with /// information about a keyboard event. KeyEvent(KeyEventRecord), /// The Event member contains a `MOUSE_EVENT_RECORD` structure with /// information about a mouse movement or button press event. MouseEvent(MouseEvent), /// The Event member contains a `WINDOW_BUFFER_SIZE_RECORD` structure with /// information about the new size of the console screen buffer. WindowBufferSizeEvent(WindowBufferSizeRecord), /// The Event member contains a `FOCUS_EVENT_RECORD` structure. These /// events are used internally and should be ignored. FocusEvent(FocusEventRecord), /// The Event member contains a `MENU_EVENT_RECORD` structure. These /// events are used internally and should be ignored. MenuEvent(MenuEventRecord), } impl From for InputRecord { #[inline] fn from(record: INPUT_RECORD) -> Self { match record.EventType { KEY_EVENT => InputRecord::KeyEvent(KeyEventRecord::from_winapi(unsafe { record.Event.KeyEvent() })), MOUSE_EVENT => InputRecord::MouseEvent(unsafe { *record.Event.MouseEvent() }.into()), WINDOW_BUFFER_SIZE_EVENT => InputRecord::WindowBufferSizeEvent( unsafe { *record.Event.WindowBufferSizeEvent() }.into(), ), FOCUS_EVENT => InputRecord::FocusEvent(unsafe { *record.Event.FocusEvent() }.into()), MENU_EVENT => InputRecord::MenuEvent(unsafe { *record.Event.MenuEvent() }.into()), code => panic!("Unexpected INPUT_RECORD EventType: {}", code), } } } crossterm_winapi-0.6.1/src/structs/size.rs010077700017500001750000000016051361003340700171530ustar0000000000000000//! This module provides a type that represents some size. //! For example, in WinAPi we have `COORD` to represent screen/buffer size but this is a little inconvenient. //! This module provides some trait implementations who will make parsing and working whit `COORD` easier. use winapi::um::wincon::COORD; /// This is type represents the size of something in width and height. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub struct Size { pub width: i16, pub height: i16, } impl Size { /// Create a new size instance by passing in the width and height. pub fn new(width: i16, height: i16) -> Size { Size { width, height } } } impl From for Size { fn from(coord: COORD) -> Self { Size::new(coord.X, coord.Y) } } impl Into<(u16, u16)> for Size { fn into(self) -> (u16, u16) { (self.width as u16, self.height as u16) } } crossterm_winapi-0.6.1/src/structs/window_coords.rs010077700017500001750000000024211361003340700210560ustar0000000000000000//! This module provides a type that represents some rectangle. //! For example, in WinAPi we have `SMALL_RECT` to represent a window size but this is a little inconvenient. //! This module provides some trait implementations who will make parsing and working whit `COORD` easier. use winapi::um::wincon::{CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT}; /// This is a wrapper for the locations of a rectangle. /// /// It has left, right, bottom, top attributes. #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub struct WindowPositions { pub left: i16, pub right: i16, pub bottom: i16, pub top: i16, } impl From for WindowPositions { fn from(csbi: CONSOLE_SCREEN_BUFFER_INFO) -> Self { csbi.srWindow.into() } } impl From for SMALL_RECT { fn from(positions: WindowPositions) -> Self { SMALL_RECT { Top: positions.top, Right: positions.right, Bottom: positions.bottom, Left: positions.left, } } } impl From for WindowPositions { fn from(rect: SMALL_RECT) -> Self { WindowPositions { left: rect.Left, right: rect.Right, bottom: rect.Bottom, top: rect.Top, } } } crossterm_winapi-0.6.1/.cargo_vcs_info.json0000644000000001120000000000000144610ustar00{ "git": { "sha1": "decee983e0d7f4a70c573bc1192e7edbef25d620" } } crossterm_winapi-0.6.1/Cargo.lock0000644000000024550000000000000124500ustar00# This file is automatically @generated by Cargo. # It is not intended for manual editing. [[package]] name = "crossterm_winapi" version = "0.6.1" dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"