diff --git a/webrdp/Cargo.toml b/webrdp/Cargo.toml
index efd7fab..b146098 100644
--- a/webrdp/Cargo.toml
+++ b/webrdp/Cargo.toml
@@ -53,6 +53,7 @@ features = [
"FileReader",
"HtmlButtonElement",
"HtmlCanvasElement",
+ "HtmlTextAreaElement",
"ImageData",
"Location",
"KeyboardEvent",
diff --git a/webrdp/assets/rdp.html b/webrdp/assets/rdp.html
index 9d82678..e21a6fc 100644
--- a/webrdp/assets/rdp.html
+++ b/webrdp/assets/rdp.html
@@ -88,8 +88,8 @@
-
-
+
+
diff --git a/webrdp/src/canvas.rs b/webrdp/src/canvas.rs
index 0c3dfb3..11f3fb1 100644
--- a/webrdp/src/canvas.rs
+++ b/webrdp/src/canvas.rs
@@ -102,64 +102,6 @@ impl Canvas {
.unwrap();
cb.forget();
- let sender = self.output.clone();
- let ctrl_alt_del_btn = web_sys::window()
- .unwrap()
- .document()
- .unwrap()
- .get_element_by_id("ctrlaltdel")
- .unwrap()
- .dyn_into::()
- .map_err(|_| ())
- .unwrap();
- let ctrl_alt_del = move || {
- let sender = sender.clone();
- futures::executor::block_on(async move {
- let _ = sender
- .send(InputEvent::KeyCode(
- 0x001D, /* Control Left */
- KeyEventType::Down,
- ))
- .await;
- let _ = sender
- .send(InputEvent::KeyCode(
- 0x0038, /* Alt Left */
- KeyEventType::Down,
- ))
- .await;
- let _ = sender
- .send(InputEvent::KeyCode(
- 0xE053, /* Delete */
- KeyEventType::Down,
- ))
- .await;
- let _ = sender
- .send(InputEvent::KeyCode(
- 0xE053, /* Delete */
- KeyEventType::Up,
- ))
- .await;
- let _ = sender
- .send(InputEvent::KeyCode(
- 0x0038, /* Alt Left */
- KeyEventType::Up,
- ))
- .await;
- let _ = sender
- .send(InputEvent::KeyCode(
- 0x001D, /* Control Left */
- KeyEventType::Up,
- ))
- .await;
- });
- };
- let handler = Box::new(ctrl_alt_del) as Box;
-
- let cb = Closure::wrap(handler);
-
- ctrl_alt_del_btn.set_onclick(Some(cb.as_ref().unchecked_ref()));
- cb.forget();
-
// On a conventional mouse, buttons 1, 2, and 3 correspond to the left,
// middle, and right buttons on the mouse. On a wheel mouse, each step
// of the wheel upwards is represented by a press and release of button
@@ -271,6 +213,101 @@ impl Canvas {
.unwrap();
cb.forget();
+ // page components
+ // ctrl+alt+del
+ let sender = self.output.clone();
+ let ctrl_alt_del_btn = web_sys::window()
+ .unwrap()
+ .document()
+ .unwrap()
+ .get_element_by_id("ctrlaltdel")
+ .unwrap()
+ .dyn_into::()
+ .map_err(|_| ())
+ .unwrap();
+ let ctrl_alt_del = move || {
+ let sender = sender.clone();
+ futures::executor::block_on(async move {
+ let _ = sender
+ .send(InputEvent::KeyCode(
+ 0x001D, /* Control Left */
+ KeyEventType::Down,
+ ))
+ .await;
+ let _ = sender
+ .send(InputEvent::KeyCode(
+ 0x0038, /* Alt Left */
+ KeyEventType::Down,
+ ))
+ .await;
+ let _ = sender
+ .send(InputEvent::KeyCode(
+ 0xE053, /* Delete */
+ KeyEventType::Down,
+ ))
+ .await;
+ let _ = sender
+ .send(InputEvent::KeyCode(
+ 0xE053, /* Delete */
+ KeyEventType::Up,
+ ))
+ .await;
+ let _ = sender
+ .send(InputEvent::KeyCode(
+ 0x0038, /* Alt Left */
+ KeyEventType::Up,
+ ))
+ .await;
+ let _ = sender
+ .send(InputEvent::KeyCode(
+ 0x001D, /* Control Left */
+ KeyEventType::Up,
+ ))
+ .await;
+ });
+ };
+ let handler = Box::new(ctrl_alt_del) as Box;
+
+ let cb = Closure::wrap(handler);
+
+ ctrl_alt_del_btn.set_onclick(Some(cb.as_ref().unchecked_ref()));
+ cb.forget();
+
+ // send text
+ let sender = self.output.clone();
+ let send_text_btn = web_sys::window()
+ .unwrap()
+ .document()
+ .unwrap()
+ .get_element_by_id("clipboardsend")
+ .unwrap()
+ .dyn_into::()
+ .map_err(|_| ())
+ .unwrap();
+ let send_text = move || {
+ let sender = sender.clone();
+ let text = web_sys::window()
+ .unwrap()
+ .document()
+ .unwrap()
+ .get_element_by_id("clipboardtxt")
+ .unwrap()
+ .dyn_into::()
+ .map_err(|_| ())
+ .unwrap()
+ .value();
+ futures::executor::block_on(async move {
+ for c in text.encode_utf16() {
+ tracing::trace!("unicode key char: {}", c);
+ let _ = sender.send(InputEvent::UnicodeKey(c, KeyEventType::Down)).await;
+ let _ = sender.send(InputEvent::UnicodeKey(c, KeyEventType::Up)).await;
+ }
+ });
+ };
+ let handler = Box::new(send_text) as Box;
+ let cb = Closure::wrap(handler);
+ send_text_btn.set_onclick(Some(cb.as_ref().unchecked_ref()));
+ cb.forget();
// initilize the timer
self.timer.set(Instant::now());
diff --git a/webrdp/src/input.rs b/webrdp/src/input.rs
index aa45eab..b2b2616 100644
--- a/webrdp/src/input.rs
+++ b/webrdp/src/input.rs
@@ -1,4 +1,4 @@
-use rdp::core::event::{KeyboardEvent as RdpKeyboard, PointerButton, PointerEvent, PointerWheel, RdpEvent};
+use rdp::core::event::{KeyboardEvent as RdpKeyboard, PointerButton, PointerEvent, PointerWheel, RdpEvent, UnicodeKeyEvent};
use tracing::trace;
use web_sys::{KeyboardEvent, MouseEvent, WheelEvent};
@@ -25,6 +25,7 @@ pub enum InputEvent {
Mouse(MouseEvent, MouseEventType),
Keyboard(KeyboardEvent, KeyEventType),
KeyCode(u16, KeyEventType),
+ UnicodeKey(u16, KeyEventType),
Wheel(WheelEvent, WheelEventType),
}
@@ -243,6 +244,10 @@ impl From for RdpEvent {
code: e,
down: matches!(t, KeyEventType::Down),
}),
+ InputEvent::UnicodeKey(e, t) => RdpEvent::UnicodeKey(UnicodeKeyEvent {
+ code: e,
+ down: matches!(t, KeyEventType::Down),
+ }),
}
}
}