|
|
|
@ -1,9 +1,9 @@
|
|
|
|
|
mod error;
|
|
|
|
|
mod input;
|
|
|
|
|
mod key;
|
|
|
|
|
mod line;
|
|
|
|
|
mod log;
|
|
|
|
|
mod input;
|
|
|
|
|
mod prompt;
|
|
|
|
|
mod key;
|
|
|
|
|
|
|
|
|
|
use line::Line;
|
|
|
|
|
use prompt::Prompt;
|
|
|
|
@ -129,6 +129,18 @@ fn setup_stdout() -> Result<()> {
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn newline(stdout: HANDLE) -> Result<()> {
|
|
|
|
|
unsafe {
|
|
|
|
|
Error::check(Console::WriteConsoleA(
|
|
|
|
|
stdout,
|
|
|
|
|
"\r\n".as_bytes(),
|
|
|
|
|
None,
|
|
|
|
|
None,
|
|
|
|
|
))?;
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() -> Result<()> {
|
|
|
|
|
match Log::file("C:\\Users\\JordanOrelli\\wash.log") {
|
|
|
|
|
Ok(f) => {
|
|
|
|
@ -151,127 +163,58 @@ fn main() -> Result<()> {
|
|
|
|
|
loop {
|
|
|
|
|
let rec = input.next()?;
|
|
|
|
|
let event: input::Event = rec.into();
|
|
|
|
|
debug!("Event Type: {}", rec.EventType);
|
|
|
|
|
if let input::Event::Key(event) = &event {
|
|
|
|
|
debug!("Key Event: {:?}", event);
|
|
|
|
|
if event.code == key::ENTER {
|
|
|
|
|
debug!("ENTER!!!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
match rec.EventType as u32 {
|
|
|
|
|
Console::FOCUS_EVENT => {
|
|
|
|
|
// The Event member contains a FOCUS_EVENT_RECORD structure. These events are
|
|
|
|
|
// used internally and should be ignored.
|
|
|
|
|
unsafe {
|
|
|
|
|
let event = rec.Event.FocusEvent;
|
|
|
|
|
debug!("Focus Event: {:?}", event);
|
|
|
|
|
match event {
|
|
|
|
|
input::Event::Key(event) => {
|
|
|
|
|
if event.down {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Console::MENU_EVENT => {
|
|
|
|
|
// The Event member contains a MENU_EVENT_RECORD structure. These events are
|
|
|
|
|
// used internally and should be ignored.
|
|
|
|
|
unsafe {
|
|
|
|
|
let event = rec.Event.MenuEvent;
|
|
|
|
|
debug!("Menu Event: {:?}", event);
|
|
|
|
|
debug!("Key Event: {}", event);
|
|
|
|
|
|
|
|
|
|
if event.code == key::ENTER {
|
|
|
|
|
newline(stdout)?;
|
|
|
|
|
line.print()?;
|
|
|
|
|
newline(stdout)?;
|
|
|
|
|
prompt.print()?;
|
|
|
|
|
line.clear();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Console::KEY_EVENT => {
|
|
|
|
|
// The Event member contains a KEY_EVENT_RECORD structure with information
|
|
|
|
|
// about a keyboard event.
|
|
|
|
|
unsafe {
|
|
|
|
|
let event = rec.Event.KeyEvent;
|
|
|
|
|
let down = event.bKeyDown.as_bool();
|
|
|
|
|
let repeats = event.wRepeatCount;
|
|
|
|
|
let key_code = event.wVirtualKeyCode;
|
|
|
|
|
let scan_code = event.wVirtualScanCode;
|
|
|
|
|
let c = event.uChar.UnicodeChar;
|
|
|
|
|
let modifiers = event.dwControlKeyState;
|
|
|
|
|
// handle key presses on key up, not key down. This is a little weird but
|
|
|
|
|
// it's sending both down and up events when you hit the key anyway. I
|
|
|
|
|
// dunno if this is right. But for some reason, the down events don't have
|
|
|
|
|
// the modifiers
|
|
|
|
|
if !down {
|
|
|
|
|
// Carriage Return (Enter key)
|
|
|
|
|
if c == 13 {
|
|
|
|
|
let mask = Console::LEFT_ALT_PRESSED
|
|
|
|
|
| Console::RIGHT_ALT_PRESSED
|
|
|
|
|
| Console::LEFT_CTRL_PRESSED
|
|
|
|
|
| Console::RIGHT_CTRL_PRESSED
|
|
|
|
|
| Console::SHIFT_PRESSED;
|
|
|
|
|
if modifiers & mask == 0 {
|
|
|
|
|
Error::check(Console::WriteConsoleA(
|
|
|
|
|
stdout,
|
|
|
|
|
"\r\n".as_bytes(),
|
|
|
|
|
None,
|
|
|
|
|
None,
|
|
|
|
|
))?;
|
|
|
|
|
line.print()?;
|
|
|
|
|
Error::check(Console::WriteConsoleA(
|
|
|
|
|
stdout,
|
|
|
|
|
"\r\n".as_bytes(),
|
|
|
|
|
None,
|
|
|
|
|
None,
|
|
|
|
|
))?;
|
|
|
|
|
prompt.print()?;
|
|
|
|
|
line.clear();
|
|
|
|
|
}
|
|
|
|
|
} else if key_code == 68
|
|
|
|
|
&& (modifiers & Console::LEFT_CTRL_PRESSED
|
|
|
|
|
== Console::LEFT_CTRL_PRESSED)
|
|
|
|
|
{
|
|
|
|
|
// this is CTRL+D
|
|
|
|
|
CloseHandle(stdout);
|
|
|
|
|
return Ok(());
|
|
|
|
|
} else if key_code == 74
|
|
|
|
|
&& (modifiers & Console::LEFT_CTRL_PRESSED
|
|
|
|
|
== Console::LEFT_CTRL_PRESSED)
|
|
|
|
|
{
|
|
|
|
|
// red bullet
|
|
|
|
|
let text = "\x1b[31m\u{2022}\x1b[0m";
|
|
|
|
|
Error::check(Console::WriteConsoleA(
|
|
|
|
|
stdout,
|
|
|
|
|
text.as_bytes(),
|
|
|
|
|
None,
|
|
|
|
|
None,
|
|
|
|
|
))?;
|
|
|
|
|
} else {
|
|
|
|
|
if let Some(c) = char::from_u32(event.uChar.UnicodeChar as u32) {
|
|
|
|
|
if !c.is_control() {
|
|
|
|
|
let mut buf = [0 as u8; 8];
|
|
|
|
|
let s = c.encode_utf8(&mut buf);
|
|
|
|
|
s.chars().for_each(|c| line.append(c));
|
|
|
|
|
Error::check(Console::WriteConsoleW(
|
|
|
|
|
stdout,
|
|
|
|
|
s.as_bytes(),
|
|
|
|
|
None,
|
|
|
|
|
None,
|
|
|
|
|
))?;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if event.ctrl && event.code == key::D {
|
|
|
|
|
unsafe {
|
|
|
|
|
CloseHandle(stdout);
|
|
|
|
|
}
|
|
|
|
|
debug!(
|
|
|
|
|
"Key Event: down: {down:?} repeats: {repeats} key-code: {key_code} scan-code: {scan_code} char: {c} modifiers: {modifiers}"
|
|
|
|
|
);
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Console::MOUSE_EVENT => {
|
|
|
|
|
// The Event member contains a MOUSE_EVENT_RECORD structure with information
|
|
|
|
|
// about a mouse movement or button press event.
|
|
|
|
|
unsafe {
|
|
|
|
|
let event = rec.Event.MouseEvent;
|
|
|
|
|
debug!("Mouse Event: {:?}", event);
|
|
|
|
|
|
|
|
|
|
if event.ctrl && event.code == key::J {
|
|
|
|
|
// red bullet
|
|
|
|
|
unsafe {
|
|
|
|
|
let text = "\x1b[31m\u{2022}\x1b[0m";
|
|
|
|
|
Error::check(Console::WriteConsoleA(stdout, text.as_bytes(), None, None))?;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Console::WINDOW_BUFFER_SIZE_EVENT => {
|
|
|
|
|
// The Event member contains a WINDOW_BUFFER_SIZE_RECORD structure with
|
|
|
|
|
// information about the new size of the console screen buffer.
|
|
|
|
|
unsafe {
|
|
|
|
|
let event = rec.Event.WindowBufferSizeEvent;
|
|
|
|
|
debug!("Window Buffer Event: {:?}", event);
|
|
|
|
|
|
|
|
|
|
if !event.char.is_control() {
|
|
|
|
|
let mut buf = [0 as u8; 8];
|
|
|
|
|
let s = event.char.encode_utf8(&mut buf);
|
|
|
|
|
s.chars().for_each(|c| line.append(c));
|
|
|
|
|
unsafe {
|
|
|
|
|
Error::check(Console::WriteConsoleW(
|
|
|
|
|
stdout,
|
|
|
|
|
s.as_bytes(),
|
|
|
|
|
None,
|
|
|
|
|
None,
|
|
|
|
|
))?;
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
input::Event::Focus(true) => {},
|
|
|
|
|
input::Event::Focus(false) => {},
|
|
|
|
|
input::Event::Menu(_command_id) => {},
|
|
|
|
|
input::Event::Mouse{..} => {},
|
|
|
|
|
input::Event::Size => {},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|