rdp/core/
event.rs

1use model::error::{RdpResult, Error, RdpError, RdpErrorKind};
2use num_enum::TryFromPrimitive;
3use codec::rle::{rle_32_decompress, rle_16_decompress, rgb565torgb32};
4
5/// A bitmap event is used
6/// to notify client that it received
7/// an old school bitmap data
8///
9/// If bitmap is compress you can use the
10/// decompress function to handle it
11pub struct BitmapEvent {
12    /// Pixel position from left of the left top angle
13    pub dest_left: u16,
14    /// Pixel position from top of the left top angle
15    pub dest_top: u16,
16    /// Pixel position from Right of the left top angle
17    pub dest_right: u16,
18    /// Pixel position from Bottom of the left top angle
19    pub dest_bottom: u16,
20    /// width of the bitmap buffer once decompress
21    /// This can be larger than dest_right minus dest_left
22    pub width: u16,
23    /// height of the bitmap buffer once decompress
24    /// This can be larger than dest_bottom minus dest_top
25    pub height: u16,
26    /// Bits Per Pixel
27    pub bpp: u16,
28    /// true if bitmap buffer is compressed using RLE
29    pub is_compress: bool,
30    /// Bitmap data
31    pub data: Vec<u8>
32}
33
34impl BitmapEvent {
35    /// Decompress a bitmap which has been encoded by the RLE algorithm
36    ///
37    /// # Example
38    /// ```no_run
39    /// use std::net::{SocketAddr, TcpStream};
40    /// use rdp::core::client::Connector;
41    /// use rdp::core::event::RdpEvent;
42    /// let addr = "127.0.0.1:3389".parse::<SocketAddr>().unwrap();
43    /// let tcp = TcpStream::connect(&addr).unwrap();
44    /// let mut connector = Connector::new()
45    ///     .screen(800, 600)
46    ///     .credentials("domain".to_string(), "username".to_string(), "password".to_string());
47    /// let mut client = connector.connect(tcp).unwrap();
48    /// client.read(|rdp_event| {
49    ///     match rdp_event {
50    ///         RdpEvent::Bitmap(bitmap) => {
51    ///             let data = if bitmap.is_compress {
52    ///                 bitmap.decompress().unwrap()
53    ///             }
54    ///             else {
55    ///                 bitmap.data
56    ///             };
57    ///         }
58    ///          _ => println!("Unhandled event")
59    ///     }
60    /// }).unwrap()
61    /// ```
62    pub fn decompress(self) -> RdpResult<Vec<u8>> {
63
64        // actually only handle 32 bpp
65        match self.bpp {
66            32 => {
67                // 32 bpp is straight forward
68                Ok(
69                    if self.is_compress {
70                        let mut result = vec![0 as u8; self.width as usize * self.height as usize * 4];
71                        rle_32_decompress(&self.data, self.width as u32, self.height as u32, &mut result)?;
72                        result
73                    } else {
74                        self.data
75                    }
76                )
77            },
78            16 => {
79                // 16 bpp is more consumer
80                let result_16bpp = if self.is_compress {
81                    let mut result = vec![0 as u16; self.width as usize * self.height as usize * 2];
82                    rle_16_decompress(&self.data, self.width as usize, self.height as usize, &mut result)?;
83                    result
84                } else {
85                    let mut result = vec![0 as u16; self.width as usize * self.height as usize];
86                    for i in 0..self.height {
87                        for j in 0..self.width {
88                            let src = (((self.height - i - 1) * self.width + j) * 2) as usize;
89                            result[(i * self.width + j) as usize] = (self.data[src + 1] as u16) << 8 | self.data[src] as u16;
90                        }
91                    }
92                    result
93                };
94
95                Ok(rgb565torgb32(&result_16bpp, self.width as usize, self.height as usize))
96            },
97            _ => Err(Error::RdpError(RdpError::new(RdpErrorKind::NotImplemented, &format!("Decompression Algorithm not implemented for bpp {}", self.bpp))))
98        }
99    }
100}
101
102#[repr(u8)]
103#[derive(Eq, PartialEq, TryFromPrimitive, Copy, Clone)]
104pub enum PointerButton {
105    /// No button but a move
106    None = 0,
107    /// Left mouse Button
108    Left = 1,
109    /// Right mouse button
110    Right = 2,
111    /// Wheel mouse button
112    Middle = 3
113}
114
115/// A mouse pointer event
116pub struct PointerEvent {
117    /// horizontal position from top left angle of the window
118    pub x: u16,
119    /// vertical position from top left angle of the window
120    pub y: u16,
121    /// Which button is pressed
122    pub button: PointerButton,
123    /// true if it's a down press action
124    pub down: bool
125}
126
127/// Keyboard event
128/// It's a raw event using Scancode
129/// to inform which key is pressed
130pub struct KeyboardEvent {
131    /// Scancode of the key
132    pub code: u16,
133    /// State of the key
134    pub down: bool
135}
136
137/// All event handle by RDP protocol implemented by rdp-rs
138pub enum RdpEvent {
139    /// Classic bitmap event
140    Bitmap(BitmapEvent),
141    /// Mouse event
142    Pointer(PointerEvent),
143    /// Keyboard event
144    Key(KeyboardEvent)
145}