prototype
This commit is contained in:
parent
759092c545
commit
904f75bbba
2
vdi/host/.cargo/config.toml
Normal file
2
vdi/host/.cargo/config.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[registries.crates-io]
|
||||
protocol = "sparse"
|
@ -1,16 +0,0 @@
|
||||
FROM rockylinux:9.1
|
||||
ENV HOME=/home/vscode
|
||||
ENV WORKDIR=$HOME/rustdesk/vdi/host
|
||||
|
||||
# https://ciq.co/blog/top-10-things-to-do-after-rocky-linux-9-install/ also gpu driver install
|
||||
WORKDIR $HOME
|
||||
RUN dnf -y install epel-release
|
||||
RUN dnf config-manager --set-enabled crb
|
||||
RUN dnf -y install cargo libvpx-devel opus-devel usbredir-devel git cmake gcc-c++ pkg-config nasm yasm ninja-build automake libtool libva-devel libvdpau-devel llvm-devel
|
||||
WORKDIR /
|
||||
|
||||
RUN git clone https://chromium.googlesource.com/libyuv/libyuv
|
||||
WORKDIR /libyuv
|
||||
RUN cmake . -DCMAKE_INSTALL_PREFIX=/user
|
||||
RUN make -j4 && make install
|
||||
WORKDIR /
|
@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "rustdesk",
|
||||
"build": {
|
||||
"dockerfile": "./Dockerfile",
|
||||
"context": "."
|
||||
},
|
||||
"workspaceMount": "source=${localWorkspaceFolder}/../..,target=/home/vscode/rustdesk,type=bind,consistency=cache",
|
||||
"workspaceFolder": "/home/vscode/rustdesk/vdi/host",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"vadimcn.vscode-lldb",
|
||||
"mutantdino.resourcemonitor",
|
||||
"rust-lang.rust-analyzer",
|
||||
"tamasfe.even-better-toml",
|
||||
"serayuzgur.crates",
|
||||
"mhutchie.git-graph",
|
||||
"formulahendry.terminal",
|
||||
"eamodio.gitlens"
|
||||
],
|
||||
"settings": {
|
||||
"files.watcherExclude": {
|
||||
"**/target/**": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
155
vdi/host/Cargo.lock
generated
155
vdi/host/Cargo.lock
generated
@ -157,17 +157,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
@ -316,6 +305,16 @@ dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.14"
|
||||
@ -475,17 +474,38 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.9.3"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
|
||||
checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.5.3"
|
||||
@ -513,6 +533,24 @@ dependencies = [
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flexi_logger"
|
||||
version = "0.25.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6eae57842a8221ef13f1f207632d786a175dd13bd8fbdc8be9d852f7c9cf1046"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
"crossbeam-queue",
|
||||
"glob",
|
||||
"is-terminal",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nu-ansi-term",
|
||||
"regex",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.26"
|
||||
@ -634,6 +672,12 @@ version = "0.27.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@ -656,6 +700,7 @@ dependencies = [
|
||||
"dirs-next",
|
||||
"env_logger",
|
||||
"filetime",
|
||||
"flexi_logger",
|
||||
"futures",
|
||||
"futures-util",
|
||||
"lazy_static",
|
||||
@ -680,15 +725,6 @@ dependencies = [
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
@ -698,6 +734,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
@ -753,6 +795,29 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"libc",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8687c819457e979cc940d09cb16e42a1bf70aa6b60a549de6d3a62a0ee90c69e"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.5"
|
||||
@ -822,6 +887,12 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
@ -941,13 +1012,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ntapi"
|
||||
version = "0.3.7"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
|
||||
checksum = "bc51db7b362b205941f71232e56c625156eb9a929f8cf74a428fd5bc094a4afc"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
|
||||
dependencies = [
|
||||
"overload",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
@ -1013,6 +1094,12 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.0.0"
|
||||
@ -1328,6 +1415,20 @@ version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.12"
|
||||
@ -1515,9 +1616,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.24.7"
|
||||
version = "0.28.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54cb4ebf3d49308b99e6e9dc95e989e2fdbdc210e4f67c39db0bb89ba927001c"
|
||||
checksum = "f69e0d827cce279e61c2f3399eb789271a8f136d8245edef70f06e3c9601a670"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"core-foundation-sys",
|
||||
|
@ -5,5 +5,10 @@ authors = ["rustdesk <info@rustdesk.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
qemu-display = { git = "https://gitlab.com/marcandre.lureau/qemu-display" }
|
||||
qemu-display = { git = "https://github.com/rustdesk/qemu-display" }
|
||||
hbb_common = { path = "../../libs/hbb_common" }
|
||||
clap = { version = "4.1", features = ["derive"] }
|
||||
zbus = { version = "3.0" }
|
||||
derivative = "2.2"
|
||||
image = "0.24"
|
||||
async-trait = "0.1"
|
||||
|
@ -1 +1,5 @@
|
||||
# RustDesk protocol on QEMU D-Bus display
|
||||
|
||||
```
|
||||
sudo apt install libusbredirparser-dev libusbredirhost-dev libusb-1.0-0-dev
|
||||
```
|
||||
|
1
vdi/host/src/lib.rs
Normal file
1
vdi/host/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod server;
|
@ -1,2 +1,6 @@
|
||||
fn main() {
|
||||
hbb_common::init_log(false, "");
|
||||
if let Err(err) = qemu_rustdesk::server::run() {
|
||||
hbb_common::log::error!("{err}");
|
||||
}
|
||||
}
|
||||
|
335
vdi/host/src/server.rs
Normal file
335
vdi/host/src/server.rs
Normal file
@ -0,0 +1,335 @@
|
||||
use clap::Parser;
|
||||
use hbb_common::{
|
||||
anyhow::{anyhow, Context},
|
||||
log,
|
||||
message_proto::*,
|
||||
tokio, ResultType,
|
||||
};
|
||||
use image::GenericImage;
|
||||
use qemu_display::{Console, ConsoleListenerHandler, MouseButton, VMProxy};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
collections::HashSet,
|
||||
error::Error,
|
||||
io,
|
||||
iter::FromIterator,
|
||||
net::{TcpListener, TcpStream},
|
||||
sync::{mpsc, Arc, Mutex},
|
||||
thread, time,
|
||||
};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct SocketAddrArgs {
|
||||
/// IP address
|
||||
#[clap(short, long, default_value = "0.0.0.0")]
|
||||
address: std::net::IpAddr,
|
||||
/// IP port number
|
||||
#[clap(short, long, default_value = "21116")]
|
||||
port: u16,
|
||||
}
|
||||
|
||||
impl From<SocketAddrArgs> for std::net::SocketAddr {
|
||||
fn from(args: SocketAddrArgs) -> Self {
|
||||
(args.address, args.port).into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Cli {
|
||||
#[clap(flatten)]
|
||||
address: SocketAddrArgs,
|
||||
#[clap(short, long)]
|
||||
dbus_address: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Event {
|
||||
ConsoleUpdate((i32, i32, i32, i32)),
|
||||
Disconnected,
|
||||
}
|
||||
|
||||
const PIXMAN_X8R8G8B8: u32 = 0x20020888;
|
||||
type BgraImage = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug)]
|
||||
struct Client {
|
||||
#[derivative(Debug = "ignore")]
|
||||
server: Server,
|
||||
share: bool,
|
||||
last_update: Option<time::Instant>,
|
||||
has_update: bool,
|
||||
req_update: bool,
|
||||
last_buttons: HashSet<MouseButton>,
|
||||
dimensions: (u16, u16),
|
||||
}
|
||||
|
||||
impl Client {
|
||||
fn new(server: Server, share: bool) -> Self {
|
||||
Self {
|
||||
server,
|
||||
share,
|
||||
last_update: None,
|
||||
has_update: false,
|
||||
req_update: false,
|
||||
last_buttons: HashSet::new(),
|
||||
dimensions: (0, 0),
|
||||
}
|
||||
}
|
||||
|
||||
fn update_pending(&self) -> bool {
|
||||
self.has_update && self.req_update
|
||||
}
|
||||
|
||||
async fn key_event(&self, qnum: u32, down: bool) -> ResultType<()> {
|
||||
let inner = self.server.inner.lock().unwrap();
|
||||
if down {
|
||||
inner.console.keyboard.press(qnum).await?;
|
||||
} else {
|
||||
inner.console.keyboard.release(qnum).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn desktop_resize(&mut self) -> ResultType<()> {
|
||||
let (width, height) = self.server.dimensions();
|
||||
if (width, height) == self.dimensions {
|
||||
return Ok(());
|
||||
}
|
||||
self.dimensions = (width, height);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_framebuffer_update(&mut self) -> ResultType<()> {
|
||||
self.desktop_resize()?;
|
||||
if self.has_update && self.req_update {
|
||||
if let Some(last_update) = self.last_update {
|
||||
if last_update.elapsed().as_millis() < 10 {
|
||||
println!("TODO: <10ms, could delay update..")
|
||||
}
|
||||
}
|
||||
// self.server.send_framebuffer_update(&self.vnc_server)?;
|
||||
self.last_update = Some(time::Instant::now());
|
||||
self.has_update = false;
|
||||
self.req_update = false;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_event(&mut self, event: Option<Event>) -> ResultType<bool> {
|
||||
match event {
|
||||
Some(Event::ConsoleUpdate(_)) => {
|
||||
self.has_update = true;
|
||||
}
|
||||
Some(Event::Disconnected) => {
|
||||
return Ok(false);
|
||||
}
|
||||
None => {
|
||||
self.send_framebuffer_update()?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ConsoleListener {
|
||||
server: Server,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl ConsoleListenerHandler for ConsoleListener {
|
||||
async fn scanout(&mut self, s: qemu_display::Scanout) {
|
||||
let mut inner = self.server.inner.lock().unwrap();
|
||||
inner.image = image_from_vec(s.format, s.width, s.height, s.stride, s.data);
|
||||
}
|
||||
|
||||
async fn update(&mut self, u: qemu_display::Update) {
|
||||
let mut inner = self.server.inner.lock().unwrap();
|
||||
let update = image_from_vec(u.format, u.w as _, u.h as _, u.stride, u.data);
|
||||
if (u.x, u.y) == (0, 0) && update.dimensions() == inner.image.dimensions() {
|
||||
inner.image = update;
|
||||
} else {
|
||||
inner.image.copy_from(&update, u.x as _, u.y as _).unwrap();
|
||||
}
|
||||
inner
|
||||
.tx
|
||||
.send(Event::ConsoleUpdate((u.x, u.y, u.w, u.h)))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
async fn scanout_dmabuf(&mut self, _scanout: qemu_display::ScanoutDMABUF) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn update_dmabuf(&mut self, _update: qemu_display::UpdateDMABUF) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
async fn mouse_set(&mut self, set: qemu_display::MouseSet) {
|
||||
dbg!(set);
|
||||
}
|
||||
|
||||
async fn cursor_define(&mut self, cursor: qemu_display::Cursor) {
|
||||
dbg!(cursor);
|
||||
}
|
||||
|
||||
fn disconnected(&mut self) {
|
||||
dbg!();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ServerInner {
|
||||
console: Console,
|
||||
image: BgraImage,
|
||||
tx: mpsc::Sender<Event>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Server {
|
||||
vm_name: String,
|
||||
rx: Arc<Mutex<mpsc::Receiver<Event>>>,
|
||||
inner: Arc<Mutex<ServerInner>>,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
async fn new(vm_name: String, console: Console) -> ResultType<Server> {
|
||||
let width = console.width().await?;
|
||||
let height = console.height().await?;
|
||||
let image = BgraImage::new(width as _, height as _);
|
||||
let (tx, rx) = mpsc::channel();
|
||||
Ok(Self {
|
||||
vm_name,
|
||||
rx: Arc::new(Mutex::new(rx)),
|
||||
inner: Arc::new(Mutex::new(ServerInner { console, image, tx })),
|
||||
})
|
||||
}
|
||||
|
||||
fn stop_console(&self) -> ResultType<()> {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
inner.console.unregister_listener();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run_console(&self) -> ResultType<()> {
|
||||
let inner = self.inner.lock().unwrap();
|
||||
inner
|
||||
.console
|
||||
.register_listener(ConsoleListener {
|
||||
server: self.clone(),
|
||||
})
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn dimensions(&self) -> (u16, u16) {
|
||||
let inner = self.inner.lock().unwrap();
|
||||
(inner.image.width() as u16, inner.image.height() as u16)
|
||||
}
|
||||
|
||||
async fn handle_connection(&self, stream: TcpStream) -> ResultType<()> {
|
||||
let (width, height) = self.dimensions();
|
||||
|
||||
let tx = self.inner.lock().unwrap().tx.clone();
|
||||
let _client_thread = thread::spawn(move || loop {});
|
||||
|
||||
self.run_console().await?;
|
||||
let rx = self.rx.lock().unwrap();
|
||||
self.stop_console()?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn button_mask_to_set(mask: u8) -> HashSet<MouseButton> {
|
||||
let mut set = HashSet::new();
|
||||
if mask & 0b0000_0001 != 0 {
|
||||
set.insert(MouseButton::Left);
|
||||
}
|
||||
if mask & 0b0000_0010 != 0 {
|
||||
set.insert(MouseButton::Middle);
|
||||
}
|
||||
if mask & 0b0000_0100 != 0 {
|
||||
set.insert(MouseButton::Right);
|
||||
}
|
||||
if mask & 0b0000_1000 != 0 {
|
||||
set.insert(MouseButton::WheelUp);
|
||||
}
|
||||
if mask & 0b0001_0000 != 0 {
|
||||
set.insert(MouseButton::WheelDown);
|
||||
}
|
||||
set
|
||||
}
|
||||
|
||||
fn image_from_vec(format: u32, width: u32, height: u32, stride: u32, data: Vec<u8>) -> BgraImage {
|
||||
if format != PIXMAN_X8R8G8B8 {
|
||||
todo!("unhandled pixman format: {}", format)
|
||||
}
|
||||
if cfg!(target_endian = "big") {
|
||||
todo!("pixman/image in big endian")
|
||||
}
|
||||
let layout = image::flat::SampleLayout {
|
||||
channels: 4,
|
||||
channel_stride: 1,
|
||||
width,
|
||||
width_stride: 4,
|
||||
height,
|
||||
height_stride: stride as _,
|
||||
};
|
||||
let samples = image::flat::FlatSamples {
|
||||
samples: data,
|
||||
layout,
|
||||
color_hint: None,
|
||||
};
|
||||
samples
|
||||
.try_into_buffer::<image::Rgba<u8>>()
|
||||
.or_else::<&str, _>(|(_err, samples)| {
|
||||
let view = samples.as_view::<image::Rgba<u8>>().unwrap();
|
||||
let mut img = BgraImage::new(width, height);
|
||||
img.copy_from(&view, 0, 0).unwrap();
|
||||
Ok(img)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn run() -> ResultType<()> {
|
||||
let args = Cli::parse();
|
||||
|
||||
let listener = TcpListener::bind::<std::net::SocketAddr>(args.address.into()).unwrap();
|
||||
let dbus = if let Some(addr) = args.dbus_address {
|
||||
zbus::ConnectionBuilder::address(addr.borrow())?
|
||||
.build()
|
||||
.await
|
||||
} else {
|
||||
zbus::Connection::session().await
|
||||
}
|
||||
.context("Failed to connect to DBus")?;
|
||||
|
||||
let vm_name = VMProxy::new(&dbus).await?.name().await?;
|
||||
|
||||
let console = Console::new(&dbus.into(), 0)
|
||||
.await
|
||||
.context("Failed to get the console")?;
|
||||
let server = Server::new(format!("qemu-rustdesk ({})", vm_name), console).await?;
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
tokio::spawn(async {
|
||||
/*
|
||||
if let Err(err) = server.handle_connection(stream).await {
|
||||
log::error!("Connection closed: {err}");
|
||||
}
|
||||
*/
|
||||
});
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("Failed to accept connection: {}", err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user