diff --git a/webvnc/src/canvas.rs b/webvnc/src/canvas.rs index 3f30de2..0c1ae45 100644 --- a/webvnc/src/canvas.rs +++ b/webvnc/src/canvas.rs @@ -2,7 +2,7 @@ use std::rc::Rc; use crate::{ console_log, log, - vnc::{ImageData, MouseEventType, Vnc}, + vnc::{ImageData, ImageType, MouseEventType, Vnc}, }; use wasm_bindgen::prelude::*; use wasm_bindgen::{Clamped, JsCast}; @@ -162,7 +162,7 @@ impl Canvas { fn draw(&self, ri: &ImageData) { match ri.type_ { - 1 => { + ImageType::Copy => { //copy let sx = (ri.data[0] as u16) << 8 | ri.data[1] as u16; let sy = (ri.data[2] as u16) << 8 | ri.data[3] as u16; @@ -181,7 +181,13 @@ impl Canvas { ri.height as f64, ); } - _ => { + ImageType::Fill => { + // fill + let (r, g, b) = (ri.data[2], ri.data[1], ri.data[0]); + let style = format!("rgb({},{},{})", r, g, b); + self.ctx.set_fill_style(&JsValue::from_str(&style)); + } + ImageType::Raw => { let data = web_sys::ImageData::new_with_u8_clamped_array_and_sh( Clamped(&ri.data), ri.width as u32, diff --git a/webvnc/src/vnc/mod.rs b/webvnc/src/vnc/mod.rs index 9f98951..a7b2d61 100644 --- a/webvnc/src/vnc/mod.rs +++ b/webvnc/src/vnc/mod.rs @@ -13,7 +13,7 @@ pub enum MouseEventType { use std::{rc::Rc, sync::Mutex}; pub struct ImageData { - pub type_: u32, + pub type_: ImageType, pub x: u16, pub y: u16, pub width: u16, @@ -21,6 +21,13 @@ pub struct ImageData { pub data: Vec, } +#[allow(dead_code)] +pub enum ImageType { + Raw, + Copy, + Fill, +} + pub enum VncOutput { WsBuf(Vec), Err(String), diff --git a/webvnc/src/vnc/vnc_impl.rs b/webvnc/src/vnc/vnc_impl.rs index 510328f..b04154a 100644 --- a/webvnc/src/vnc/vnc_impl.rs +++ b/webvnc/src/vnc/vnc_impl.rs @@ -37,6 +37,18 @@ pub enum VncEncoding { DesktopSizePseudo = -223, } +impl From for VncEncoding { + fn from(num: u32) -> Self { + unsafe { std::mem::transmute(num) } + } +} + +impl From for u32 { + fn from(e: VncEncoding) -> Self { + e as u32 + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum VncState { Init, @@ -396,7 +408,7 @@ impl Vnc { VncState::Authing => self.handle_auth_result(), VncState::ServerInit => self.handle_server_init(), VncState::Connected => self.handle_server_message(), - _ => unimplemented!(), + VncState::Disconnected => (), } } @@ -533,9 +545,8 @@ impl Vnc { let y = self.read_u16(); let width = self.read_u16(); let height = self.read_u16(); - let encoding_type = self.read_u32(); - let encoding_enum = unsafe { std::mem::transmute(encoding_type) }; - match encoding_enum { + let encoding_type = self.read_u32().into(); + match encoding_type { VncEncoding::Raw => self.handle_raw_encoding(x, y, width, height), VncEncoding::CopyRect => self.handle_copy_rect_encoding(x, y, width, height), VncEncoding::RRE => self.handle_rre_encoding(x, y, width, height), @@ -550,21 +561,18 @@ impl Vnc { } } } else { - match self.padding_rect.as_ref().unwrap().encoding_type { - 16 => { - if self.require == 4 { - self.require = self.read_u32() as usize; - return; - } + if let VncEncoding::ZRLE = self.padding_rect.as_ref().unwrap().encoding_type { + if self.require == 4 { + self.require = self.read_u32() as usize; + return; } - _ => (), } // we now have an entire rectangle let rect = self.padding_rect.take().unwrap(); let mut image_data: Vec = Vec::with_capacity(self.require); self.read_exact_vec(&mut image_data, self.require); match rect.encoding_type { - 0 => { + VncEncoding::Raw => { // raw let mut y = 0; let mut x = 0; @@ -579,7 +587,7 @@ impl Vnc { y += 1; } self.outs.push(VncOutput::RenderImage(ImageData { - type_: rect.encoding_type, + type_: ImageType::Raw, x: rect.x, y: rect.y, width: rect.width, @@ -587,10 +595,10 @@ impl Vnc { data: image_data, })); } - 1 => { + VncEncoding::CopyRect => { // copy rectangle self.outs.push(VncOutput::RenderImage(ImageData { - type_: rect.encoding_type, + type_: ImageType::Copy, x: rect.x, y: rect.y, width: rect.width, @@ -598,7 +606,7 @@ impl Vnc { data: image_data, })); } - 16 => { + VncEncoding::ZRLE => { // ZRLE match self.zlib_decoder.decode(&self.pf, &rect, &image_data) { Ok(images) => { @@ -607,11 +615,11 @@ impl Vnc { } } Err(e) => { - self.outs.push(VncOutput::Err(format!("{:?}", e))); + self.disconnect_with_err(&format!("{:?}", e)); } } } - _ => unimplemented!("Unknow encoding {}", rect.encoding_type), + _ => unimplemented!("Unknow encoding {}", rect.encoding_type as u32), } self.num_rect_left -= 1; if 0 == self.num_rect_left { @@ -697,7 +705,7 @@ impl Vnc { y, width, height, - encoding_type: 0, + encoding_type: VncEncoding::Raw, }); } @@ -709,7 +717,7 @@ impl Vnc { y, width, height, - encoding_type: 1, + encoding_type: VncEncoding::CopyRect, }); } @@ -737,7 +745,7 @@ impl Vnc { y, width, height, - encoding_type: 16, + encoding_type: VncEncoding::ZRLE, }) } @@ -848,5 +856,5 @@ pub struct VncRect { pub y: u16, pub width: u16, pub height: u16, - pub encoding_type: u32, + pub encoding_type: VncEncoding, } diff --git a/webvnc/src/vnc/zlib.rs b/webvnc/src/vnc/zlib.rs index c88e5a6..a03f7b5 100644 --- a/webvnc/src/vnc/zlib.rs +++ b/webvnc/src/vnc/zlib.rs @@ -27,7 +27,7 @@ DEALINGS IN THE SOFTWARE. */ use super::vnc_impl::*; -use super::ImageData; +use super::{ImageData, ImageType}; use byteorder::ReadBytesExt; use std::io::{Read, Result}; @@ -330,7 +330,7 @@ impl Decoder { width, x: rect.x + x, y: rect.y + y, - type_: 0, + type_: ImageType::Raw, }); x += width; }