#![allow(unused_crate_dependencies)]
use anyhow::Context as _;
use ironrdp::client::rdp::{RdpClient, RdpOutputEvent};
use ironrdp_viewer::app::App;
use ironrdp_viewer::cli::ViewerConfig;
use tokio::runtime;
use tokio::sync::mpsc;
use tracing::debug;
use winit::dpi::PhysicalSize;
use winit::event_loop::EventLoop;
fn main() -> anyhow::Result<()> {
let cli = ViewerConfig::parse_args().context("CLI arguments parsing")?;
setup_logging(cli.log_file()).context("unable to initialize logging")?;
let dump_rdp = cli.dump_rdp().map(ToOwned::to_owned);
let config = cli.into_config().context("configuration")?;
if let Some(dump_path) = dump_rdp {
let content = ironrdp_rdpfile::write(config.properties());
std::fs::write(&dump_path, &content).with_context(|| format!("failed to write {}", dump_path.display()))?;
return Ok(());
}
debug!("Initialize App");
let event_loop = EventLoop::<RdpOutputEvent>::with_user_event().build()?;
let event_loop_proxy = event_loop.create_proxy();
let (output_event_sender, mut output_event_receiver) = mpsc::channel::<RdpOutputEvent>(64);
let initial_window_size = PhysicalSize::new(
u32::from(config.connector().desktop_size.width),
u32::from(config.connector().desktop_size.height),
);
let client = RdpClient::new(config, output_event_sender);
let input_event_sender = client.input_sender();
let mut app =
App::new(&event_loop, &input_event_sender, initial_window_size).context("unable to initialize App")?;
let rt = runtime::Builder::new_multi_thread()
.enable_all()
.build()
.context("unable to create tokio runtime")?;
rt.spawn(async move {
while let Some(event) = output_event_receiver.recv().await {
if event_loop_proxy.send_event(event).is_err() {
break;
}
}
});
debug!("Start RDP thread");
std::thread::spawn(move || {
rt.block_on(client.run());
});
debug!("Run App");
event_loop.run_app(&mut app)?;
Ok(())
}
fn setup_logging(log_file: Option<&str>) -> anyhow::Result<()> {
use std::fs::OpenOptions;
use tracing::metadata::LevelFilter;
use tracing_subscriber::EnvFilter;
use tracing_subscriber::prelude::*;
let env_filter = EnvFilter::builder()
.with_default_directive(LevelFilter::WARN.into())
.with_env_var("IRONRDP_LOG")
.from_env_lossy();
if let Some(log_file) = log_file {
let file = OpenOptions::new()
.create(true)
.append(true)
.open(log_file)
.with_context(|| format!("couldn't open {log_file}"))?;
let fmt_layer = tracing_subscriber::fmt::layer()
.with_ansi(false)
.with_writer(file)
.compact();
tracing_subscriber::registry()
.with(env_filter)
.with(fmt_layer)
.try_init()
.context("failed to set tracing global subscriber")?;
} else {
let fmt_layer = tracing_subscriber::fmt::layer()
.compact()
.with_file(true)
.with_line_number(true)
.with_thread_ids(true)
.with_target(false);
tracing_subscriber::registry()
.with(env_filter)
.with(fmt_layer)
.try_init()
.context("failed to set tracing global subscriber")?;
};
Ok(())
}