keypress events initially

This commit is contained in:
Jovi Hsu 2021-11-17 14:43:10 +08:00
parent f21a180053
commit 7e5074e15b
4 changed files with 99 additions and 30 deletions

View File

@ -5,8 +5,6 @@ mod protocal;
mod utils; mod utils;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::{console, KeyboardEvent};
#[cfg(feature = "wee_alloc")] #[cfg(feature = "wee_alloc")]
#[global_allocator] #[global_allocator]
@ -14,20 +12,6 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen] #[wasm_bindgen]
pub fn run_app() -> Result<(), JsValue> { pub fn run_app() -> Result<(), JsValue> {
let window = web_sys::window().unwrap();
let handler_submit = move |e: KeyboardEvent| {
e.stop_propagation();
console::log_1(&format!("{:?}", e).into())
};
let handler = Box::new(handler_submit) as Box<dyn FnMut(_)>;
let cb = Closure::wrap(handler);
window
.add_event_listener_with_callback("keydown", cb.as_ref().unchecked_ref())
.unwrap();
cb.forget();
yew::start_app::<app::App>(); yew::start_app::<app::App>();
Ok(()) Ok(())

View File

@ -1,5 +1,5 @@
use serde_json::{json, Value}; use serde_json::{json, Value};
use wasm_bindgen::{Clamped, JsValue}; use wasm_bindgen::{prelude::Closure, Clamped, JsCast, JsValue};
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement, ImageData}; use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement, ImageData};
use yew::{ use yew::{
format::Json, format::Json,
@ -121,6 +121,22 @@ impl Component for PageRemote {
true true
} }
RemoteMsg::Connected => { RemoteMsg::Connected => {
let window = web_sys::window().unwrap();
let handler = self.handler.clone();
let key_down = move |e: KeyboardEvent| {
e.stop_propagation();
handler.key_down(e.key_code());
};
let handler = Box::new(key_down) as Box<dyn FnMut(_)>;
let cb = Closure::wrap(handler);
window
.add_event_listener_with_callback("keypress", cb.as_ref().unchecked_ref())
.unwrap();
cb.forget();
self.connected = true; self.connected = true;
true true
} }
@ -155,7 +171,7 @@ impl Component for PageRemote {
if self.interval.is_none() { if self.interval.is_none() {
let link = self.link.clone(); let link = self.link.clone();
let tick = let tick =
Interval::new(250, move || link.send_message(RemoteMsg::RequireFrame(1))); Interval::new(20, move || link.send_message(RemoteMsg::RequireFrame(1)));
self.interval = Some(tick); self.interval = Some(tick);
} }
self.protocal_out_handler() self.protocal_out_handler()

View File

@ -1,3 +1,8 @@
use std::{
rc::Rc,
sync::{Mutex},
};
pub struct CanvasData { pub struct CanvasData {
pub x: u16, pub x: u16,
pub y: u16, pub y: u16,
@ -20,7 +25,18 @@ pub struct ProtocalHandler<T>
where where
T: ProtocalImpl, T: ProtocalImpl,
{ {
inner: T, inner: Rc<Mutex<T>>,
}
impl<T> Clone for ProtocalHandler<T>
where
T: ProtocalImpl,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
} }
impl<T> ProtocalHandler<T> impl<T> ProtocalHandler<T>
@ -28,27 +44,45 @@ where
T: ProtocalImpl, T: ProtocalImpl,
{ {
pub fn new() -> Self { pub fn new() -> Self {
Self { inner: T::new() } Self {
inner: Rc::new(Mutex::new(T::new())),
}
} }
pub fn do_input(&mut self, input: Vec<u8>) { pub fn do_input(&self, input: Vec<u8>) {
self.inner.do_input(input); self.inner.as_ref().lock().unwrap().do_input(input);
} }
pub fn get_output(&mut self) -> Vec<ProtocalHandlerOutput> { pub fn get_output(&self) -> Vec<ProtocalHandlerOutput> {
self.inner.get_output() self.inner.as_ref().lock().unwrap().get_output()
} }
pub fn set_credential(&mut self, username: &str, password: &str) { pub fn set_credential(&self, username: &str, password: &str) {
self.inner.set_credential(username, password); self.inner
.as_ref()
.lock()
.unwrap()
.set_credential(username, password);
} }
pub fn set_resolution(&mut self, width: u16, height: u16) { pub fn set_resolution(&self, width: u16, height: u16) {
self.inner.set_resolution(width, height); self.inner
.as_ref()
.lock()
.unwrap()
.set_resolution(width, height);
} }
pub fn require_frame(&mut self, incremental: u8) { pub fn require_frame(&self, incremental: u8) {
self.inner.require_frame(incremental); self.inner
.as_ref()
.lock()
.unwrap()
.require_frame(incremental);
}
pub fn key_down(&self, key: u32) {
self.inner.as_ref().lock().unwrap().key_down(key);
} }
} }
@ -58,6 +92,7 @@ pub trait ProtocalImpl {
fn get_output(&mut self) -> Vec<ProtocalHandlerOutput>; fn get_output(&mut self) -> Vec<ProtocalHandlerOutput>;
fn set_credential(&mut self, username: &str, password: &str); fn set_credential(&mut self, username: &str, password: &str);
fn set_resolution(&mut self, width: u16, height: u16); fn set_resolution(&mut self, width: u16, height: u16);
fn key_down(&mut self, key: u32);
fn require_frame(&mut self, incremental: u8); fn require_frame(&mut self, incremental: u8);
} }

View File

@ -8,6 +8,10 @@ const VNC_RFB38: &[u8; 12] = b"RFB 003.008\n";
const VNC_VER_UNSUPPORTED: &str = "unsupported version"; const VNC_VER_UNSUPPORTED: &str = "unsupported version";
const VNC_FAILED: &str = "Connection failed with unknow reason"; const VNC_FAILED: &str = "Connection failed with unknow reason";
fn jskey_to_x11(key: u32) -> u32 {
key
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)] #[repr(u8)]
pub enum SecurityType { pub enum SecurityType {
@ -35,6 +39,7 @@ pub enum VncEncoding {
DesktopSizePseudo = -223, DesktopSizePseudo = -223,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VncState { pub enum VncState {
Init, Init,
Handshake, Handshake,
@ -162,6 +167,16 @@ impl ProtocalImpl for VncHandler {
// VNC client doen't support resolution change // VNC client doen't support resolution change
} }
fn key_down(&mut self, key: u32) {
if self.state != VncState::Connected {
return;
}
let key = jskey_to_x11(key);
if let ServerMessage::None = self.msg_handling {
self.send_key_event(key, true);
}
}
fn require_frame(&mut self, incremental: u8) { fn require_frame(&mut self, incremental: u8) {
if 0 == incremental { if 0 == incremental {
// first frame // first frame
@ -264,6 +279,25 @@ impl VncHandler {
self.outbuf.extend_from_slice(&out); self.outbuf.extend_from_slice(&out);
} }
// +--------------+--------------+--------------+
// | No. of bytes | Type [Value] | Description |
// +--------------+--------------+--------------+
// | 1 | U8 [4] | message-type |
// | 1 | U8 | down-flag |
// | 2 | | padding |
// | 4 | U32 | key |
// +--------------+--------------+--------------+
fn send_key_event(&mut self, key: u32, down: bool) {
let mut out = Vec::with_capacity(10);
let mut sw = StreamWriter::new(&mut out);
sw.write_u8(4); // message-type
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));
self.outbuf.extend_from_slice(&out);
}
// No. of bytes Type [Value] Description // No. of bytes Type [Value] Description
// 1 CARD8 3 message-type // 1 CARD8 3 message-type
// 1 CARD8 incremental // 1 CARD8 incremental