use crate::config::{GuestOs, Result, VmProfile};
use crate::ssh::VmSession;
pub fn click(session: &mut VmSession, profile: &VmProfile, x: u32, y: u32) -> Result<()> {
match profile.os {
GuestOs::Linux | GuestOs::MacOS => click_linux(session, x, y),
GuestOs::Windows => click_windows(session, x, y),
}
}
pub fn r#type(session: &mut VmSession, profile: &VmProfile, text: &str) -> Result<()> {
match profile.os {
GuestOs::Linux | GuestOs::MacOS => type_linux(session, text),
GuestOs::Windows => type_windows(session, text),
}
}
fn click_linux(session: &mut VmSession, x: u32, y: u32) -> Result<()> {
crate::ssh::exec(
session,
&format!("DISPLAY=:99 xdotool mousemove {x} {y} click 1"),
)?;
Ok(())
}
fn click_windows(session: &mut VmSession, x: u32, y: u32) -> Result<()> {
let script = format!(
r#"
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Cursor]::Position = [System.Drawing.Point]::new({x}, {y})
Start-Sleep -Milliseconds 100
[System.Windows.Forms.SendKeys]::SendWait("{{LeftButton}}")
"#
);
crate::ssh::exec(session, &script)?;
Ok(())
}
fn type_linux(session: &mut VmSession, text: &str) -> Result<()> {
let escaped = text.replace("\\", "\\\\").replace("'", "\\'");
crate::ssh::exec(
session,
&format!("DISPLAY=:99 xdotool type --delay 50 '{escaped}'"),
)?;
Ok(())
}
fn type_windows(session: &mut VmSession, text: &str) -> Result<()> {
let escaped = text
.replace("+", "{{+}}")
.replace("^", "{{^}}")
.replace("%", "{{%}}")
.replace("~", "{{~}}");
let script = format!(
r#"
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait('{escaped}')
"#
);
crate::ssh::exec(session, &script)?;
Ok(())
}