diff --git a/frontend/src/pages/page_remote.rs b/frontend/src/pages/page_remote.rs index 20b73e7..d043038 100644 --- a/frontend/src/pages/page_remote.rs +++ b/frontend/src/pages/page_remote.rs @@ -187,7 +187,7 @@ impl Component for PageRemote { {self.button_connect_view()} - + {self.error_msg.clone()} @@ -369,11 +369,7 @@ impl PageRemote { let handler = self.handler.clone(); let mouse_move = move |e: MouseEvent| { e.stop_propagation(); - handler.mouse_event( - e.client_x().try_into().unwrap_or(0), - e.client_y().try_into().unwrap_or(0), - 0, - ); + handler.mouse_event(e, MouseEventType::MouseMove); }; let handler = Box::new(mouse_move) as Box; @@ -388,11 +384,7 @@ impl PageRemote { let handler = self.handler.clone(); let mouse_down = move |e: MouseEvent| { e.stop_propagation(); - handler.mouse_event( - e.client_x().try_into().unwrap_or(0), - e.client_y().try_into().unwrap_or(0), - 1 | 1 << 1, - ); + handler.mouse_event(e, MouseEventType::MouseDown); }; let handler = Box::new(mouse_down) as Box; @@ -407,11 +399,7 @@ impl PageRemote { let handler = self.handler.clone(); let mouse_up = move |e: MouseEvent| { e.stop_propagation(); - handler.mouse_event( - e.client_x().try_into().unwrap_or(0), - e.client_y().try_into().unwrap_or(0), - 0, - ); + handler.mouse_event(e, MouseEventType::MouseUp); }; let handler = Box::new(mouse_up) as Box; @@ -422,5 +410,19 @@ impl PageRemote { .add_event_listener_with_callback("mouseup", cb.as_ref().unchecked_ref()) .unwrap(); cb.forget(); + + let get_context_menu = move |e: MouseEvent| { + e.prevent_default(); + e.stop_propagation(); + }; + + let handler = Box::new(get_context_menu) as Box; + + let cb = Closure::wrap(handler); + + canvas + .add_event_listener_with_callback("contextmenu", cb.as_ref().unchecked_ref()) + .unwrap(); + cb.forget(); } } diff --git a/frontend/src/protocal/common.rs b/frontend/src/protocal/common.rs index cb04d05..176b494 100644 --- a/frontend/src/protocal/common.rs +++ b/frontend/src/protocal/common.rs @@ -8,6 +8,12 @@ pub struct CanvasData { pub data: Vec, } +pub enum MouseEventType { + MouseDown, + MouseUp, + MouseMove, +} + pub enum ProtocalHandlerOutput { WsBuf(Vec), Err(String), @@ -82,12 +88,8 @@ where self.inner.as_ref().lock().unwrap().key_press(key, down); } - pub fn mouse_event(&self, x: u16, y: u16, button: u8) { - self.inner - .as_ref() - .lock() - .unwrap() - .mouse_event(x, y, button); + pub fn mouse_event(&self, mouse: web_sys::MouseEvent, et: MouseEventType) { + self.inner.as_ref().lock().unwrap().mouse_event(mouse, et); } } @@ -100,7 +102,7 @@ pub trait ProtocalImpl { fn set_credential(&mut self, username: &str, password: &str); fn set_resolution(&mut self, width: u16, height: u16); fn key_press(&mut self, key: web_sys::KeyboardEvent, down: bool); - fn mouse_event(&mut self, x: u16, y: u16, button: u8); + fn mouse_event(&mut self, mouse: web_sys::MouseEvent, et: MouseEventType); fn require_frame(&mut self, incremental: u8); } diff --git a/frontend/src/protocal/vnc/mod.rs b/frontend/src/protocal/vnc/mod.rs index 71ccae2..7cf5972 100644 --- a/frontend/src/protocal/vnc/mod.rs +++ b/frontend/src/protocal/vnc/mod.rs @@ -1,3 +1,4 @@ mod des; pub mod vnc; +mod x11cursor; mod x11keyboard; diff --git a/frontend/src/protocal/vnc/vnc.rs b/frontend/src/protocal/vnc/vnc.rs index 76a759e..323a8e2 100644 --- a/frontend/src/protocal/vnc/vnc.rs +++ b/frontend/src/protocal/vnc/vnc.rs @@ -1,5 +1,6 @@ -use super::des; -use super::{super::common::*, x11keyboard}; +use crate::protocal::common::MouseEventType; + +use super::{super::common::*, des, x11cursor::MouseUtils, x11keyboard}; use yew::services::ConsoleService; const VNC_RFB33: &[u8; 12] = b"RFB 003.003\n"; @@ -59,6 +60,7 @@ pub struct VncHandler { security_type: SecurityType, challenge: [u8; 16], reader: StreamReader, + mouse: MouseUtils, require: usize, width: u16, height: u16, @@ -88,6 +90,7 @@ impl ProtocalImpl for VncHandler { security_type: SecurityType::Invalid, challenge: [0; 16], reader: StreamReader::new(Vec::with_capacity(10)), + mouse: MouseUtils::new(), require: 12, // the handleshake message length width: 0, height: 0, @@ -167,18 +170,19 @@ impl ProtocalImpl for VncHandler { if self.state != VncState::Connected { return; } + let key = x11keyboard::KeyboardUtils::get_keysym(key); if let ServerMessage::None = self.msg_handling { - let key = x11keyboard::KeyboardUtils::get_keysym(key); self.send_key_event(key, down); } } - fn mouse_event(&mut self, x: u16, y: u16, button: u8) { + fn mouse_event(&mut self, mouse: web_sys::MouseEvent, et: MouseEventType) { if self.state != VncState::Connected { return; } + let (x, y, mask) = self.mouse.get_mouse_sym(mouse, et); if let ServerMessage::None = self.msg_handling { - self.send_pointer_event(x, y, button); + self.send_pointer_event(x, y, mask); } } @@ -299,7 +303,8 @@ impl VncHandler { sw.write_u8(if down { 1 } else { 0 }); // down sw.write_u16(0); // padding sw.write_u32(key); // key - ConsoleService::log(&format!("send key event {:x?} {:?}", key, down)); + + // ConsoleService::log(&format!("send key event {:x?} {:?}", key, down)); self.outbuf.extend_from_slice(&out); } @@ -311,14 +316,15 @@ impl VncHandler { // | 2 | U16 | x-position | // | 2 | U16 | y-position | // +--------------+--------------+--------------+ - fn send_pointer_event(&mut self, x: u16, y: u16, button: u8) { + fn send_pointer_event(&mut self, x: u16, y: u16, mask: u8) { let mut out = Vec::with_capacity(10); let mut sw = StreamWriter::new(&mut out); sw.write_u8(5); // message-type - sw.write_u8(button); // button + sw.write_u8(mask); // mask sw.write_u16(x); // x sw.write_u16(y); // y - // ConsoleService::log(&format!("send mouse event {:x?} {:x?} {:x?}", x, y, button)); + + ConsoleService::log(&format!("send mouse event {:x?} {:x?} {:#08b}", x, y, mask)); self.outbuf.extend_from_slice(&out); } diff --git a/frontend/src/protocal/vnc/x11cursor.rs b/frontend/src/protocal/vnc/x11cursor.rs new file mode 100644 index 0000000..3595c83 --- /dev/null +++ b/frontend/src/protocal/vnc/x11cursor.rs @@ -0,0 +1,38 @@ +use crate::protocal::common::MouseEventType; + +pub struct MouseUtils { + down: bool, + mask: u8, +} + +impl MouseUtils { + pub fn new() -> Self { + Self { + down: false, + mask: 0, + } + } + pub fn get_mouse_sym( + &mut self, + event: web_sys::MouseEvent, + et: MouseEventType, + ) -> (u16, u16, u8) { + let x: u16 = event.client_x().try_into().unwrap_or(0); + let y: u16 = event.client_y().try_into().unwrap_or(0); + let mask: u8 = (event.button() << 1).try_into().unwrap_or(0); + + match et { + MouseEventType::MouseDown => { + self.down = true; + self.mask = self.down as u8 | mask; + } + MouseEventType::MouseUp => { + self.down = false; + self.mask = self.down as u8 & (!mask); + } + + MouseEventType::MouseMove => {} + } + (x, y, self.mask) + } +}