1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
mod err; pub mod code; use std::str; use std::io::Write; use ::libc; use super::In; pub use self::err::MouseError; use self::code::Code; #[repr(C)] #[derive(Default, Clone, Copy, Debug, Hash, Eq, PartialEq)] pub struct Mouse { pub code: Code, pub pressed: bool, pub x: libc::c_ushort, pub y: libc::c_ushort, } impl Mouse { fn with_code(action: u8, next: &[u8]) -> Result<Self, MouseError> { match next { &[ref coordinate.., m @ b'M'...b'm'] => { match Code::new(action) { Ok(code) => { coordinate.iter().position(|&sep| sep.eq(&b';')).map(|index: usize| unsafe { let (term_x, term_y): (&[u8], &[u8]) = coordinate.split_at(index); let term_y: &[u8] = &term_y[1..term_y.len()]; if let (Ok(x), Ok(y)) = ( u16::from_str_radix(str::from_utf8_unchecked(term_x), 10), u16::from_str_radix(str::from_utf8_unchecked(term_y), 10) ) { Ok(Mouse::from((code, m.eq(&b'M'), [x, y]))) } else { Err(MouseError::FromStrFail) } }).unwrap_or(Err(MouseError::PositionNotFound)) }, Err(why) => Err(MouseError::Code(why)), } }, _ => Err(MouseError::Other), } } pub fn new(buf: &[u8]) -> Result<Self, MouseError> { match buf { &[b'\x1B', b'[', b'<', action1 @ b'0'...b'9', action2 @ b'0'...b'9', b';', ref next..] => { Mouse::with_code((action1 - 48) * 10 + action2 - 48, next) }, &[b'\x1B', b'[', b'<', action @ b'0'...b'9', b';', ref next..] => { Mouse::with_code(action - 48, next) }, _ => Err(MouseError::Other), } } pub fn as_input(&self) -> (In, libc::size_t) { let mut input: In = In::default(); let mut length: libc::size_t = 3; let xx: String = self.x.to_string(); let x: &[u8] = xx.as_bytes(); let yy: String = self.y.to_string(); let y: &[u8] = yy.as_bytes(); let _ = input.as_mut()[..].as_mut().write(&[b'\x1B', b'[', b'<']); let _ = input.as_mut()[length..].as_mut().write(x); length += x.len(); let _ = input.as_mut()[length..].as_mut().write(&[b';']); length += 1; let _ = input.as_mut()[length..].as_mut().write(y); length += y.len(); if self.pressed { let _ = input.as_mut()[length..].as_mut().write(&[b'M']); } else { let _ = input.as_mut()[length..].as_mut().write(&[b'm']); } length += 1; (input, length) } } impl From<(Code, bool, [libc::c_ushort; 2])> for Mouse { fn from((code, pressed, [x, y]): (Code, bool, [libc::c_ushort; 2])) -> Mouse { Mouse { code: code, pressed: pressed, x: x, y: y, } } } impl From<(u8, bool, [libc::c_ushort; 2])> for Mouse { fn from((code, pressed, [x, y]): (u8, bool, [libc::c_ushort; 2])) -> Mouse { Mouse { code: Code::from(code), pressed: pressed, x: x, y: y, } } }