diff --git a/README.md b/README.md
index b171f36..2f5d1cc 100644
--- a/README.md
+++ b/README.md
@@ -18,9 +18,7 @@
* VNC Clients:
- Raw encoding support (Done)
- + Clipboard support is limit
- Other encoding support (WIP)
- - Client to server message (WIP)
* SSH Clients:
- WIP
diff --git a/frontend/src/pages/mod.rs b/frontend/src/pages/mod.rs
index 58fc0a1..d2d582a 100644
--- a/frontend/src/pages/mod.rs
+++ b/frontend/src/pages/mod.rs
@@ -1,3 +1,3 @@
pub mod page_home;
pub mod page_not_found;
-pub mod page_remote;
+pub mod page_vnc;
diff --git a/frontend/src/pages/page_home.rs b/frontend/src/pages/page_home.rs
index 30c837a..91648db 100644
--- a/frontend/src/pages/page_home.rs
+++ b/frontend/src/pages/page_home.rs
@@ -14,7 +14,7 @@ impl Component for PageHome {
fn view(&self) -> Html {
html! {
-
+
}
}
diff --git a/frontend/src/pages/page_remote.rs b/frontend/src/pages/page_vnc.rs
similarity index 82%
rename from frontend/src/pages/page_remote.rs
rename to frontend/src/pages/page_vnc.rs
index bf7280a..f7fcf1d 100644
--- a/frontend/src/pages/page_remote.rs
+++ b/frontend/src/pages/page_vnc.rs
@@ -19,7 +19,7 @@ use crate::{
utils::WeakComponentLink,
};
-pub struct PageRemote {
+pub struct PageVnc {
link: ComponentLink,
target: (String, u16),
error_msg: String,
@@ -38,9 +38,9 @@ pub struct PageRemote {
}
#[derive(Clone, PartialEq, Properties)]
-pub struct RemoteProps {}
+pub struct VncProps {}
-pub enum RemoteMsg {
+pub enum VncMsg {
Connect((String, u16)),
ConnectResp(Result),
Connected,
@@ -53,12 +53,12 @@ pub enum RemoteMsg {
RequireFrame(u8),
}
-impl Component for PageRemote {
- type Message = RemoteMsg;
- type Properties = RemoteProps;
+impl Component for PageVnc {
+ type Message = VncMsg;
+ type Properties = VncProps;
fn create(_: Self::Properties, link: ComponentLink) -> Self {
- PageRemote {
+ PageVnc {
link,
target: (String::from(""), 0),
error_msg: String::from(""),
@@ -79,7 +79,7 @@ impl Component for PageRemote {
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
- RemoteMsg::Connect(target) => {
+ VncMsg::Connect(target) => {
self.target = target;
// ConsoleService::log(&self.target);
let to_post = json!({
@@ -98,7 +98,7 @@ impl Component for PageRemote {
.callback(|response: Response>>| {
// ConsoleService::error(&format!("{:?}", response));
let Json(data) = response.into_body();
- RemoteMsg::ConnectResp(data)
+ VncMsg::ConnectResp(data)
});
// 3. pass the request and callback to the fetch service
let task = FetchService::fetch(request, callback).expect("failed to start request");
@@ -106,12 +106,12 @@ impl Component for PageRemote {
self.fetch_task = Some(task);
true
}
- RemoteMsg::ConnectResp(response) => {
+ VncMsg::ConnectResp(response) => {
if let Ok(response) = response {
self.error_msg = response["status"].to_string();
if "\"success\"" == self.error_msg {
- self.link.send_message(RemoteMsg::Connected);
+ self.link.send_message(VncMsg::Connected);
} else {
self.error_msg = response["message"].to_string();
}
@@ -123,15 +123,15 @@ impl Component for PageRemote {
self.fetch_task = None;
true
}
- RemoteMsg::Connected => {
+ VncMsg::Connected => {
self.connected = true;
true
}
- RemoteMsg::Recv(v) => {
+ VncMsg::Recv(v) => {
self.handler.do_input(v);
self.protocal_out_handler()
}
- RemoteMsg::Send(v) => {
+ VncMsg::Send(v) => {
self.websocket
.borrow()
.as_ref()
@@ -139,31 +139,31 @@ impl Component for PageRemote {
.send_message(WebsocketMsg::Send(Ok(v)));
false
}
- RemoteMsg::UpdateUsername(username) => {
+ VncMsg::UpdateUsername(username) => {
self.username = username;
true
}
- RemoteMsg::UpdatePassword(password) => {
+ VncMsg::UpdatePassword(password) => {
self.password = password;
true
}
- RemoteMsg::SendCredential => {
+ VncMsg::SendCredential => {
self.request_username = false;
self.request_password = false;
self.handler.set_credential(&self.username, &self.password);
self.protocal_out_handler()
}
- RemoteMsg::RequireFrame(incremental) => {
+ VncMsg::RequireFrame(incremental) => {
self.handler.require_frame(incremental);
if self.interval.is_none() {
let link = self.link.clone();
let tick =
- Interval::new(20, move || link.send_message(RemoteMsg::RequireFrame(1)));
+ Interval::new(20, move || link.send_message(VncMsg::RequireFrame(1)));
self.interval = Some(tick);
}
self.protocal_out_handler()
}
- RemoteMsg::UpdateClipboard(clipboard) => {
+ VncMsg::UpdateClipboard(clipboard) => {
if clipboard.len() > 0 {
self.handler.set_clipboard(&clipboard);
self.protocal_out_handler()
@@ -180,7 +180,7 @@ impl Component for PageRemote {
fn view(&self) -> Html {
if !self.connected {
- let connect_remote = self.link.callback(RemoteMsg::Connect);
+ let connect_remote = self.link.callback(VncMsg::Connect);
html! {
<>
@@ -188,8 +188,8 @@ impl Component for PageRemote {
>
}
} else {
- let recv_msg = self.link.callback(RemoteMsg::Recv);
- let clipboard_update = self.link.callback(RemoteMsg::UpdateClipboard);
+ let recv_msg = self.link.callback(VncMsg::Recv);
+ let clipboard_update = self.link.callback(VncMsg::UpdateClipboard);
let websocket = &self.websocket;
let clipboard = &self.clipboard;
html! {
@@ -218,7 +218,7 @@ impl Component for PageRemote {
}
// impl PageRemote
-impl PageRemote {
+impl PageVnc {
fn protocal_out_handler(&mut self) -> ShouldRender {
let out = self.handler.get_output();
let mut should_render = false;
@@ -236,7 +236,7 @@ impl PageRemote {
}
ProtocalHandlerOutput::WsBuf(out) => {
if out.len() > 0 {
- self.link.send_message(RemoteMsg::Send(out));
+ self.link.send_message(VncMsg::Send(out));
}
}
ProtocalHandlerOutput::RequirePassword => {
@@ -256,17 +256,40 @@ impl PageRemote {
}
};
- let data = ImageData::new_with_u8_clamped_array_and_sh(
- Clamped(&cr.data),
- cr.width as u32,
- cr.height as u32,
- )
- .unwrap();
- // ConsoleService::log(&format!(
- // "renderring at ({}, {}), width {}, height {}",
- // cr.x, cr.y, cr.width, cr.height
- // ));
- let _ = ctx.put_image_data(&data, cr.x as f64, cr.y as f64);
+ match cr.type_ {
+ 1 => {
+ //copy
+ let sx = (cr.data[0] as u16) << 8 | cr.data[1] as u16;
+ let sy = (cr.data[2] as u16) << 8 | cr.data[3] as u16;
+
+ let _ = ctx.
+ draw_image_with_html_canvas_element_and_sw_and_sh_and_dx_and_dy_and_dw_and_dh(
+ &canvas,
+ sx as f64,
+ sy as f64,
+ cr.width as f64,
+ cr.height as f64,
+ cr.x as f64,
+ cr.y as f64,
+ cr.width as f64,
+ cr.height as f64
+ );
+ }
+ _ => {
+ let data = ImageData::new_with_u8_clamped_array_and_sh(
+ Clamped(&cr.data),
+ cr.width as u32,
+ cr.height as u32,
+ )
+ .unwrap();
+ // ConsoleService::log(&format!(
+ // "renderring at ({}, {}), width {}, height {}",
+ // cr.x, cr.y, cr.width, cr.height
+ // ));
+ let _ = ctx.put_image_data(&data, cr.x as f64, cr.y as f64);
+ }
+ }
+
should_render = true;
}
ProtocalHandlerOutput::SetCanvas(width, height) => {
@@ -274,7 +297,7 @@ impl PageRemote {
canvas.set_width(width as u32);
canvas.set_height(height as u32);
self.bind_mouse_and_key(&canvas);
- self.link.send_message(RemoteMsg::RequireFrame(0));
+ self.link.send_message(VncMsg::RequireFrame(0));
let ctx = match &self.canvas_ctx {
Some(ctx) => ctx,
None => {
@@ -305,7 +328,7 @@ impl PageRemote {
fn username_view(&self) -> Html {
if self.request_username {
- let update_username = self.link.callback(RemoteMsg::UpdateUsername);
+ let update_username = self.link.callback(VncMsg::UpdateUsername);
html! {
<>
@@ -319,7 +342,7 @@ impl PageRemote {
fn password_view(&self) -> Html {
if self.request_password {
- let update_password = self.link.callback(RemoteMsg::UpdatePassword);
+ let update_password = self.link.callback(VncMsg::UpdatePassword);
html! {
<>
@@ -333,7 +356,7 @@ impl PageRemote {
fn button_connect_view(&self) -> Html {
if self.request_username || self.request_password {
- let send_credential = self.link.callback(|_| RemoteMsg::SendCredential);
+ let send_credential = self.link.callback(|_| VncMsg::SendCredential);
html! {
<>
diff --git a/frontend/src/protocal/common.rs b/frontend/src/protocal/common.rs
index 18f7f46..e66dceb 100644
--- a/frontend/src/protocal/common.rs
+++ b/frontend/src/protocal/common.rs
@@ -1,6 +1,7 @@
use std::{rc::Rc, sync::Mutex};
pub struct CanvasData {
+ pub type_: u32,
pub x: u16,
pub y: u16,
pub width: u16,
diff --git a/frontend/src/protocal/vnc/vnc.rs b/frontend/src/protocal/vnc/vnc.rs
index 51737e4..f587bc2 100644
--- a/frontend/src/protocal/vnc/vnc.rs
+++ b/frontend/src/protocal/vnc/vnc.rs
@@ -23,6 +23,7 @@ pub enum SecurityType {
// VeNCrypt = 19,
}
+#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(i32)]
pub enum VncEncoding {
@@ -79,7 +80,7 @@ impl ProtocalImpl for VncHandler {
state: VncState::Init,
supported_encodings: vec![
VncEncoding::Raw,
- // VncEncoding::CopyRect,
+ VncEncoding::CopyRect,
// VncEncoding::RRE,
// VncEncoding::Hextile,
// VncEncoding::TRLE,
@@ -554,10 +555,15 @@ impl VncHandler {
}
}
}
+ 1 => {
+ // copy rectangle
+ self.read_exact_vec(&mut image_data, 4);
+ }
_ => unimplemented!(),
}
self.outs
.push(ProtocalHandlerOutput::RenderCanvas(CanvasData {
+ type_: rect.encoding_type,
x: rect.x,
y: rect.y,
width: rect.width,
@@ -649,19 +655,31 @@ impl VncHandler {
width,
height,
encoding_type: 0,
- encoding_data: Vec::new(), // we donnot need to store the data
});
}
- fn handle_copy_rect_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
- unimplemented!()
+ fn handle_copy_rect_encoding(&mut self, x: u16, y: u16, width: u16, height: u16) {
+ ConsoleService::log(&format!("VNC: CopyRect {} {} {} {}", x, y, width, height));
+ self.require = 4;
+ self.padding_rect = Some(VncRect {
+ x,
+ y,
+ width,
+ height,
+ encoding_type: 1,
+ });
}
fn handle_rre_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
+ // Note: RRE encoding is obsolescent. In general, ZRLE and TRLE
+ // encodings are more compact.
+
unimplemented!()
}
fn handle_hextile_encoding(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
+ // Note: Hextile encoding is obsolescent. In general, ZRLE and TRLE
+ // encodings are more compact.
unimplemented!()
}
@@ -800,5 +818,4 @@ struct VncRect {
width: u16,
height: u16,
encoding_type: u32,
- encoding_data: Vec,
}
diff --git a/frontend/src/protocal/vnc/x11keyboard.rs b/frontend/src/protocal/vnc/x11keyboard.rs
index 0354440..9c51c98 100644
--- a/frontend/src/protocal/vnc/x11keyboard.rs
+++ b/frontend/src/protocal/vnc/x11keyboard.rs
@@ -3,8 +3,6 @@
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
-
-
// referring:
// https://github.com/AltF02/x11-rs/blob/master/src/keysym.rs