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}