Skip to content

Commit

Permalink
refactor(client): drop GuiContext, use App directly
Browse files Browse the repository at this point in the history
Signed-off-by: Marc-André Lureau <[email protected]>
  • Loading branch information
elmarco committed Aug 6, 2024
1 parent dc10c81 commit 7745e2c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,16 @@ use tokio::sync::mpsc;
use winit::application::ApplicationHandler;
use winit::dpi::LogicalPosition;
use winit::event::{self, WindowEvent};
use winit::event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy};
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::keyboard::ModifiersKeyState;
use winit::platform::scancode::PhysicalKeyExtScancode;
use winit::window::{Window, WindowAttributes};

use crate::rdp::{RdpInputEvent, RdpOutputEvent};

pub struct GuiContext {
event_loop: EventLoop<RdpOutputEvent>,
context: softbuffer::Context<DisplayHandle<'static>>,
}

impl GuiContext {
pub fn init() -> anyhow::Result<Self> {
let event_loop = EventLoop::<RdpOutputEvent>::with_user_event().build()?;

// SAFETY: we drop the context right before the event loop is stopped, thus making it safe.
let context = softbuffer::Context::new(unsafe {
std::mem::transmute::<DisplayHandle<'_>, DisplayHandle<'static>>(event_loop.display_handle().unwrap())
})
.map_err(|e| anyhow::Error::msg(format!("unable to initialize softbuffer context: {e}")))?;

Ok(Self { event_loop, context })
}

pub fn create_event_proxy(&self) -> EventLoopProxy<RdpOutputEvent> {
self.event_loop.create_proxy()
}

pub fn run(self, input_event_sender: mpsc::UnboundedSender<RdpInputEvent>) -> anyhow::Result<()> {
let Self { event_loop, context } = self;

let mut app = App::new(input_event_sender, context);
event_loop.run_app(&mut app)?;
Ok(())
}
}

type WindowSurface = (Arc<Window>, softbuffer::Surface<DisplayHandle<'static>, Arc<Window>>);

struct App {
pub struct App {
input_event_sender: mpsc::UnboundedSender<RdpInputEvent>,
context: softbuffer::Context<DisplayHandle<'static>>,
window: Option<WindowSurface>,
Expand All @@ -57,18 +26,24 @@ struct App {
}

impl App {
fn new(
input_event_sender: mpsc::UnboundedSender<RdpInputEvent>,
context: softbuffer::Context<DisplayHandle<'static>>,
) -> Self {
pub fn new(
event_loop: &EventLoop<RdpOutputEvent>,
input_event_sender: &mpsc::UnboundedSender<RdpInputEvent>,
) -> anyhow::Result<Self> {
// SAFETY: we drop the context right before the event loop is stopped, thus making it safe.
let context = softbuffer::Context::new(unsafe {
std::mem::transmute::<DisplayHandle<'_>, DisplayHandle<'static>>(event_loop.display_handle().unwrap())
})
.map_err(|e| anyhow::Error::msg(format!("unable to initialize softbuffer context: {e}")))?;

let input_database = ironrdp::input::Database::new();
Self {
input_event_sender,
Ok(Self {
input_event_sender: input_event_sender.clone(),
context,
window: None,
buffer_size: (0, 0),
input_database,
}
})
}
}

Expand Down Expand Up @@ -179,8 +154,8 @@ impl ApplicationHandler<RdpOutputEvent> for App {
}
WindowEvent::CursorMoved { position, .. } => {
let win_size = window.inner_size();
let x = (position.x / win_size.width as f64 * self.buffer_size.0 as f64) as _;
let y = (position.y / win_size.height as f64 * self.buffer_size.1 as f64) as _;
let x = (position.x / win_size.width as f64 * self.buffer_size.0 as f64) as u16;
let y = (position.y / win_size.height as f64 * self.buffer_size.1 as f64) as u16;
let operation = ironrdp::input::Operation::MouseMove(ironrdp::input::MousePosition { x, y });

let input_events = self.input_database.apply(std::iter::once(operation));
Expand Down
2 changes: 1 addition & 1 deletion crates/ironrdp-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#[macro_use]
extern crate tracing;

pub mod app;
pub mod clipboard;
pub mod config;
pub mod gui;
pub mod network_client;
pub mod rdp;
24 changes: 12 additions & 12 deletions crates/ironrdp-client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,33 @@
extern crate tracing;

use anyhow::Context as _;
use ironrdp_client::app::App;
use ironrdp_client::config::{ClipboardType, Config};
use ironrdp_client::gui::GuiContext;
use ironrdp_client::rdp::{RdpClient, RdpInputEvent};
use ironrdp_client::rdp::{RdpClient, RdpInputEvent, RdpOutputEvent};
use tokio::runtime;
use winit::event_loop::EventLoop;

fn main() -> anyhow::Result<()> {
let mut config = Config::parse_args().context("CLI arguments parsing")?;

setup_logging(config.log_file.as_deref()).context("unable to initialize logging")?;

debug!("Initialize GUI context");
let gui = GuiContext::init().context("unable to initialize GUI context")?;
debug!("GUI context initialized");
debug!("Initialize App");
let event_loop = EventLoop::<RdpOutputEvent>::with_user_event().build()?;
let event_loop_proxy = event_loop.create_proxy();
let (input_event_sender, input_event_receiver) = RdpInputEvent::create_channel();
let mut app = App::new(&event_loop, &input_event_sender).context("unable to initialize App")?;

let window_size = (1024, 768); // TODO: get window size from GUI
config.connector.desktop_scale_factor = 0; // TODO: should this be `(gui.window().scale_factor() * 100.0) as u32`?
config.connector.desktop_size.width = u16::try_from(window_size.0).unwrap();
config.connector.desktop_size.height = u16::try_from(window_size.1).unwrap();

let event_loop_proxy = gui.create_event_proxy();

let rt = runtime::Builder::new_multi_thread()
.enable_all()
.build()
.context("unable to create tokio runtime")?;

let (input_event_sender, input_event_receiver) = RdpInputEvent::create_channel();

// NOTE: we need to keep `win_clipboard` alive, otherwise it will be dropped before IronRDP
// starts and clipboard functionality will not be available.
#[cfg(windows)]
Expand All @@ -52,7 +51,7 @@ fn main() -> anyhow::Result<()> {

// SAFETY: provided window handle from `winit` is valid and is guaranteed to be alive
// while the gui window is still open.
let cliprdr = WinClipboard::new(ClientClipboardMessageProxy::new(input_event_sender.clone()))?;
let cliprdr = WinClipboard::new(ClientClipboardMessageProxy::new(input_event_sender))?;

let factory = cliprdr.backend_factory();
_win_clipboard = cliprdr;
Expand All @@ -73,8 +72,9 @@ fn main() -> anyhow::Result<()> {
rt.block_on(client.run());
});

debug!("Run GUI");
gui.run(input_event_sender)
debug!("Run App");
event_loop.run_app(&mut app)?;
Ok(())
}

fn setup_logging(log_file: Option<&str>) -> anyhow::Result<()> {
Expand Down

0 comments on commit 7745e2c

Please sign in to comment.